// Step 341: Phase 12d Integration + Sprint 12 Summary (8 tests) // Full C++ depth validation: parse → AST → generate roundtrips, cross-language, // combined workflow + C++ constructs, sprint 12 totals verification #include #include #include #include #include "ast/PreprocessorNodes.h" #include "ast/EnumNamespaceNodes.h" #include "ast/ClassDeclaration.h" #include "ast/GenericType.h" #include "ast/AsyncNodes.h" #include "ast/Serialization.h" #include "ast/Parser.h" #include "ast/PythonGenerator.h" #include "ast/CppGenerator.h" #include "ast/JavaGenerator.h" #include "ast/RustGenerator.h" #include "ast/GoGenerator.h" #include "ast/JavaScriptGenerator.h" #include "ast/ElispGenerator.h" #include "ast/KotlinGenerator.h" #include "ast/CSharpGenerator.h" #include "CompactAST.h" int main() { int passed = 0; // Test 1: Parse realistic C++ header: includes + pragma + namespace + enum + class + function { std::string src = R"( #pragma once #include #include "ast/ASTNode.h" namespace whetstone { enum class NodeKind : int { Function = 0, Variable = 1, Class = 2 }; class ASTVisitor { public: virtual void visit() {} }; void helper(int x) { return; } } )"; auto mod = TreeSitterParser::parseCpp(src); auto stmts = mod->getChildren("statements"); // Collect all concept types present std::set types; for (auto* s : stmts) types.insert(s->conceptType); assert(types.count("PragmaDirective") || types.count("IncludeDirective")); assert(types.count("NamespaceDeclaration")); // Namespace should contain enum, class, function bool foundNs = false; for (auto* s : stmts) { if (s->conceptType == "NamespaceDeclaration") { foundNs = true; auto body = s->getChildren("body"); std::set bodyTypes; for (auto* b : body) bodyTypes.insert(b->conceptType); assert(bodyTypes.count("EnumDeclaration")); assert(bodyTypes.count("ClassDeclaration")); assert(bodyTypes.count("Function")); } } assert(foundNs); std::cout << "Test 1 PASSED: Parse realistic C++ header with all constructs\n"; passed++; } // Test 2: Round-trip: C++ header → AST → JSON → fromJson → generate → verify structure { std::string src = R"( enum class Color : int { Red = 0, Green = 1 }; )"; auto mod = TreeSitterParser::parseCpp(src); auto stmts = mod->getChildren("statements"); bool foundEnum = false; for (auto* s : stmts) { if (s->conceptType == "EnumDeclaration") { foundEnum = true; // JSON roundtrip nlohmann::json j = propertiesToJson(s); auto* restored = createNode(s->conceptType); setPropertiesFromJson(restored, j); // Verify properties survived auto* orig = static_cast(s); auto* rest = static_cast(restored); assert(rest->name == orig->name); assert(rest->isScoped == orig->isScoped); delete restored; } } assert(foundEnum); std::cout << "Test 2 PASSED: Enum parse → JSON roundtrip → verify\n"; passed++; } // Test 3: Enum inside namespace: parse → verify scoping in AST { std::string src = R"( namespace outer { enum class Status { Active, Inactive }; } )"; auto mod = TreeSitterParser::parseCpp(src); auto stmts = mod->getChildren("statements"); bool found = false; for (auto* s : stmts) { if (s->conceptType == "NamespaceDeclaration") { auto* ns = static_cast(s); assert(ns->name == "outer"); auto body = ns->getChildren("body"); bool hasEnum = false; for (auto* b : body) { if (b->conceptType == "EnumDeclaration") { hasEnum = true; auto* e = static_cast(b); assert(e->name == "Status"); assert(e->isScoped); } } assert(hasEnum); found = true; } } assert(found); std::cout << "Test 3 PASSED: Enum inside namespace scoping\n"; passed++; } // Test 4: Cross-language: C++ enum → Java enum + Python class(Enum) + Rust enum { EnumDeclaration e; e.name = "Color"; e.isScoped = true; e.addChild("members", new EnumMember("m1", "Red", "0")); e.addChild("members", new EnumMember("m2", "Green", "1")); e.addChild("members", new EnumMember("m3", "Blue", "2")); CppGenerator cppGen; std::string cppOut = cppGen.generate(&e); assert(cppOut.find("enum class Color") != std::string::npos); JavaGenerator javaGen; std::string javaOut = javaGen.generate(&e); assert(javaOut.find("enum Color") != std::string::npos); assert(javaOut.find("Red") != std::string::npos); PythonGenerator pyGen; std::string pyOut = pyGen.generate(&e); assert(pyOut.find("class Color(Enum)") != std::string::npos); RustGenerator rustGen; std::string rustOut = rustGen.generate(&e); assert(rustOut.find("enum Color") != std::string::npos); KotlinGenerator ktGen; std::string ktOut = ktGen.generate(&e); assert(ktOut.find("enum class Color") != std::string::npos); CSharpGenerator csGen; std::string csOut = csGen.generate(&e); assert(csOut.find("enum Color") != std::string::npos); std::cout << "Test 4 PASSED: C++ enum → 6 language outputs\n"; passed++; } // Test 5: Combined namespace + class + enum + function → full pipeline { NamespaceDeclaration ns; ns.name = "ast"; auto* cls = new ClassDeclaration(); cls->name = "Node"; cls->isAbstract = true; auto* meth = new Function(); meth->name = "accept"; cls->addChild("methods", meth); ns.addChild("body", cls); auto* e = new EnumDeclaration(); e->name = "Kind"; e->isScoped = true; e->addChild("members", new EnumMember("m1", "Expr")); e->addChild("members", new EnumMember("m2", "Stmt")); ns.addChild("body", e); auto* func = new Function(); func->name = "createNode"; ns.addChild("body", func); CppGenerator gen; std::string out = gen.generate(&ns); assert(out.find("namespace ast") != std::string::npos); assert(out.find("Node") != std::string::npos); assert(out.find("accept") != std::string::npos); assert(out.find("enum class Kind") != std::string::npos); assert(out.find("Expr") != std::string::npos); assert(out.find("createNode") != std::string::npos); std::cout << "Test 5 PASSED: Combined namespace + class + enum + function pipeline\n"; passed++; } // Test 6: All new AST nodes serialize/deserialize correctly (batch verification) { // IncludeDirective IncludeDirective inc; inc.path = "vector"; inc.isSystem = true; nlohmann::json j1 = propertiesToJson(&inc); auto* r1 = createNode("IncludeDirective"); setPropertiesFromJson(r1, j1); assert(static_cast(r1)->path == "vector"); assert(static_cast(r1)->isSystem); // PragmaDirective PragmaDirective prag; prag.directive = "once"; nlohmann::json j2 = propertiesToJson(&prag); auto* r2 = createNode("PragmaDirective"); setPropertiesFromJson(r2, j2); assert(static_cast(r2)->directive == "once"); // MacroDefinition MacroDefinition mac; mac.name = "MAX"; mac.isFunctionLike = true; mac.parameters = {"a", "b"}; mac.body = "((a)>(b)?(a):(b))"; nlohmann::json j3 = propertiesToJson(&mac); auto* r3 = createNode("MacroDefinition"); setPropertiesFromJson(r3, j3); auto* rm = static_cast(r3); assert(rm->name == "MAX"); assert(rm->isFunctionLike); assert(rm->parameters.size() == 2); // EnumDeclaration EnumDeclaration ed; ed.name = "Color"; ed.isScoped = true; ed.underlyingType = "int"; nlohmann::json j4 = propertiesToJson(&ed); auto* r4 = createNode("EnumDeclaration"); setPropertiesFromJson(r4, j4); auto* re = static_cast(r4); assert(re->name == "Color"); assert(re->isScoped); assert(re->underlyingType == "int"); // NamespaceDeclaration NamespaceDeclaration nsd; nsd.name = "whetstone"; nlohmann::json j5 = propertiesToJson(&nsd); auto* r5 = createNode("NamespaceDeclaration"); setPropertiesFromJson(r5, j5); assert(static_cast(r5)->name == "whetstone"); // TypeAlias TypeAlias ta; ta.aliasName = "Ptr"; ta.targetType = "int*"; ta.isUsing = true; nlohmann::json j6 = propertiesToJson(&ta); auto* r6 = createNode("TypeAlias"); setPropertiesFromJson(r6, j6); auto* rt = static_cast(r6); assert(rt->aliasName == "Ptr"); assert(rt->targetType == "int*"); assert(rt->isUsing); delete r1; delete r2; delete r3; delete r4; delete r5; delete r6; std::cout << "Test 6 PASSED: All 6 new AST nodes serialize/deserialize correctly\n"; passed++; } // Test 7: CompactAST names for all new node types { IncludeDirective inc; inc.path = "vector"; inc.isSystem = true; PragmaDirective prag; prag.directive = "once"; MacroDefinition mac; mac.name = "MAX"; EnumDeclaration ed; ed.name = "Color"; EnumMember em("m1", "Red", "0"); NamespaceDeclaration nsd; nsd.name = "whetstone"; TypeAlias ta; ta.aliasName = "Ptr"; assert(getNodeName(&inc) == "vector"); assert(getNodeName(&prag) == "once"); assert(getNodeName(&mac) == "MAX"); assert(getNodeName(&ed) == "Color"); assert(getNodeName(&em) == "Red"); assert(getNodeName(&nsd) == "whetstone"); assert(getNodeName(&ta) == "Ptr"); std::cout << "Test 7 PASSED: CompactAST names for all new node types\n"; passed++; } // Test 8: C++ self-hosting progress — parse simplified Whetstone header fragment { std::string src = R"( #pragma once #include #include #include "ASTNode.h" namespace whetstone { enum class NodeKind { Module, Function, Variable }; class ProjectionGenerator { public: virtual std::string generate() {} }; class CppGenerator : public ProjectionGenerator { public: std::string generate() {} }; } )"; auto mod = TreeSitterParser::parseCpp(src); auto stmts = mod->getChildren("statements"); // Count constructs found int includes = 0, pragmas = 0, namespaces = 0; for (auto* s : stmts) { if (s->conceptType == "IncludeDirective") includes++; if (s->conceptType == "PragmaDirective") pragmas++; if (s->conceptType == "NamespaceDeclaration") namespaces++; } assert(includes >= 2); // , , "ASTNode.h" assert(pragmas >= 1); assert(namespaces >= 1); // Inside namespace: enum + 2 classes for (auto* s : stmts) { if (s->conceptType == "NamespaceDeclaration") { auto body = s->getChildren("body"); int enums = 0, classes = 0; for (auto* b : body) { if (b->conceptType == "EnumDeclaration") enums++; if (b->conceptType == "ClassDeclaration") classes++; } assert(enums >= 1); assert(classes >= 2); // CppGenerator should inherit from ProjectionGenerator for (auto* b : body) { if (b->conceptType == "ClassDeclaration") { auto* cls = static_cast(b); if (cls->name == "CppGenerator") { auto bases = cls->getBases(); assert(!bases.empty()); assert(bases[0].name == "ProjectionGenerator"); } } } } } std::cout << "Test 8 PASSED: Self-hosting progress — Whetstone header fragment parsed\n"; passed++; } std::cout << "\nResults: " << passed << "/8\n"; assert(passed == 8); return 0; }