GCC Code Coverage Report


src/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
52 / 52
100.0%
Branches:
8 / 8, 2 excl
100.0%
Functions:
9 / 9, 1 excl
100.0%

symboltablebuilder/scope-handle.spice
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 // Own imports
4 import "@/compiler-pass";
5 import "@/ast/ast-nodes";
6 import "@/symboltablebuilder/scope";
7 import "@/irgenerator/ir-generator";
8
9 /**
10 * This struct is used to change the current scope to a child scope and change it back to the parent scope when the handle
11 * object is destroyed. This can be used in visit functions to automatically leave the scope when the function returns.
12 *
13 * The constructors that take an IRGenerator additionally push/pop a lexical block for the debug info.
14 */
15 public type ScopeHandle struct {
16 CompilerPass* pass
17 ScopeType scopeType
18 107168 bool alreadyExecuted = false
19 107168 IRGenerator* generator = nil<IRGenerator*>
20 }
21
22 5605 public p ScopeHandle.ctor(CompilerPass* pass, Scope* childScope, ScopeType scopeType) {
23 5605 this.pass = pass;
24 5605 this.scopeType = scopeType;
25 5605 this.pass.changeToScope(childScope, scopeType);
26 5605 }
27
28 54981 public p ScopeHandle.ctor(CompilerPass* pass, const String& childScopeId, ScopeType scopeType) {
29 54981 this.pass = pass;
30 54981 this.scopeType = scopeType;
31 54981 Scope* currentScope = this.pass.currentScope;
32 54981 this.pass.changeToScope(currentScope.getChildScope(childScopeId), scopeType);
33 54981 }
34
35 46582 public p ScopeHandle.ctor(IRGenerator* generator, const String& childScopeId, ScopeType scopeType, const ASTNode* node) {
36 46582 assert scopeType != ScopeType::FUNC_PROC_BODY; // Functions/procedures manage scopes manually
37 46582 this.pass = &generator.compilerPass;
38 46582 this.scopeType = scopeType;
39 46582 this.generator = generator;
40 46582 Scope* currentScope = this.pass.currentScope;
41 46582 this.pass.changeToScope(currentScope.getChildScope(childScopeId), scopeType);
42 46582 generator.diGenerator.pushLexicalBlock(node);
43 46582 }
44
45 107168 public p ScopeHandle.dtor() {
46
2/2
✓ Branch 0 taken 65177 times.
✓ Branch 1 taken 41991 times.
107168 if !this.alreadyExecuted {
47 41991 this.leaveScope();
48 41991 }
49 107168 }
50
51 /**
52 * Leave the scope before the handle is destroyed
53 */
54 65177 public p ScopeHandle.leaveScopeEarly() {
55 65177 this.leaveScope();
56 65177 this.alreadyExecuted = true;
57 65177 }
58
59 107168 p ScopeHandle.leaveScope() {
60 107168 this.pass.changeToParentScope(this.scopeType);
61
2/2
✓ Branch 0 taken 60586 times.
✓ Branch 1 taken 46582 times.
107168 if this.generator != nil<IRGenerator*> {
62 46582 this.generator.diGenerator.popLexicalBlock();
63 46582 }
64 107168 }
65
66 /**
67 * This struct enters the expression scope of an expression, if it has one, and leaves it again when the handle object is
68 * destroyed.
69 *
70 * An expression scope holds the temporaries of an expression that is evaluated as a unit: a condition or an operand that is
71 * only evaluated conditionally. This allows destructing the temporaries right after the expression was evaluated, on every
72 * path. If the expression has no scope, the handle does nothing and the temporaries stay in the current scope.
73 */
74 public type ExprScopeHandle struct {
75 CompilerPass* pass
76 Scope* exprScope
77 }
78
79 100620 public p ExprScopeHandle.ctor(CompilerPass* pass, IVisitable* expr) {
80 100620 this.pass = pass;
81 100620 Scope* currentScope = this.pass.currentScope;
82 100620 this.exprScope = currentScope.getChildScope(getExprScopeId(expr));
83
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 100560 times.
100620 if this.exprScope != nil<Scope*> {
84 100560 this.pass.changeToScope(this.exprScope, ScopeType::EXPR_BODY);
85 100560 }
86 100620 }
87
88 100620 public p ExprScopeHandle.dtor() {
89
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 100560 times.
100620 if this.exprScope != nil<Scope*> {
90 100560 this.pass.changeToParentScope(ScopeType::EXPR_BODY);
91 100560 }
92 100620 }
93
94 96288 public f<Scope*> ExprScopeHandle.getExprScope() {
95 96288 return this.exprScope;
96 }
97