Steps 272-277: Phase 10c — type system, concurrency & scope annotations (68/68 tests)

- Step 272: Type layout/constraints — BitWidth, Endian, Layout, Nullability, Variance (37 tests)
- Step 273: Type identity/mutability — Identity, Mut, TypeState (25 tests)
- Step 274: Concurrency primitives — Atomic, Sync, ThreadModel, MemoryBarrier (25 tests)
- Step 275: Async/error handling — Exec, Blocking, Parallel, Trap, Exception, Panic (36 tests)
- Step 276: Scope/namespace — Binding, Lookup, Capture, Visibility, Namespace, Scope (32 tests)
- Step 277: Integration tests — cross-subject workflows, sidecar roundtrip, RPC (16 tests)
- 24 new annotation classes with JSON roundtrip, compact AST, sidecar persistence
- Generic fallback in getSemanticAnnotations RPC for extensible annotation queries

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Bill
2026-02-12 18:15:21 +00:00
parent a049d6010b
commit e2d1872f35
12 changed files with 1959 additions and 14 deletions

View File

@@ -0,0 +1,201 @@
// Step 272: Type System Annotations — Layout & Constraints (12 tests)
// Tests: BitWidthAnnotation, EndianAnnotation, LayoutAnnotation,
// NullabilityAnnotation, VarianceAnnotation
// + JSON roundtrip + compact AST integration
#include <cassert>
#include <iostream>
#include <string>
#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;
static int failed = 0;
static void check(bool cond, const std::string& name) {
if (cond) { std::cout << " PASS: " << name << "\n"; ++passed; }
else { std::cout << " FAIL: " << name << "\n"; ++failed; }
}
// --- Test 1: BitWidthAnnotation creation and fields ---
static void test_bitwidth_annotation() {
BitWidthAnnotation bw;
check(bw.conceptType == "BitWidthAnnotation", "conceptType is BitWidthAnnotation");
bw.width = 32;
check(bw.width == 32, "width field set to 32");
}
// --- Test 2: EndianAnnotation creation and fields ---
static void test_endian_annotation() {
EndianAnnotation ea;
check(ea.conceptType == "EndianAnnotation", "conceptType is EndianAnnotation");
ea.order = "big";
check(ea.order == "big", "order field set to big");
}
// --- Test 3: LayoutAnnotation creation and fields ---
static void test_layout_annotation() {
LayoutAnnotation la;
check(la.conceptType == "LayoutAnnotation", "conceptType is LayoutAnnotation");
la.mode = "packed";
la.alignment = 8;
check(la.mode == "packed", "mode field set to packed");
check(la.alignment == 8, "alignment field set to 8");
}
// --- Test 4: NullabilityAnnotation creation and fields ---
static void test_nullability_annotation() {
NullabilityAnnotation na;
check(na.conceptType == "NullabilityAnnotation", "conceptType is NullabilityAnnotation");
na.nullable = true;
na.strategy = "strict";
check(na.nullable == true, "nullable field set to true");
check(na.strategy == "strict", "strategy field set to strict");
}
// --- Test 5: VarianceAnnotation creation and fields ---
static void test_variance_annotation() {
VarianceAnnotation va;
check(va.conceptType == "VarianceAnnotation", "conceptType is VarianceAnnotation");
va.variance = "covariant";
check(va.variance == "covariant", "variance field set to covariant");
}
// --- Test 6: BitWidthAnnotation JSON roundtrip ---
static void test_bitwidth_json_roundtrip() {
auto* bw = new BitWidthAnnotation();
bw->id = "bw1";
bw->width = 64;
json j = toJson(bw);
check(j["concept"] == "BitWidthAnnotation", "JSON concept correct");
check(j["properties"]["width"] == 64, "JSON width correct");
ASTNode* restored = fromJson(j);
auto* rbw = dynamic_cast<BitWidthAnnotation*>(restored);
check(rbw != nullptr, "fromJson creates BitWidthAnnotation");
check(rbw->width == 64, "roundtrip width preserved");
delete bw;
delete restored;
}
// --- Test 7: LayoutAnnotation JSON roundtrip ---
static void test_layout_json_roundtrip() {
auto* la = new LayoutAnnotation();
la->id = "la1";
la->mode = "aligned";
la->alignment = 16;
json j = toJson(la);
ASTNode* restored = fromJson(j);
auto* rla = dynamic_cast<LayoutAnnotation*>(restored);
check(rla != nullptr, "fromJson creates LayoutAnnotation");
check(rla->mode == "aligned", "roundtrip mode preserved");
check(rla->alignment == 16, "roundtrip alignment preserved");
delete la;
delete restored;
}
// --- Test 8: NullabilityAnnotation JSON roundtrip ---
static void test_nullability_json_roundtrip() {
auto* na = new NullabilityAnnotation();
na->id = "na1";
na->nullable = true;
na->strategy = "nullable";
json j = toJson(na);
check(j["properties"]["nullable"] == true, "JSON nullable correct");
ASTNode* restored = fromJson(j);
auto* rna = dynamic_cast<NullabilityAnnotation*>(restored);
check(rna != nullptr, "fromJson creates NullabilityAnnotation");
check(rna->nullable == true, "roundtrip nullable preserved");
check(rna->strategy == "nullable", "roundtrip strategy preserved");
delete na;
delete restored;
}
// --- Test 9: All 5 types survive createNode factory ---
static void test_create_node_factory() {
std::vector<std::string> types = {
"BitWidthAnnotation", "EndianAnnotation", "LayoutAnnotation",
"NullabilityAnnotation", "VarianceAnnotation"
};
for (const auto& t : types) {
ASTNode* node = createNode(t);
check(node != nullptr && node->conceptType == t,
"createNode(" + t + ") works");
delete node;
}
}
// --- Test 10: Compact AST shows bitWidth in semantic summary ---
static void test_compact_ast_bitwidth() {
auto* func = new Function();
func->id = "f1";
func->name = "getInt";
auto* bw = new BitWidthAnnotation();
bw->width = 32;
func->addChild("annotations", bw);
json sem = extractSemanticSummary(func);
check(!sem.empty(), "semantic summary not empty");
check(sem.contains("bitWidth"), "bitWidth in semantic summary");
check(sem["bitWidth"] == 32, "bitWidth value correct");
delete func;
}
// --- Test 11: Compact AST shows layout in semantic summary ---
static void test_compact_ast_layout() {
auto* func = new Function();
func->id = "f2";
func->name = "pack";
auto* la = new LayoutAnnotation();
la->mode = "packed";
la->alignment = 4;
func->addChild("annotations", la);
json sem = extractSemanticSummary(func);
check(sem.contains("layout"), "layout in semantic summary");
check(sem["layout"]["mode"] == "packed", "layout mode correct");
check(sem["layout"]["alignment"] == 4, "layout alignment correct");
delete func;
}
// --- Test 12: Multiple type annotations on one node ---
static void test_multiple_type_annotations() {
auto* func = new Function();
func->id = "f3";
func->name = "convert";
auto* bw = new BitWidthAnnotation();
bw->width = 16;
func->addChild("annotations", bw);
auto* ea = new EndianAnnotation();
ea->order = "little";
func->addChild("annotations", ea);
auto* va = new VarianceAnnotation();
va->variance = "invariant";
func->addChild("annotations", va);
json sem = extractSemanticSummary(func);
check(sem["bitWidth"] == 16, "bitWidth present in multi-annotation");
check(sem["endian"] == "little", "endian present in multi-annotation");
check(sem["variance"] == "invariant", "variance present in multi-annotation");
delete func;
}
int main() {
std::cout << "=== Step 272: Type System Annotations — Layout & Constraints ===\n";
test_bitwidth_annotation();
test_endian_annotation();
test_layout_annotation();
test_nullability_annotation();
test_variance_annotation();
test_bitwidth_json_roundtrip();
test_layout_json_roundtrip();
test_nullability_json_roundtrip();
test_create_node_factory();
test_compact_ast_bitwidth();
test_compact_ast_layout();
test_multiple_type_annotations();
std::cout << "\nResults: " << passed << " passed, " << failed << " failed out of "
<< (passed + failed) << "\n";
return failed > 0 ? 1 : 0;
}

