@jpoly1219/context-extractor 0.2.8 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/src/app.d.ts +7 -3
  2. package/dist/src/app.js +304 -101
  3. package/dist/src/ast.d.ts +6 -0
  4. package/dist/src/ast.js +80 -0
  5. package/dist/src/codeql.js +17 -7
  6. package/dist/src/constants.js +17 -7
  7. package/dist/src/core.d.ts +0 -1
  8. package/dist/src/core.js +17 -7
  9. package/dist/src/main.d.ts +8 -2
  10. package/dist/src/main.js +51 -13
  11. package/dist/src/ocaml-driver.d.ts +55 -5
  12. package/dist/src/ocaml-driver.js +295 -190
  13. package/dist/src/ocaml-utils/_build/default/test_parser.bc.cjs +194658 -0
  14. package/dist/src/runner.js +118 -3
  15. package/dist/src/tree-sitter-files/queries/hole-queries/typescript.scm +36 -0
  16. package/dist/src/tree-sitter-files/queries/relevant-headers-queries/typescript-get-toplevel-headers.scm +22 -0
  17. package/dist/src/tree-sitter-files/queries/relevant-types-queries/typescript-extract-identifiers.scm +10 -0
  18. package/dist/src/tree-sitter-files/queries/relevant-types-queries/typescript-find-typedecl-given-typeidentifier.scm +11 -0
  19. package/dist/src/tree-sitter-files/wasms/tree-sitter-ocaml.wasm +0 -0
  20. package/dist/src/tree-sitter-files/wasms/tree-sitter-typescript.wasm +0 -0
  21. package/dist/src/tree-sitter-files/wasms/tree-sitter.wasm +0 -0
  22. package/dist/src/tree-sitter.d.ts +40 -0
  23. package/dist/src/tree-sitter.js +334 -0
  24. package/dist/src/types.d.ts +79 -9
  25. package/dist/src/types.js +1 -6
  26. package/dist/src/typescript-driver.d.ts +81 -13
  27. package/dist/src/typescript-driver.js +1150 -237
  28. package/dist/src/typescript-type-checker.d.ts +6 -2
  29. package/dist/src/typescript-type-checker.js +222 -10
  30. package/dist/src/utils.d.ts +11 -1
  31. package/dist/src/utils.js +87 -10
  32. package/dist/src/vscode-ide.d.ts +29 -0
  33. package/dist/src/vscode-ide.js +161 -0
  34. package/package.json +12 -6
@@ -1,15 +1,118 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  const main_1 = require("./main");
4
- const types_1 = require("./types");
37
+ const pprof = __importStar(require("pprof"));
38
+ const fs = __importStar(require("fs"));
5
39
  // extract("/home/jacob/projects/context-extractor/targets/todo/sketch.ts").then(r => console.log("todo\n", r));
6
40
  // extract("/home/jacob/projects/context-extractor/targets/playlist/sketch.ts").then(r => console.log("playlist\n", r));
7
41
  // extract("/home/jacob/projects/context-extractor/targets/passwords/sketch.ts").then(r => console.log("passwords\n", r));
8
42
  // extract("/home/jacob/projects/context-extractor/targets/booking/sketch.ts").then(r => console.log("booking\n", r));
9
43
  // extract("/home/jacob/projects/context-extractor/targets/emojipaint/sketch.ts").then(r => console.log("emojipaint\n", r));
