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 6019 PostTypeCheckingVerifier::PostTypeCheckingVerifier(GlobalResourceManager &resourceManager, SourceFile *sourceFile)
15 6019 : CompilerPass(resourceManager, sourceFile) {}
16
17
1/2
✓ Branch 2 → 3 taken 6019 times.
✗ Branch 2 → 5 not taken.
6019 void PostTypeCheckingVerifier::verify(ASTNode *ast) { visit(ast); }
18
19 52433 std::any PostTypeCheckingVerifier::visitFctDef(FctDefNode *node) {
20
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 52433 times.
52433 assert(node->entry != nullptr);
21
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 52433 times.
52433 assert(!node->manifestations.empty());
22 52433 return visitChildren(node);
23 }
24
25 30335 std::any PostTypeCheckingVerifier::visitProcDef(ProcDefNode *node) {
26
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 30335 times.
30335 assert(node->entry != nullptr);
27
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 30335 times.
30335 assert(!node->manifestations.empty());
28 30335 return visitChildren(node);
29 }
30
31 8753 std::any PostTypeCheckingVerifier::visitStructDef(StructDefNode *node) {
32
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 8753 times.
8753 assert(node->entry != nullptr);
33 8753 return visitChildren(node);
34 }
35
36 1283 std::any PostTypeCheckingVerifier::visitInterfaceDef(InterfaceDefNode *node) {
37
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1283 times.
1283 assert(node->entry != nullptr);
38 1283 return visitChildren(node);
39 }
40
41 1105 std::any PostTypeCheckingVerifier::visitEnumDef(EnumDefNode *node) {
42
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1105 times.
1105 assert(node->entry != nullptr);
43 1105 return visitChildren(node);
44 }
45
46 14922 std::any PostTypeCheckingVerifier::visitEnumItem(EnumItemNode *node) {
47 // EnumItemNode::entry is intentionally not stored on the node; the entry lives in the enum scope.
48 14922 return visitChildren(node);
49 }
50
51 936 std::any PostTypeCheckingVerifier::visitAliasDef(AliasDefNode *node) {
52
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 936 times.
936 assert(node->entry != nullptr);
53 936 return visitChildren(node);
54 }
55
56 5905 std::any PostTypeCheckingVerifier::visitGlobalVarDef(GlobalVarDefNode *node) {
57
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 5905 times.
5905 assert(node->entry != nullptr);
58 5905 return visitChildren(node);
59 }
60
61 7838 std::any PostTypeCheckingVerifier::visitSignature(SignatureNode *node) {
62
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 7838 times.
7838 assert(node->entry != nullptr);
63 7838 return visitChildren(node);
64 }
65
66 129597 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 128638 times.
✓ Branch 2 → 6 taken 959 times.
129597 if (!node->isForEachItem)
70
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 128638 times.
128638 assert(!node->entries.empty());
71 129597 return visitChildren(node);
72 }
73
74 125981 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 2015944 times.
✓ Branch 8 → 9 taken 113468 times.
2129412 for (const auto &[builtinFctName, _] : BUILTIN_FUNCTIONS)
78
2/2
✓ Branch 5 → 6 taken 12513 times.
✓ Branch 5 → 7 taken 2003431 times.
2015944 if (node->fqFunctionName == builtinFctName)
79 12513 return visitChildren(node);
80
81
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 113468 times.
113468 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 140999 times.
✓ Branch 2 → 4 taken 30228 times.
✓ Branch 3 → 4 taken 140999 times.
✗ Branch 3 → 5 not taken.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 113468 times.
284695 assert(std::ranges::all_of(node->data, [](const FctCallNode::FctCallData &d) {
85 return d.calleeParentScope == nullptr || d.callee != nullptr;
86 }));
87 113468 return visitChildren(node);
88 }
89
90 564994 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 331053 times.
✓ Branch 3 → 10 taken 233941 times.
564994 if (!node->fqIdentifier.empty()) {
95
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 331053 times.
331053 assert(!node->data.empty());
96
4/6
✓ Branch 2 → 3 taken 404875 times.
✓ Branch 2 → 4 taken 122950 times.
✓ Branch 3 → 4 taken 404875 times.
✗ Branch 3 → 5 not taken.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 331053 times.
858878 assert(std::ranges::all_of(node->data, [](const AtomicExprNode::VarAccessData &d) {
97 return d.accessScope == nullptr || d.entry != nullptr;
98 }));
99 }
100 564994 return visitChildren(node);
101 }
102
103 2729 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 2729 times.
2729 assert(!node->instantiatedStructs.empty());
108 2729 return visitChildren(node);
109 }
110
111 16 std::any PostTypeCheckingVerifier::visitLambdaFunc(LambdaFuncNode *node) {
112
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 16 times.
16 assert(!node->manifestations.empty());
113 16 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