View File

@@ -0,0 +1,205 @@
// Step 273: Type System Annotations — Identity & Mutability (12 tests)
// Tests: IdentityAnnotation, MutAnnotation, TypeStateAnnotation
// + JSON roundtrip + compact AST + all 8 type annotation types together
#include <cassert>
#include <iostream>
#include <string>
#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;
static int failed = 0;
static void check(bool cond, const std::string& name) {
if (cond) { std::cout << " PASS: " << name << "\n"; ++passed; }
else { std::cout << " FAIL: " << name << "\n"; ++failed; }
}
// --- Test 1: IdentityAnnotation creation ---
static void test_identity_annotation() {
IdentityAnnotation ia;
check(ia.conceptType == "IdentityAnnotation", "conceptType is IdentityAnnotation");
ia.mode = "nominal";
check(ia.mode == "nominal", "mode field set to nominal");
}
// --- Test 2: MutAnnotation creation ---
static void test_mut_annotation() {
MutAnnotation ma;
check(ma.conceptType == "MutAnnotation", "conceptType is MutAnnotation");
ma.depth = "deep";
check(ma.depth == "deep", "depth field set to deep");
}
// --- Test 3: TypeStateAnnotation creation ---
static void test_typestate_annotation() {
TypeStateAnnotation ts;
check(ts.conceptType == "TypeStateAnnotation", "conceptType is TypeStateAnnotation");
ts.state = "reified";
check(ts.state == "reified", "state field set to reified");
}
// --- Test 4: IdentityAnnotation JSON roundtrip ---
static void test_identity_json_roundtrip() {
auto* ia = new IdentityAnnotation();
ia->id = "id1";
ia->mode = "structural";
json j = toJson(ia);
check(j["properties"]["mode"] == "structural", "JSON mode correct");
ASTNode* restored = fromJson(j);
auto* ria = dynamic_cast<IdentityAnnotation*>(restored);
check(ria != nullptr, "fromJson creates IdentityAnnotation");
check(ria->mode == "structural", "roundtrip mode preserved");
delete ia;
delete restored;
}
// --- Test 5: MutAnnotation JSON roundtrip ---
static void test_mut_json_roundtrip() {
auto* ma = new MutAnnotation();
ma->id = "mut1";
ma->depth = "interior";
json j = toJson(ma);
ASTNode* restored = fromJson(j);
auto* rma = dynamic_cast<MutAnnotation*>(restored);
check(rma != nullptr, "fromJson creates MutAnnotation");
check(rma->depth == "interior", "roundtrip depth preserved");
delete ma;
delete restored;
}
// --- Test 6: TypeStateAnnotation JSON roundtrip ---
static void test_typestate_json_roundtrip() {
auto* ts = new TypeStateAnnotation();
ts->id = "ts1";
ts->state = "erased";
json j = toJson(ts);
ASTNode* restored = fromJson(j);
auto* rts = dynamic_cast<TypeStateAnnotation*>(restored);
check(rts != nullptr, "fromJson creates TypeStateAnnotation");
check(rts->state == "erased", "roundtrip state preserved");
delete ts;
delete restored;
}
// --- Test 7: createNode factory for Step 273 types ---
static void test_create_node_factory() {
std::vector<std::string> types = {
"IdentityAnnotation", "MutAnnotation", "TypeStateAnnotation"
};
for (const auto& t : types) {
ASTNode* node = createNode(t);
check(node != nullptr && node->conceptType == t,
"createNode(" + t + ") works");
delete node;
}
}
// --- Test 8: Compact AST shows identity in semantic summary ---
static void test_compact_ast_identity() {
auto* func = new Function();
func->id = "f1";
func->name = "compare";
auto* ia = new IdentityAnnotation();
ia->mode = "nominal";
func->addChild("annotations", ia);
json sem = extractSemanticSummary(func);
check(sem.contains("identity"), "identity in semantic summary");
check(sem["identity"] == "nominal", "identity value correct");
delete func;
}
// --- Test 9: Compact AST shows mutability in semantic summary ---
static void test_compact_ast_mutability() {
auto* func = new Function();
func->id = "f2";
func->name = "freeze";
auto* ma = new MutAnnotation();
ma->depth = "deep";
func->addChild("annotations", ma);
json sem = extractSemanticSummary(func);
check(sem.contains("mutability"), "mutability in semantic summary");
check(sem["mutability"] == "deep", "mutability value correct");
delete func;
}
// --- Test 10: Compact AST shows typeState in semantic summary ---
static void test_compact_ast_typestate() {
auto* func = new Function();
func->id = "f3";
func->name = "reflect";
auto* ts = new TypeStateAnnotation();
ts->state = "reified";
func->addChild("annotations", ts);
json sem = extractSemanticSummary(func);
check(sem.contains("typeState"), "typeState in semantic summary");
check(sem["typeState"] == "reified", "typeState value correct");
delete func;
}
// --- Test 11: All 8 Subject 2 type annotations on one function ---
static void test_all_subject2_annotations() {
auto* func = new Function();
func->id = "f4";
func->name = "fullType";
auto* bw = new BitWidthAnnotation(); bw->width = 32;
auto* ea = new EndianAnnotation(); ea->order = "little";
auto* la = new LayoutAnnotation(); la->mode = "aligned"; la->alignment = 8;
auto* na = new NullabilityAnnotation(); na->nullable = false; na->strategy = "strict";
auto* va = new VarianceAnnotation(); va->variance = "covariant";
auto* id = new IdentityAnnotation(); id->mode = "nominal";
auto* mu = new MutAnnotation(); mu->depth = "shallow";
auto* ts = new TypeStateAnnotation(); ts->state = "erased";
func->addChild("annotations", bw);
func->addChild("annotations", ea);
func->addChild("annotations", la);
func->addChild("annotations", na);
func->addChild("annotations", va);
func->addChild("annotations", id);
func->addChild("annotations", mu);
func->addChild("annotations", ts);
json sem = extractSemanticSummary(func);
check(sem.contains("bitWidth") && sem.contains("endian") &&
sem.contains("layout") && sem.contains("nullability") &&
sem.contains("variance") && sem.contains("identity") &&
sem.contains("mutability") && sem.contains("typeState"),
"all 8 type system annotations in semantic summary");
delete func;
}
// --- Test 12: MutAnnotation drives const qualification hint ---
static void test_mut_const_qualification() {
// MutAnnotation("deep") → implies deeply immutable
MutAnnotation ma;
ma.depth = "deep";
check(ma.depth == "deep", "deep mutability implies deeply immutable");
// MutAnnotation("shallow") → only top-level const
MutAnnotation ma2;
ma2.depth = "shallow";
check(ma2.depth == "shallow", "shallow mutability implies top-level const");
}
int main() {
std::cout << "=== Step 273: Type System Annotations — Identity & Mutability ===\n";
test_identity_annotation();
test_mut_annotation();
test_typestate_annotation();
test_identity_json_roundtrip();
test_mut_json_roundtrip();
test_typestate_json_roundtrip();
test_create_node_factory();
test_compact_ast_identity();
test_compact_ast_mutability();
test_compact_ast_typestate();
test_all_subject2_annotations();
test_mut_const_qualification();
std::cout << "\nResults: " << passed << " passed, " << failed << " failed out of "
<< (passed + failed) << "\n";
return failed > 0 ? 1 : 0;
}