10
44
  (async () => {
45
+ const profile = await pprof.time.start(10000); // Collect for 10s
11
46
  try {
12
47
  let x;
48
+ x = await (0, main_1.extractContext)("typescript", "/home/jacob/projects/context-extractor/targets/booking/sketch.ts", "/home/jacob/projects/context-extractor/targets/booking/", "standalone", { line: 3, character: 56 });
49
+ console.dir(x, { depth: null });
50
+ }
51
+ catch (err) {
52
+ console.log("top level err: ", err);
53
+ }
54
+ finally {
55
+ const buf = await pprof.encode(profile());
56
+ fs.writeFile('wall.pb.gz', buf, (err) => {
57
+ if (err)
58
+ throw err;
59
+ });
60
+ }
61
+ })();
62
+ (async () => {
63
+ // try {
64
+ const app = (0, main_1.spawnApp)("typescript",
65
+ // "/home/jacob/projects/context-extractor/targets/vscode/src/main.ts",
66
+ // "/home/jacob/projects/context-extractor/targets/vscode/",
67
+ "/home/jacob/projects/context-extractor/targets/booking/sketch.ts", "/home/jacob/projects/context-extractor/targets/booking/", "standalone", { line: 3, character: 56 });
68
+ const x = await (0, main_1.extractContextWithReuse)(app, 0);
69
+ console.dir(x, { depth: null });
70
+ // for (let i = 0; i < 11; ++i) {
71
+ //
72
+ // await (async (ms: number) => new Promise((r) => setTimeout(r, ms)))(2000)
73
+ //
74
+ // try {
75
+ // console.log(`loop ${i}`)
76
+ // let start = performance.now();
77
+ // const x = await extractContextWithReuse(app, i);
78
+ // let end = performance.now();
79
+ // console.log(end - start);
80
+ // // console.dir(x, { depth: null })
81
+ // } catch (err) {
82
+ // console.log("error!")
83
+ // continue;
84
+ // }
85
+ //
86
+ // }
87
+ app.close();
88
+ // } catch (err) {
89
+ // console.error(err)
90
+ // }
91
+ });
92
+ (async () => {
93
+ // const profile = await pprof.time.start(10000); // Collect for 10s
94
+ try {
95
+ let x;
96
+ // x = await extractContext(
97
+ // Language.TypeScript,
98
+ // "/home/jacob/projects/context-extractor/targets/vscode/src/main.ts",
99
+ // "/home/jacob/projects/context-extractor/targets/vscode/",
100
+ // IDE.Standalone
101
+ // )
102
+ // console.dir(x, { depth: null })
103
+ // x = await extractContext(
104
+ // Language.TypeScript,
105
+ // "/home/jacob/projects/context-extractor/targets/angular/packages/elements/src/utils.ts",
106
+ // "/home/jacob/projects/context-extractor/targets/angular/",
107
+ // )
108
+ // console.dir(x, { depth: null })
109
+ // x = await extractContext(
110
+ // Language.TypeScript,
111
+ // "/home/jacob/projects/context-extractor/targets/ionic-framework/core/src/components/img/img.tsx",
112
+ // "/home/jacob/projects/context-extractor/targets/ionic-framework/",
113
+ // )
114
+ // console.dir(x, { depth: null })
115
+ //
13
116
  // x = await extractContext(
14
117
  // Language.TypeScript,
15
118
  // "/home/jacob/projects/context-extractor/targets/todo/sketch.ts",
@@ -30,14 +133,22 @@ const types_1 = require("./types");
30
133
  // "/home/jacob/projects/context-extractor/targets/passwords/",
31
134
  // )
32
135
  // console.dir(x, { depth: null })
33
- x = await (0, main_1.extractContext)(types_1.Language.TypeScript, "/home/jacob/projects/context-extractor/targets/booking/sketch.ts", "/home/jacob/projects/context-extractor/targets/booking/");
136
+ //
137
+ x = await (0, main_1.extractContext)("typescript", "/home/jacob/projects/context-extractor/targets/booking/sketch.ts", "/home/jacob/projects/context-extractor/targets/booking/", "standalone", { line: 3, character: 56 });
34
138
  console.dir(x, { depth: null });
139
+ //
35
140
  // x = await extractContext(
36
141
  // Language.TypeScript,
37
142
  // "/home/jacob/projects/context-extractor/targets/emojipaint/sketch.ts",
38
143
  // "/home/jacob/projects/context-extractor/targets/emojipaint/",
39
144
  // )
40
145
  // console.dir(x, { depth: null })
146
+ // x = await extractContext(
147
+ // Language.TypeScript,
148
+ // "/home/jacob/projects/continue/manual-testing-sandbox/booking/sketch.ts",
149
+ // "/home/jacob/projects/continue/manual-testing-sandbox/booking",
150
+ // )
151
+ // console.dir(x, { depth: null })
41
152
  // const y = await completeWithLLM(
42
153
  // x!,
43
154
  // Language.TypeScript,
@@ -66,7 +177,11 @@ const types_1 = require("./types");
66
177
  // }
67
178
  // process.exit(0);
68
179
  }
69
- })();
180
+ // const buf = await pprof.encode(profile());
181
+ // fs.writeFile('wall.pb.gz', buf, (err) => {
182
+ // if (err) throw err;
183
+ // });
184
+ });
70
185
  // extractWithNew(Language.TypeScript, "/home/jacob/projects/context-extractor/targets/playlist/sketch.ts", "/home/jacob/projects/context-extractor/credentials.json").then(r => console.log("playlist\n", r));
