From 090320f1657a61d4a6a9f30ae581f860d90945db Mon Sep 17 00:00:00 2001 From: Bill Date: Thu, 12 Feb 2026 18:29:43 +0000 Subject: [PATCH] =?UTF-8?q?Steps=20278-283:=20Phase=2010d=20=E2=80=94=20sh?= =?UTF-8?q?ims,=20optimization,=20meta-programming=20&=20policy=20annotati?= =?UTF-8?q?ons=20(117/117=20tests)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Step 278: Shim/escape hatch — Intrinsic, Raw, CallingConv, Link, Shim, PointerArithmetic, Opaque (25 tests) - Step 279: Platform/provenance — Target, Feature, Original, Mapping (19 tests) - Step 280: Optimization completion — TailCall, Loop, Data, Align, Pack, BoundsCheck, Overflow (22 tests) - Step 281: Meta-programming — Meta, Symbol, Evaluate, Template, Synthetic (20 tests) - Step 282: Strategy/policy — Policy, Ambiguity, Candidate, Tradeoff, Choice, Decision (22 tests) - Step 283: Integration tests — FFI workflow, sidecar roundtrip, RPC, taxonomy completeness (9 tests) - 29 new annotation classes with JSON roundtrip, compact AST, sidecar persistence - All 58 semantic annotation types recognized across 8 subjects Co-Authored-By: Claude Opus 4.6 --- editor/CMakeLists.txt | 36 ++++ editor/src/CompactAST.h | 152 +++++++++++++ editor/src/HeadlessAgentRPCHandler.h | 34 +++ editor/src/SidecarPersistence.h | 36 +++- editor/src/ast/Annotation.h | 200 +++++++++++++++++ editor/src/ast/Serialization.h | 312 +++++++++++++++++++++++++++ editor/tests/step278_test.cpp | 145 +++++++++++++ editor/tests/step279_test.cpp | 127 +++++++++++ editor/tests/step280_test.cpp | 135 ++++++++++++ editor/tests/step281_test.cpp | 130 +++++++++++ editor/tests/step282_test.cpp | 144 +++++++++++++ editor/tests/step283_test.cpp | 266 +++++++++++++++++++++++ 12 files changed, 1716 insertions(+), 1 deletion(-) create mode 100644 editor/tests/step278_test.cpp create mode 100644 editor/tests/step279_test.cpp create mode 100644 editor/tests/step280_test.cpp create mode 100644 editor/tests/step281_test.cpp create mode 100644 editor/tests/step282_test.cpp create mode 100644 editor/tests/step283_test.cpp diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 1d4f9e6..adc9f00 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -1698,4 +1698,40 @@ target_link_libraries(step277_test PRIVATE tree_sitter_java tree_sitter_rust tree_sitter_go tree_sitter_org) +# Step 278: Shim & Escape Hatch Annotations +add_executable(step278_test tests/step278_test.cpp) +target_include_directories(step278_test PRIVATE src) +target_link_libraries(step278_test PRIVATE nlohmann_json::nlohmann_json) + +# Step 279: Platform & Provenance Annotations +add_executable(step279_test tests/step279_test.cpp) +target_include_directories(step279_test PRIVATE src) +target_link_libraries(step279_test PRIVATE nlohmann_json::nlohmann_json) + +# Step 280: Optimization Annotation Completion +add_executable(step280_test tests/step280_test.cpp) +target_include_directories(step280_test PRIVATE src) +target_link_libraries(step280_test PRIVATE nlohmann_json::nlohmann_json) + +# Step 281: Meta-Programming Annotations +add_executable(step281_test tests/step281_test.cpp) +target_include_directories(step281_test PRIVATE src) +target_link_libraries(step281_test PRIVATE nlohmann_json::nlohmann_json) + +# Step 282: Strategy & Policy Annotations +add_executable(step282_test tests/step282_test.cpp) +target_include_directories(step282_test PRIVATE src) +target_link_libraries(step282_test PRIVATE nlohmann_json::nlohmann_json) + +# Step 283: Phase 10d Integration Tests +add_executable(step283_test tests/step283_test.cpp) +target_include_directories(step283_test PRIVATE src) +target_link_libraries(step283_test PRIVATE + nlohmann_json::nlohmann_json + unofficial::tree-sitter::tree-sitter + tree_sitter_python tree_sitter_cpp tree_sitter_elisp + tree_sitter_javascript tree_sitter_typescript + tree_sitter_java tree_sitter_rust tree_sitter_go + tree_sitter_org) + # Step 12: Dear ImGui shell scaffolding created (main.cpp exists but not built due to dependencies) diff --git a/editor/src/CompactAST.h b/editor/src/CompactAST.h index 36b395f..e9a55c7 100644 --- a/editor/src/CompactAST.h +++ b/editor/src/CompactAST.h @@ -167,6 +167,158 @@ inline json extractSemanticSummary(const ASTNode* node) { auto* sa = static_cast(a); if (!sa->kind.empty()) sem["scope"] = sa->kind; } + // Shim & Escape Hatch (Step 278) + else if (a->conceptType == "IntrinsicAnnotation") { + auto* ia = static_cast(a); + json obj; + if (!ia->instruction.empty()) obj["instruction"] = ia->instruction; + if (!ia->arch.empty()) obj["arch"] = ia->arch; + if (!obj.empty()) sem["intrinsic"] = obj; + } + else if (a->conceptType == "RawAnnotation") { + auto* ra = static_cast(a); + json obj; + if (!ra->language.empty()) obj["language"] = ra->language; + if (!ra->code.empty()) obj["code"] = ra->code; + if (!obj.empty()) sem["raw"] = obj; + } + else if (a->conceptType == "CallingConvAnnotation") { + auto* cc = static_cast(a); + if (!cc->convention.empty()) sem["callingConv"] = cc->convention; + } + else if (a->conceptType == "LinkAnnotation") { + auto* la = static_cast(a); + json obj; + if (!la->symbolName.empty()) obj["symbol"] = la->symbolName; + if (!la->library.empty()) obj["library"] = la->library; + if (!obj.empty()) sem["link"] = obj; + } + else if (a->conceptType == "ShimAnnotation") { + auto* sa = static_cast(a); + if (!sa->strategy.empty()) sem["shim"] = sa->strategy; + } + else if (a->conceptType == "PointerArithmeticAnnotation") { + sem["pointerArithmetic"] = true; + } + else if (a->conceptType == "OpaqueAnnotation") { + auto* oa = static_cast(a); + if (!oa->reason.empty()) sem["opaque"] = oa->reason; + } + // Platform & Provenance (Step 279) + else if (a->conceptType == "TargetAnnotation") { + auto* ta = static_cast(a); + json obj; + if (!ta->platform.empty()) obj["platform"] = ta->platform; + if (!ta->arch.empty()) obj["arch"] = ta->arch; + if (!obj.empty()) sem["target"] = obj; + } + else if (a->conceptType == "FeatureAnnotation") { + auto* fa = static_cast(a); + json obj; + if (!fa->flag.empty()) obj["flag"] = fa->flag; + obj["enabled"] = fa->enabled; + sem["feature"] = obj; + } + else if (a->conceptType == "OriginalAnnotation") { + auto* oa = static_cast(a); + json obj; + if (!oa->sourceLanguage.empty()) obj["lang"] = oa->sourceLanguage; + if (!oa->sourceCode.empty()) obj["hasSource"] = true; + if (!obj.empty()) sem["original"] = obj; + } + else if (a->conceptType == "MappingAnnotation") { + auto* ma = static_cast(a); + if (!ma->history.empty()) sem["mappingSteps"] = (int)ma->history.size(); + } + // Optimization Completion (Step 280) + else if (a->conceptType == "TailCallAnnotation") { + sem["tailCall"] = true; + } + else if (a->conceptType == "LoopAnnotation") { + auto* la = static_cast(a); + json obj; + if (!la->hint.empty()) obj["hint"] = la->hint; + if (la->factor > 0) obj["factor"] = la->factor; + if (!obj.empty()) sem["loop"] = obj; + } + else if (a->conceptType == "DataAnnotation") { + auto* da = static_cast(a); + if (!da->hint.empty()) sem["data"] = da->hint; + } + else if (a->conceptType == "AlignAnnotation") { + auto* aa = static_cast(a); + if (aa->bytes > 0) sem["align"] = aa->bytes; + } + else if (a->conceptType == "PackAnnotation") { + sem["pack"] = true; + } + else if (a->conceptType == "BoundsCheckAnnotation") { + auto* bc = static_cast(a); + sem["boundsCheck"] = bc->enabled; + } + else if (a->conceptType == "OverflowAnnotation") { + auto* oa = static_cast(a); + if (!oa->behavior.empty()) sem["overflow"] = oa->behavior; + } + // Meta-Programming (Step 281) + else if (a->conceptType == "MetaAnnotation") { + auto* ma = static_cast(a); + json obj; + if (!ma->state.empty()) obj["state"] = ma->state; + if (!ma->phase.empty()) obj["phase"] = ma->phase; + if (!obj.empty()) sem["meta"] = obj; + } + else if (a->conceptType == "SymbolAnnotation") { + auto* sa = static_cast(a); + if (!sa->mode.empty()) sem["symbol"] = sa->mode; + } + else if (a->conceptType == "EvaluateAnnotation") { + auto* ea = static_cast(a); + if (!ea->phase.empty()) sem["evaluate"] = ea->phase; + } + else if (a->conceptType == "TemplateAnnotation") { + auto* ta = static_cast(a); + if (!ta->specialization.empty()) sem["template"] = ta->specialization; + } + else if (a->conceptType == "SyntheticAnnotation") { + auto* sa = static_cast(a); + json obj; + if (!sa->generator.empty()) obj["generator"] = sa->generator; + obj["risk"] = sa->isStructuralRisk; + sem["synthetic"] = obj; + } + // Strategy & Policy (Step 282) + else if (a->conceptType == "PolicyAnnotation") { + auto* pa = static_cast(a); + json obj; + if (!pa->strictness.empty()) obj["strictness"] = pa->strictness; + if (!pa->perf.empty()) obj["perf"] = pa->perf; + if (!pa->style.empty()) obj["style"] = pa->style; + if (!obj.empty()) sem["policy"] = obj; + } + else if (a->conceptType == "AmbiguityAnnotation") { + auto* aa = static_cast(a); + if (!aa->intent.empty()) sem["ambiguity"] = aa->intent; + } + else if (a->conceptType == "CandidateAnnotation") { + auto* ca = static_cast(a); + if (!ca->inferredTypes.empty()) sem["candidates"] = ca->inferredTypes; + } + else if (a->conceptType == "TradeoffAnnotation") { + auto* ta = static_cast(a); + if (!ta->reason.empty()) sem["tradeoff"] = ta->reason; + } + else if (a->conceptType == "ChoiceAnnotation") { + auto* ca = static_cast(a); + if (!ca->choiceId.empty()) sem["choice"] = ca->choiceId; + } + else if (a->conceptType == "DecisionAnnotation") { + auto* da = static_cast(a); + json obj; + if (!da->choiceId.empty()) obj["choiceId"] = da->choiceId; + if (!da->selection.empty()) obj["selection"] = da->selection; + if (!obj.empty()) sem["decision"] = obj; + } } return sem.empty() ? json() : sem; } diff --git a/editor/src/HeadlessAgentRPCHandler.h b/editor/src/HeadlessAgentRPCHandler.h index ffab5de..34da2e0 100644 --- a/editor/src/HeadlessAgentRPCHandler.h +++ b/editor/src/HeadlessAgentRPCHandler.h @@ -1682,6 +1682,40 @@ inline json handleHeadlessAgentRequest(HeadlessEditorState& state, else if (type == "visibility") conceptType = "VisibilityAnnotation"; else if (type == "namespace") conceptType = "NamespaceAnnotation"; else if (type == "scope") conceptType = "ScopeAnnotation"; + // Shim & Escape Hatch (Step 278) + else if (type == "intrinsic") conceptType = "IntrinsicAnnotation"; + else if (type == "raw") conceptType = "RawAnnotation"; + else if (type == "callingConv") conceptType = "CallingConvAnnotation"; + else if (type == "link") conceptType = "LinkAnnotation"; + else if (type == "shim") conceptType = "ShimAnnotation"; + else if (type == "pointerArithmetic") conceptType = "PointerArithmeticAnnotation"; + else if (type == "opaque") conceptType = "OpaqueAnnotation"; + // Platform & Provenance (Step 279) + else if (type == "target") conceptType = "TargetAnnotation"; + else if (type == "feature") conceptType = "FeatureAnnotation"; + else if (type == "original") conceptType = "OriginalAnnotation"; + else if (type == "mapping") conceptType = "MappingAnnotation"; + // Optimization Completion (Step 280) + else if (type == "tailCall") conceptType = "TailCallAnnotation"; + else if (type == "loop") conceptType = "LoopAnnotation"; + else if (type == "dataHint") conceptType = "DataAnnotation"; + else if (type == "align") conceptType = "AlignAnnotation"; + else if (type == "pack") conceptType = "PackAnnotation"; + else if (type == "boundsCheck") conceptType = "BoundsCheckAnnotation"; + else if (type == "overflow") conceptType = "OverflowAnnotation"; + // Meta-Programming (Step 281) + else if (type == "meta") conceptType = "MetaAnnotation"; + else if (type == "symbolMode") conceptType = "SymbolAnnotation"; + else if (type == "evaluate") conceptType = "EvaluateAnnotation"; + else if (type == "template") conceptType = "TemplateAnnotation"; + else if (type == "synthetic") conceptType = "SyntheticAnnotation"; + // Strategy & Policy (Step 282) + else if (type == "policy") conceptType = "PolicyAnnotation"; + else if (type == "ambiguity") conceptType = "AmbiguityAnnotation"; + else if (type == "candidate") conceptType = "CandidateAnnotation"; + else if (type == "tradeoff") conceptType = "TradeoffAnnotation"; + else if (type == "choice") conceptType = "ChoiceAnnotation"; + else if (type == "decision") conceptType = "DecisionAnnotation"; else return headlessRpcError(id, -32602, "Unknown annotation type: " + type); // Remove existing annotation of same type (update semantics) diff --git a/editor/src/SidecarPersistence.h b/editor/src/SidecarPersistence.h index 9650c31..90ceb44 100644 --- a/editor/src/SidecarPersistence.h +++ b/editor/src/SidecarPersistence.h @@ -57,7 +57,41 @@ inline bool isSemanticAnnotation(const std::string& conceptType) { conceptType == "CaptureAnnotation" || conceptType == "VisibilityAnnotation" || conceptType == "NamespaceAnnotation" || - conceptType == "ScopeAnnotation"; + conceptType == "ScopeAnnotation" || + // Shim & Escape Hatch (Step 278) + conceptType == "IntrinsicAnnotation" || + conceptType == "RawAnnotation" || + conceptType == "CallingConvAnnotation" || + conceptType == "LinkAnnotation" || + conceptType == "ShimAnnotation" || + conceptType == "PointerArithmeticAnnotation" || + conceptType == "OpaqueAnnotation" || + // Platform & Provenance (Step 279) + conceptType == "TargetAnnotation" || + conceptType == "FeatureAnnotation" || + conceptType == "OriginalAnnotation" || + conceptType == "MappingAnnotation" || + // Optimization Completion (Step 280) + conceptType == "TailCallAnnotation" || + conceptType == "LoopAnnotation" || + conceptType == "DataAnnotation" || + conceptType == "AlignAnnotation" || + conceptType == "PackAnnotation" || + conceptType == "BoundsCheckAnnotation" || + conceptType == "OverflowAnnotation" || + // Meta-Programming (Step 281) + conceptType == "MetaAnnotation" || + conceptType == "SymbolAnnotation" || + conceptType == "EvaluateAnnotation" || + conceptType == "TemplateAnnotation" || + conceptType == "SyntheticAnnotation" || + // Strategy & Policy (Step 282) + conceptType == "PolicyAnnotation" || + conceptType == "AmbiguityAnnotation" || + conceptType == "CandidateAnnotation" || + conceptType == "TradeoffAnnotation" || + conceptType == "ChoiceAnnotation" || + conceptType == "DecisionAnnotation"; } // --- Count semantic annotations in an AST --- diff --git a/editor/src/ast/Annotation.h b/editor/src/ast/Annotation.h index b30fb49..9d20e2a 100644 --- a/editor/src/ast/Annotation.h +++ b/editor/src/ast/Annotation.h @@ -338,3 +338,203 @@ public: std::string kind; // "local" | "global_leaked" | "singleton" ScopeAnnotation() { conceptType = "ScopeAnnotation"; } }; + +// Shim & Escape Hatch Annotations (Step 278, Subject 5) + +class IntrinsicAnnotation : public Annotation { +public: + std::string instruction; // e.g. "_mm256_add_ps" + std::string arch; // e.g. "x86_avx2" + IntrinsicAnnotation() { conceptType = "IntrinsicAnnotation"; } +}; + +class RawAnnotation : public Annotation { +public: + std::string language; // target language + std::string code; // literal code fragment + RawAnnotation() { conceptType = "RawAnnotation"; } +}; + +class CallingConvAnnotation : public Annotation { +public: + std::string convention; // "stdcall" | "cdecl" | "fastcall" + CallingConvAnnotation() { conceptType = "CallingConvAnnotation"; } +}; + +class LinkAnnotation : public Annotation { +public: + std::string symbolName; + std::string library; + LinkAnnotation() { conceptType = "LinkAnnotation"; } +}; + +class ShimAnnotation : public Annotation { +public: + std::string strategy; // "vtable" | "trampoline" | "union_tag" | "cast" + ShimAnnotation() { conceptType = "ShimAnnotation"; } +}; + +class PointerArithmeticAnnotation : public Annotation { +public: + PointerArithmeticAnnotation() { conceptType = "PointerArithmeticAnnotation"; } +}; + +class OpaqueAnnotation : public Annotation { +public: + std::string reason; + OpaqueAnnotation() { conceptType = "OpaqueAnnotation"; } +}; + +// Platform & Provenance Annotations (Step 279, Subject 5) + +class TargetAnnotation : public Annotation { +public: + std::string platform; // e.g. "linux", "windows" + std::string arch; // e.g. "x86_64", "arm64" + TargetAnnotation() { conceptType = "TargetAnnotation"; } +}; + +class FeatureAnnotation : public Annotation { +public: + std::string flag; // e.g. "SSE4_2", "NEON" + bool enabled = true; + FeatureAnnotation() { conceptType = "FeatureAnnotation"; } +}; + +class OriginalAnnotation : public Annotation { +public: + std::string sourceCode; + std::string sourceLanguage; + OriginalAnnotation() { conceptType = "OriginalAnnotation"; } +}; + +class MappingAnnotation : public Annotation { +public: + std::vector history; // transformation steps applied + MappingAnnotation() { conceptType = "MappingAnnotation"; } +}; + +// Optimization Annotation Completion (Step 280, Subject 6) + +class TailCallAnnotation : public Annotation { +public: + TailCallAnnotation() { conceptType = "TailCallAnnotation"; } +}; + +class LoopAnnotation : public Annotation { +public: + std::string hint; // "unroll" | "vectorize" | "fuse" + int factor = 0; // optional unroll/vectorize factor + LoopAnnotation() { conceptType = "LoopAnnotation"; } +}; + +class DataAnnotation : public Annotation { +public: + std::string hint; // "prefetch" | "restrict" + DataAnnotation() { conceptType = "DataAnnotation"; } +}; + +class AlignAnnotation : public Annotation { +public: + int bytes = 0; + AlignAnnotation() { conceptType = "AlignAnnotation"; } +}; + +class PackAnnotation : public Annotation { +public: + PackAnnotation() { conceptType = "PackAnnotation"; } +}; + +class BoundsCheckAnnotation : public Annotation { +public: + bool enabled = true; + BoundsCheckAnnotation() { conceptType = "BoundsCheckAnnotation"; } +}; + +class OverflowAnnotation : public Annotation { +public: + std::string behavior; // "wrap" | "saturation" | "panic" + OverflowAnnotation() { conceptType = "OverflowAnnotation"; } +}; + +// Meta-Programming Annotations (Step 281, Subject 7) + +class MetaAnnotation : public Annotation { +public: + std::string state; // "quoted" | "unquoted" + std::string phase; // "compile" | "runtime" + MetaAnnotation() { conceptType = "MetaAnnotation"; } +}; + +class SymbolAnnotation : public Annotation { +public: + std::string mode; // "gensym" | "interned" + SymbolAnnotation() { conceptType = "SymbolAnnotation"; } +}; + +class EvaluateAnnotation : public Annotation { +public: + std::string phase; // "compile_time" | "runtime" + EvaluateAnnotation() { conceptType = "EvaluateAnnotation"; } +}; + +class TemplateAnnotation : public Annotation { +public: + std::string specialization; // "trait" | "monomorphize" | "erasure" + TemplateAnnotation() { conceptType = "TemplateAnnotation"; } +}; + +class SyntheticAnnotation : public Annotation { +public: + std::string generator; + bool isStructuralRisk = false; + SyntheticAnnotation() { conceptType = "SyntheticAnnotation"; } +}; + +// Strategy & Policy Annotations (Step 282, Subject 8) + +class PolicyAnnotation : public Annotation { +public: + std::string strictness; // "high" | "low" + std::string perf; // "critical" | "normal" + std::string style; // "idiomatic" | "literal" + bool binaryStable = false; + PolicyAnnotation() { conceptType = "PolicyAnnotation"; } +}; + +class AmbiguityAnnotation : public Annotation { +public: + std::string intent; + std::vector options; + AmbiguityAnnotation() { conceptType = "AmbiguityAnnotation"; } +}; + +class CandidateAnnotation : public Annotation { +public: + std::vector inferredTypes; + CandidateAnnotation() { conceptType = "CandidateAnnotation"; } +}; + +class TradeoffAnnotation : public Annotation { +public: + std::string reason; + std::string safetyCost; + std::string perfCost; + TradeoffAnnotation() { conceptType = "TradeoffAnnotation"; } +}; + +class ChoiceAnnotation : public Annotation { +public: + std::string choiceId; + std::vector options; + ChoiceAnnotation() { conceptType = "ChoiceAnnotation"; } +}; + +class DecisionAnnotation : public Annotation { +public: + std::string choiceId; + std::string selection; + std::string author; + std::string reason; + DecisionAnnotation() { conceptType = "DecisionAnnotation"; } +}; diff --git a/editor/src/ast/Serialization.h b/editor/src/ast/Serialization.h index 3e09869..4870387 100644 --- a/editor/src/ast/Serialization.h +++ b/editor/src/ast/Serialization.h @@ -264,6 +264,137 @@ inline json propertiesToJson(const ASTNode* node) { auto* n = static_cast(node); if (!n->kind.empty()) props["kind"] = n->kind; } + // Shim & Escape Hatch (Step 278) + else if (ct == "IntrinsicAnnotation") { + auto* n = static_cast(node); + if (!n->instruction.empty()) props["instruction"] = n->instruction; + if (!n->arch.empty()) props["arch"] = n->arch; + } + else if (ct == "RawAnnotation") { + auto* n = static_cast(node); + if (!n->language.empty()) props["language"] = n->language; + if (!n->code.empty()) props["code"] = n->code; + } + else if (ct == "CallingConvAnnotation") { + auto* n = static_cast(node); + if (!n->convention.empty()) props["convention"] = n->convention; + } + else if (ct == "LinkAnnotation") { + auto* n = static_cast(node); + if (!n->symbolName.empty()) props["symbolName"] = n->symbolName; + if (!n->library.empty()) props["library"] = n->library; + } + else if (ct == "ShimAnnotation") { + auto* n = static_cast(node); + if (!n->strategy.empty()) props["strategy"] = n->strategy; + } + // PointerArithmeticAnnotation — marker, no fields + else if (ct == "OpaqueAnnotation") { + auto* n = static_cast(node); + if (!n->reason.empty()) props["reason"] = n->reason; + } + // Platform & Provenance (Step 279) + else if (ct == "TargetAnnotation") { + auto* n = static_cast(node); + if (!n->platform.empty()) props["platform"] = n->platform; + if (!n->arch.empty()) props["arch"] = n->arch; + } + else if (ct == "FeatureAnnotation") { + auto* n = static_cast(node); + if (!n->flag.empty()) props["flag"] = n->flag; + props["enabled"] = n->enabled; + } + else if (ct == "OriginalAnnotation") { + auto* n = static_cast(node); + if (!n->sourceCode.empty()) props["sourceCode"] = n->sourceCode; + if (!n->sourceLanguage.empty()) props["sourceLanguage"] = n->sourceLanguage; + } + else if (ct == "MappingAnnotation") { + auto* n = static_cast(node); + if (!n->history.empty()) props["history"] = n->history; + } + // Optimization Completion (Step 280) + // TailCallAnnotation — marker, no fields + else if (ct == "LoopAnnotation") { + auto* n = static_cast(node); + if (!n->hint.empty()) props["hint"] = n->hint; + if (n->factor > 0) props["factor"] = n->factor; + } + else if (ct == "DataAnnotation") { + auto* n = static_cast(node); + if (!n->hint.empty()) props["hint"] = n->hint; + } + else if (ct == "AlignAnnotation") { + auto* n = static_cast(node); + props["bytes"] = n->bytes; + } + // PackAnnotation — marker, no fields + else if (ct == "BoundsCheckAnnotation") { + auto* n = static_cast(node); + props["enabled"] = n->enabled; + } + else if (ct == "OverflowAnnotation") { + auto* n = static_cast(node); + if (!n->behavior.empty()) props["behavior"] = n->behavior; + } + // Meta-Programming (Step 281) + else if (ct == "MetaAnnotation") { + auto* n = static_cast(node); + if (!n->state.empty()) props["state"] = n->state; + if (!n->phase.empty()) props["phase"] = n->phase; + } + else if (ct == "SymbolAnnotation") { + auto* n = static_cast(node); + if (!n->mode.empty()) props["mode"] = n->mode; + } + else if (ct == "EvaluateAnnotation") { + auto* n = static_cast(node); + if (!n->phase.empty()) props["phase"] = n->phase; + } + else if (ct == "TemplateAnnotation") { + auto* n = static_cast(node); + if (!n->specialization.empty()) props["specialization"] = n->specialization; + } + else if (ct == "SyntheticAnnotation") { + auto* n = static_cast(node); + if (!n->generator.empty()) props["generator"] = n->generator; + props["isStructuralRisk"] = n->isStructuralRisk; + } + // Strategy & Policy (Step 282) + else if (ct == "PolicyAnnotation") { + auto* n = static_cast(node); + if (!n->strictness.empty()) props["strictness"] = n->strictness; + if (!n->perf.empty()) props["perf"] = n->perf; + if (!n->style.empty()) props["style"] = n->style; + props["binaryStable"] = n->binaryStable; + } + else if (ct == "AmbiguityAnnotation") { + auto* n = static_cast(node); + if (!n->intent.empty()) props["intent"] = n->intent; + if (!n->options.empty()) props["options"] = n->options; + } + else if (ct == "CandidateAnnotation") { + auto* n = static_cast(node); + if (!n->inferredTypes.empty()) props["inferredTypes"] = n->inferredTypes; + } + else if (ct == "TradeoffAnnotation") { + auto* n = static_cast(node); + if (!n->reason.empty()) props["reason"] = n->reason; + if (!n->safetyCost.empty()) props["safetyCost"] = n->safetyCost; + if (!n->perfCost.empty()) props["perfCost"] = n->perfCost; + } + else if (ct == "ChoiceAnnotation") { + auto* n = static_cast(node); + if (!n->choiceId.empty()) props["choiceId"] = n->choiceId; + if (!n->options.empty()) props["options"] = n->options; + } + else if (ct == "DecisionAnnotation") { + auto* n = static_cast(node); + if (!n->choiceId.empty()) props["choiceId"] = n->choiceId; + if (!n->selection.empty()) props["selection"] = n->selection; + if (!n->author.empty()) props["author"] = n->author; + if (!n->reason.empty()) props["reason"] = n->reason; + } // NullLiteral, ListLiteral, IndexAccess, Block, Assignment, IfStatement, // WhileLoop, Return, ExpressionStatement, ListType, SetType, MapType, // TupleType, ArrayType, OptionalType — no extra properties @@ -370,6 +501,40 @@ inline ASTNode* createNode(const std::string& conceptName) { if (conceptName == "VisibilityAnnotation") return new VisibilityAnnotation(); if (conceptName == "NamespaceAnnotation") return new NamespaceAnnotation(); if (conceptName == "ScopeAnnotation") return new ScopeAnnotation(); + // Shim & Escape Hatch (Step 278) + if (conceptName == "IntrinsicAnnotation") return new IntrinsicAnnotation(); + if (conceptName == "RawAnnotation") return new RawAnnotation(); + if (conceptName == "CallingConvAnnotation") return new CallingConvAnnotation(); + if (conceptName == "LinkAnnotation") return new LinkAnnotation(); + if (conceptName == "ShimAnnotation") return new ShimAnnotation(); + if (conceptName == "PointerArithmeticAnnotation") return new PointerArithmeticAnnotation(); + if (conceptName == "OpaqueAnnotation") return new OpaqueAnnotation(); + // Platform & Provenance (Step 279) + if (conceptName == "TargetAnnotation") return new TargetAnnotation(); + if (conceptName == "FeatureAnnotation") return new FeatureAnnotation(); + if (conceptName == "OriginalAnnotation") return new OriginalAnnotation(); + if (conceptName == "MappingAnnotation") return new MappingAnnotation(); + // Optimization Completion (Step 280) + if (conceptName == "TailCallAnnotation") return new TailCallAnnotation(); + if (conceptName == "LoopAnnotation") return new LoopAnnotation(); + if (conceptName == "DataAnnotation") return new DataAnnotation(); + if (conceptName == "AlignAnnotation") return new AlignAnnotation(); + if (conceptName == "PackAnnotation") return new PackAnnotation(); + if (conceptName == "BoundsCheckAnnotation") return new BoundsCheckAnnotation(); + if (conceptName == "OverflowAnnotation") return new OverflowAnnotation(); + // Meta-Programming (Step 281) + if (conceptName == "MetaAnnotation") return new MetaAnnotation(); + if (conceptName == "SymbolAnnotation") return new SymbolAnnotation(); + if (conceptName == "EvaluateAnnotation") return new EvaluateAnnotation(); + if (conceptName == "TemplateAnnotation") return new TemplateAnnotation(); + if (conceptName == "SyntheticAnnotation") return new SyntheticAnnotation(); + // Strategy & Policy (Step 282) + if (conceptName == "PolicyAnnotation") return new PolicyAnnotation(); + if (conceptName == "AmbiguityAnnotation") return new AmbiguityAnnotation(); + if (conceptName == "CandidateAnnotation") return new CandidateAnnotation(); + if (conceptName == "TradeoffAnnotation") return new TradeoffAnnotation(); + if (conceptName == "ChoiceAnnotation") return new ChoiceAnnotation(); + if (conceptName == "DecisionAnnotation") return new DecisionAnnotation(); return nullptr; } @@ -627,6 +792,153 @@ inline void setPropertiesFromJson(ASTNode* node, const json& props) { auto* n = static_cast(node); if (props.contains("kind")) n->kind = props["kind"].get(); } + // Shim & Escape Hatch (Step 278) + else if (ct == "IntrinsicAnnotation") { + auto* n = static_cast(node); + if (props.contains("instruction")) n->instruction = props["instruction"].get(); + if (props.contains("arch")) n->arch = props["arch"].get(); + } + else if (ct == "RawAnnotation") { + auto* n = static_cast(node); + if (props.contains("language")) n->language = props["language"].get(); + if (props.contains("code")) n->code = props["code"].get(); + } + else if (ct == "CallingConvAnnotation") { + auto* n = static_cast(node); + if (props.contains("convention")) n->convention = props["convention"].get(); + } + else if (ct == "LinkAnnotation") { + auto* n = static_cast(node); + if (props.contains("symbolName")) n->symbolName = props["symbolName"].get(); + if (props.contains("library")) n->library = props["library"].get(); + } + else if (ct == "ShimAnnotation") { + auto* n = static_cast(node); + if (props.contains("strategy")) n->strategy = props["strategy"].get(); + } + // PointerArithmeticAnnotation — no fields + else if (ct == "OpaqueAnnotation") { + auto* n = static_cast(node); + if (props.contains("reason")) n->reason = props["reason"].get(); + } + // Platform & Provenance (Step 279) + else if (ct == "TargetAnnotation") { + auto* n = static_cast(node); + if (props.contains("platform")) n->platform = props["platform"].get(); + if (props.contains("arch")) n->arch = props["arch"].get(); + } + else if (ct == "FeatureAnnotation") { + auto* n = static_cast(node); + if (props.contains("flag")) n->flag = props["flag"].get(); + if (props.contains("enabled")) n->enabled = props["enabled"].get(); + } + else if (ct == "OriginalAnnotation") { + auto* n = static_cast(node); + if (props.contains("sourceCode")) n->sourceCode = props["sourceCode"].get(); + if (props.contains("sourceLanguage")) n->sourceLanguage = props["sourceLanguage"].get(); + } + else if (ct == "MappingAnnotation") { + auto* n = static_cast(node); + if (props.contains("history") && props["history"].is_array()) { + n->history.clear(); + for (const auto& h : props["history"]) + if (h.is_string()) n->history.push_back(h.get()); + } + } + // Optimization Completion (Step 280) + // TailCallAnnotation — no fields + else if (ct == "LoopAnnotation") { + auto* n = static_cast(node); + if (props.contains("hint")) n->hint = props["hint"].get(); + if (props.contains("factor")) n->factor = props["factor"].get(); + } + else if (ct == "DataAnnotation") { + auto* n = static_cast(node); + if (props.contains("hint")) n->hint = props["hint"].get(); + } + else if (ct == "AlignAnnotation") { + auto* n = static_cast(node); + if (props.contains("bytes")) n->bytes = props["bytes"].get(); + } + // PackAnnotation — no fields + else if (ct == "BoundsCheckAnnotation") { + auto* n = static_cast(node); + if (props.contains("enabled")) n->enabled = props["enabled"].get(); + } + else if (ct == "OverflowAnnotation") { + auto* n = static_cast(node); + if (props.contains("behavior")) n->behavior = props["behavior"].get(); + } + // Meta-Programming (Step 281) + else if (ct == "MetaAnnotation") { + auto* n = static_cast(node); + if (props.contains("state")) n->state = props["state"].get(); + if (props.contains("phase")) n->phase = props["phase"].get(); + } + else if (ct == "SymbolAnnotation") { + auto* n = static_cast(node); + if (props.contains("mode")) n->mode = props["mode"].get(); + } + else if (ct == "EvaluateAnnotation") { + auto* n = static_cast(node); + if (props.contains("phase")) n->phase = props["phase"].get(); + } + else if (ct == "TemplateAnnotation") { + auto* n = static_cast(node); + if (props.contains("specialization")) n->specialization = props["specialization"].get(); + } + else if (ct == "SyntheticAnnotation") { + auto* n = static_cast(node); + if (props.contains("generator")) n->generator = props["generator"].get(); + if (props.contains("isStructuralRisk")) n->isStructuralRisk = props["isStructuralRisk"].get(); + } + // Strategy & Policy (Step 282) + else if (ct == "PolicyAnnotation") { + auto* n = static_cast(node); + if (props.contains("strictness")) n->strictness = props["strictness"].get(); + if (props.contains("perf")) n->perf = props["perf"].get(); + if (props.contains("style")) n->style = props["style"].get(); + if (props.contains("binaryStable")) n->binaryStable = props["binaryStable"].get(); + } + else if (ct == "AmbiguityAnnotation") { + auto* n = static_cast(node); + if (props.contains("intent")) n->intent = props["intent"].get(); + if (props.contains("options") && props["options"].is_array()) { + n->options.clear(); + for (const auto& o : props["options"]) + if (o.is_string()) n->options.push_back(o.get()); + } + } + else if (ct == "CandidateAnnotation") { + auto* n = static_cast(node); + if (props.contains("inferredTypes") && props["inferredTypes"].is_array()) { + n->inferredTypes.clear(); + for (const auto& t : props["inferredTypes"]) + if (t.is_string()) n->inferredTypes.push_back(t.get()); + } + } + else if (ct == "TradeoffAnnotation") { + auto* n = static_cast(node); + if (props.contains("reason")) n->reason = props["reason"].get(); + if (props.contains("safetyCost")) n->safetyCost = props["safetyCost"].get(); + if (props.contains("perfCost")) n->perfCost = props["perfCost"].get(); + } + else if (ct == "ChoiceAnnotation") { + auto* n = static_cast(node); + if (props.contains("choiceId")) n->choiceId = props["choiceId"].get(); + if (props.contains("options") && props["options"].is_array()) { + n->options.clear(); + for (const auto& o : props["options"]) + if (o.is_string()) n->options.push_back(o.get()); + } + } + else if (ct == "DecisionAnnotation") { + auto* n = static_cast(node); + if (props.contains("choiceId")) n->choiceId = props["choiceId"].get(); + if (props.contains("selection")) n->selection = props["selection"].get(); + if (props.contains("author")) n->author = props["author"].get(); + if (props.contains("reason")) n->reason = props["reason"].get(); + } } inline std::string generateNodeId() { diff --git a/editor/tests/step278_test.cpp b/editor/tests/step278_test.cpp new file mode 100644 index 0000000..2d5b072 --- /dev/null +++ b/editor/tests/step278_test.cpp @@ -0,0 +1,145 @@ +// Step 278: Shim & Escape Hatch Annotations (12 tests) +#include +#include +#include +#include "ast/ASTNode.h" +#include "ast/Module.h" +#include "ast/Function.h" +#include "ast/Annotation.h" +#include "ast/Serialization.h" +#include "ASTUtils.h" +#include "CompactAST.h" + +static int passed = 0, failed = 0; +static void check(bool c, const std::string& n) { + if (c) { std::cout << " PASS: " << n << "\n"; ++passed; } + else { std::cout << " FAIL: " << n << "\n"; ++failed; } +} + +static void test_intrinsic() { + IntrinsicAnnotation a; + check(a.conceptType == "IntrinsicAnnotation", "IntrinsicAnnotation conceptType"); + a.instruction = "_mm256_add_ps"; a.arch = "x86_avx2"; + check(a.instruction == "_mm256_add_ps" && a.arch == "x86_avx2", "fields set"); +} + +static void test_raw() { + RawAnnotation a; a.language = "c"; a.code = "asm volatile(\"nop\")"; + check(a.conceptType == "RawAnnotation", "RawAnnotation conceptType"); + check(a.language == "c" && a.code == "asm volatile(\"nop\")", "fields set"); +} + +static void test_callingconv_link_shim() { + CallingConvAnnotation cc; cc.convention = "stdcall"; + check(cc.convention == "stdcall", "CallingConvAnnotation field"); + LinkAnnotation la; la.symbolName = "printf"; la.library = "libc.so"; + check(la.symbolName == "printf" && la.library == "libc.so", "LinkAnnotation fields"); + ShimAnnotation sa; sa.strategy = "vtable"; + check(sa.strategy == "vtable", "ShimAnnotation field"); +} + +static void test_marker_and_opaque() { + PointerArithmeticAnnotation pa; + check(pa.conceptType == "PointerArithmeticAnnotation", "PointerArithmeticAnnotation conceptType"); + OpaqueAnnotation oa; oa.reason = "platform-specific ABI"; + check(oa.reason == "platform-specific ABI", "OpaqueAnnotation field"); +} + +static void test_intrinsic_roundtrip() { + auto* a = new IntrinsicAnnotation(); a->id = "i1"; + a->instruction = "_mm_mul_ps"; a->arch = "x86_sse"; + json j = toJson(a); + check(j["properties"]["instruction"] == "_mm_mul_ps", "JSON instruction"); + ASTNode* r = fromJson(j); + auto* ri = dynamic_cast(r); + check(ri && ri->instruction == "_mm_mul_ps" && ri->arch == "x86_sse", "roundtrip"); + delete a; delete r; +} + +static void test_link_roundtrip() { + auto* a = new LinkAnnotation(); a->id = "l1"; + a->symbolName = "malloc"; a->library = "libc"; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* rl = dynamic_cast(r); + check(rl && rl->symbolName == "malloc" && rl->library == "libc", "LinkAnnotation roundtrip"); + delete a; delete r; +} + +static void test_raw_roundtrip() { + auto* a = new RawAnnotation(); a->id = "r1"; + a->language = "cpp"; a->code = "__attribute__((packed))"; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* rr = dynamic_cast(r); + check(rr && rr->language == "cpp" && rr->code == "__attribute__((packed))", "RawAnnotation roundtrip"); + delete a; delete r; +} + +static void test_create_node_factory() { + std::vector types = { + "IntrinsicAnnotation", "RawAnnotation", "CallingConvAnnotation", + "LinkAnnotation", "ShimAnnotation", "PointerArithmeticAnnotation", + "OpaqueAnnotation" + }; + for (const auto& t : types) { + ASTNode* n = createNode(t); + check(n && n->conceptType == t, "createNode(" + t + ")"); + delete n; + } +} + +static void test_compact_ast_intrinsic() { + auto* f = new Function(); f->id = "f1"; f->name = "simd_add"; + auto* a = new IntrinsicAnnotation(); a->instruction = "_mm_add"; a->arch = "sse"; + f->addChild("annotations", a); + json sem = extractSemanticSummary(f); + check(sem.contains("intrinsic") && sem["intrinsic"]["instruction"] == "_mm_add", "intrinsic in compact AST"); + delete f; +} + +static void test_compact_ast_shim_pointer() { + auto* f = new Function(); f->id = "f2"; f->name = "ffi_bridge"; + auto* s = new ShimAnnotation(); s->strategy = "trampoline"; + auto* p = new PointerArithmeticAnnotation(); + f->addChild("annotations", s); f->addChild("annotations", p); + json sem = extractSemanticSummary(f); + check(sem["shim"] == "trampoline", "shim in compact AST"); + check(sem["pointerArithmetic"] == true, "pointerArithmetic in compact AST"); + delete f; +} + +static void test_all_shim_annotations() { + auto* f = new Function(); f->id = "f3"; f->name = "fullShim"; + f->addChild("annotations", [&]{ auto* a = new IntrinsicAnnotation(); a->instruction="x"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new RawAnnotation(); a->code="x"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new CallingConvAnnotation(); a->convention="cdecl"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new LinkAnnotation(); a->symbolName="x"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new ShimAnnotation(); a->strategy="cast"; return a; }()); + f->addChild("annotations", new PointerArithmeticAnnotation()); + f->addChild("annotations", [&]{ auto* a = new OpaqueAnnotation(); a->reason="x"; return a; }()); + json sem = extractSemanticSummary(f); + check(sem.contains("intrinsic") && sem.contains("raw") && + sem.contains("callingConv") && sem.contains("link") && + sem.contains("shim") && sem.contains("pointerArithmetic") && + sem.contains("opaque"), "all 7 shim annotations in summary"); + delete f; +} + +static void test_callingconv_roundtrip() { + auto* a = new CallingConvAnnotation(); a->id="cc1"; a->convention="fastcall"; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* rc = dynamic_cast(r); + check(rc && rc->convention == "fastcall", "CallingConvAnnotation roundtrip"); + delete a; delete r; +} + +int main() { + std::cout << "=== Step 278: Shim & Escape Hatch Annotations ===\n"; + test_intrinsic(); test_raw(); test_callingconv_link_shim(); + test_marker_and_opaque(); test_intrinsic_roundtrip(); + test_link_roundtrip(); test_raw_roundtrip(); + test_create_node_factory(); test_compact_ast_intrinsic(); + test_compact_ast_shim_pointer(); test_all_shim_annotations(); + test_callingconv_roundtrip(); + std::cout << "\nResults: " << passed << "/" << (passed+failed) << "\n"; + return failed > 0 ? 1 : 0; +} diff --git a/editor/tests/step279_test.cpp b/editor/tests/step279_test.cpp new file mode 100644 index 0000000..525c59f --- /dev/null +++ b/editor/tests/step279_test.cpp @@ -0,0 +1,127 @@ +// Step 279: Platform & Provenance Annotations (12 tests) +#include +#include +#include +#include "ast/ASTNode.h" +#include "ast/Module.h" +#include "ast/Function.h" +#include "ast/Annotation.h" +#include "ast/Serialization.h" +#include "ASTUtils.h" +#include "CompactAST.h" + +static int passed = 0, failed = 0; +static void check(bool c, const std::string& n) { + if (c) { std::cout << " PASS: " << n << "\n"; ++passed; } + else { std::cout << " FAIL: " << n << "\n"; ++failed; } +} + +static void test_target() { + TargetAnnotation a; a.platform = "linux"; a.arch = "x86_64"; + check(a.conceptType == "TargetAnnotation", "conceptType"); + check(a.platform == "linux" && a.arch == "x86_64", "fields"); +} + +static void test_feature() { + FeatureAnnotation a; a.flag = "SSE4_2"; a.enabled = true; + check(a.conceptType == "FeatureAnnotation", "conceptType"); + check(a.flag == "SSE4_2" && a.enabled, "fields"); +} + +static void test_original() { + OriginalAnnotation a; a.sourceCode = "def foo(): pass"; a.sourceLanguage = "python"; + check(a.conceptType == "OriginalAnnotation", "conceptType"); + check(a.sourceCode == "def foo(): pass" && a.sourceLanguage == "python", "fields"); +} + +static void test_mapping() { + MappingAnnotation a; a.history = {"python→whetstone", "whetstone→cpp"}; + check(a.conceptType == "MappingAnnotation", "conceptType"); + check(a.history.size() == 2, "history has 2 entries"); +} + +static void test_target_roundtrip() { + auto* a = new TargetAnnotation(); a->id = "t1"; a->platform = "windows"; a->arch = "arm64"; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* rt = dynamic_cast(r); + check(rt && rt->platform == "windows" && rt->arch == "arm64", "TargetAnnotation roundtrip"); + delete a; delete r; +} + +static void test_feature_roundtrip() { + auto* a = new FeatureAnnotation(); a->id = "f1"; a->flag = "NEON"; a->enabled = false; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* rf = dynamic_cast(r); + check(rf && rf->flag == "NEON" && !rf->enabled, "FeatureAnnotation roundtrip"); + delete a; delete r; +} + +static void test_original_roundtrip() { + auto* a = new OriginalAnnotation(); a->id = "o1"; + a->sourceCode = "print('hello')"; a->sourceLanguage = "python"; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* ro = dynamic_cast(r); + check(ro && ro->sourceCode == "print('hello')" && ro->sourceLanguage == "python", + "OriginalAnnotation roundtrip"); + delete a; delete r; +} + +static void test_mapping_roundtrip() { + auto* a = new MappingAnnotation(); a->id = "m1"; + a->history = {"step1", "step2", "step3"}; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* rm = dynamic_cast(r); + check(rm && rm->history.size() == 3 && rm->history[2] == "step3", "MappingAnnotation roundtrip"); + delete a; delete r; +} + +static void test_create_node_factory() { + for (const auto& t : {"TargetAnnotation", "FeatureAnnotation", + "OriginalAnnotation", "MappingAnnotation"}) { + ASTNode* n = createNode(t); + check(n && n->conceptType == t, std::string("createNode(") + t + ")"); + delete n; + } +} + +static void test_compact_ast_target() { + auto* f = new Function(); f->id = "f1"; f->name = "platform_init"; + auto* a = new TargetAnnotation(); a->platform = "linux"; a->arch = "x86_64"; + f->addChild("annotations", a); + json sem = extractSemanticSummary(f); + check(sem.contains("target") && sem["target"]["platform"] == "linux", "target in compact AST"); + delete f; +} + +static void test_compact_ast_original() { + auto* f = new Function(); f->id = "f2"; f->name = "legacy"; + auto* a = new OriginalAnnotation(); a->sourceCode = "x"; a->sourceLanguage = "java"; + f->addChild("annotations", a); + json sem = extractSemanticSummary(f); + check(sem.contains("original") && sem["original"]["lang"] == "java", "original in compact AST"); + delete f; +} + +static void test_all_provenance_annotations() { + auto* f = new Function(); f->id = "f3"; f->name = "full"; + f->addChild("annotations", [&]{ auto* a = new TargetAnnotation(); a->platform="x"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new FeatureAnnotation(); a->flag="x"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new OriginalAnnotation(); a->sourceCode="x"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new MappingAnnotation(); a->history={"x"}; return a; }()); + json sem = extractSemanticSummary(f); + check(sem.contains("target") && sem.contains("feature") && + sem.contains("original") && sem.contains("mappingSteps"), + "all 4 provenance annotations in summary"); + delete f; +} + +int main() { + std::cout << "=== Step 279: Platform & Provenance Annotations ===\n"; + test_target(); test_feature(); test_original(); test_mapping(); + test_target_roundtrip(); test_feature_roundtrip(); + test_original_roundtrip(); test_mapping_roundtrip(); + test_create_node_factory(); test_compact_ast_target(); + test_compact_ast_original(); test_all_provenance_annotations(); + std::cout << "\nResults: " << passed << "/" << (passed+failed) << "\n"; + return failed > 0 ? 1 : 0; +} diff --git a/editor/tests/step280_test.cpp b/editor/tests/step280_test.cpp new file mode 100644 index 0000000..bb0cf2b --- /dev/null +++ b/editor/tests/step280_test.cpp @@ -0,0 +1,135 @@ +// Step 280: Optimization Annotation Completion (12 tests) +#include +#include +#include +#include "ast/ASTNode.h" +#include "ast/Module.h" +#include "ast/Function.h" +#include "ast/Annotation.h" +#include "ast/Serialization.h" +#include "ASTUtils.h" +#include "CompactAST.h" + +static int passed = 0, failed = 0; +static void check(bool c, const std::string& n) { + if (c) { std::cout << " PASS: " << n << "\n"; ++passed; } + else { std::cout << " FAIL: " << n << "\n"; ++failed; } +} + +static void test_tailcall() { + TailCallAnnotation a; + check(a.conceptType == "TailCallAnnotation", "TailCallAnnotation conceptType"); +} + +static void test_loop() { + LoopAnnotation a; a.hint = "unroll"; a.factor = 4; + check(a.conceptType == "LoopAnnotation", "LoopAnnotation conceptType"); + check(a.hint == "unroll" && a.factor == 4, "fields"); +} + +static void test_data_align() { + DataAnnotation d; d.hint = "prefetch"; + check(d.hint == "prefetch", "DataAnnotation hint"); + AlignAnnotation a; a.bytes = 64; + check(a.bytes == 64, "AlignAnnotation bytes"); +} + +static void test_pack_bounds_overflow() { + PackAnnotation p; + check(p.conceptType == "PackAnnotation", "PackAnnotation conceptType"); + BoundsCheckAnnotation b; b.enabled = false; + check(!b.enabled, "BoundsCheckAnnotation enabled=false"); + OverflowAnnotation o; o.behavior = "wrap"; + check(o.behavior == "wrap", "OverflowAnnotation behavior"); +} + +static void test_loop_roundtrip() { + auto* a = new LoopAnnotation(); a->id = "l1"; a->hint = "vectorize"; a->factor = 8; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* rl = dynamic_cast(r); + check(rl && rl->hint == "vectorize" && rl->factor == 8, "LoopAnnotation roundtrip"); + delete a; delete r; +} + +static void test_align_roundtrip() { + auto* a = new AlignAnnotation(); a->id = "a1"; a->bytes = 32; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* ra = dynamic_cast(r); + check(ra && ra->bytes == 32, "AlignAnnotation roundtrip"); + delete a; delete r; +} + +static void test_overflow_roundtrip() { + auto* a = new OverflowAnnotation(); a->id = "o1"; a->behavior = "saturation"; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* ro = dynamic_cast(r); + check(ro && ro->behavior == "saturation", "OverflowAnnotation roundtrip"); + delete a; delete r; +} + +static void test_create_node_factory() { + for (const auto& t : {"TailCallAnnotation", "LoopAnnotation", "DataAnnotation", + "AlignAnnotation", "PackAnnotation", + "BoundsCheckAnnotation", "OverflowAnnotation"}) { + ASTNode* n = createNode(t); + check(n && n->conceptType == t, std::string("createNode(") + t + ")"); + delete n; + } +} + +static void test_compact_ast_loop() { + auto* f = new Function(); f->id = "f1"; f->name = "vectorOp"; + auto* a = new LoopAnnotation(); a->hint = "vectorize"; a->factor = 4; + f->addChild("annotations", a); + json sem = extractSemanticSummary(f); + check(sem.contains("loop") && sem["loop"]["hint"] == "vectorize", "loop in compact AST"); + delete f; +} + +static void test_compact_ast_markers() { + auto* f = new Function(); f->id = "f2"; f->name = "recursive"; + f->addChild("annotations", new TailCallAnnotation()); + f->addChild("annotations", new PackAnnotation()); + json sem = extractSemanticSummary(f); + check(sem["tailCall"] == true && sem["pack"] == true, "markers in compact AST"); + delete f; +} + +static void test_compact_ast_safety() { + auto* f = new Function(); f->id = "f3"; f->name = "unsafeOp"; + auto* b = new BoundsCheckAnnotation(); b->enabled = false; + auto* o = new OverflowAnnotation(); o->behavior = "panic"; + f->addChild("annotations", b); f->addChild("annotations", o); + json sem = extractSemanticSummary(f); + check(sem["boundsCheck"] == false && sem["overflow"] == "panic", "safety annotations"); + delete f; +} + +static void test_all_optimization_annotations() { + auto* f = new Function(); f->id = "f4"; f->name = "full"; + f->addChild("annotations", new TailCallAnnotation()); + f->addChild("annotations", [&]{ auto* a = new LoopAnnotation(); a->hint="fuse"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new DataAnnotation(); a->hint="restrict"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new AlignAnnotation(); a->bytes=16; return a; }()); + f->addChild("annotations", new PackAnnotation()); + f->addChild("annotations", [&]{ auto* a = new BoundsCheckAnnotation(); a->enabled=true; return a; }()); + f->addChild("annotations", [&]{ auto* a = new OverflowAnnotation(); a->behavior="wrap"; return a; }()); + json sem = extractSemanticSummary(f); + check(sem.contains("tailCall") && sem.contains("loop") && + sem.contains("data") && sem.contains("align") && + sem.contains("pack") && sem.contains("boundsCheck") && + sem.contains("overflow"), "all 7 optimization annotations in summary"); + delete f; +} + +int main() { + std::cout << "=== Step 280: Optimization Annotation Completion ===\n"; + test_tailcall(); test_loop(); test_data_align(); + test_pack_bounds_overflow(); test_loop_roundtrip(); + test_align_roundtrip(); test_overflow_roundtrip(); + test_create_node_factory(); test_compact_ast_loop(); + test_compact_ast_markers(); test_compact_ast_safety(); + test_all_optimization_annotations(); + std::cout << "\nResults: " << passed << "/" << (passed+failed) << "\n"; + return failed > 0 ? 1 : 0; +} diff --git a/editor/tests/step281_test.cpp b/editor/tests/step281_test.cpp new file mode 100644 index 0000000..b2ee3ad --- /dev/null +++ b/editor/tests/step281_test.cpp @@ -0,0 +1,130 @@ +// Step 281: Meta-Programming Annotations (12 tests) +#include +#include +#include +#include "ast/ASTNode.h" +#include "ast/Module.h" +#include "ast/Function.h" +#include "ast/Annotation.h" +#include "ast/Serialization.h" +#include "ASTUtils.h" +#include "CompactAST.h" + +static int passed = 0, failed = 0; +static void check(bool c, const std::string& n) { + if (c) { std::cout << " PASS: " << n << "\n"; ++passed; } + else { std::cout << " FAIL: " << n << "\n"; ++failed; } +} + +static void test_meta() { + MetaAnnotation a; a.state = "quoted"; a.phase = "compile"; + check(a.conceptType == "MetaAnnotation", "conceptType"); + check(a.state == "quoted" && a.phase == "compile", "fields"); +} + +static void test_symbol() { + SymbolAnnotation a; a.mode = "gensym"; + check(a.conceptType == "SymbolAnnotation", "conceptType"); + check(a.mode == "gensym", "mode field"); +} + +static void test_evaluate() { + EvaluateAnnotation a; a.phase = "compile_time"; + check(a.conceptType == "EvaluateAnnotation", "conceptType"); + check(a.phase == "compile_time", "phase field"); +} + +static void test_template_synthetic() { + TemplateAnnotation t; t.specialization = "monomorphize"; + check(t.specialization == "monomorphize", "TemplateAnnotation field"); + SyntheticAnnotation s; s.generator = "macro_expand"; s.isStructuralRisk = true; + check(s.generator == "macro_expand" && s.isStructuralRisk, "SyntheticAnnotation fields"); +} + +static void test_meta_roundtrip() { + auto* a = new MetaAnnotation(); a->id = "m1"; a->state = "unquoted"; a->phase = "runtime"; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* rm = dynamic_cast(r); + check(rm && rm->state == "unquoted" && rm->phase == "runtime", "MetaAnnotation roundtrip"); + delete a; delete r; +} + +static void test_template_roundtrip() { + auto* a = new TemplateAnnotation(); a->id = "t1"; a->specialization = "erasure"; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* rt = dynamic_cast(r); + check(rt && rt->specialization == "erasure", "TemplateAnnotation roundtrip"); + delete a; delete r; +} + +static void test_synthetic_roundtrip() { + auto* a = new SyntheticAnnotation(); a->id = "s1"; + a->generator = "derive_macro"; a->isStructuralRisk = true; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* rs = dynamic_cast(r); + check(rs && rs->generator == "derive_macro" && rs->isStructuralRisk, "SyntheticAnnotation roundtrip"); + delete a; delete r; +} + +static void test_create_node_factory() { + for (const auto& t : {"MetaAnnotation", "SymbolAnnotation", "EvaluateAnnotation", + "TemplateAnnotation", "SyntheticAnnotation"}) { + ASTNode* n = createNode(t); + check(n && n->conceptType == t, std::string("createNode(") + t + ")"); + delete n; + } +} + +static void test_compact_ast_meta() { + auto* f = new Function(); f->id = "f1"; f->name = "macroExpand"; + auto* a = new MetaAnnotation(); a->state = "quoted"; a->phase = "compile"; + f->addChild("annotations", a); + json sem = extractSemanticSummary(f); + check(sem.contains("meta") && sem["meta"]["state"] == "quoted", "meta in compact AST"); + delete f; +} + +static void test_compact_ast_template() { + auto* f = new Function(); f->id = "f2"; f->name = "generic"; + auto* a = new TemplateAnnotation(); a->specialization = "trait"; + f->addChild("annotations", a); + json sem = extractSemanticSummary(f); + check(sem["template"] == "trait", "template in compact AST"); + delete f; +} + +static void test_compact_ast_synthetic() { + auto* f = new Function(); f->id = "f3"; f->name = "generated"; + auto* a = new SyntheticAnnotation(); a->generator = "proc_macro"; a->isStructuralRisk = true; + f->addChild("annotations", a); + json sem = extractSemanticSummary(f); + check(sem.contains("synthetic") && sem["synthetic"]["generator"] == "proc_macro" && + sem["synthetic"]["risk"] == true, "synthetic in compact AST"); + delete f; +} + +static void test_all_meta_annotations() { + auto* f = new Function(); f->id = "f4"; f->name = "full"; + f->addChild("annotations", [&]{ auto* a = new MetaAnnotation(); a->state="quoted"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new SymbolAnnotation(); a->mode="interned"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new EvaluateAnnotation(); a->phase="runtime"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new TemplateAnnotation(); a->specialization="trait"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new SyntheticAnnotation(); a->generator="x"; return a; }()); + json sem = extractSemanticSummary(f); + check(sem.contains("meta") && sem.contains("symbol") && + sem.contains("evaluate") && sem.contains("template") && + sem.contains("synthetic"), "all 5 meta annotations in summary"); + delete f; +} + +int main() { + std::cout << "=== Step 281: Meta-Programming Annotations ===\n"; + test_meta(); test_symbol(); test_evaluate(); + test_template_synthetic(); test_meta_roundtrip(); + test_template_roundtrip(); test_synthetic_roundtrip(); + test_create_node_factory(); test_compact_ast_meta(); + test_compact_ast_template(); test_compact_ast_synthetic(); + test_all_meta_annotations(); + std::cout << "\nResults: " << passed << "/" << (passed+failed) << "\n"; + return failed > 0 ? 1 : 0; +} diff --git a/editor/tests/step282_test.cpp b/editor/tests/step282_test.cpp new file mode 100644 index 0000000..ec751b9 --- /dev/null +++ b/editor/tests/step282_test.cpp @@ -0,0 +1,144 @@ +// Step 282: Strategy & Policy Annotations (12 tests) +#include +#include +#include +#include "ast/ASTNode.h" +#include "ast/Module.h" +#include "ast/Function.h" +#include "ast/Annotation.h" +#include "ast/Serialization.h" +#include "ASTUtils.h" +#include "CompactAST.h" + +static int passed = 0, failed = 0; +static void check(bool c, const std::string& n) { + if (c) { std::cout << " PASS: " << n << "\n"; ++passed; } + else { std::cout << " FAIL: " << n << "\n"; ++failed; } +} + +static void test_policy() { + PolicyAnnotation a; + a.strictness = "high"; a.perf = "critical"; a.style = "idiomatic"; a.binaryStable = true; + check(a.conceptType == "PolicyAnnotation", "conceptType"); + check(a.strictness == "high" && a.perf == "critical" && + a.style == "idiomatic" && a.binaryStable, "fields"); +} + +static void test_ambiguity() { + AmbiguityAnnotation a; a.intent = "string vs bytes"; a.options = {"String", "Vec"}; + check(a.conceptType == "AmbiguityAnnotation", "conceptType"); + check(a.options.size() == 2, "options has 2 entries"); +} + +static void test_candidate_tradeoff() { + CandidateAnnotation c; c.inferredTypes = {"i32", "i64", "f64"}; + check(c.inferredTypes.size() == 3, "CandidateAnnotation 3 types"); + TradeoffAnnotation t; t.reason = "perf vs safety"; t.safetyCost = "high"; t.perfCost = "low"; + check(t.reason == "perf vs safety", "TradeoffAnnotation reason"); +} + +static void test_choice_decision() { + ChoiceAnnotation ch; ch.choiceId = "ch1"; ch.options = {"mutex", "rwlock", "atomic"}; + check(ch.choiceId == "ch1" && ch.options.size() == 3, "ChoiceAnnotation fields"); + DecisionAnnotation d; d.choiceId = "ch1"; d.selection = "atomic"; + d.author = "agent"; d.reason = "single-writer pattern"; + check(d.selection == "atomic" && d.author == "agent", "DecisionAnnotation fields"); +} + +static void test_policy_roundtrip() { + auto* a = new PolicyAnnotation(); a->id = "p1"; + a->strictness = "low"; a->perf = "normal"; a->style = "literal"; a->binaryStable = false; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* rp = dynamic_cast(r); + check(rp && rp->strictness == "low" && rp->perf == "normal" && + rp->style == "literal" && !rp->binaryStable, "PolicyAnnotation roundtrip"); + delete a; delete r; +} + +static void test_ambiguity_roundtrip() { + auto* a = new AmbiguityAnnotation(); a->id = "a1"; + a->intent = "type choice"; a->options = {"A", "B"}; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* ra = dynamic_cast(r); + check(ra && ra->intent == "type choice" && ra->options.size() == 2, "AmbiguityAnnotation roundtrip"); + delete a; delete r; +} + +static void test_choice_decision_roundtrip() { + auto* ch = new ChoiceAnnotation(); ch->id = "ch1"; + ch->choiceId = "sync_strategy"; ch->options = {"mutex", "rwlock"}; + json jch = toJson(ch); ASTNode* rch = fromJson(jch); + auto* rc = dynamic_cast(rch); + check(rc && rc->choiceId == "sync_strategy" && rc->options.size() == 2, "ChoiceAnnotation roundtrip"); + + auto* d = new DecisionAnnotation(); d->id = "d1"; + d->choiceId = "sync_strategy"; d->selection = "rwlock"; d->author = "human"; d->reason = "read-heavy"; + json jd = toJson(d); ASTNode* rd = fromJson(jd); + auto* rr = dynamic_cast(rd); + check(rr && rr->selection == "rwlock" && rr->author == "human", "DecisionAnnotation roundtrip"); + delete ch; delete rch; delete d; delete rd; +} + +static void test_create_node_factory() { + for (const auto& t : {"PolicyAnnotation", "AmbiguityAnnotation", "CandidateAnnotation", + "TradeoffAnnotation", "ChoiceAnnotation", "DecisionAnnotation"}) { + ASTNode* n = createNode(t); + check(n && n->conceptType == t, std::string("createNode(") + t + ")"); + delete n; + } +} + +static void test_compact_ast_policy() { + auto* f = new Function(); f->id = "f1"; f->name = "configure"; + auto* a = new PolicyAnnotation(); a->strictness = "high"; a->perf = "critical"; + f->addChild("annotations", a); + json sem = extractSemanticSummary(f); + check(sem.contains("policy") && sem["policy"]["strictness"] == "high", "policy in compact AST"); + delete f; +} + +static void test_compact_ast_decision() { + auto* f = new Function(); f->id = "f2"; f->name = "decided"; + auto* a = new DecisionAnnotation(); a->choiceId = "c1"; a->selection = "optA"; + f->addChild("annotations", a); + json sem = extractSemanticSummary(f); + check(sem.contains("decision") && sem["decision"]["selection"] == "optA", "decision in compact AST"); + delete f; +} + +static void test_all_policy_annotations() { + auto* f = new Function(); f->id = "f3"; f->name = "full"; + f->addChild("annotations", [&]{ auto* a = new PolicyAnnotation(); a->strictness="high"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new AmbiguityAnnotation(); a->intent="x"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new CandidateAnnotation(); a->inferredTypes={"i32"}; return a; }()); + f->addChild("annotations", [&]{ auto* a = new TradeoffAnnotation(); a->reason="x"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new ChoiceAnnotation(); a->choiceId="x"; return a; }()); + f->addChild("annotations", [&]{ auto* a = new DecisionAnnotation(); a->choiceId="x"; return a; }()); + json sem = extractSemanticSummary(f); + check(sem.contains("policy") && sem.contains("ambiguity") && + sem.contains("candidates") && sem.contains("tradeoff") && + sem.contains("choice") && sem.contains("decision"), + "all 6 policy annotations in summary"); + delete f; +} + +static void test_candidate_roundtrip() { + auto* a = new CandidateAnnotation(); a->id = "c1"; + a->inferredTypes = {"String", "&str", "Vec"}; + json j = toJson(a); ASTNode* r = fromJson(j); + auto* rc = dynamic_cast(r); + check(rc && rc->inferredTypes.size() == 3, "CandidateAnnotation roundtrip"); + delete a; delete r; +} + +int main() { + std::cout << "=== Step 282: Strategy & Policy Annotations ===\n"; + test_policy(); test_ambiguity(); test_candidate_tradeoff(); + test_choice_decision(); test_policy_roundtrip(); + test_ambiguity_roundtrip(); test_choice_decision_roundtrip(); + test_create_node_factory(); test_compact_ast_policy(); + test_compact_ast_decision(); test_all_policy_annotations(); + test_candidate_roundtrip(); + std::cout << "\nResults: " << passed << "/" << (passed+failed) << "\n"; + return failed > 0 ? 1 : 0; +} diff --git a/editor/tests/step283_test.cpp b/editor/tests/step283_test.cpp new file mode 100644 index 0000000..30fa384 --- /dev/null +++ b/editor/tests/step283_test.cpp @@ -0,0 +1,266 @@ +// Step 283: Phase 10d Integration Tests (8 tests) +#include +#include +#include +#include +#include +#include "ast/ASTNode.h" +#include "ast/Module.h" +#include "ast/Function.h" +#include "ast/Annotation.h" +#include "ast/Serialization.h" +#include "ASTUtils.h" +#include "CompactAST.h" +#include "SidecarPersistence.h" +#include "HeadlessEditorState.h" + +static int passed = 0, failed = 0; +static void check(bool c, const std::string& n) { + if (c) { std::cout << " PASS: " << n << "\n"; ++passed; } + else { std::cout << " FAIL: " << n << "\n"; ++failed; } +} + +static Module* buildTestAST() { + auto* mod = new Module(); mod->id = "mod1"; mod->name = "test"; + auto* fn1 = new Function(); fn1->id = "fn1"; fn1->name = "ffi_bridge"; + auto* fn2 = new Function(); fn2->id = "fn2"; fn2->name = "optimize"; + mod->addChild("functions", fn1); + mod->addChild("functions", fn2); + return mod; +} + +static json rpc(HeadlessEditorState& st, const std::string& method, + const json& params = {}, const std::string& sess = "s1") { + json req = {{"jsonrpc","2.0"},{"id",1},{"method",method}}; + if (!params.empty()) req["params"] = params; + return handleHeadlessAgentRequest(st, req, sess); +} + +// Test 1: Shim annotations on FFI boundary function +static void test_shim_on_ffi() { + auto* mod = buildTestAST(); + auto* fn = findNodeById(mod, "fn1"); + auto* ia = new IntrinsicAnnotation(); ia->instruction = "_mm_add"; ia->arch = "sse"; + auto* cc = new CallingConvAnnotation(); cc->convention = "cdecl"; + auto* la = new LinkAnnotation(); la->symbolName = "ext_func"; la->library = "libext.so"; + fn->addChild("annotations", ia); + fn->addChild("annotations", cc); + fn->addChild("annotations", la); + json sem = extractSemanticSummary(fn); + check(sem.contains("intrinsic") && sem.contains("callingConv") && sem.contains("link"), + "shim annotations on FFI function"); + delete mod; +} + +// Test 2: OriginalAnnotation preserves legacy source +static void test_original_preserves_source() { + auto* mod = buildTestAST(); + auto* fn = findNodeById(mod, "fn1"); + auto* oa = new OriginalAnnotation(); + oa->sourceCode = "def bridge(x): return ext_call(x)"; + oa->sourceLanguage = "python"; + fn->addChild("annotations", oa); + json sem = extractSemanticSummary(fn); + check(sem.contains("original") && sem["original"]["lang"] == "python" && + sem["original"]["hasSource"] == true, "original annotation preserves source info"); + delete mod; +} + +// Test 3: Optimization annotations in compact AST +static void test_optimization_compact_ast() { + auto* mod = buildTestAST(); + auto* fn = findNodeById(mod, "fn2"); + auto* la = new LoopAnnotation(); la->hint = "vectorize"; la->factor = 4; + auto* aa = new AlignAnnotation(); aa->bytes = 32; + fn->addChild("annotations", la); + fn->addChild("annotations", aa); + json compact = toJsonCompactSummary(mod); + bool found = false; + for (const auto& n : compact) { + if (n.value("id","") == "fn2" && n.contains("semantic")) { + auto& s = n["semantic"]; + found = s.contains("loop") && s.contains("align"); + } + } + check(found, "optimization annotations in compact AST summary"); + delete mod; +} + +// Test 4: Meta-programming annotations mark macro-expanded code +static void test_meta_marks_generated() { + auto* f = new Function(); f->id = "f1"; f->name = "generated_fn"; + auto* syn = new SyntheticAnnotation(); syn->generator = "derive_macro"; syn->isStructuralRisk = true; + auto* meta = new MetaAnnotation(); meta->state = "unquoted"; meta->phase = "compile"; + f->addChild("annotations", syn); + f->addChild("annotations", meta); + json sem = extractSemanticSummary(f); + check(sem.contains("synthetic") && sem["synthetic"]["risk"] == true && + sem.contains("meta") && sem["meta"]["phase"] == "compile", + "meta annotations mark generated code"); + delete f; +} + +// Test 5: Policy + Choice + Decision workflow +static void test_policy_choice_decision() { + auto* f = new Function(); f->id = "f1"; f->name = "sync_op"; + auto* policy = new PolicyAnnotation(); policy->strictness = "high"; policy->perf = "critical"; + auto* choice = new ChoiceAnnotation(); choice->choiceId = "sync1"; choice->options = {"mutex","rwlock","atomic"}; + auto* decision = new DecisionAnnotation(); decision->choiceId = "sync1"; + decision->selection = "atomic"; decision->author = "agent"; decision->reason = "single-writer"; + f->addChild("annotations", policy); + f->addChild("annotations", choice); + f->addChild("annotations", decision); + json sem = extractSemanticSummary(f); + check(sem.contains("policy") && sem.contains("choice") && sem.contains("decision") && + sem["decision"]["selection"] == "atomic", + "policy → choice → decision workflow"); + delete f; +} + +// Test 6: All Subject 5-8 annotations survive sidecar roundtrip +static void test_sidecar_roundtrip() { + namespace fs = std::filesystem; + std::string ws = "/tmp/step283_test_ws"; + fs::create_directories(ws); + + auto* mod = buildTestAST(); + auto* fn1 = findNodeById(mod, "fn1"); + auto* fn2 = findNodeById(mod, "fn2"); + // Subject 5 + fn1->addChild("annotations", [&]{ auto* a = new IntrinsicAnnotation(); a->instruction="x"; return a; }()); + fn1->addChild("annotations", [&]{ auto* a = new TargetAnnotation(); a->platform="linux"; return a; }()); + // Subject 6 + fn2->addChild("annotations", [&]{ auto* a = new LoopAnnotation(); a->hint="unroll"; return a; }()); + // Subject 7 + fn2->addChild("annotations", [&]{ auto* a = new MetaAnnotation(); a->state="quoted"; return a; }()); + // Subject 8 + fn1->addChild("annotations", [&]{ auto* a = new PolicyAnnotation(); a->strictness="high"; return a; }()); + + auto sr = saveSidecarAST(ws, "test.wh", mod); + check(sr.success && sr.annotationCount == 5, "sidecar save 5 annotations"); + + auto* mod2 = buildTestAST(); + auto lr = loadSidecarAST(ws, "test.wh", mod2); + check(lr.success && lr.mergedCount == 5, "sidecar load restores 5 annotations"); + + delete mod; delete mod2; + fs::remove_all(ws); +} + +// Test 7: setSemanticAnnotation RPC works for all new types +static void test_rpc_new_types() { + HeadlessEditorState state; + state.openBuffer("test.wh", "", "python"); + auto* mod = buildTestAST(); + state.activeBuffer->sync.setAST(std::unique_ptr(mod)); + state.setAgentRole("s1", AgentRole::Refactor); + + std::vector> tests = { + {"intrinsic", {{"instruction","x"},{"arch","x"}}}, + {"raw", {{"language","c"},{"code","x"}}}, + {"callingConv", {{"convention","cdecl"}}}, + {"link", {{"symbolName","x"},{"library","x"}}}, + {"shim", {{"strategy","vtable"}}}, + {"pointerArithmetic", json::object()}, + {"opaque", {{"reason","x"}}}, + {"target", {{"platform","linux"},{"arch","x86"}}}, + {"feature", {{"flag","SSE"},{"enabled",true}}}, + {"original", {{"sourceCode","x"},{"sourceLanguage","py"}}}, + {"mapping", {{"history",json::array({"a","b"})}}}, + {"tailCall", json::object()}, + {"loop", {{"hint","unroll"},{"factor",4}}}, + {"dataHint", {{"hint","prefetch"}}}, + {"align", {{"bytes",16}}}, + {"pack", json::object()}, + {"boundsCheck", {{"enabled",false}}}, + {"overflow", {{"behavior","wrap"}}}, + {"meta", {{"state","quoted"},{"phase","compile"}}}, + {"symbolMode", {{"mode","gensym"}}}, + {"evaluate", {{"phase","runtime"}}}, + {"template", {{"specialization","trait"}}}, + {"synthetic", {{"generator","x"},{"isStructuralRisk",true}}}, + {"policy", {{"strictness","high"},{"perf","normal"}}}, + {"ambiguity", {{"intent","x"},{"options",json::array({"a"})}}}, + {"candidate", {{"inferredTypes",json::array({"i32"})}}}, + {"tradeoff", {{"reason","x"},{"safetyCost","low"}}}, + {"choice", {{"choiceId","c1"},{"options",json::array({"a","b"})}}}, + {"decision", {{"choiceId","c1"},{"selection","a"},{"author","agent"}}}, + }; + + int ok = 0; + for (const auto& [type, fields] : tests) { + auto r = rpc(state, "setSemanticAnnotation", { + {"nodeId","fn1"}, {"type",type}, {"fields",fields} + }); + if (r.contains("result") && r["result"].value("success", false)) ++ok; + } + check(ok == (int)tests.size(), + "all 29 new type keys accepted by setSemanticAnnotation RPC"); +} + +// Test 8: Annotation taxonomy completeness — all 8 subjects represented +static void test_taxonomy_completeness() { + // Subject 1: Intent, Complexity, Risk, Contract, SemanticTag (Phase 10a) + // Subject 2: BitWidth, Endian, Layout, Nullability, Variance, Identity, Mut, TypeState (Phase 10c) + // Subject 3: Atomic, Sync, ThreadModel, MemoryBarrier, Exec, Blocking, Parallel, Trap, Exception, Panic (Phase 10c) + // Subject 4: Binding, Lookup, Capture, Visibility, Namespace, Scope (Phase 10c) + // Subject 5: Intrinsic, Raw, CallingConv, Link, Shim, PointerArithmetic, Opaque, Target, Feature, Original, Mapping + // Subject 6: HotCold, Inline, Pure, ConstExpr, TailCall, Loop, Data, Align, Pack, BoundsCheck, Overflow + // Subject 7: Meta, Symbol, Evaluate, Template, Synthetic + // Subject 8: Policy, Ambiguity, Candidate, Tradeoff, Choice, Decision + + std::vector allSemantic = { + // Subject 1 + "IntentAnnotation", "ComplexityAnnotation", "RiskAnnotation", + "ContractAnnotation", "SemanticTagAnnotation", + // Subject 2 + "BitWidthAnnotation", "EndianAnnotation", "LayoutAnnotation", + "NullabilityAnnotation", "VarianceAnnotation", "IdentityAnnotation", + "MutAnnotation", "TypeStateAnnotation", + // Subject 3 + "AtomicAnnotation", "SyncAnnotation", "ThreadModelAnnotation", + "MemoryBarrierAnnotation", "ExecAnnotation", "BlockingAnnotation", + "ParallelAnnotation", "TrapAnnotation", "ExceptionAnnotation", "PanicAnnotation", + // Subject 4 + "BindingAnnotation", "LookupAnnotation", "CaptureAnnotation", + "VisibilityAnnotation", "NamespaceAnnotation", "ScopeAnnotation", + // Subject 5 + "IntrinsicAnnotation", "RawAnnotation", "CallingConvAnnotation", + "LinkAnnotation", "ShimAnnotation", "PointerArithmeticAnnotation", + "OpaqueAnnotation", "TargetAnnotation", "FeatureAnnotation", + "OriginalAnnotation", "MappingAnnotation", + // Subject 6 (new in 10d) + "TailCallAnnotation", "LoopAnnotation", "DataAnnotation", + "AlignAnnotation", "PackAnnotation", "BoundsCheckAnnotation", + "OverflowAnnotation", + // Subject 7 + "MetaAnnotation", "SymbolAnnotation", "EvaluateAnnotation", + "TemplateAnnotation", "SyntheticAnnotation", + // Subject 8 + "PolicyAnnotation", "AmbiguityAnnotation", "CandidateAnnotation", + "TradeoffAnnotation", "ChoiceAnnotation", "DecisionAnnotation" + }; + + int recognized = 0; + for (const auto& t : allSemantic) { + if (isSemanticAnnotation(t)) ++recognized; + ASTNode* n = createNode(t); + if (n) { delete n; } else { recognized--; } + } + check(recognized == (int)allSemantic.size(), + "all " + std::to_string(allSemantic.size()) + " annotation types recognized and creatable"); +} + +int main() { + std::cout << "=== Step 283: Phase 10d Integration Tests ===\n"; + test_shim_on_ffi(); + test_original_preserves_source(); + test_optimization_compact_ast(); + test_meta_marks_generated(); + test_policy_choice_decision(); + test_sidecar_roundtrip(); + test_rpc_new_types(); + test_taxonomy_completeness(); + std::cout << "\nResults: " << passed << "/" << (passed+failed) << "\n"; + return failed > 0 ? 1 : 0; +}