GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 59 / 0 / 59
Functions: 100.0% 20 / 0 / 20
Branches: 60.7% 34 / 0 / 56

src/typechecker/PostTypeCheckingVerifier.cpp
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #include "PostTypeCheckingVerifier.h"
4
5 #include <algorithm>
6 #include <cassert>
7 #include <ranges>
8
9 #include <ast/ASTNodes.h>
10 #include <typechecker/Builtins.h>
11
12 namespace spice::compiler {
13
14 7659 PostTypeCheckingVerifier::PostTypeCheckingVerifier(GlobalResourceManager &resourceManager, SourceFile *sourceFile)
15 7659 : CompilerPass(resourceManager, sourceFile) {}
16
17
1/2
✓ Branch 2 → 3 taken 7659 times.
✗ Branch 2 → 5 not taken.
7659 void PostTypeCheckingVerifier::verify(ASTNode *ast) { visit(ast); }
18
19 64394 std::any PostTypeCheckingVerifier::visitFctDef(FctDefNode *node) {
20
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 64394 times.
64394 assert(node->entry != nullptr);
21
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 64394 times.
64394 assert(!node->manifestations.empty());
22 64394 return visitChildren(node);
23 }
24
25 39612 std::any PostTypeCheckingVerifier::visitProcDef(ProcDefNode *node) {
26
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 39612 times.
39612 assert(node->entry != nullptr);
27
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 39612 times.
39612 assert(!node->manifestations.empty());
28 39612 return visitChildren(node);
29 }
30
31 10478 std::any PostTypeCheckingVerifier::visitStructDef(StructDefNode *node) {
32
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 10478 times.
10478 assert(node->entry != nullptr);
33 10478 return visitChildren(node);
34 }
35
36 1464 std::any PostTypeCheckingVerifier::visitInterfaceDef(InterfaceDefNode *node) {
37
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1464 times.
1464 assert(node->entry != nullptr);
38 1464 return visitChildren(node);
39 }
40
41 1164 std::any PostTypeCheckingVerifier::visitEnumDef(EnumDefNode *node) {
42
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1164 times.
1164 assert(node->entry != nullptr);
43 1164 return visitChildren(node);
44 }
45
46 15716 std::any PostTypeCheckingVerifier::visitEnumItem(EnumItemNode *node) {
47 // EnumItemNode::entry is intentionally not stored on the node; the entry lives in the enum scope.
48 15716 return visitChildren(node);
49 }
50
51 998 std::any PostTypeCheckingVerifier::visitAliasDef(AliasDefNode *node) {
52
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 998 times.
998 assert(node->entry != nullptr);
53 998 return visitChildren(node);
54 }
55
56 6477 std::any PostTypeCheckingVerifier::visitGlobalVarDef(GlobalVarDefNode *node) {
57
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 6477 times.
6477 assert(node->entry != nullptr);
58 6477 return visitChildren(node);
59 }
60
61 8783 std::any PostTypeCheckingVerifier::visitSignature(SignatureNode *node) {
62
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 8783 times.
8783 assert(node->entry != nullptr);
63 8783 return visitChildren(node);
64 }
65
66 164705 std::any PostTypeCheckingVerifier::visitDeclStmt(DeclStmtNode *node) {
67 // entries is resized to manifestationCount; unsubstantiated generic slots remain null.
68 // We can only assert the vector was populated at all.
69
2/2
✓ Branch 2 → 3 taken 163600 times.
✓ Branch 2 → 6 taken 1105 times.
164705 if (!node->isForEachItem)
70
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 163600 times.
163600 assert(!node->entries.empty());
71 164705 return visitChildren(node);
72 }
73
74 156341 std::any PostTypeCheckingVerifier::visitFctCall(FctCallNode *node) {
75 // Builtin calls (printf, len, panic, etc.) return early in the TypeChecker before
76 // populating callee/calleeParentScope — skip them, matching the IRGenerator's behavior.
77
2/2
✓ Branch 8 → 3 taken 2496703 times.
✓ Branch 8 → 9 taken 139566 times.
2636269 for (const auto &[builtinFctName, _] : BUILTIN_FUNCTIONS)
78
2/2
✓ Branch 5 → 6 taken 16775 times.
✓ Branch 5 → 7 taken 2479928 times.
2496703 if (node->fqFunctionName == builtinFctName)
79 16775 return visitChildren(node);
80
81
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 139566 times.
139566 assert(!node->data.empty());
82 // calleeParentScope is set for every visited non-fct-ptr non-builtin slot; use it as the
83 // "was this slot actually resolved?" indicator. Unsubstantiated/uncompiled slots have it null.
84
4/6
✓ Branch 2 → 3 taken 180422 times.
✓ Branch 2 → 4 taken 41675 times.
✓ Branch 3 → 4 taken 180422 times.
✗ Branch 3 → 5 not taken.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 139566 times.
361663 assert(std::ranges::all_of(node->data, [](const FctCallNode::FctCallData &d) {
85 return d.calleeParentScope == nullptr || d.callee != nullptr;
86 }));
87 139566 return visitChildren(node);
88 }
89
90 733459 std::any PostTypeCheckingVerifier::visitAtomicExpr(AtomicExprNode *node) {
91 // data is only populated for identifier accesses (not for constants / nested exprs).
92 // Within identifier accesses, only substantiated manifestation slots have accessScope set;
93 // unsubstantiated generic slots are left at the default-initialized nullptr.
94
2/2
✓ Branch 3 → 4 taken 431397 times.
✓ Branch 3 → 10 taken 302062 times.
733459 if (!node->fqIdentifier.empty()) {
95
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 431397 times.
431397 assert(!node->data.empty());
96
4/6
✓ Branch 2 → 3 taken 556245 times.
✓ Branch 2 → 4 taken 167629 times.
✓ Branch 3 → 4 taken 556245 times.
✗ Branch 3 → 5 not taken.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 431397 times.
1155271 assert(std::ranges::all_of(node->data, [](const AtomicExprNode::VarAccessData &d) {
97 return d.accessScope == nullptr || d.entry != nullptr;
98 }));
99 }
100 733459 return visitChildren(node);
101 }
102
103 2850 std::any PostTypeCheckingVerifier::visitStructInstantiation(StructInstantiationNode *node) {
104 // instantiatedStructs is resized to manifestationCount; unsubstantiated generic slots remain null.
105 // We can only safely assert the vector was populated — element-level null checks would false-positive
106 // on unsubstantiated generic manifestation slots.
107
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 2850 times.
2850 assert(!node->instantiatedStructs.empty());
108 2850 return visitChildren(node);
109 }
110
111 18 std::any PostTypeCheckingVerifier::visitLambdaFunc(LambdaFuncNode *node) {
112
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 18 times.
18 assert(!node->manifestations.empty());
113 18 return visitChildren(node);
114 }
115
116 157 std::any PostTypeCheckingVerifier::visitLambdaProc(LambdaProcNode *node) {
117
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 157 times.
157 assert(!node->manifestations.empty());
118 157 return visitChildren(node);
119 }
120
121 1 std::any PostTypeCheckingVerifier::visitLambdaExpr(LambdaExprNode *node) {
122
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 1 time.
1 assert(!node->manifestations.empty());
123 1 return visitChildren(node);
124 }
125
126 } // namespace spice::compiler
127