71
186
  // extractWithNew(Language.TypeScript, "/home/jacob/projects/context-extractor/targets/passwords/sketch.ts", "/home/jacob/projects/context-extractor/credentials.json").then(r => console.log("passwords\n", r));
72
187
  // extractWithNew(Language.TypeScript, "/home/jacob/projects/context-extractor/targets/booking/sketch.ts", "/home/jacob/projects/context-extractor/credentials.json").then(r => console.log("booking\n", r));
@@ -0,0 +1,36 @@
1
+ ;; Capture the variable/function name
2
+ (variable_declarator
3
+ name: (identifier) @function.name
4
+ type: (type_annotation
5
+ (function_type) @function.type))
6
+
7
+ ;; Capture the full parameter list
8
+ (function_type
9
+ parameters: (formal_parameters) @function.params)
10
+
11
+ ;; Capture the type identifiers used in the parameters
12
+ (formal_parameters
13
+ (required_parameter
14
+ type: (type_annotation
15
+ (type_identifier) @param.type))
16
+ (required_parameter
17
+ type: (type_annotation
18
+ (type_identifier) @param.type)))
19
+
20
+ ;; Capture the return type of the function
21
+ (function_type
22
+ return_type: (type_identifier) @return.type)
23
+
24
+ ;; Capture any parse errors (e.g., the `??`)
25
+ (ERROR) @error.node
26
+
27
+ ;; Capture the entire function declaration line
28
+ (lexical_declaration) @function.decl
29
+
30
+ ;; Matches import declarations like: import { A, B } from "module";
31
+ (import_statement
32
+ (import_clause
33
+ (named_imports
34
+ (import_specifier
35
+ name: (identifier) @import.name)))
36
+ source: (string) @import.source)
@@ -0,0 +1,22 @@
1
+ ;; Match top-level `var`, `let`, or `const` declarations
2
+ (lexical_declaration
3
+ (variable_declarator
4
+ name: (identifier) @top.var.name
5
+ type: (type_annotation
6
+ (_) @top.var.type))) @top.var.decl
7
+
8
+ (variable_declaration
9
+ (variable_declarator
10
+ name: (identifier) @top.var.name
11
+ type: (type_annotation
12
+ (_) @top.var.type))) @top.var.decl
13
+
14
+ ;; Match function declarations
15
+ (function_declaration
16
+ name: (identifier) @top.fn.name
17
+ parameters: (formal_parameters
18
+ (required_parameter
19
+ pattern: (identifier) @top.fn.param.name
20
+ type: (type_annotation (_) @top.fn.param.type)))*
21
+
22
+ return_type: (type_annotation (_) @top.fn.type)?) @top.fn.decl
@@ -0,0 +1,10 @@
1
+ ;; Capture the type alias name (left-hand side)
2
+ ; (type_alias_declaration
3
+ ; name: (type_identifier) @type.name)
4
+
5
+ ;; Capture all identifiers on the right-hand side (value), recursively
6
+ ; (type_alias_declaration
7
+ ; value: (_) @type.value)
8
+
9
+ ;; Match all identifiers inside the type value — deeply nested
10
+ (type_identifier) @type.identifier
@@ -0,0 +1,11 @@
1
+ (type_alias_declaration
2
+ name: (type_identifier) @type.identifier
3
+ value: (_) @type.value)
4
+
5
+ (interface_declaration
6
+ name: (type_identifier) @type.identifier
7
+ body: (_) @type.value)
8
+
9
+ (enum_declaration
10
+ name: (type_identifier) @type.identifier
11
+ body: (_) @type.value)
@@ -0,0 +1,40 @@
1
+ import Parser from "web-tree-sitter";
2
+ import { SymbolWithRange } from "./types";
3
+ export declare enum LanguageName {
4
+ TYPESCRIPT = "typescript",
5
+ OCAML = "ocaml"
6
+ }
7
+ export declare const supportedLanguages: {
8
+ [key: string]: LanguageName;
9
+ };
10
+ export declare const IGNORE_PATH_PATTERNS: Partial<Record<LanguageName, RegExp[]>>;
11
+ export declare function getParserForFile(filepath: string): Promise<Parser | undefined>;
12
+ export declare function getLanguageForFile(filepath: string): Promise<Parser.Language | undefined>;
13
+ export declare const getFullLanguageName: (filepath: string) => LanguageName;
14
+ export declare function getQueryForFile(filepath: string, queryPath: string): Promise<Parser.Query | undefined>;
15
+ export declare function getSymbolsForFile(filepath: string, contents: string): Promise<SymbolWithRange[] | undefined>;
16
+ export declare function findTypeDeclarationGivenIdentifier(captures: Parser.QueryCapture[], typeIdentifier: string): {
17
+ name: Parser.SyntaxNode;
18
+ value: Parser.SyntaxNode | undefined;
19
+ kind: string | undefined;
20
+ } | null;
21
+ interface TypeDeclarationResult {
22
+ name: string;
23
+ fullText: string;
24
+ startLine: number;
25
+ startColumn: number;
26
+ endLine: number;
27
+ endColumn: number;
28
+ kind: string;
29
+ }
30
+ export declare function findEnclosingTypeDeclaration(sourceCode: string, cursorLine: number, cursorColumn: number, ast: Parser.Tree): TypeDeclarationResult | null;
31
+ export declare function extractTopLevelDecls(currentFile: string): Promise<Parser.QueryMatch[]>;
32
+ export declare function extractTopLevelDeclsWithFormatting(currentFile: string): Promise<{
33
+ declaration: string;
34
+ nodeType: string;
35
+ name: string;
36
+ declaredType: string;
37
+ returnType?: string;
38
+ }[]>;
39
+ export declare function extractFunctionTypeFromDecl(match: Parser.QueryMatch): string;
40
+ export {};
@@ -0,0 +1,334 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getFullLanguageName = exports.IGNORE_PATH_PATTERNS = exports.supportedLanguages = exports.LanguageName = void 0;
7
+ exports.getParserForFile = getParserForFile;
8
+ exports.getLanguageForFile = getLanguageForFile;
9
+ exports.getQueryForFile = getQueryForFile;
10
+ exports.getSymbolsForFile = getSymbolsForFile;
11
+ exports.findTypeDeclarationGivenIdentifier = findTypeDeclarationGivenIdentifier;
12
+ exports.findEnclosingTypeDeclaration = findEnclosingTypeDeclaration;
13
+ exports.extractTopLevelDecls = extractTopLevelDecls;
14
+ exports.extractTopLevelDeclsWithFormatting = extractTopLevelDeclsWithFormatting;
15
+ exports.extractFunctionTypeFromDecl = extractFunctionTypeFromDecl;
16
+ const fs_1 = __importDefault(require("fs"));
17
+ const web_tree_sitter_1 = __importDefault(require("web-tree-sitter"));
18
+ const utils_1 = require("./utils");
19
+ const ast_1 = require("./ast");
20
+ var LanguageName;
21
+ (function (LanguageName) {
22
+ LanguageName["TYPESCRIPT"] = "typescript";
23
+ LanguageName["OCAML"] = "ocaml";
24
+ })(LanguageName || (exports.LanguageName = LanguageName = {}));
25
+ exports.supportedLanguages = {
26
+ ts: LanguageName.TYPESCRIPT,
27
+ mts: LanguageName.TYPESCRIPT,
28
+ cts: LanguageName.TYPESCRIPT,
29
+ ocaml: LanguageName.OCAML,
30
+ ml: LanguageName.OCAML,
31
+ mli: LanguageName.OCAML,
32
+ };
33
+ exports.IGNORE_PATH_PATTERNS = {
34
+ [LanguageName.TYPESCRIPT]: [/.*node_modules/],
35
+ };
36
+ async function getParserForFile(filepath) {
37
+ try {
38
+ await web_tree_sitter_1.default.init();
39
+ const parser = new web_tree_sitter_1.default();
40
+ const language = await getLanguageForFile(filepath);
41
+ if (!language) {
42
+ return undefined;
43
+ }
44
+ parser.setLanguage(language);
45
+ return parser;
46
+ }
47
+ catch (e) {
48
+ console.debug("Unable to load language for file", filepath, e);
49
+ return undefined;
50
+ }
51
+ }
52
+ // Loading the wasm files to create a Language object is an expensive operation and with
53
+ // sufficient number of files can result in errors, instead keep a map of language name
54
+ // to Language object
55
+ const nameToLanguage = new Map();
56
+ async function getLanguageForFile(filepath) {
57
+ try {
58
+ await web_tree_sitter_1.default.init();
59
+ const extension = (0, utils_1.getUriFileExtension)(filepath);
60
+ const languageName = exports.supportedLanguages[extension];
61
+ if (!languageName) {
62
+ return undefined;
63
+ }
64
+ let language = nameToLanguage.get(languageName);
65
+ if (!language) {
66
+ language = await loadLanguageForFileExt(extension);
67
+ nameToLanguage.set(languageName, language);
68
+ }
69
+ return language;
70
+ }
71
+ catch (e) {
72
+ console.debug("Unable to load language for file", filepath, e);
73
+ return undefined;
74
+ }
75
+ }
76
+ const getFullLanguageName = (filepath) => {
77
+ const extension = (0, utils_1.getUriFileExtension)(filepath);
78
+ return exports.supportedLanguages[extension];
79
+ };
80
+ exports.getFullLanguageName = getFullLanguageName;
81
+ async function getQueryForFile(filepath, queryPath) {
82
+ const language = await getLanguageForFile(filepath);
83
+ if (!language) {
84
+ return undefined;
85
+ }
86
+ if (!fs_1.default.existsSync(queryPath)) {
87
+ return undefined;
88
+ }
89
+ const querySource = fs_1.default.readFileSync(queryPath).toString();
90
+ const query = language.query(querySource);
91
+ return query;
92
+ }
93
+ async function loadLanguageForFileExt(fileExtension) {
94
+ const wasmPath = require.resolve(`./tree-sitter-files/wasms/tree-sitter-${exports.supportedLanguages[fileExtension]}.wasm`);
95
+ // const wasmPath = path.join(
96
+ // __dirname,
97
+ // "tree-sitter-files",
98
+ // "wasms",
99
+ // `tree-sitter-${supportedLanguages[fileExtension]}.wasm`
100
+ // );
101
+ return await web_tree_sitter_1.default.Language.load(wasmPath);
102
+ }
103
+ const GET_SYMBOLS_FOR_NODE_TYPES = [
104
+ "class_declaration",
105
+ "class_definition",
106
+ "function_item", // function name = first "identifier" child
107
+ "function_definition",
108
+ "method_declaration", // method name = first "identifier" child
109
+ "method_definition",
110
+ "generator_function_declaration",
111
+ // property_identifier
112
+ // field_declaration
113
+ // "arrow_function",
114
+ ];
115
+ async function getSymbolsForFile(filepath, contents) {
116
+ const parser = await getParserForFile(filepath);
117
+ if (!parser) {
118
+ return;
119
+ }
120
+ let tree;
121
+ try {
122
+ tree = parser.parse(contents);
123
+ if (!tree) {
124
+ throw new Error("tree parsing failed");
125
+ }
126
+ }
127
+ catch (e) {
128
+ console.log(`Error parsing file: ${filepath}`);
129
+ return;
130
+ }
131
+ // console.log(`file: ${filepath}`);
132
+ // Function to recursively find all named nodes (classes and functions)
133
+ const symbols = [];
134
+ function findNamedNodesRecursive(node) {
135
+ if (!node) {
136
+ return;
137
+ }
138
+ // console.log(`node: ${node.type}, ${node.text}`);
139
+ if (GET_SYMBOLS_FOR_NODE_TYPES.includes(node.type)) {
140
+ // console.log(`parent: ${node.type}, ${node.text.substring(0, 200)}`);
141
+ // node.children.forEach((child) => {
142
+ // console.log(`child: ${child.type}, ${child.text}`);
143
+ // });
144
+ // Empirically, the actual name is the last identifier in the node
145
+ // Especially with languages where return type is declared before the name
146
+ // TODO use findLast in newer version of node target
147
+ let identifier = undefined;
148
+ for (let i = node.children.length - 1; i >= 0; i--) {
149
+ if (node.children[i] &&
150
+ (node.children[i].type === "identifier" ||
151
+ node.children[i].type === "property_identifier")) {
152
+ identifier = node.children[i];
153
+ break;
154
+ }
155
+ }
156
+ if (identifier === null || identifier === void 0 ? void 0 : identifier.text) {
157
+ symbols.push({
158
+ filepath,
159
+ type: node.type,
160
+ name: identifier.text,
161
+ range: {
162
+ start: {
163
+ character: node.startPosition.column,
164
+ line: node.startPosition.row,
165
+ },
166
+ end: {
167
+ character: node.endPosition.column + 1,
168
+ line: node.endPosition.row + 1,
169
+ },
170
+ },
171
+ content: node.text,
172
+ });
173
+ }
174
+ }
175
+ node.children.forEach(findNamedNodesRecursive);
176
+ }
177
+ findNamedNodesRecursive(tree.rootNode);
178
+ return symbols;
179
+ }
180
+ function findTypeDeclarationGivenIdentifier(captures, typeIdentifier) {
181
+ for (let i = 0; i < captures.length; i++) {
182
+ const cap = captures[i];
183
+ if (cap.name === "type.identifier" && cap.node.text === typeIdentifier) {
184
+ const parent = cap.node.parent;
185
+ const value = captures.find((c) => c.name === "type.value" && c.node.parent === parent);
186
+ return { name: cap.node, value: value === null || value === void 0 ? void 0 : value.node, kind: parent === null || parent === void 0 ? void 0 : parent.type };
187
+ }
188
+ }
189
+ return null;
190
+ }
191
+ function findEnclosingTypeDeclaration(sourceCode, cursorLine, cursorColumn, ast) {
192
+ var _a;
193
+ const point = { row: cursorLine, column: cursorColumn };
194
+ let node = ast.rootNode.descendantForPosition(point);
195
+ while (node &&
196
+ ![
197
+ "type_alias_declaration",
198
+ "interface_declaration",
199
+ "enum_declaration",
200
+ ].includes(node.type)) {
201
+ if (!node.parent)
202
+ return null;
203
+ node = node.parent;
204
+ }
205
+ if (!node)
206
+ return null;
207
+ const nameNode = node.childForFieldName("name");
208
+ const name = (_a = nameNode === null || nameNode === void 0 ? void 0 : nameNode.text) !== null && _a !== void 0 ? _a : "<anonymous>";
209
+ const fullText = sourceCode.slice(node.startIndex, node.endIndex);
210
+ return {
211
+ name,
212
+ fullText,
213
+ startLine: node.startPosition.row,
214
+ startColumn: node.startPosition.column,
215
+ endLine: node.endPosition.row,
216
+ endColumn: node.endPosition.column,
217
+ kind: node.type,
218
+ };
219
+ }
220
+ async function extractTopLevelDecls(currentFile) {
221
+ const ast = await (0, ast_1.getAst)(currentFile, fs_1.default.readFileSync(currentFile, "utf8"));
222
+ if (!ast) {
223
+ throw new Error(`failed to get ast for file ${currentFile}`);
224
+ }
225
+ const language = (0, exports.getFullLanguageName)(currentFile);
226
+ const queryPath = require.resolve(`./tree-sitter-files/queries/relevant-headers-queries/${language}-get-toplevel-headers.scm`);
227
+ const query = await getQueryForFile(currentFile, queryPath
228
+ // path.join(
229
+ // __dirname,
230
+ // "tree-sitter-files",
231
+ // "queries",
232
+ // "relevant-headers-queries",
233
+ // `${language}-get-toplevel-headers.scm`
234
+ // )
235
+ );
236
+ if (!query) {
237
+ throw new Error(`failed to get query for file ${currentFile} and language ${language}`);
238
+ }
239
+ return query.matches(ast.rootNode);
240
+ }
241
+ async function extractTopLevelDeclsWithFormatting(currentFile) {
242
+ var _a;
243
+ const ast = await (0, ast_1.getAst)(currentFile, fs_1.default.readFileSync(currentFile, "utf8"));
244
+ if (!ast) {
245
+ throw new Error(`failed to get ast for file ${currentFile}`);
246
+ }
247
+ const language = (0, exports.getFullLanguageName)(currentFile);
248
+ const queryPath = require.resolve(`./tree-sitter-files/queries/relevant-headers-queries/${language}-get-toplevel-headers.scm`);
249
+ const query = await getQueryForFile(currentFile, queryPath
250
+ // path.join(
251
+ // __dirname,
252
+ // "tree-sitter-files",
253
+ // "queries",
254
+ // "relevant-headers-queries",
255
+ // `${language}-get-toplevel-headers.scm`
256
+ // )
257
+ );
258
+ if (!query) {
259
+ throw new Error(`failed to get query for file ${currentFile} and language ${language}`);
260
+ }
261
+ const matches = query.matches(ast.rootNode);
262
+ const results = [];
263
+ for (const match of matches) {
264
+ const item = {
265
+ declaration: "",
266
+ nodeType: "",
267
+ name: "",
268
+ declaredType: "",
269
+ };
270
+ for (const { name, node } of match.captures) {
271
+ if (name === "top.var.decl") {
272
+ item.nodeType = "variable";
273
+ item.declaration = node.text;
274
+ // Attempt to get the declared type (e.g., const x: string = ...)
275
+ const typeNode = node.descendantsOfType("type_annotation")[0];
276
+ if (typeNode) {
277
+ item.declaredType = typeNode.text.replace(/^:\s*/, "");
278
+ }
279
+ }
280
+ else if (name === "top.var.name" || name === "top.fn.name") {
281
+ item.name = node.text;
282
+ }
283
+ else if (name === "top.fn.decl") {
284
+ item.nodeType = "function";
285
+ item.declaration = node.text;
286
+ // Get the return type (e.g., function foo(): string)
287
+ const returnTypeNode = node.childForFieldName("return_type");
288
+ if (returnTypeNode) {
289
+ item.returnType = returnTypeNode.text.replace(/^:\s*/, "");
290
+ }
291
+ // Get declaredType if needed (TypeScript style)
292
+ const nameNode = node.childForFieldName("name");
293
+ if (nameNode && ((_a = nameNode.nextSibling) === null || _a === void 0 ? void 0 : _a.type) === "type_annotation") {
294
+ item.declaredType = nameNode.nextSibling.text.replace(/^:\s*/, "");
295
+ }
296
+ }
297
+ }
298
+ if (item.name && item.declaration) {
299
+ results.push(item);
300
+ }
301
+ }
302
+ return results;
303
+ }
304
+ function extractFunctionTypeFromDecl(match) {
305
+ let paramsNode;
306
+ let returnNode;
307
+ for (const capture of match.captures) {
308
+ if (capture.name === "top.fn.param.type") {
309
+ paramsNode = capture.node;
310
+ }
311
+ else if (capture.name === "top.fn.type") {
312
+ returnNode = capture.node;
313
+ }
314
+ }
315
+ return `${paramsNode.text} => ${returnNode.text}`;
316
+ }
317
+ // export async function getSymbolsForManyFiles(
318
+ // uris: string[],
319
+ // ide: IDE,
320
+ // ): Promise<FileSymbolMap> {
321
+ // const filesAndSymbols = await Promise.all(
322
+ // uris.map(async (uri): Promise<[string, SymbolWithRange[]]> => {
323
+ // const contents = await ide.readFile(uri);
324
+ // let symbols = undefined;
325
+ // try {
326
+ // symbols = await getSymbolsForFile(uri, contents);
327
+ // } catch (e) {
328
+ // console.error(`Failed to get symbols for ${uri}:`, e);
329
+ // }
330
+ // return [uri, symbols ?? []];
331
+ // }),
332
+ // );
333
+ // return Object.fromEntries(filesAndSymbols);
334
+ // }