Skip to content

Commit c1a1012

Browse files
committed
Invocation resolver
1 parent b9a4472 commit c1a1012

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { Invocations } from "./types.js";
2+
import { C_INVOCATION_QUERY } from "./queries.js";
3+
import { CIncludeResolver } from "../includeResolver/index.js";
4+
import { Symbol, Function } from "../symbolRegistry/types.js";
5+
import Parser from "tree-sitter";
6+
7+
export class CInvocationResolver {
8+
includeResolver: CIncludeResolver;
9+
10+
constructor(includeResolver: CIncludeResolver) {
11+
this.includeResolver = includeResolver;
12+
}
13+
14+
getInvocationsForNode(
15+
node: Parser.SyntaxNode,
16+
filepath: string,
17+
symbolname: string = undefined,
18+
): Invocations {
19+
const availableSymbols = this.includeResolver
20+
.getInclusions()
21+
.get(filepath).symbols;
22+
const localSymbols =
23+
this.includeResolver.symbolRegistry.get(filepath).symbols;
24+
const unresolved = new Set<string>();
25+
const resolved = new Map<string, Symbol>();
26+
const captures = C_INVOCATION_QUERY.captures(node);
27+
for (const capture of captures) {
28+
const name = capture.node.text;
29+
// if the symbol name is the same as the one we are looking at, skip it
30+
if (symbolname && name === symbolname) {
31+
continue;
32+
}
33+
if (availableSymbols.has(name)) {
34+
resolved.set(name, availableSymbols.get(name));
35+
} else if (localSymbols.has(name)) {
36+
resolved.set(name, localSymbols.get(name));
37+
} else {
38+
unresolved.add(name);
39+
}
40+
}
41+
return {
42+
resolved,
43+
unresolved,
44+
};
45+
}
46+
47+
getInvocationsForFile(filepath: string): Invocations {
48+
const symbols = this.includeResolver.symbolRegistry.get(filepath).symbols;
49+
let unresolved = new Set<string>();
50+
const resolved = new Map<string, Symbol>();
51+
for (const symbol of symbols.values()) {
52+
const node =
53+
symbol instanceof Function
54+
? (symbol as Function).definition
55+
: symbol.declaration.node;
56+
const name = symbol.name;
57+
const invocations = this.getInvocationsForNode(node, filepath, name);
58+
unresolved = new Set([...unresolved, ...invocations.unresolved]);
59+
for (const [key, value] of invocations.resolved) {
60+
if (!resolved.has(key)) {
61+
resolved.set(key, value);
62+
}
63+
}
64+
}
65+
return {
66+
resolved,
67+
unresolved,
68+
};
69+
}
70+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Parser from "tree-sitter";
2+
import { cParser } from "../../../helpers/treeSitter/parsers.js";
3+
4+
export const C_INVOCATION_QUERY = new Parser.Query(
5+
cParser.getLanguage(),
6+
`
7+
(type_identifier) @type
8+
(identifier) @id
9+
`, // The nuclear option, but unlike C# we can afford to do it.
10+
);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Symbol } from "../symbolRegistry/types.js";
2+
3+
/** Interface representing the invoked symbols in a file */
4+
export interface Invocations {
5+
/** Symbols that are part of the project */
6+
resolved: Map<string, Symbol>;
7+
/** Symbols that are not part of the project or local variables */
8+
unresolved: Set<string>;
9+
}

0 commit comments

Comments
 (0)