View File

@@ -0,0 +1,188 @@
// Step 274: Concurrency Annotations — Primitives & Memory Model (12 tests)
// Tests: AtomicAnnotation, SyncAnnotation, ThreadModelAnnotation,
// MemoryBarrierAnnotation + JSON roundtrip + compact AST
#include <cassert>
#include <iostream>
#include <string>
#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;
static int failed = 0;
static void check(bool cond, const std::string& name) {
if (cond) { std::cout << " PASS: " << name << "\n"; ++passed; }
else { std::cout << " FAIL: " << name << "\n"; ++failed; }
}
// --- Test 1: AtomicAnnotation creation ---
static void test_atomic_annotation() {
AtomicAnnotation aa;
check(aa.conceptType == "AtomicAnnotation", "conceptType is AtomicAnnotation");
aa.consistency = "seq_cst";
check(aa.consistency == "seq_cst", "consistency field set to seq_cst");
}
// --- Test 2: SyncAnnotation creation ---
static void test_sync_annotation() {
SyncAnnotation sa;
check(sa.conceptType == "SyncAnnotation", "conceptType is SyncAnnotation");
sa.primitive = "monitor";
check(sa.primitive == "monitor", "primitive field set to monitor");
}
// --- Test 3: ThreadModelAnnotation creation ---
static void test_threadmodel_annotation() {
ThreadModelAnnotation tm;
check(tm.conceptType == "ThreadModelAnnotation", "conceptType is ThreadModelAnnotation");
tm.model = "green";
check(tm.model == "green", "model field set to green");
}
// --- Test 4: MemoryBarrierAnnotation creation (marker, no fields) ---
static void test_memorybarrier_annotation() {
MemoryBarrierAnnotation mb;
check(mb.conceptType == "MemoryBarrierAnnotation", "conceptType is MemoryBarrierAnnotation");
}
// --- Test 5: AtomicAnnotation JSON roundtrip ---
static void test_atomic_json_roundtrip() {
auto* aa = new AtomicAnnotation();
aa->id = "a1";
aa->consistency = "relaxed";
json j = toJson(aa);
check(j["properties"]["consistency"] == "relaxed", "JSON consistency correct");
ASTNode* restored = fromJson(j);
auto* raa = dynamic_cast<AtomicAnnotation*>(restored);
check(raa != nullptr, "fromJson creates AtomicAnnotation");
check(raa->consistency == "relaxed", "roundtrip consistency preserved");
delete aa;
delete restored;
}
// --- Test 6: SyncAnnotation JSON roundtrip ---
static void test_sync_json_roundtrip() {
auto* sa = new SyncAnnotation();
sa->id = "s1";
sa->primitive = "semaphore";
json j = toJson(sa);
ASTNode* restored = fromJson(j);
auto* rsa = dynamic_cast<SyncAnnotation*>(restored);
check(rsa != nullptr, "fromJson creates SyncAnnotation");
check(rsa->primitive == "semaphore", "roundtrip primitive preserved");
delete sa;
delete restored;
}
// --- Test 7: ThreadModelAnnotation JSON roundtrip ---
static void test_threadmodel_json_roundtrip() {
auto* tm = new ThreadModelAnnotation();
tm->id = "tm1";
tm->model = "fiber";
json j = toJson(tm);
ASTNode* restored = fromJson(j);
auto* rtm = dynamic_cast<ThreadModelAnnotation*>(restored);
check(rtm != nullptr, "fromJson creates ThreadModelAnnotation");
check(rtm->model == "fiber", "roundtrip model preserved");
delete tm;
delete restored;
}
// --- Test 8: MemoryBarrierAnnotation JSON roundtrip ---
static void test_memorybarrier_json_roundtrip() {
auto* mb = new MemoryBarrierAnnotation();
mb->id = "mb1";
json j = toJson(mb);
check(j["concept"] == "MemoryBarrierAnnotation", "JSON concept correct");
ASTNode* restored = fromJson(j);
auto* rmb = dynamic_cast<MemoryBarrierAnnotation*>(restored);
check(rmb != nullptr, "fromJson creates MemoryBarrierAnnotation");
delete mb;
delete restored;
}
// --- Test 9: createNode factory for Step 274 types ---
static void test_create_node_factory() {
std::vector<std::string> types = {
"AtomicAnnotation", "SyncAnnotation",
"ThreadModelAnnotation", "MemoryBarrierAnnotation"
};
for (const auto& t : types) {
ASTNode* node = createNode(t);
check(node != nullptr && node->conceptType == t,
"createNode(" + t + ") works");
delete node;
}
}
// --- Test 10: Compact AST shows atomic in semantic summary ---
static void test_compact_ast_atomic() {
auto* func = new Function();
func->id = "f1";
func->name = "incrementCounter";
auto* aa = new AtomicAnnotation();
aa->consistency = "seq_cst";
func->addChild("annotations", aa);
json sem = extractSemanticSummary(func);
check(sem.contains("atomic"), "atomic in semantic summary");
check(sem["atomic"] == "seq_cst", "atomic value correct");
delete func;
}
// --- Test 11: Compact AST shows memoryBarrier marker ---
static void test_compact_ast_memorybarrier() {
auto* func = new Function();
func->id = "f2";
func->name = "fence";
auto* mb = new MemoryBarrierAnnotation();
func->addChild("annotations", mb);
json sem = extractSemanticSummary(func);
check(sem.contains("memoryBarrier"), "memoryBarrier in semantic summary");
check(sem["memoryBarrier"] == true, "memoryBarrier is true");
delete func;
}
// --- Test 12: All 4 concurrency annotations on one function ---
static void test_all_concurrency_annotations() {
auto* func = new Function();
func->id = "f3";
func->name = "concurrentOp";
auto* aa = new AtomicAnnotation(); aa->consistency = "acquire";
auto* sa = new SyncAnnotation(); sa->primitive = "spin";
auto* tm = new ThreadModelAnnotation(); tm->model = "os";
auto* mb = new MemoryBarrierAnnotation();
func->addChild("annotations", aa);
func->addChild("annotations", sa);
func->addChild("annotations", tm);
func->addChild("annotations", mb);
json sem = extractSemanticSummary(func);
check(sem.contains("atomic") && sem.contains("sync") &&
sem.contains("threadModel") && sem.contains("memoryBarrier"),
"all 4 concurrency annotations in semantic summary");
delete func;
}
int main() {
std::cout << "=== Step 274: Concurrency Annotations — Primitives & Memory Model ===\n";
test_atomic_annotation();
test_sync_annotation();
test_threadmodel_annotation();
test_memorybarrier_annotation();
test_atomic_json_roundtrip();
test_sync_json_roundtrip();
test_threadmodel_json_roundtrip();
test_memorybarrier_json_roundtrip();
test_create_node_factory();
test_compact_ast_atomic();
test_compact_ast_memorybarrier();
test_all_concurrency_annotations();
std::cout << "\nResults: " << passed << " passed, " << failed << " failed out of "
<< (passed + failed) << "\n";
return failed > 0 ? 1 : 0;
}

