GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 88.4% 38 / 0 / 43
Functions: 100.0% 12 / 0 / 12
Branches: 48.7% 37 / 0 / 76

src/model/Union.cpp
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #include "Union.h"
4
5 #include <ast/ASTBuilder.h>
6 #include <ast/ASTNodes.h>
7 #include <model/GenericType.h>
8 #include <symboltablebuilder/Scope.h>
9 #include <util/CommonUtil.h>
10
11 namespace spice::compiler {
12
13 static constexpr auto UNION_SCOPE_PREFIX = "union:";
14
15 60 Union::Union(std::string name, SymbolTableEntry *entry, Scope *scope, QualTypeList fieldTypes,
16 std::vector<GenericType> templateTypes, ASTNode *declNode)
17 180 : name(std::move(name)), templateTypes(std::move(templateTypes)), entry(entry), scope(scope), declNode(declNode),
18 120 fieldTypes(std::move(fieldTypes)) {}
19
20 /**
21 * Get a string representation of the current union
22 *
23 * @return String representation as union signature
24 */
25
2/4
✓ Branch 2 → 3 taken 116 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 116 times.
✗ Branch 3 → 8 not taken.
232 std::string Union::getSignature() const { return getSignature(name, getConcreteTemplateTypes()); }
26
27 /**
28 * Get the signature from the union name and the concrete template types
29 *
30 * Example:
31 * Pair<int,double>
32 *
33 * @param name Union name
34 * @param concreteTemplateTypes Concrete template types
35 * @return Signature
36 */
37 248 std::string Union::getSignature(const std::string &name, const QualTypeList &concreteTemplateTypes) {
38 // Build template type string
39
1/2
✓ Branch 2 → 3 taken 248 times.
✗ Branch 2 → 48 not taken.
248 std::stringstream templateTyStr;
40
2/2
✓ Branch 4 → 5 taken 37 times.
✓ Branch 4 → 17 taken 211 times.
248 if (!concreteTemplateTypes.empty()) {
41
1/2
✓ Branch 5 → 6 taken 37 times.
✗ Branch 5 → 46 not taken.
37 templateTyStr << "<";
42
2/2
✓ Branch 15 → 7 taken 37 times.
✓ Branch 15 → 16 taken 37 times.
74 for (size_t i = 0; i < concreteTemplateTypes.size(); i++) {
43
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 37 times.
37 if (i > 0)
44 templateTyStr << ",";
45
3/6
✓ Branch 9 → 10 taken 37 times.
✗ Branch 9 → 33 not taken.
✓ Branch 10 → 11 taken 37 times.
✗ Branch 10 → 33 not taken.
✓ Branch 11 → 12 taken 37 times.
✗ Branch 11 → 31 not taken.
37 templateTyStr << concreteTemplateTypes.at(i).getName(false, true);
46 }
47
1/2
✓ Branch 16 → 17 taken 37 times.
✗ Branch 16 → 46 not taken.
37 templateTyStr << ">";
48 }
49
50
4/8
✓ Branch 17 → 18 taken 248 times.
✗ Branch 17 → 45 not taken.
✓ Branch 20 → 21 taken 248 times.
✗ Branch 20 → 38 not taken.
✓ Branch 21 → 22 taken 248 times.
✗ Branch 21 → 36 not taken.
✓ Branch 22 → 23 taken 248 times.
✗ Branch 22 → 34 not taken.
1240 return CommonUtil::getLastFragment(name, SCOPE_ACCESS_TOKEN) + templateTyStr.str();
51 248 }
52
53 /**
54 * Retrieve the name of the scope, where fields are placed. This is used to navigate to the scope of the union
55 * from the parent scope.
56 *
57 * @return Name of the union scope
58 */
59 12 std::string Union::getScopeName() const {
60
4/6
✓ Branch 3 → 4 taken 6 times.
✓ Branch 3 → 5 taken 6 times.
✓ Branch 4 → 6 taken 6 times.
✗ Branch 4 → 13 not taken.
✓ Branch 5 → 6 taken 6 times.
✗ Branch 5 → 13 not taken.
12 const std::string &appendix = isGenericSubstantiation() ? getSignature() : name;
61
1/2
✓ Branch 6 → 7 taken 12 times.
✗ Branch 6 → 11 not taken.
24 return UNION_SCOPE_PREFIX + appendix;
62 12 }
63
64 /**
65 * Retrieve the name of the scope, where fields are placed. This is used to navigate to the scope of the
66 * union from the parent scope.
67 *
68 * @param name Union name
69 * @param concreteTemplateTypes Concrete template types
70 * @return Name of the union scope
71 */
72 68 std::string Union::getScopeName(const std::string &name, const QualTypeList &concreteTemplateTypes) {
73
2/4
✓ Branch 2 → 3 taken 68 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 68 times.
✗ Branch 3 → 8 not taken.
136 return UNION_SCOPE_PREFIX + getSignature(name, concreteTemplateTypes);
74 }
75
76 /**
77 * Checks if a union contains generic template types.
78 * This would imply that the union is not substantiated by its generic types yet.
79 *
80 * @return Substantiated generics or not
81 */
82 90 bool Union::hasSubstantiatedGenerics() const {
83 4 const auto pred = [](const GenericType &genericType) { return genericType.hasAnyGenericParts(); };
84
1/2
✓ Branch 2 → 3 taken 90 times.
✗ Branch 2 → 6 not taken.
180 return std::ranges::none_of(templateTypes, pred);
85 }
86
87 /**
88 * Checks if a union has generic types present.
89 * This would imply that the union is not fully substantiated yet.
90 *
91 * @return Fully substantiated or not
92 */
93 90 bool Union::isFullySubstantiated() const { return hasSubstantiatedGenerics(); }
94
95 /**
96 * Retrieve the concrete template types of this union. For generic substantiations, the generic types are replaced
97 * by the concrete types from the type mapping.
98 *
99 * @return Concrete template types as vector of symbol types
100 */
101 116 QualTypeList Union::getConcreteTemplateTypes() const {
102 116 QualTypeList concreteTemplateTypes;
103
1/2
✓ Branch 3 → 4 taken 116 times.
✗ Branch 3 → 36 not taken.
116 concreteTemplateTypes.reserve(templateTypes.size());
104
2/2
✓ Branch 32 → 6 taken 31 times.
✓ Branch 32 → 33 taken 116 times.
263 for (const GenericType &genericType : templateTypes) {
105
5/8
✓ Branch 8 → 9 taken 31 times.
✗ Branch 8 → 35 not taken.
✓ Branch 9 → 10 taken 4 times.
✓ Branch 9 → 13 taken 27 times.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 4 times.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 22 taken 31 times.
31 if (genericType.is(TY_GENERIC) && !typeMapping.empty()) {
106 assert(typeMapping.contains(genericType.getSubType()));
107 concreteTemplateTypes.push_back(typeMapping.at(genericType.getSubType()));
108 } else {
109
1/2
✓ Branch 22 → 23 taken 31 times.
✗ Branch 22 → 35 not taken.
31 concreteTemplateTypes.push_back(genericType);
110 }
111 }
112 116 return concreteTemplateTypes;
113 }
114
115 /**
116 * Retrieve the template types as vector of symbol types
117 *
118 * @return Template types as vector of symbol types
119 */
120 6 QualTypeList Union::getTemplateTypes() const {
121 6 QualTypeList templateSymbolTypes;
122
2/2
✓ Branch 16 → 4 taken 6 times.
✓ Branch 16 → 17 taken 6 times.
18 for (const GenericType &genericTemplateType : templateTypes)
123
1/2
✓ Branch 6 → 7 taken 6 times.
✗ Branch 6 → 19 not taken.
6 templateSymbolTypes.push_back(genericTemplateType);
124 6 return templateSymbolTypes;
125 }
126
127 /**
128 * Retrieve the declaration code location of this union
129 *
130 * @return Declaration code location
131 */
132 32 const CodeLoc &Union::getDeclCodeLoc() const { return declNode->codeLoc; }
133
134 /**
135 * Returns, if this union is a substantiation of a generic one.
136 *
137 * @return Generic substantiation or not
138 */
139 74 bool Union::isGenericSubstantiation() const { return genericPreset != nullptr; }
140
141 } // namespace spice::compiler
142