Skip to content

Commit f13f18a

Browse files
committed
Separated function definition and signature
1 parent a411778 commit f13f18a

File tree

11 files changed

+187
-132
lines changed

11 files changed

+187
-132
lines changed

packages/cli/src/languagePlugins/c/dependencyFormatting/index.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
import { CDependency, CDepFile, CDepSymbol } from "./types.js";
1+
import {
2+
C_DEP_FUNCTION_TYPE,
3+
CDependency,
4+
CDepFile,
5+
CDepSymbol,
6+
CDepSymbolType,
7+
} from "./types.js";
28
import { CSymbolRegistry } from "../symbolRegistry/index.js";
39
import { CIncludeResolver } from "../includeResolver/index.js";
410
import { CInvocationResolver } from "../invocationResolver/index.js";
511
import { CFile, Symbol } from "../symbolRegistry/types.js";
612
import { Invocations } from "../invocationResolver/types.js";
713
import Parser from "tree-sitter";
8-
import { SymbolType } from "../headerResolver/types.js";
14+
import { C_VARIABLE_TYPE, SymbolType } from "../headerResolver/types.js";
915

1016
export class CDependencyFormatter {
1117
symbolRegistry: CSymbolRegistry;
@@ -22,6 +28,22 @@ export class CDependencyFormatter {
2228
this.invocationResolver = new CInvocationResolver(this.includeResolver);
2329
}
2430

31+
#formatSymbolType(st: SymbolType): CDepSymbolType {
32+
if (["struct", "enum", "union", "typedef", "variable"].includes(st)) {
33+
return st as CDepSymbolType;
34+
}
35+
if (
36+
["function_signature", "function_definition", "macro_function"].includes(
37+
st,
38+
)
39+
) {
40+
return C_DEP_FUNCTION_TYPE;
41+
}
42+
if (st === "macro_constant") {
43+
return C_VARIABLE_TYPE as CDepSymbolType;
44+
}
45+
}
46+
2547
/**
2648
* Formats the dependencies of a file.
2749
* @param fileDependencies - The dependencies of the file.
@@ -86,7 +108,7 @@ export class CDependencyFormatter {
86108
if (!symbols[id]) {
87109
symbols[id] = {
88110
id: id,
89-
type: symbol.declaration.type as SymbolType,
111+
type: this.#formatSymbolType(symbol.declaration.type),
90112
lineCount:
91113
symbol.declaration.node.endPosition.row -
92114
symbol.declaration.node.startPosition.row,

packages/cli/src/languagePlugins/c/dependencyFormatting/types.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { SymbolType } from "../headerResolver/types.js";
1+
import {
2+
C_ENUM_TYPE,
3+
C_UNION_TYPE,
4+
C_STRUCT_TYPE,
5+
C_TYPEDEF_TYPE,
6+
C_VARIABLE_TYPE,
7+
} from "../headerResolver/types.js";
28
import Parser from "tree-sitter";
39

410
/**
@@ -18,12 +24,21 @@ export interface CDependent {
1824
symbols: Record<string, string>;
1925
}
2026

27+
export const C_DEP_FUNCTION_TYPE = "function";
28+
export type CDepSymbolType =
29+
| typeof C_ENUM_TYPE
30+
| typeof C_UNION_TYPE
31+
| typeof C_STRUCT_TYPE
32+
| typeof C_TYPEDEF_TYPE
33+
| typeof C_VARIABLE_TYPE
34+
| typeof C_DEP_FUNCTION_TYPE;
35+
2136
/**
2237
* Represents a symbol in a C file
2338
*/
2439
export interface CDepSymbol {
2540
id: string;
26-
type: SymbolType;
41+
type: CDepSymbolType;
2742
lineCount: number;
2843
characterCount: number;
2944
node: Parser.SyntaxNode;

packages/cli/src/languagePlugins/c/headerResolver/index.test.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ describe("CHeaderResolver", () => {
7272
expect(drink_t.filepath).toBe(burgers);
7373
});
7474

75-
test("resolves variables and constant macros", () => {
75+
test("resolves variables", () => {
7676
const classicburger = exportedSymbols.find(
7777
(symbol) => symbol.name === "classicBurger",
7878
);
@@ -94,12 +94,14 @@ describe("CHeaderResolver", () => {
9494
expect(burger_count.node.type).toBe("declaration");
9595
expect(burger_count.identifierNode.type).toBe("identifier");
9696
expect(burger_count.filepath).toBe(burgers);
97+
});
9798

99+
test("resolves macro constants", () => {
98100
const burgers_h = exportedSymbols.find(
99101
(symbol) => symbol.name === "BURGERS_H",
100102
);
101103
expect(burgers_h).toBeDefined();
102-
expect(burgers_h.type).toBe("variable");
104+
expect(burgers_h.type).toBe("macro_constant");
103105
expect(burgers_h.specifiers).toEqual([]);
104106
expect(burgers_h.qualifiers).toEqual([]);
105107
expect(burgers_h.node.type).toBe("preproc_def");
@@ -110,28 +112,30 @@ describe("CHeaderResolver", () => {
110112
(symbol) => symbol.name === "MAX_BURGERS",
111113
);
112114
expect(max_burgers).toBeDefined();
113-
expect(max_burgers.type).toBe("variable");
115+
expect(max_burgers.type).toBe("macro_constant");
114116
expect(max_burgers.specifiers).toEqual([]);
115117
expect(max_burgers.qualifiers).toEqual([]);
116118
expect(max_burgers.node.type).toBe("preproc_def");
117119
expect(max_burgers.identifierNode.type).toBe("identifier");
118120
expect(max_burgers.filepath).toBe(burgers);
119121
});
120122

121-
test("resolves functions and macros", () => {
123+
test("resolves function signatures", () => {
122124
const function_names = exportedSymbols
123-
.filter((symbol) => symbol.type === "function")
125+
.filter((symbol) => symbol.type === "function_signature")
124126
.map((symbol) => symbol.name);
125-
expect(function_names).toHaveLength(5);
127+
expect(function_names).toHaveLength(4);
126128
expect(function_names).toContain("get_burger_by_id");
127129
expect(function_names).toContain("get_cheapest_burger");
128130
expect(function_names).toContain("create_burger");
129131
expect(function_names).toContain("destroy_burger");
130-
expect(function_names).toContain("MAX");
132+
expect(function_names).not.toContain("MAX");
133+
});
131134

135+
test("resolves macro functions", () => {
132136
const max_macro = exportedSymbols.find((symbol) => symbol.name === "MAX");
133137
expect(max_macro).toBeDefined();
134-
expect(max_macro.type).toBe("function");
138+
expect(max_macro.type).toBe("macro_function");
135139
expect(max_macro.specifiers).toEqual([]);
136140
expect(max_macro.qualifiers).toEqual([]);
137141
expect(max_macro.node.type).toBe("preproc_function_def");
@@ -176,7 +180,7 @@ describe("CHeaderResolver", () => {
176180
(s) => s.name === "PlaceholderFunction",
177181
);
178182
expect(placeholderfunction).toBeDefined();
179-
expect(placeholderfunction.type).toBe("function");
183+
expect(placeholderfunction.type).toBe("function_signature");
180184
expect(placeholderfunction.specifiers).toEqual([]);
181185
expect(placeholderfunction.qualifiers).toEqual([]);
182186
expect(placeholderfunction.node.type).toBe("declaration");

packages/cli/src/languagePlugins/c/headerResolver/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export class CHeaderResolver {
2424
const query = C_DECLARATION_QUERY;
2525
const captures = query.captures(file.rootNode);
2626
for (const capture of captures) {
27-
if (capture.name !== "decl") {
27+
if (capture.name !== "decl" && capture.name !== "function_definition") {
2828
let idNode: Parser.SyntaxNode;
2929
if (capture.name !== "typedef") {
3030
idNode = capture.node.childForFieldName("name");
@@ -65,7 +65,11 @@ export class CHeaderResolver {
6565
}
6666
}
6767
const type =
68-
currentNode.type === "function_declarator" ? "function" : "variable";
68+
capture.name === "function_definition"
69+
? "function_definition"
70+
: currentNode.type === "function_declarator"
71+
? "function_signature"
72+
: "variable";
6973
const idNode = currentNode.childForFieldName("declarator");
7074
exportedSymbols.push({
7175
name: idNode.text,

packages/cli/src/languagePlugins/c/headerResolver/queries.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const C_DECLARATION_QUERY = new Parser.Query(
1313
(struct_specifier) @struct
1414
(enum_specifier) @enum
1515
(union_specifier) @union
16+
(function_definition) @function_definition
1617
(type_definition
1718
type:[
1819
(struct_specifier
@@ -41,6 +42,7 @@ export const C_DECLARATION_QUERY = new Parser.Query(
4142
(struct_specifier) @struct
4243
(enum_specifier) @enum
4344
(union_specifier) @union
45+
(function_definition) @function_definition
4446
(type_definition
4547
type:[
4648
(struct_specifier
@@ -63,7 +65,7 @@ export const C_DECLARATION_QUERY = new Parser.Query(
6365
]
6466
) @typedef
6567
])
66-
(preproc_def) @variable
67-
(preproc_function_def) @function
68+
(preproc_def) @macro_constant
69+
(preproc_function_def) @macro_function
6870
`,
6971
);

packages/cli/src/languagePlugins/c/headerResolver/types.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import Parser from "tree-sitter";
44
export const C_STRUCT_TYPE = "struct";
55
export const C_UNION_TYPE = "union";
66
export const C_ENUM_TYPE = "enum";
7-
export const C_FUNCTION_TYPE = "function";
7+
export const C_FUNCTION_DEFINITION_TYPE = "function_definition";
8+
export const C_FUNCTION_SIGNATURE_TYPE = "function_signature";
9+
export const C_MACRO_FUNCTION_TYPE = "macro_function";
10+
export const C_MACRO_CONSTANT_TYPE = "macro_constant";
811
export const C_VARIABLE_TYPE = "variable";
912
export const C_TYPEDEF_TYPE = "typedef";
1013

@@ -25,7 +28,10 @@ export type SymbolType =
2528
| typeof C_STRUCT_TYPE
2629
| typeof C_UNION_TYPE
2730
| typeof C_ENUM_TYPE
28-
| typeof C_FUNCTION_TYPE
31+
| typeof C_FUNCTION_DEFINITION_TYPE
32+
| typeof C_FUNCTION_SIGNATURE_TYPE
33+
| typeof C_MACRO_FUNCTION_TYPE
34+
| typeof C_MACRO_CONSTANT_TYPE
2935
| typeof C_VARIABLE_TYPE
3036
| typeof C_TYPEDEF_TYPE;
3137

packages/cli/src/languagePlugins/c/invocationResolver/index.test.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ describe("CInvocationResolver", () => {
1212
const invocationResolver = new CInvocationResolver(includeResolver);
1313
const burgersh = path.join(cFilesFolder, "burgers.h");
1414
const burgersc = path.join(cFilesFolder, "burgers.c");
15-
const personnelh = path.join(cFilesFolder, "personnel.h");
15+
const personnelc = path.join(cFilesFolder, "personnel.c");
1616
const crashcasesh = path.join(cFilesFolder, "crashcases.h");
1717
const main = path.join(cFilesFolder, "main.c");
1818
const registry = symbolRegistry.getRegistry();
@@ -41,7 +41,7 @@ describe("CInvocationResolver", () => {
4141
});
4242

4343
test("resolves invocations for burgers.c", () => {
44-
const symbols = registry.get(burgersh).symbols;
44+
const symbols = registry.get(burgersc).symbols;
4545
if (!symbols) {
4646
throw new Error(`Symbol not found for: ${burgersc}`);
4747
}
@@ -51,7 +51,8 @@ describe("CInvocationResolver", () => {
5151
const create_resolved = Array.from(
5252
create_burger_invocations.resolved.keys(),
5353
);
54-
expect(create_resolved.length).toBe(4);
54+
expect(create_resolved.length).toBe(5);
55+
expect(create_resolved).toContain("create_burger");
5556
expect(create_resolved).toContain("Burger");
5657
expect(create_resolved).toContain("Condiment");
5758
expect(create_resolved).toContain("Sauce");
@@ -63,7 +64,8 @@ describe("CInvocationResolver", () => {
6364
const destroy_resolved = Array.from(
6465
destroy_burger_invocations.resolved.keys(),
6566
);
66-
expect(destroy_resolved.length).toBe(1);
67+
expect(destroy_resolved.length).toBe(2);
68+
expect(destroy_resolved).toContain("destroy_burger");
6769
expect(destroy_resolved).toContain("Burger");
6870

6971
const symbolsc = registry.get(burgersc).symbols;
@@ -78,17 +80,18 @@ describe("CInvocationResolver", () => {
7880
});
7981

8082
test("resolves invocations for personnel.c", () => {
81-
const symbols = registry.get(personnelh).symbols;
83+
const symbols = registry.get(personnelc).symbols;
8284
if (!symbols) {
83-
throw new Error(`Symbol not found for: ${personnelh}`);
85+
throw new Error(`Symbol not found for: ${personnelc}`);
8486
}
8587
const create_employee = symbols.get("create_employee");
8688
const create_employee_invocations =
8789
invocationResolver.getInvocationsForSymbol(create_employee);
8890
const create_resolved = Array.from(
8991
create_employee_invocations.resolved.keys(),
9092
);
91-
expect(create_resolved.length).toBe(5);
93+
expect(create_resolved.length).toBe(6);
94+
expect(create_resolved).toContain("create_employee");
9295
expect(create_resolved).toContain("Employee");
9396
expect(create_resolved).toContain("Department");
9497
expect(create_resolved).toContain("MAX_EMPLOYEES");

packages/cli/src/languagePlugins/c/invocationResolver/index.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { Invocations } from "./types.js";
22
import { C_INVOCATION_QUERY, C_MACRO_CONTENT_QUERY } from "./queries.js";
33
import { CIncludeResolver } from "../includeResolver/index.js";
4-
import { Symbol, Function } from "../symbolRegistry/types.js";
4+
import {
5+
Symbol,
6+
FunctionDefinition,
7+
FunctionSignature,
8+
} from "../symbolRegistry/types.js";
59
import Parser from "tree-sitter";
610
import { cParser } from "../../../helpers/treeSitter/parsers.js";
711

@@ -66,14 +70,17 @@ export class CInvocationResolver {
6670
}
6771

6872
getInvocationsForSymbol(symbol: Symbol) {
69-
let filepath = symbol.declaration.filepath;
70-
let node = symbol.declaration.node;
71-
if (symbol instanceof Function) {
72-
filepath = symbol.definitionPath;
73-
node = symbol.definition;
74-
}
73+
const filepath = symbol.declaration.filepath;
74+
const node = symbol.declaration.node;
7575
const name = symbol.name;
7676
const invocations = this.getInvocationsForNode(node, filepath, name);
77+
const resolved = invocations.resolved;
78+
if (symbol instanceof FunctionSignature && symbol.definition) {
79+
resolved.set(symbol.name, symbol.definition);
80+
}
81+
if (symbol instanceof FunctionDefinition && symbol.signature) {
82+
resolved.set(symbol.name, symbol.signature);
83+
}
7784
return {
7885
resolved: invocations.resolved,
7986
unresolved: invocations.unresolved,

0 commit comments

Comments
 (0)