View File

@@ -0,0 +1,221 @@
// Step 275: Async, Parallelism & Error Handling Annotations (12 tests)
// Tests: ExecAnnotation, BlockingAnnotation, ParallelAnnotation,
// TrapAnnotation, ExceptionAnnotation, PanicAnnotation
// + JSON roundtrip + compact AST
#include <cassert>
#include <iostream>
#include <string>
#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;
static int failed = 0;
static void check(bool cond, const std::string& name) {
if (cond) { std::cout << " PASS: " << name << "\n"; ++passed; }
else { std::cout << " FAIL: " << name << "\n"; ++failed; }
}
// --- Test 1: ExecAnnotation creation ---
static void test_exec_annotation() {
ExecAnnotation ea;
check(ea.conceptType == "ExecAnnotation", "conceptType is ExecAnnotation");
ea.mode = "async";
ea.runtimeHint = "tokio";
check(ea.mode == "async", "mode field set to async");
check(ea.runtimeHint == "tokio", "runtimeHint field set to tokio");
}
// --- Test 2: BlockingAnnotation creation ---
static void test_blocking_annotation() {
BlockingAnnotation ba;
check(ba.conceptType == "BlockingAnnotation", "conceptType is BlockingAnnotation");
ba.kind = "io";
check(ba.kind == "io", "kind field set to io");
}
// --- Test 3: ParallelAnnotation creation ---
static void test_parallel_annotation() {
ParallelAnnotation pa;
check(pa.conceptType == "ParallelAnnotation", "conceptType is ParallelAnnotation");
pa.kind = "data";
check(pa.kind == "data", "kind field set to data");
}
// --- Test 4: TrapAnnotation, ExceptionAnnotation, PanicAnnotation ---
static void test_error_annotations() {
TrapAnnotation ta;
check(ta.conceptType == "TrapAnnotation", "TrapAnnotation conceptType");
ta.signal = "SIGSEGV";
check(ta.signal == "SIGSEGV", "signal set to SIGSEGV");
ExceptionAnnotation ea;
check(ea.conceptType == "ExceptionAnnotation", "ExceptionAnnotation conceptType");
ea.style = "checked";
check(ea.style == "checked", "style set to checked");
PanicAnnotation pa;
check(pa.conceptType == "PanicAnnotation", "PanicAnnotation conceptType");
pa.behavior = "unwind";
check(pa.behavior == "unwind", "behavior set to unwind");
}
// --- Test 5: ExecAnnotation JSON roundtrip ---
static void test_exec_json_roundtrip() {
auto* ea = new ExecAnnotation();
ea->id = "e1";
ea->mode = "event";
ea->runtimeHint = "libuv";
json j = toJson(ea);
check(j["properties"]["mode"] == "event", "JSON mode correct");
check(j["properties"]["runtimeHint"] == "libuv", "JSON runtimeHint correct");
ASTNode* restored = fromJson(j);
auto* rea = dynamic_cast<ExecAnnotation*>(restored);
check(rea != nullptr, "fromJson creates ExecAnnotation");
check(rea->mode == "event" && rea->runtimeHint == "libuv",
"roundtrip fields preserved");
delete ea;
delete restored;
}
// --- Test 6: PanicAnnotation JSON roundtrip ---
static void test_panic_json_roundtrip() {
auto* pa = new PanicAnnotation();
pa->id = "p1";
pa->behavior = "abort";
json j = toJson(pa);
ASTNode* restored = fromJson(j);
auto* rpa = dynamic_cast<PanicAnnotation*>(restored);
check(rpa != nullptr, "fromJson creates PanicAnnotation");
check(rpa->behavior == "abort", "roundtrip behavior preserved");
delete pa;
delete restored;
}
// --- Test 7: createNode factory for Step 275 types ---
static void test_create_node_factory() {
std::vector<std::string> types = {
"ExecAnnotation", "BlockingAnnotation", "ParallelAnnotation",
"TrapAnnotation", "ExceptionAnnotation", "PanicAnnotation"
};
for (const auto& t : types) {
ASTNode* node = createNode(t);
check(node != nullptr && node->conceptType == t,
"createNode(" + t + ") works");
delete node;
}
}
// --- Test 8: Compact AST shows exec in semantic summary ---
static void test_compact_ast_exec() {
auto* func = new Function();
func->id = "f1";
func->name = "fetchData";
auto* ea = new ExecAnnotation();
ea->mode = "async";
ea->runtimeHint = "tokio";
func->addChild("annotations", ea);
json sem = extractSemanticSummary(func);
check(sem.contains("exec"), "exec in semantic summary");
check(sem["exec"]["mode"] == "async", "exec mode correct");
check(sem["exec"]["runtime"] == "tokio", "exec runtime correct");
delete func;
}
// --- Test 9: Compact AST shows parallel and blocking ---
static void test_compact_ast_parallel_blocking() {
auto* func = new Function();
func->id = "f2";
func->name = "processArray";
auto* pa = new ParallelAnnotation(); pa->kind = "data";
auto* ba = new BlockingAnnotation(); ba->kind = "compute";
func->addChild("annotations", pa);
func->addChild("annotations", ba);
json sem = extractSemanticSummary(func);
check(sem["parallel"] == "data", "parallel in semantic summary");
check(sem["blocking"] == "compute", "blocking in semantic summary");
delete func;
}
// --- Test 10: Compact AST shows error handling annotations ---
static void test_compact_ast_error_handling() {
auto* func = new Function();
func->id = "f3";
func->name = "riskyOp";
auto* ta = new TrapAnnotation(); ta->signal = "SIGFPE";
auto* ea = new ExceptionAnnotation(); ea->style = "unchecked";
auto* pa = new PanicAnnotation(); pa->behavior = "unwind";
func->addChild("annotations", ta);
func->addChild("annotations", ea);
func->addChild("annotations", pa);
json sem = extractSemanticSummary(func);
check(sem["trap"] == "SIGFPE", "trap in semantic summary");
check(sem["exception"] == "unchecked", "exception in semantic summary");
check(sem["panic"] == "unwind", "panic in semantic summary");
delete func;
}
// --- Test 11: All 6 async/error annotations on one function ---
static void test_all_async_error_annotations() {
auto* func = new Function();
func->id = "f4";
func->name = "fullAsync";
func->addChild("annotations", [&]{ auto* a = new ExecAnnotation(); a->mode = "async"; return a; }());
func->addChild("annotations", [&]{ auto* a = new BlockingAnnotation(); a->kind = "io"; return a; }());
func->addChild("annotations", [&]{ auto* a = new ParallelAnnotation(); a->kind = "task"; return a; }());
func->addChild("annotations", [&]{ auto* a = new TrapAnnotation(); a->signal = "SIGSEGV"; return a; }());
func->addChild("annotations", [&]{ auto* a = new ExceptionAnnotation(); a->style = "checked"; return a; }());
func->addChild("annotations", [&]{ auto* a = new PanicAnnotation(); a->behavior = "abort"; return a; }());
json sem = extractSemanticSummary(func);
check(sem.contains("exec") && sem.contains("blocking") &&
sem.contains("parallel") && sem.contains("trap") &&
sem.contains("exception") && sem.contains("panic"),
"all 6 async/error annotations in semantic summary");
delete func;
}
// --- Test 12: TrapAnnotation and ExceptionAnnotation JSON roundtrip ---
static void test_trap_exception_roundtrip() {
auto* ta = new TrapAnnotation();
ta->id = "t1";
ta->signal = "SIGABRT";
json jt = toJson(ta);
ASTNode* rt = fromJson(jt);
auto* rta = dynamic_cast<TrapAnnotation*>(rt);
check(rta != nullptr && rta->signal == "SIGABRT", "TrapAnnotation roundtrip");
auto* ea = new ExceptionAnnotation();
ea->id = "ex1";
ea->style = "checked";
json je = toJson(ea);
ASTNode* re = fromJson(je);
auto* rea = dynamic_cast<ExceptionAnnotation*>(re);
check(rea != nullptr && rea->style == "checked", "ExceptionAnnotation roundtrip");
delete ta; delete rt; delete ea; delete re;
}
int main() {
std::cout << "=== Step 275: Async, Parallelism & Error Handling Annotations ===\n";
test_exec_annotation();
test_blocking_annotation();
test_parallel_annotation();
test_error_annotations();
test_exec_json_roundtrip();
test_panic_json_roundtrip();
test_create_node_factory();
test_compact_ast_exec();
test_compact_ast_parallel_blocking();
test_compact_ast_error_handling();
test_all_async_error_annotations();
test_trap_exception_roundtrip();
std::cout << "\nResults: " << passed << " passed, " << failed << " failed out of "
<< (passed + failed) << "\n";
return failed > 0 ? 1 : 0;
}

