Skip to content

Commit a3508b5

Browse files
committed
C Manifest generation
1 parent 81f7b6b commit a3508b5

File tree

2 files changed

+122
-1
lines changed
  • packages
    • cli/src/manifest/dependencyManifest/c
    • shared/src/manifest/dependencyManifest

2 files changed

+122
-1
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import {
2+
DependencyManifest,
3+
metricLinesCount,
4+
metricCharacterCount,
5+
metricCodeLineCount,
6+
metricCodeCharacterCount,
7+
metricDependencyCount,
8+
metricDependentCount,
9+
metricCyclomaticComplexity,
10+
SymbolDependencyManifest,
11+
SymbolType,
12+
} from "@nanoapi.io/shared";
13+
import { CDependencyFormatter } from "../../../languagePlugins/c/dependencyFormatting/index.js";
14+
import Parser from "tree-sitter";
15+
import { cLanguage, cParser } from "../../../helpers/treeSitter/parsers.js";
16+
17+
export function generateCDependencyManifest(
18+
files: Map<string, { path: string; content: string }>,
19+
): DependencyManifest {
20+
console.time("generateCDependencyManifest");
21+
console.info("Processing project...");
22+
const parsedFiles = new Map<
23+
string,
24+
{ path: string; rootNode: Parser.SyntaxNode }
25+
>();
26+
for (const [filePath, { content: fileContent }] of files) {
27+
try {
28+
const rootNode = cParser.parse(fileContent, undefined, {
29+
bufferSize: fileContent.length + 10,
30+
}).rootNode;
31+
parsedFiles.set(filePath, { path: filePath, rootNode });
32+
} catch (e) {
33+
console.error(`Failed to parse ${filePath}, skipping`);
34+
console.error(e);
35+
}
36+
}
37+
38+
const formatter = new CDependencyFormatter(parsedFiles);
39+
const manifest: DependencyManifest = {};
40+
const filecount = parsedFiles.size;
41+
let i = 0;
42+
for (const [, { path }] of parsedFiles) {
43+
console.info(`Processing ${path} (${++i}/${filecount})`);
44+
const fm = formatter.formatFile(path);
45+
const cSyms = fm.symbols;
46+
const symbols: Record<string, SymbolDependencyManifest> = {};
47+
for (const [symName, symbol] of Object.entries(cSyms)) {
48+
const symType = symbol.type;
49+
const lineCount = symbol.lineCount;
50+
const characterCount = symbol.characterCount;
51+
const dependencies = symbol.dependencies;
52+
// TODO : metrics
53+
symbols[symName] = {
54+
id: symName,
55+
type: symType as SymbolType,
56+
metrics: {
57+
[metricCharacterCount]: characterCount,
58+
[metricCodeCharacterCount]: 0, // TODO: fix this
59+
[metricLinesCount]: lineCount,
60+
[metricCodeLineCount]: 0, // TODO: fix this
61+
[metricDependencyCount]: Object.keys(dependencies).length,
62+
[metricDependentCount]: 0,
63+
[metricCyclomaticComplexity]: 0, // TODO: fix this
64+
},
65+
dependencies: dependencies,
66+
dependents: {},
67+
};
68+
}
69+
// TODO : metrics
70+
manifest[path] = {
71+
id: fm.id,
72+
filePath: fm.filePath,
73+
language: cLanguage,
74+
metrics: {
75+
[metricCharacterCount]: fm.characterCount,
76+
[metricCodeCharacterCount]: 0, // TODO: fix this
77+
[metricLinesCount]: fm.lineCount,
78+
[metricCodeLineCount]: 0, // TODO: fix this
79+
[metricDependencyCount]: Object.keys(fm.dependencies).length,
80+
[metricDependentCount]: 0,
81+
[metricCyclomaticComplexity]: 0, // TODO: fix this
82+
},
83+
dependencies: fm.dependencies,
84+
symbols: symbols,
85+
dependents: {},
86+
};
87+
}
88+
console.info("Populating dependents...");
89+
i = 0;
90+
for (const fm of Object.values(manifest)) {
91+
const path = fm.filePath;
92+
console.info(`Populating dependents for ${path} (${++i}/${filecount})`);
93+
for (const symbol of Object.values(fm.symbols)) {
94+
for (const dpncy of Object.values(symbol.dependencies)) {
95+
for (const depsymbol of Object.values(dpncy.symbols)) {
96+
const otherFile = manifest[dpncy.id];
97+
const otherSymbol = otherFile.symbols[depsymbol];
98+
if (!otherSymbol.dependents[fm.id]) {
99+
otherSymbol.dependents[fm.id] = {
100+
id: fm.id,
101+
symbols: {},
102+
};
103+
}
104+
otherSymbol.dependents[fm.id].symbols[symbol.id] = symbol.id;
105+
fm.metrics[metricDependentCount]++;
106+
symbol.metrics[metricDependentCount]++;
107+
}
108+
}
109+
}
110+
}
111+
console.timeEnd("generateCDependencyManifest");
112+
return manifest;
113+
}

packages/shared/src/manifest/dependencyManifest/types.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ export const structSymbolType = "struct";
77
/** Identifies the "enum" instance type. */
88
export const enumSymbolType = "enum";
99

10+
/** Identifies the "union" instance type. */
11+
export const unionSymbolType = "union";
12+
13+
/** Identifies the "typedef" instance type. */
14+
export const typedefSymbolType = "typedef";
15+
1016
/** Identifies the "function" instance type. */
1117
export const functionSymbolType = "function";
1218

@@ -24,7 +30,9 @@ export type SymbolType =
2430
| typeof functionSymbolType
2531
| typeof variableSymbolType
2632
| typeof structSymbolType
27-
| typeof enumSymbolType;
33+
| typeof enumSymbolType
34+
| typeof unionSymbolType
35+
| typeof typedefSymbolType;
2836

2937
export const metricLinesCount = "linesCount";
3038
export const metricCodeLineCount = "codeLineCount";

0 commit comments

Comments
 (0)