GCC Code Coverage Report


Directory: ../
File: src/importcollector/ImportCollector.cpp
Date: 2024-11-22 23:10:59
Exec Total Coverage
Lines: 51 55 92.7%
Functions: 3 3 100.0%
Branches: 89 166 53.6%

Line Branch Exec Source
1 // Copyright (c) 2021-2024 ChilliBits. All rights reserved.
2
3 #include "ImportCollector.h"
4
5 #include <SourceFile.h>
6 #include <ast/ASTNodes.h>
7 #include <ast/Attributes.h>
8 #include <exception/SemanticError.h>
9 #include <util/FileUtil.h>
10
11 namespace spice::compiler {
12
13 894 std::any ImportCollector::visitEntry(EntryNode *node) {
14 // Visit all module attributes
15
3/4
✓ Branch 1 taken 894 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 277 times.
✓ Branch 8 taken 894 times.
1171 for (ModAttrNode *attr : node->modAttrs())
16
1/2
✓ Branch 1 taken 277 times.
✗ Branch 2 not taken.
1171 visit(attr);
17
18 // Visit all import defs
19
3/4
✓ Branch 1 taken 894 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 371 times.
✓ Branch 8 taken 889 times.
1260 for (ImportDefNode *importDef : node->importDefs())
20
2/2
✓ Branch 1 taken 366 times.
✓ Branch 2 taken 5 times.
1260 visit(importDef);
21
22
1/2
✓ Branch 1 taken 889 times.
✗ Branch 2 not taken.
889 return nullptr;
23 }
24
25 371 std::any ImportCollector::visitImportDef(ImportDefNode *node) {
26 371 const bool isStd = node->importPath.starts_with("std/");
27 371 const bool isBootstrap = node->importPath.starts_with("bootstrap/");
28
29 371 std::filesystem::path basePath;
30
2/2
✓ Branch 0 taken 329 times.
✓ Branch 1 taken 42 times.
371 if (isStd) { // Include source file from standard library
31 // Find std library
32
1/2
✓ Branch 1 taken 329 times.
✗ Branch 2 not taken.
329 const std::filesystem::path stdPath = FileUtil::getStdDir();
33
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 329 times.
329 if (stdPath.empty())
34 throw CompilerError(STD_NOT_FOUND, "Standard library could not be found. Check if the env var SPICE_STD_DIR exists");
35 // Format: /dir/to/path/file
36
3/6
✓ Branch 2 taken 329 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 329 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 329 times.
✗ Branch 9 not taken.
329 basePath = stdPath / node->importPath.substr(node->importPath.find("std/") + 4);
37
2/2
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 31 times.
371 } else if (isBootstrap) { // Include source file from bootstrap library
38 // Find bootstrap library
39
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 const std::filesystem::path bootstrapPath = FileUtil::getBootstrapDir();
40
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if (bootstrapPath.empty())
41 throw CompilerError(BOOTSTRAP_NOT_FOUND,
42 "Bootstrap compiler could not be found. Check if the env var SPICE_BOOTSTRAP_DIR exists");
43 // Format: /dir/to/path/file
44
3/6
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 11 times.
✗ Branch 9 not taken.
11 basePath = bootstrapPath / node->importPath.substr(node->importPath.find("bootstrap/") + 10);
45 11 } else { // Include own source file
46 // Format: /dir/to/path/file
47
3/6
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 31 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 31 times.
✗ Branch 8 not taken.
31 basePath = sourceFile->filePath.parent_path() / node->importPath;
48 }
49 371 basePath.make_preferred();
50
51 // Format: /dir/to/path/file.spice
52
1/2
✓ Branch 1 taken 371 times.
✗ Branch 2 not taken.
371 std::filesystem::path defaultPath = basePath;
53
5/10
✓ Branch 1 taken 371 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 371 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 371 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 371 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 371 times.
✗ Branch 14 not taken.
371 defaultPath.replace_filename(basePath.stem().string() + ".spice");
54 // Format: /dir/to/path/file_linux.spice
55
1/2
✓ Branch 1 taken 371 times.
✗ Branch 2 not taken.
371 std::filesystem::path osPath = basePath;
56
7/14
✓ Branch 1 taken 371 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 371 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 371 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 371 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 371 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 371 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 371 times.
✗ Branch 20 not taken.
371 osPath.replace_filename(basePath.stem().string() + "_" + cliOptions.targetOs + ".spice");
57 // Format: /dir/to/path/file_linux_x86_64.spice
58
1/2
✓ Branch 1 taken 371 times.
✗ Branch 2 not taken.
371 std::filesystem::path osArchPath = basePath;
59
9/18
✓ Branch 1 taken 371 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 371 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 371 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 371 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 371 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 371 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 371 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 371 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 371 times.
✗ Branch 26 not taken.
371 osArchPath.replace_filename(basePath.stem().string() + "_" + cliOptions.targetOs + "_" + cliOptions.targetArch + ".spice");
60
61 // Check which source file to import
62 371 std::filesystem::path importPath;
63
2/4
✓ Branch 1 taken 371 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 371 times.
371 if (exists(osArchPath)) // file_os_arch.spice is first choice
64 importPath = osArchPath;
65
3/4
✓ Branch 1 taken 371 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 351 times.
371 else if (exists(osPath)) // file_os.spice is second choice
66
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 importPath = osPath;
67
3/4
✓ Branch 1 taken 351 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 349 times.
✓ Branch 4 taken 2 times.
351 else if (exists(defaultPath)) // file.spice is third choice
68
1/2
✓ Branch 1 taken 349 times.
✗ Branch 2 not taken.
349 importPath = defaultPath;
69 else
70
3/6
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
2 throw SemanticError(node, IMPORTED_FILE_NOT_EXISTING, "The source file '" + node->importPath + ".spice' does not exist");
71
72 // Check if the import already exists
73
1/2
✓ Branch 1 taken 369 times.
✗ Branch 2 not taken.
369 SymbolTableEntry *importEntry = rootScope->lookupStrict(node->importName);
74
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 367 times.
369 if (importEntry != nullptr)
75
3/6
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
2 throw SemanticError(node, DUPLICATE_IMPORT_NAME, "Duplicate import '" + node->importName + "'");
76
77 // Create symbol for import
78
1/2
✓ Branch 1 taken 367 times.
✗ Branch 2 not taken.
367 node->entry = rootScope->insert(node->importName, node);
79
80 // Create the imported source file
81
1/2
✓ Branch 1 taken 367 times.
✗ Branch 2 not taken.
367 const auto importedSourceFile = resourceManager.createSourceFile(sourceFile, node->importName, importPath, isStd);
82 // Register it as a dependency to the current source file
83
3/4
✓ Branch 1 taken 367 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 366 times.
✓ Branch 5 taken 1 times.
368 sourceFile->addDependency(importedSourceFile, node, node->importName, importPath.generic_string());
84
85
1/2
✓ Branch 1 taken 366 times.
✗ Branch 2 not taken.
732 return nullptr;
86 391 }
87
88 277 std::any ImportCollector::visitModAttr(ModAttrNode *node) {
89 // Retrieve attributes
90 277 const AttrLstNode *attrs = node->attrLst();
91
92 // !!! Only bool attributes allowed here, due to missing attribute value checks being executed in a later stage !!!
93
94 // core.compiler.keep-on-name-collision
95
4/6
✓ Branch 1 taken 277 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 277 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 271 times.
✓ Branch 8 taken 6 times.
831 if (attrs->hasAttr(ATTR_CORE_COMPILER_KEEP_ON_NAME_COLLISION)) {
96
2/4
✓ Branch 1 taken 271 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 271 times.
✗ Branch 5 not taken.
542 const bool keepOnCollision = attrs->getAttrValueByName(ATTR_CORE_COMPILER_KEEP_ON_NAME_COLLISION)->boolValue;
97 271 sourceFile->alwaysKeepSymbolsOnNameCollision = keepOnCollision;
98 }
99
100 // core.compiler.warnings.ignore
101
4/6
✓ Branch 1 taken 277 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 277 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 276 times.
831 if (attrs->hasAttr(ATTR_CORE_COMPILER_WARNINGS_IGNORE)) {
102
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 const bool ignoreWarnings = attrs->getAttrValueByName(ATTR_CORE_COMPILER_WARNINGS_IGNORE)->boolValue;
103 1 sourceFile->ignoreWarnings = ignoreWarnings;
104 }
105
106
1/2
✓ Branch 1 taken 277 times.
✗ Branch 2 not taken.
277 return nullptr;
107 }
108
109 } // namespace spice::compiler
110