View File

@@ -0,0 +1,211 @@
// Step 276: Scope & Namespace Annotations (12 tests)
// Tests: BindingAnnotation, LookupAnnotation, CaptureAnnotation,
// VisibilityAnnotation, NamespaceAnnotation, ScopeAnnotation
// + JSON roundtrip + compact AST
#include <cassert>
#include <iostream>
#include <string>
#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;
static int failed = 0;
static void check(bool cond, const std::string& name) {
if (cond) { std::cout << " PASS: " << name << "\n"; ++passed; }
else { std::cout << " FAIL: " << name << "\n"; ++failed; }
}
// --- Test 1: BindingAnnotation creation ---
static void test_binding_annotation() {
BindingAnnotation ba;
check(ba.conceptType == "BindingAnnotation", "conceptType is BindingAnnotation");
ba.time = "static";
check(ba.time == "static", "time field set to static");
}
// --- Test 2: LookupAnnotation creation ---
static void test_lookup_annotation() {
LookupAnnotation la;
check(la.conceptType == "LookupAnnotation", "conceptType is LookupAnnotation");
la.mode = "lexical";
check(la.mode == "lexical", "mode field set to lexical");
}
// --- Test 3: CaptureAnnotation creation ---
static void test_capture_annotation() {
CaptureAnnotation ca;
check(ca.conceptType == "CaptureAnnotation", "conceptType is CaptureAnnotation");
ca.strategy = "move";
check(ca.strategy == "move", "strategy field set to move");
}
// --- Test 4: VisibilityAnnotation, NamespaceAnnotation, ScopeAnnotation ---
static void test_visibility_namespace_scope() {
VisibilityAnnotation va;
check(va.conceptType == "VisibilityAnnotation", "VisibilityAnnotation conceptType");
va.level = "friend";
check(va.level == "friend", "level set to friend");
NamespaceAnnotation na;
check(na.conceptType == "NamespaceAnnotation", "NamespaceAnnotation conceptType");
na.style = "qualified";
check(na.style == "qualified", "style set to qualified");
ScopeAnnotation sa;
check(sa.conceptType == "ScopeAnnotation", "ScopeAnnotation conceptType");
sa.kind = "singleton";
check(sa.kind == "singleton", "kind set to singleton");
}
// --- Test 5: CaptureAnnotation JSON roundtrip ---
static void test_capture_json_roundtrip() {
auto* ca = new CaptureAnnotation();
ca->id = "c1";
ca->strategy = "ref";
json j = toJson(ca);
check(j["properties"]["strategy"] == "ref", "JSON strategy correct");
ASTNode* restored = fromJson(j);
auto* rca = dynamic_cast<CaptureAnnotation*>(restored);
check(rca != nullptr, "fromJson creates CaptureAnnotation");
check(rca->strategy == "ref", "roundtrip strategy preserved");
delete ca;
delete restored;
}
// --- Test 6: VisibilityAnnotation JSON roundtrip ---
static void test_visibility_json_roundtrip() {
auto* va = new VisibilityAnnotation();
va->id = "v1";
va->level = "internal";
json j = toJson(va);
ASTNode* restored = fromJson(j);
auto* rva = dynamic_cast<VisibilityAnnotation*>(restored);
check(rva != nullptr, "fromJson creates VisibilityAnnotation");
check(rva->level == "internal", "roundtrip level preserved");
delete va;
delete restored;
}
// --- Test 7: ScopeAnnotation JSON roundtrip ---
static void test_scope_json_roundtrip() {
auto* sa = new ScopeAnnotation();
sa->id = "s1";
sa->kind = "global_leaked";
json j = toJson(sa);
ASTNode* restored = fromJson(j);
auto* rsa = dynamic_cast<ScopeAnnotation*>(restored);
check(rsa != nullptr, "fromJson creates ScopeAnnotation");
check(rsa->kind == "global_leaked", "roundtrip kind preserved");
delete sa;
delete restored;
}
// --- Test 8: createNode factory for Step 276 types ---
static void test_create_node_factory() {
std::vector<std::string> types = {
"BindingAnnotation", "LookupAnnotation", "CaptureAnnotation",
"VisibilityAnnotation", "NamespaceAnnotation", "ScopeAnnotation"
};
for (const auto& t : types) {
ASTNode* node = createNode(t);
check(node != nullptr && node->conceptType == t,
"createNode(" + t + ") works");
delete node;
}
}
// --- Test 9: Compact AST shows binding and lookup ---
static void test_compact_ast_binding_lookup() {
auto* func = new Function();
func->id = "f1";
func->name = "resolve";
auto* ba = new BindingAnnotation(); ba->time = "dynamic";
auto* la = new LookupAnnotation(); la->mode = "hoisted";
func->addChild("annotations", ba);
func->addChild("annotations", la);
json sem = extractSemanticSummary(func);
check(sem["binding"] == "dynamic", "binding in semantic summary");
check(sem["lookup"] == "hoisted", "lookup in semantic summary");
delete func;
}
// --- Test 10: Compact AST shows capture and visibility ---
static void test_compact_ast_capture_visibility() {
auto* func = new Function();
func->id = "f2";
func->name = "closureFactory";
auto* ca = new CaptureAnnotation(); ca->strategy = "value";
auto* va = new VisibilityAnnotation(); va->level = "private";
func->addChild("annotations", ca);
func->addChild("annotations", va);
json sem = extractSemanticSummary(func);
check(sem["capture"] == "value", "capture in semantic summary");
check(sem["visibility"] == "private", "visibility in semantic summary");
delete func;
}
// --- Test 11: All 6 scope annotations on one function ---
static void test_all_scope_annotations() {
auto* func = new Function();
func->id = "f3";
func->name = "fullScope";
func->addChild("annotations", [&]{ auto* a = new BindingAnnotation(); a->time = "static"; return a; }());
func->addChild("annotations", [&]{ auto* a = new LookupAnnotation(); a->mode = "lexical"; return a; }());
func->addChild("annotations", [&]{ auto* a = new CaptureAnnotation(); a->strategy = "move"; return a; }());
func->addChild("annotations", [&]{ auto* a = new VisibilityAnnotation(); a->level = "public"; return a; }());
func->addChild("annotations", [&]{ auto* a = new NamespaceAnnotation(); a->style = "flat"; return a; }());
func->addChild("annotations", [&]{ auto* a = new ScopeAnnotation(); a->kind = "local"; return a; }());
json sem = extractSemanticSummary(func);
check(sem.contains("binding") && sem.contains("lookup") &&
sem.contains("capture") && sem.contains("visibility") &&
sem.contains("namespace") && sem.contains("scope"),
"all 6 scope annotations in semantic summary");
delete func;
}
// --- Test 12: BindingAnnotation and NamespaceAnnotation JSON roundtrip ---
static void test_binding_namespace_roundtrip() {
auto* ba = new BindingAnnotation();
ba->id = "b1";
ba->time = "dynamic";
json jb = toJson(ba);
ASTNode* rb = fromJson(jb);
auto* rba = dynamic_cast<BindingAnnotation*>(rb);
check(rba != nullptr && rba->time == "dynamic", "BindingAnnotation roundtrip");
auto* na = new NamespaceAnnotation();
na->id = "n1";
na->style = "qualified";
json jn = toJson(na);
ASTNode* rn = fromJson(jn);
auto* rna = dynamic_cast<NamespaceAnnotation*>(rn);
check(rna != nullptr && rna->style == "qualified", "NamespaceAnnotation roundtrip");
delete ba; delete rb; delete na; delete rn;
}
int main() {
std::cout << "=== Step 276: Scope & Namespace Annotations ===\n";
test_binding_annotation();
test_lookup_annotation();
test_capture_annotation();
test_visibility_namespace_scope();
test_capture_json_roundtrip();
test_visibility_json_roundtrip();
test_scope_json_roundtrip();
test_create_node_factory();
test_compact_ast_binding_lookup();
test_compact_ast_capture_visibility();
test_all_scope_annotations();
test_binding_namespace_roundtrip();
std::cout << "\nResults: " << passed << " passed, " << failed << " failed out of "
<< (passed + failed) << "\n";
return failed > 0 ? 1 : 0;
}

View File

@@ -0,0 +1,324 @@
// Step 277: Phase 10c Integration Tests (8 tests)
// Cross-subject annotation workflows: type + concurrency + scope on AST,
// compact AST, sidecar roundtrip, RPC set/get for new types.
#include <cassert>
#include <iostream>
#include <string>
#include <filesystem>
#include "ast/ASTNode.h"
#include "ast/Module.h"
#include "ast/Function.h"
#include "ast/Variable.h"
#include "ast/Parameter.h"
#include "ast/Statement.h"
#include "ast/Expression.h"
#include "ast/Annotation.h"
#include "ast/Serialization.h"
#include "ASTUtils.h"
#include "CompactAST.h"
#include "SidecarPersistence.h"
#include "HeadlessEditorState.h"
#include <memory>
static int passed = 0;
static int failed = 0;
static void check(bool cond, const std::string& name) {
if (cond) { std::cout << " PASS: " << name << "\n"; ++passed; }
else { std::cout << " FAIL: " << name << "\n"; ++failed; }
}
// Helper: build a simple function AST
static Module* buildTestAST() {
auto* mod = new Module();
mod->id = "mod1";
mod->name = "test_module";
auto* fn = new Function();
fn->id = "fn1";
fn->name = "processData";
mod->addChild("functions", fn);
auto* fn2 = new Function();
fn2->id = "fn2";
fn2->name = "transformItem";
mod->addChild("functions", fn2);
return mod;
}
// Helper: invoke RPC
static json rpc(HeadlessEditorState& state, const std::string& method,
const json& params = {}, const std::string& session = "s1") {
json req = {{"jsonrpc", "2.0"}, {"id", 1}, {"method", method}};
if (!params.empty()) req["params"] = params;
return handleHeadlessAgentRequest(state, req, session);
}
// --- Test 1: Type annotations drive compact AST output ---
static void test_type_annotations_compact_ast() {
auto* mod = buildTestAST();
auto* fn = findNodeById(mod, "fn1");
// Add type annotations
auto* bw = new BitWidthAnnotation(); bw->width = 32;
auto* la = new LayoutAnnotation(); la->mode = "aligned"; la->alignment = 8;
auto* mu = new MutAnnotation(); mu->depth = "deep";
fn->addChild("annotations", bw);
fn->addChild("annotations", la);
fn->addChild("annotations", mu);
json compact = toJsonCompactSummary(mod);
// Find fn1 in compact summary
bool found = false;
for (const auto& node : compact) {
if (node.value("id", "") == "fn1" && node.contains("semantic")) {
auto& sem = node["semantic"];
found = sem.contains("bitWidth") && sem.contains("layout") &&
sem.contains("mutability");
}
}
check(found, "type annotations appear in compact AST summary");
delete mod;
}
// --- Test 2: Concurrency annotations in compact AST ---
static void test_concurrency_annotations_compact_ast() {
auto* mod = buildTestAST();
auto* fn = findNodeById(mod, "fn1");
auto* aa = new AtomicAnnotation(); aa->consistency = "seq_cst";
auto* sa = new SyncAnnotation(); sa->primitive = "monitor";
fn->addChild("annotations", aa);
fn->addChild("annotations", sa);
json compact = toJsonCompactSummary(mod);
bool found = false;
for (const auto& node : compact) {
if (node.value("id", "") == "fn1" && node.contains("semantic")) {
auto& sem = node["semantic"];
found = sem.contains("atomic") && sem.contains("sync");
}
}
check(found, "concurrency annotations appear in compact AST summary");
delete mod;
}
// --- Test 3: Scope annotations in compact AST ---
static void test_scope_annotations_compact_ast() {
auto* mod = buildTestAST();
auto* fn = findNodeById(mod, "fn2");
auto* ca = new CaptureAnnotation(); ca->strategy = "ref";
auto* va = new VisibilityAnnotation(); va->level = "private";
fn->addChild("annotations", ca);
fn->addChild("annotations", va);
json compact = toJsonCompactSummary(mod);
bool found = false;
for (const auto& node : compact) {
if (node.value("id", "") == "fn2" && node.contains("semantic")) {
auto& sem = node["semantic"];
found = sem.contains("capture") && sem.contains("visibility");
}
}
check(found, "scope annotations appear in compact AST summary");
delete mod;
}
// --- Test 4: All Subject 2-4 annotations survive sidecar save/load ---
static void test_sidecar_roundtrip() {
namespace fs = std::filesystem;
std::string workspace = "/tmp/step277_test_ws";
fs::create_directories(workspace);
auto* mod = buildTestAST();
auto* fn1 = findNodeById(mod, "fn1");
auto* fn2 = findNodeById(mod, "fn2");
// Add one annotation from each subject
auto* bw = new BitWidthAnnotation(); bw->width = 64;
fn1->addChild("annotations", bw);
auto* aa = new AtomicAnnotation(); aa->consistency = "relaxed";
fn1->addChild("annotations", aa);
auto* ba = new BindingAnnotation(); ba->time = "static";
fn2->addChild("annotations", ba);
auto saveResult = saveSidecarAST(workspace, "test.wh", mod);
check(saveResult.success, "sidecar save succeeds");
check(saveResult.annotationCount == 3, "3 annotations saved");
// Build fresh AST and load
auto* mod2 = buildTestAST();
auto loadResult = loadSidecarAST(workspace, "test.wh", mod2);
check(loadResult.success, "sidecar load succeeds");
check(loadResult.mergedCount == 3, "3 annotations merged");
// Verify annotations on reloaded AST
auto* rfn1 = findNodeById(mod2, "fn1");
auto annos1 = rfn1->getChildren("annotations");
bool hasBitWidth = false, hasAtomic = false;
for (auto* a : annos1) {
if (a->conceptType == "BitWidthAnnotation") hasBitWidth = true;
if (a->conceptType == "AtomicAnnotation") hasAtomic = true;
}
check(hasBitWidth && hasAtomic, "type and concurrency annotations survive roundtrip");
delete mod;
delete mod2;
fs::remove_all(workspace);
}
// --- Test 5: Mixed annotations on single function ---
static void test_mixed_annotations_single_function() {
auto* func = new Function();
func->id = "f1";
func->name = "mixedOp";
// Subject 2: type
auto* bw = new BitWidthAnnotation(); bw->width = 16;
auto* id = new IdentityAnnotation(); id->mode = "structural";
// Subject 3: concurrency
auto* tm = new ThreadModelAnnotation(); tm->model = "green";
auto* ea = new ExecAnnotation(); ea->mode = "async";
// Subject 4: scope
auto* va = new VisibilityAnnotation(); va->level = "public";
auto* ca = new CaptureAnnotation(); ca->strategy = "value";
func->addChild("annotations", bw);
func->addChild("annotations", id);
func->addChild("annotations", tm);
func->addChild("annotations", ea);
func->addChild("annotations", va);
func->addChild("annotations", ca);
json sem = extractSemanticSummary(func);
check(sem.contains("bitWidth") && sem.contains("identity") &&
sem.contains("threadModel") && sem.contains("exec") &&
sem.contains("visibility") && sem.contains("capture"),
"mixed annotations from 3 subjects on single function");
delete func;
}
// --- Test 6: getSemanticAnnotations returns Subject 2-4 types via RPC ---
static void test_rpc_get_annotations() {
HeadlessEditorState state;
state.openBuffer("test.wh", "", "python");
auto* mod = buildTestAST();
state.activeBuffer->sync.setAST(std::unique_ptr<Module>(mod));
state.setAgentRole("s1", AgentRole::Refactor);
// Set type annotation via RPC
auto r1 = rpc(state, "setSemanticAnnotation", {
{"nodeId", "fn1"}, {"type", "bitWidth"}, {"fields", {{"width", 32}}}
});
check(r1.contains("result"), "setSemanticAnnotation bitWidth via RPC");
// Set concurrency annotation via RPC
auto r2 = rpc(state, "setSemanticAnnotation", {
{"nodeId", "fn1"}, {"type", "atomic"}, {"fields", {{"consistency", "seq_cst"}}}
});
check(r2.contains("result"), "setSemanticAnnotation atomic via RPC");
// Set scope annotation via RPC
auto r3 = rpc(state, "setSemanticAnnotation", {
{"nodeId", "fn1"}, {"type", "visibility"}, {"fields", {{"level", "public"}}}
});
check(r3.contains("result"), "setSemanticAnnotation visibility via RPC");
// Query all annotations
auto r4 = rpc(state, "getSemanticAnnotations", {{"nodeId", "fn1"}});
auto annos = r4["result"]["annotations"];
bool hasBW = false, hasAtom = false, hasVis = false;
for (const auto& a : annos) {
std::string t = a.value("type", "");
if (t == "BitWidthAnnotation") hasBW = true;
if (t == "AtomicAnnotation") hasAtom = true;
if (t == "VisibilityAnnotation") hasVis = true;
}
check(hasBW && hasAtom && hasVis,
"getSemanticAnnotations returns Subject 2-4 types");
}
// --- Test 7: setSemanticAnnotation works for all new type keys ---
static void test_rpc_set_all_new_types() {
HeadlessEditorState state;
state.openBuffer("test.wh", "", "python");
auto* mod = buildTestAST();
state.activeBuffer->sync.setAST(std::unique_ptr<Module>(mod));
state.setAgentRole("s1", AgentRole::Refactor);
// Test a representative selection of new type keys
std::vector<std::pair<std::string, json>> tests = {
{"endian", {{"order", "big"}}},
{"layout", {{"mode", "packed"}, {"alignment", 4}}},
{"nullability", {{"nullable", true}, {"strategy", "strict"}}},
{"variance", {{"variance", "covariant"}}},
{"identity", {{"mode", "nominal"}}},
{"mut", {{"depth", "deep"}}},
{"typeState", {{"state", "reified"}}},
{"sync", {{"primitive", "monitor"}}},
{"threadModel", {{"model", "os"}}},
{"memoryBarrier", json::object()},
{"exec", {{"mode", "async"}, {"runtimeHint", "tokio"}}},
{"blocking", {{"kind", "io"}}},
{"parallel", {{"kind", "data"}}},
{"trap", {{"signal", "SIGSEGV"}}},
{"exception", {{"style", "checked"}}},
{"panic", {{"behavior", "abort"}}},
{"binding", {{"time", "static"}}},
{"lookup", {{"mode", "lexical"}}},
{"capture", {{"strategy", "move"}}},
{"namespace", {{"style", "qualified"}}},
{"scope", {{"kind", "local"}}},
};
int successCount = 0;
for (const auto& [type, fields] : tests) {
auto r = rpc(state, "setSemanticAnnotation", {
{"nodeId", "fn2"}, {"type", type}, {"fields", fields}
});
if (r.contains("result") && r["result"].value("success", false))
++successCount;
}
check(successCount == (int)tests.size(),
"all 21 new type keys accepted by setSemanticAnnotation RPC");
}
// --- Test 8: isSemanticAnnotation recognizes all new types ---
static void test_is_semantic_annotation() {
std::vector<std::string> allTypes = {
"BitWidthAnnotation", "EndianAnnotation", "LayoutAnnotation",
"NullabilityAnnotation", "VarianceAnnotation",
"IdentityAnnotation", "MutAnnotation", "TypeStateAnnotation",
"AtomicAnnotation", "SyncAnnotation", "ThreadModelAnnotation",
"MemoryBarrierAnnotation",
"ExecAnnotation", "BlockingAnnotation", "ParallelAnnotation",
"TrapAnnotation", "ExceptionAnnotation", "PanicAnnotation",
"BindingAnnotation", "LookupAnnotation", "CaptureAnnotation",
"VisibilityAnnotation", "NamespaceAnnotation", "ScopeAnnotation"
};
int recognized = 0;
for (const auto& t : allTypes) {
if (isSemanticAnnotation(t)) ++recognized;
}
check(recognized == 24, "isSemanticAnnotation recognizes all 24 new types");
check(!isSemanticAnnotation("DerefStrategy"),
"isSemanticAnnotation rejects non-semantic DerefStrategy");
}
int main() {
std::cout << "=== Step 277: Phase 10c Integration Tests ===\n";
test_type_annotations_compact_ast();
test_concurrency_annotations_compact_ast();
test_scope_annotations_compact_ast();
test_sidecar_roundtrip();
test_mixed_annotations_single_function();
test_rpc_get_annotations();
test_rpc_set_all_new_types();
test_is_semantic_annotation();
std::cout << "\nResults: " << passed << " passed, " << failed << " failed out of "
<< (passed + failed) << "\n";
return failed > 0 ? 1 : 0;
}