@jpoly1219/context-extractor 0.2.9 → 0.2.11

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.
@@ -14,7 +14,6 @@ exports.extractTopLevelDecls = extractTopLevelDecls;
14
14
  exports.extractTopLevelDeclsWithFormatting = extractTopLevelDeclsWithFormatting;
15
15
  exports.extractFunctionTypeFromDecl = extractFunctionTypeFromDecl;
16
16
  const fs_1 = __importDefault(require("fs"));
17
- const path_1 = __importDefault(require("path"));
18
17
  const web_tree_sitter_1 = __importDefault(require("web-tree-sitter"));
19
18
  const utils_1 = require("./utils");
20
19
  const ast_1 = require("./ast");
@@ -38,6 +37,24 @@ async function getParserForFile(filepath) {
38
37
  try {
39
38
  await web_tree_sitter_1.default.init();
40
39
  const parser = new web_tree_sitter_1.default();
40
+ // const packageRoot = path.dirname(
41
+ // require.resolve("./package.json", { paths: [__dirname] })
42
+ // );
43
+ // console.log(packageRoot);
44
+ // const wasmPath2 = require.resolve(
45
+ // path.join(
46
+ // __dirname,
47
+ // `tree-sitter-files/wasms/tree-sitter-${supportedLanguages["ts"]}.wasm`
48
+ // )
49
+ // );
50
+ // console.log(wasmPath2);
51
+ // const wasmPath3 = require.resolve(
52
+ // path.resolve(
53
+ // __dirname,
54
+ // `tree-sitter-files/wasms/tree-sitter-${supportedLanguages["ts"]}.wasm`
55
+ // )
56
+ // );
57
+ // console.log(wasmPath3);
41
58
  const language = await getLanguageForFile(filepath);
42
59
  if (!language) {
43
60
  return undefined;
@@ -92,7 +109,13 @@ async function getQueryForFile(filepath, queryPath) {
92
109
  return query;
93
110
  }
94
111
  async function loadLanguageForFileExt(fileExtension) {
95
- const wasmPath = path_1.default.join(__dirname, "tree-sitter-files", "wasms", `tree-sitter-${exports.supportedLanguages[fileExtension]}.wasm`);
112
+ const wasmPath = require.resolve(`@jpoly1219/context-extractor/src/tree-sitter-files/wasms/tree-sitter-${exports.supportedLanguages[fileExtension]}.wasm`);
113
+ // const wasmPath = path.join(
114
+ // __dirname,
115
+ // "tree-sitter-files",
116
+ // "wasms",
117
+ // `tree-sitter-${supportedLanguages[fileExtension]}.wasm`
118
+ // );
96
119
  return await web_tree_sitter_1.default.Language.load(wasmPath);
97
120
  }
98
121
  const GET_SYMBOLS_FOR_NODE_TYPES = [
@@ -218,7 +241,16 @@ async function extractTopLevelDecls(currentFile) {
218
241
  throw new Error(`failed to get ast for file ${currentFile}`);
219
242
  }
220
243
  const language = (0, exports.getFullLanguageName)(currentFile);
221
- const query = await getQueryForFile(currentFile, path_1.default.join(__dirname, "tree-sitter-files", "queries", "relevant-headers-queries", `${language}-get-toplevel-headers.scm`));
244
+ const queryPath = require.resolve(`@jpoly1219/context-extractor/src/tree-sitter-files/queries/relevant-headers-queries/${language}-get-toplevel-headers.scm`);
245
+ const query = await getQueryForFile(currentFile, queryPath
246
+ // path.join(
247
+ // __dirname,
248
+ // "tree-sitter-files",
249
+ // "queries",
250
+ // "relevant-headers-queries",
251
+ // `${language}-get-toplevel-headers.scm`
252
+ // )
253
+ );
222
254
  if (!query) {
223
255
  throw new Error(`failed to get query for file ${currentFile} and language ${language}`);
224
256
  }
@@ -231,7 +263,16 @@ async function extractTopLevelDeclsWithFormatting(currentFile) {
231
263
  throw new Error(`failed to get ast for file ${currentFile}`);
232
264
  }
233
265
  const language = (0, exports.getFullLanguageName)(currentFile);
234
- const query = await getQueryForFile(currentFile, path_1.default.join(__dirname, "tree-sitter-files", "queries", "relevant-headers-queries", `${language}-get-toplevel-headers.scm`));
266
+ const queryPath = require.resolve(`@jpoly1219/context-extractor/src/tree-sitter-files/queries/relevant-headers-queries/${language}-get-toplevel-headers.scm`);
267
+ const query = await getQueryForFile(currentFile, queryPath
268
+ // path.join(
269
+ // __dirname,
270
+ // "tree-sitter-files",
271
+ // "queries",
272
+ // "relevant-headers-queries",
273
+ // `${language}-get-toplevel-headers.scm`
274
+ // )
275
+ );
235
276
  if (!query) {
236
277
  throw new Error(`failed to get query for file ${currentFile} and language ${language}`);
237
278
  }
@@ -1,9 +1,9 @@
1
- import * as ts from 'typescript';
1
+ import * as ts from "typescript";
2
2
  import * as fs from "fs";
3
3
  import { LspClient, Location, Range, SymbolInformation } from "../ts-lsp-client-dist/src/main";
4
4
  import { LanguageDriver, TypeSpanAndSourceFile, TypeAnalysis, IDE, TypeSpanAndSourceFileAndAst } from "./types";
5
5
  import { TypeScriptTypeChecker } from "./typescript-type-checker";
6
- import Parser from 'web-tree-sitter';
6
+ import Parser from "web-tree-sitter";
7
7
  export declare class TypeScriptDriver implements LanguageDriver {
8
8
  ide: IDE;
9
9
  typeChecker: TypeScriptTypeChecker;
@@ -47,7 +47,7 @@ class TypeScriptDriver {
47
47
  this.typeChecker = new typescript_type_checker_1.TypeScriptTypeChecker();
48
48
  this.ide = ide;
49
49
  if (ide == "vscode") {
50
- Promise.resolve().then(() => __importStar(require("./vscode-ide"))).then(module => this.vscodeImport = module);
50
+ Promise.resolve().then(() => __importStar(require("./vscode-ide"))).then((module) => (this.vscodeImport = module));
51
51
  }
52
52
  // Initialize TypeScript compiler API.
53
53
  this.tsCompilerProgram = this.typeChecker.createTsCompilerProgram(sources, projectRoot);
@@ -56,89 +56,101 @@ class TypeScriptDriver {
56
56
  async init(lspClient, sketchPath) {
57
57
  if (lspClient) {
58
58
  const capabilities = {
59
- 'textDocument': {
60
- 'codeAction': { 'dynamicRegistration': true },
61
- 'codeLens': { 'dynamicRegistration': true },
62
- 'colorProvider': { 'dynamicRegistration': true },
63
- 'completion': {
64
- 'completionItem': {
65
- 'commitCharactersSupport': true,
66
- 'documentationFormat': ['markdown', 'plaintext'],
67
- 'snippetSupport': true
59
+ textDocument: {
60
+ codeAction: { dynamicRegistration: true },
61
+ codeLens: { dynamicRegistration: true },
62
+ colorProvider: { dynamicRegistration: true },
63
+ completion: {
64
+ completionItem: {
65
+ commitCharactersSupport: true,
66
+ documentationFormat: ["markdown", "plaintext"],
67
+ snippetSupport: true,
68
68
  },
69
- 'completionItemKind': {
70
- 'valueSet': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
69
+ completionItemKind: {
70
+ valueSet: [
71
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
72
+ 19, 20, 21, 22, 23, 24, 25,
73
+ ],
71
74
  },
72
- 'contextSupport': true,
73
- 'dynamicRegistration': true
75
+ contextSupport: true,
76
+ dynamicRegistration: true,
74
77
  },
75
- 'definition': { 'dynamicRegistration': true },
76
- 'documentHighlight': { 'dynamicRegistration': true },
77
- 'documentLink': { 'dynamicRegistration': true },
78
- 'documentSymbol': {
79
- 'dynamicRegistration': true,
80
- 'symbolKind': {
81
- 'valueSet': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
82
- }
78
+ definition: { dynamicRegistration: true },
79
+ documentHighlight: { dynamicRegistration: true },
80
+ documentLink: { dynamicRegistration: true },
81
+ documentSymbol: {
82
+ dynamicRegistration: true,
83
+ symbolKind: {
84
+ valueSet: [
85
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
86
+ 19, 20, 21, 22, 23, 24, 25, 26,
87
+ ],
88
+ },
83
89
  },
84
- 'formatting': { 'dynamicRegistration': true },
85
- 'hover': {
86
- 'contentFormat': ['markdown', 'plaintext'],
87
- 'dynamicRegistration': true
90
+ formatting: { dynamicRegistration: true },
91
+ hover: {
92
+ contentFormat: ["markdown", "plaintext"],
93
+ dynamicRegistration: true,
88
94
  },
89
- 'implementation': { 'dynamicRegistration': true },
95
+ implementation: { dynamicRegistration: true },
90
96
  // 'inlayhint': { 'dynamicRegistration': true },
91
- 'onTypeFormatting': { 'dynamicRegistration': true },
92
- 'publishDiagnostics': { 'relatedInformation': true },
93
- 'rangeFormatting': { 'dynamicRegistration': true },
94
- 'references': { 'dynamicRegistration': true },
95
- 'rename': { 'dynamicRegistration': true },
96
- 'signatureHelp': {
97
- 'dynamicRegistration': true,
98
- 'signatureInformation': { 'documentationFormat': ['markdown', 'plaintext'] }
97
+ onTypeFormatting: { dynamicRegistration: true },
98
+ publishDiagnostics: { relatedInformation: true },
99
+ rangeFormatting: { dynamicRegistration: true },
100
+ references: { dynamicRegistration: true },
101
+ rename: { dynamicRegistration: true },
102
+ signatureHelp: {
103
+ dynamicRegistration: true,
104
+ signatureInformation: {
105
+ documentationFormat: ["markdown", "plaintext"],
106
+ },
99
107
  },
100
- 'synchronization': {
101
- 'didSave': true,
102
- 'dynamicRegistration': true,
103
- 'willSave': true,
104
- 'willSaveWaitUntil': true
108
+ synchronization: {
109
+ didSave: true,
110
+ dynamicRegistration: true,
111
+ willSave: true,
112
+ willSaveWaitUntil: true,
105
113
  },
106
- 'typeDefinition': { 'dynamicRegistration': true, 'linkSupport': true },
114
+ typeDefinition: { dynamicRegistration: true, linkSupport: true },
107
115
  // 'typeHierarchy': { 'dynamicRegistration': true }
108
116
  },
109
- 'workspace': {
110
- 'applyEdit': true,
111
- 'configuration': true,
112
- 'didChangeConfiguration': { 'dynamicRegistration': true },
113
- 'didChangeWatchedFiles': { 'dynamicRegistration': true },
114
- 'executeCommand': { 'dynamicRegistration': true },
115
- 'symbol': {
116
- 'dynamicRegistration': true,
117
- 'symbolKind': {
118
- 'valueSet': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
119
- }
120
- }, 'workspaceEdit': { 'documentChanges': true },
121
- 'workspaceFolders': true
117
+ workspace: {
118
+ applyEdit: true,
119
+ configuration: true,
120
+ didChangeConfiguration: { dynamicRegistration: true },
121
+ didChangeWatchedFiles: { dynamicRegistration: true },
122
+ executeCommand: { dynamicRegistration: true },
123
+ symbol: {
124
+ dynamicRegistration: true,
125
+ symbolKind: {
126
+ valueSet: [
127
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
128
+ 19, 20, 21, 22, 23, 24, 25, 26,
129
+ ],
130
+ },
131
+ },
132
+ workspaceEdit: { documentChanges: true },
133
+ workspaceFolders: true,
122
134
  },
123
- 'general': {
124
- 'positionEncodings': ['utf-8']
135
+ general: {
136
+ positionEncodings: ["utf-8"],
125
137
  },
126
138
  };
127
139
  const rootPath = path.dirname(sketchPath);
128
140
  const rootUri = `file://${rootPath}`;
129
- const workspaceFolders = [{ 'name': 'context-extractor', 'uri': rootUri }];
141
+ const workspaceFolders = [{ name: "context-extractor", uri: rootUri }];
130
142
  await lspClient.initialize({
131
143
  processId: process.pid,
132
144
  capabilities: capabilities,
133
- trace: 'off',
145
+ trace: "off",
134
146
  rootUri: null,
135
147
  workspaceFolders: workspaceFolders,
136
148
  initializationOptions: {
137
149
  disableAutomaticTypingAcquisition: true,
138
150
  preferences: {
139
151
  includeInlayVariableTypeHints: true,
140
- }
141
- }
152
+ },
153
+ },
142
154
  });
143
155
  }
144
156
  }
@@ -163,13 +175,12 @@ class TypeScriptDriver {
163
175
  // Get the hole's position.
164
176
  const holePattern = /_\(\)/;
165
177
  const firstPatternIndex = injectedSketchFileContent.search(holePattern);
166
- const linePosition = (injectedSketchFileContent
178
+ const linePosition = injectedSketchFileContent
167
179
  .substring(0, firstPatternIndex)
168
- .match(/\n/g)).length;
169
- const characterPosition = firstPatternIndex - (injectedSketchFileContent
170
- .split("\n", linePosition)
171
- .join("\n")
172
- .length) - 1;
180
+ .match(/\n/g).length;
181
+ const characterPosition = firstPatternIndex -
182
+ injectedSketchFileContent.split("\n", linePosition).join("\n").length -
183
+ 1;
173
184
  if (lspClient) {
174
185
  // Sync client and server by notifying that
175
186
  // the client has opened all the files
@@ -207,15 +218,17 @@ class TypeScriptDriver {
207
218
  console.time("hover");
208
219
  const holeHoverResult = await lspClient.hover({
209
220
  textDocument: {
210
- uri: injectedSketchFilePath
221
+ uri: injectedSketchFilePath,
211
222
  },
212
223
  position: {
213
224
  character: characterPosition,
214
- line: linePosition
215
- }
225
+ line: linePosition,
226
+ },
216
227
  });
217
228
  console.timeEnd("hover");
218
- const formattedHoverResult = holeHoverResult.contents.value.split("\n").reduce((acc, curr) => {
229
+ const formattedHoverResult = holeHoverResult.contents.value
230
+ .split("\n")
231
+ .reduce((acc, curr) => {
219
232
  if (curr != "" && curr != "```typescript" && curr != "```") {
220
233
  return acc + curr;
221
234
  }
@@ -240,18 +253,20 @@ class TypeScriptDriver {
240
253
  lspClient.didChange({
241
254
  textDocument: {
242
255
  uri: `file://${injectedSketchFilePath}`,
243
- version: 2
256
+ version: 2,
244
257
  },
245
- contentChanges: [{
246
- text: trueInjectedSketchFileContent
247
- }]
258
+ contentChanges: [
259
+ {
260
+ text: trueInjectedSketchFileContent,
261
+ },
262
+ ],
248
263
  });
249
264
  console.timeEnd("didChange");
250
265
  console.time("documentSymbol");
251
266
  const sketchSymbol = await lspClient.documentSymbol({
252
267
  textDocument: {
253
268
  uri: `file://${injectedSketchFilePath}`,
254
- }
269
+ },
255
270
  });
256
271
  console.timeEnd("documentSymbol");
257
272
  return {
@@ -265,7 +280,7 @@ class TypeScriptDriver {
265
280
  // range: { start: { line: 0, character: 0 }, end: { line: 0, character: 52 } }
266
281
  range: sketchSymbol[0].location.range,
267
282
  source: `file://${injectedSketchFilePath}`,
268
- trueHoleFunction: trueHoleFunction
283
+ trueHoleFunction: trueHoleFunction,
269
284
  };
270
285
  }
271
286
  else {
@@ -273,10 +288,12 @@ class TypeScriptDriver {
273
288
  filepath: injectedSketchFilePath,
274
289
  position: {
275
290
  line: linePosition,
276
- character: characterPosition
277
- }
291
+ character: characterPosition,
292
+ },
278
293
  });
279
- const formattedHoverResult = holeHoverResult.text.split("\n").reduce((acc, curr) => {
294
+ const formattedHoverResult = holeHoverResult.text
295
+ .split("\n")
296
+ .reduce((acc, curr) => {
280
297
  if (curr != "" && curr != "```typescript" && curr != "```") {
281
298
  return acc + curr;
282
299
  }
@@ -294,7 +311,7 @@ class TypeScriptDriver {
294
311
  const trueInjectedSketchFileContent = `${trueHoleFunction}\n${sketchFileContent}`;
295
312
  fs.writeFileSync(injectedSketchFilePath, trueInjectedSketchFileContent);
296
313
  const sketchSymbol = await this.vscodeImport.VsCode.getDocumentSymbols({
297
- filepath: injectedSketchFilePath
314
+ filepath: injectedSketchFilePath,
298
315
  });
299
316
  return {
300
317
  fullHoverResult: formattedHoverResult,
@@ -306,7 +323,7 @@ class TypeScriptDriver {
306
323
  holeTypeDefCharPos: "declare function _(): ".length,
307
324
  range: sketchSymbol[0].range,
308
325
  source: `file://${injectedSketchFilePath}`,
309
- trueHoleFunction: trueHoleFunction
326
+ trueHoleFunction: trueHoleFunction,
310
327
  };
311
328
  }
312
329
  }
@@ -322,13 +339,12 @@ class TypeScriptDriver {
322
339
  // Get the hole's position.
323
340
  const holePattern = /_\(\)/;
324
341
  const firstPatternIndex = injectedSketchFileContent.search(holePattern);
325
- const linePosition = (injectedSketchFileContent
342
+ const linePosition = injectedSketchFileContent
326
343
  .substring(0, firstPatternIndex)
327
- .match(/\n/g)).length;
328
- const characterPosition = firstPatternIndex - (injectedSketchFileContent
329
- .split("\n", linePosition)
330
- .join("\n")
331
- .length) - 1;
344
+ .match(/\n/g).length;
345
+ const characterPosition = firstPatternIndex -
346
+ injectedSketchFileContent.split("\n", linePosition).join("\n").length -
347
+ 1;
332
348
  // const sourceFile = ts.createSourceFile("sample.ts", injectedSketchFileContent, ts.ScriptTarget.Latest, true);
333
349
  const sourceFile = this.tsCompilerProgram.getSourceFile(injectedSketchFilePath);
334
350
  const position = ts.getPositionOfLineAndCharacter(sourceFile, linePosition, characterPosition);
@@ -368,10 +384,13 @@ class TypeScriptDriver {
368
384
  characterPosition: characterPosition,
369
385
  holeTypeDefLinePos: 0,
370
386
  holeTypeDefCharPos: "declare function _(): ".length,
371
- range: { start: { line: 0, character: 0 }, end: { line: 0, character: 52 } },
387
+ range: {
388
+ start: { line: 0, character: 0 },
389
+ end: { line: 0, character: 52 },
390
+ },
372
391
  // range: (sketchSymbol![0] as SymbolInformation).location.range,
373
392
  source: `file://${injectedSketchFilePath}`,
374
- trueHoleFunction: trueHoleFunction
393
+ trueHoleFunction: trueHoleFunction,
375
394
  };
376
395
  }
377
396
  async getHoleContextWithTreesitter(sketchFilePath, cursorPosition, logStream) {
@@ -382,7 +401,10 @@ class TypeScriptDriver {
382
401
  const sketchFileContent = fs.readFileSync(sketchFilePath, "utf8");
383
402
  const injectedContent = (0, utils_1.insertAtPosition)(sketchFileContent, cursorPosition, "@;");
384
403
  // The hole's position is cursorPosition.
385
- const snip = (0, utils_1.extractSnippet)(injectedContent, cursorPosition, { line: cursorPosition.line, character: cursorPosition.character + 2 });
404
+ const snip = (0, utils_1.extractSnippet)(injectedContent, cursorPosition, {
405
+ line: cursorPosition.line,
406
+ character: cursorPosition.character + 2,
407
+ });
386
408
  // console.log(snip)
387
409
  // Use treesitter to parse.
388
410
  const ast = await (0, ast_1.getAst)(sketchFilePath, injectedContent);
@@ -390,7 +412,16 @@ class TypeScriptDriver {
390
412
  throw new Error("failed to get ast");
391
413
  }
392
414
  const language = (0, tree_sitter_1.getFullLanguageName)(sketchFilePath);
393
- const query = await (0, tree_sitter_1.getQueryForFile)(sketchFilePath, path.join(__dirname, "tree-sitter-files", "queries", "hole-queries", `${language}.scm`));
415
+ const queryPath = require.resolve(`@jpoly1219/context-extractor/src/tree-sitter-files/queries/hole-queries/${language}.scm`);
416
+ const query = await (0, tree_sitter_1.getQueryForFile)(sketchFilePath, queryPath
417
+ // path.join(
418
+ // __dirname,
419
+ // "tree-sitter-files",
420
+ // "queries",
421
+ // "hole-queries",
422
+ // `${language}.scm`
423
+ // ),
424
+ );
394
425
  if (!query) {
395
426
  throw new Error(`failed to get query for file ${sketchFilePath} and language ${language}`);
396
427
  }
@@ -414,10 +445,13 @@ class TypeScriptDriver {
414
445
  characterPosition: 0,
415
446
  holeTypeDefLinePos: 0,
416
447
  holeTypeDefCharPos: "declare function _(): ".length,
417
- range: { start: { line: 0, character: 0 }, end: { line: 0, character: 52 } },
448
+ range: {
449
+ start: { line: 0, character: 0 },
450
+ end: { line: 0, character: 52 },
451
+ },
418
452
  // range: (sketchSymbol![0] as SymbolInformation).location.range,
419
453
  source: `file://${sketchFilePath}`,
420
- trueHoleFunction: ""
454
+ trueHoleFunction: "",
421
455
  };
422
456
  for (const c of captures) {
423
457
  const { name, node } = c;
@@ -439,7 +473,7 @@ class TypeScriptDriver {
439
473
  end: {
440
474
  line: node.endPosition.row,
441
475
  character: node.endPosition.column,
442
- }
476
+ },
443
477
  };
444
478
  }
445
479
  }
@@ -452,32 +486,39 @@ class TypeScriptDriver {
452
486
  // outputFile: fs.WriteStream,
453
487
  ) {
454
488
  if (!foundSoFar.has(typeName)) {
455
- foundSoFar.set(typeName, { typeSpan: fullHoverResult, sourceFile: currentFile.slice(7) });
489
+ foundSoFar.set(typeName, {
490
+ typeSpan: fullHoverResult,
491
+ sourceFile: currentFile.slice(7),
492
+ });
456
493
  // outputFile.write(`${fullHoverResult};\n`);
457
494
  const content = fs.readFileSync(currentFile.slice(7), "utf8");
458
495
  for (let linePos = startLine; linePos <= endLine; ++linePos) {
459
496
  // TODO: use a platform-agnostic command here
460
- const numOfCharsInLine = parseInt((0, child_process_1.execSync)(`wc -m <<< "${content.split("\n")[linePos]}"`, { shell: "/bin/bash" }).toString());
497
+ const numOfCharsInLine = parseInt((0, child_process_1.execSync)(`wc -m <<< "${content.split("\n")[linePos]}"`, {
498
+ shell: "/bin/bash",
499
+ }).toString());
461
500
  const numOfCharsInLine2 = content.split("\n")[linePos].length;
462
- const numOfCharsInLine3 = [...content.split("\n")[linePos]].map(c => c.codePointAt(0)).length;
501
+ const numOfCharsInLine3 = [...content.split("\n")[linePos]].map((c) => c.codePointAt(0)).length;
463
502
  // console.log(numOfCharsInLine === numOfCharsInLine2, content.split("\n")[linePos], numOfCharsInLine, numOfCharsInLine2, numOfCharsInLine3)
464
503
  // console.time(`===loop ${content.split("\n")[linePos]}===`);
465
504
  for (let charPos = 0; charPos < numOfCharsInLine2; ++charPos) {
466
505
  try {
467
506
  const typeDefinitionResult = await lspClient.typeDefinition({
468
507
  textDocument: {
469
- uri: currentFile
508
+ uri: currentFile,
470
509
  },
471
510
  position: {
472
511
  character: charPos,
473
- line: linePos
474
- }
512
+ line: linePos,
513
+ },
475
514
  });
476
515
  // if (content.split("\n")[linePos] === `type Action = AddBooking | CancelBooking | ClearBookings;`) {
477
516
  // console.dir(typeDefinitionResult, { depth: null })
478
517
  // console.log(charPos)
479
518
  // }
480
- if (typeDefinitionResult && typeDefinitionResult instanceof Array && typeDefinitionResult.length != 0) {
519
+ if (typeDefinitionResult &&
520
+ typeDefinitionResult instanceof Array &&
521
+ typeDefinitionResult.length != 0) {
481
522
  const tdResultStr = JSON.stringify(typeDefinitionResult);
482
523
  if (!foundTypeDefinitions.has(tdResultStr)) {
483
524
  foundTypeDefinitions.set(tdResultStr, typeDefinitionResult);
@@ -492,17 +533,18 @@ class TypeScriptDriver {
492
533
  documentSymbolResult = foundSymbols.get(tdUri);
493
534
  }
494
535
  else {
495
- documentSymbolResult = await lspClient.documentSymbol({
536
+ documentSymbolResult = (await lspClient.documentSymbol({
496
537
  textDocument: {
497
- uri: typeDefinitionResult[0].uri
498
- }
499
- });
538
+ uri: typeDefinitionResult[0].uri,
539
+ },
540
+ }));
500
541
  foundSymbols.set(tdUri, documentSymbolResult);
501
542
  }
502
543
  // console.timeEnd("docSymbol")
503
544
  // console.time("dsMap")
504
545
  const dsMap = documentSymbolResult.reduce((m, obj) => {
505
- m.set(obj.location.range.start.line, obj.location.range);
546
+ m.set(obj.location.range.start.line, obj.location
547
+ .range);
506
548
  return m;
507
549
  }, new Map());
508
550
  // console.timeEnd("dsMap")
@@ -517,7 +559,9 @@ class TypeScriptDriver {
517
559
  // }, new Map<number, Range>());
518
560
  const matchingSymbolRange = dsMap.get(typeDefinitionResult[0].range.start.line);
519
561
  if (matchingSymbolRange) {
520
- const snippetInRange = (0, utils_1.extractSnippet)(fs.readFileSync(typeDefinitionResult[0].uri.slice(7)).toString("utf8"), matchingSymbolRange.start, matchingSymbolRange.end);
562
+ const snippetInRange = (0, utils_1.extractSnippet)(fs
563
+ .readFileSync(typeDefinitionResult[0].uri.slice(7))
564
+ .toString("utf8"), matchingSymbolRange.start, matchingSymbolRange.end);
521
565
  // TODO: this can potentially be its own method. the driver would require some way to get type context.
522
566
  // potentially, this type checker can be its own class.
523
567
  const identifier = this.typeChecker.getIdentifierFromDecl(snippetInRange);
@@ -568,7 +612,10 @@ class TypeScriptDriver {
568
612
  // Split the type span into identifiers, where each include the text, line number, and character range.
569
613
  // For each identifier, invoke go to type definition.
570
614
  if (!foundSoFar.has(typeName)) {
571
- foundSoFar.set(typeName, { typeSpan: fullHoverResult, sourceFile: currentFile.slice(7) });
615
+ foundSoFar.set(typeName, {
616
+ typeSpan: fullHoverResult,
617
+ sourceFile: currentFile.slice(7),
618
+ });
572
619
  // console.log(fullHoverResult)
573
620
  const identifiers = this.typeChecker.extractIdentifiers(fullHoverResult);
574
621
  // DEBUG: REMOVE
@@ -590,12 +637,12 @@ class TypeScriptDriver {
590
637
  // const start = performance.now()
591
638
  const typeDefinitionResult = await lspClient.typeDefinition({
592
639
  textDocument: {
593
- uri: currentFile
640
+ uri: currentFile,
594
641
  },
595
642
  position: {
596
643
  character: identifier.start,
597
- line: startLine + identifier.line - 1 // startLine is already 1-indexed
598
- }
644
+ line: startLine + identifier.line - 1, // startLine is already 1-indexed
645
+ },
599
646
  });
600
647
  // const end = performance.now()
601
648
  // console.log(end - start)
@@ -603,7 +650,9 @@ class TypeScriptDriver {
603
650
  // console.log(identifier)
604
651
  // console.dir(typeDefinitionResult, { depth: null })
605
652
  // }
606
- if (typeDefinitionResult && typeDefinitionResult instanceof Array && typeDefinitionResult.length != 0) {
653
+ if (typeDefinitionResult &&
654
+ typeDefinitionResult instanceof Array &&
655
+ typeDefinitionResult.length != 0) {
607
656
  const tdLocation = typeDefinitionResult[0];
608
657
  let content = "";
609
658
  if (foundContents.has(tdLocation.uri.slice(7))) {
@@ -645,7 +694,10 @@ class TypeScriptDriver {
645
694
  else {
646
695
  // TODO: Test this.
647
696
  if (!foundSoFar.has(typeName)) {
648
- foundSoFar.set(typeName, { typeSpan: fullHoverResult, sourceFile: currentFile.slice(7) });
697
+ foundSoFar.set(typeName, {
698
+ typeSpan: fullHoverResult,
699
+ sourceFile: currentFile.slice(7),
700
+ });
649
701
  const identifiers = this.typeChecker.extractIdentifiers(fullHoverResult);
650
702
  for (const identifier of identifiers) {
651
703
  if (!foundSoFar.has(identifier.name)) {
@@ -654,8 +706,8 @@ class TypeScriptDriver {
654
706
  filepath: currentFile,
655
707
  position: {
656
708
  line: startLine + identifier.line - 1,
657
- character: identifier.start
658
- }
709
+ character: identifier.start,
710
+ },
659
711
  });
660
712
  if (typeDefinitionResult.length != 0) {
661
713
  const tdLocation = typeDefinitionResult[0];
@@ -708,7 +760,10 @@ class TypeScriptDriver {
708
760
  // Split the type span into identifiers, where each include the text, line number, and character range.
709
761
  // For each identifier, invoke go to type definition.
710
762
  if (!foundSoFar.has(typeName)) {
711
- foundSoFar.set(typeName, { typeSpan: fullHoverResult, sourceFile: currentFile.slice(7) });
763
+ foundSoFar.set(typeName, {
764
+ typeSpan: fullHoverResult,
765
+ sourceFile: currentFile.slice(7),
766
+ });
712
767
  const identifiers = this.typeChecker.extractIdentifiers(fullHoverResult);
713
768
  const sourceFile = this.tsCompilerProgram.getSourceFile(currentFile.slice(7));
714
769
  for (const identifier of identifiers) {
@@ -733,7 +788,9 @@ class TypeScriptDriver {
733
788
  }
734
789
  function findIdentifierAtPosition(sourceFile, position) {
735
790
  function find(node) {
736
- if (ts.isIdentifier(node) && position >= node.getStart() && position <= node.getEnd()) {
791
+ if (ts.isIdentifier(node) &&
792
+ position >= node.getStart() &&
793
+ position <= node.getEnd()) {
737
794
  return node;
738
795
  }
739
796
  return ts.forEachChild(node, find);
@@ -811,9 +868,22 @@ class TypeScriptDriver {
811
868
  if (!ast) {
812
869
  throw new Error(`failed to get ast for file ${currentFile}`);
813
870
  }
814
- foundSoFar.set(typeName, { typeSpan: fullHoverResult, sourceFile: currentFile.slice(7), ast: ast });
871
+ foundSoFar.set(typeName, {
872
+ typeSpan: fullHoverResult,
873
+ sourceFile: currentFile.slice(7),
874
+ ast: ast,
875
+ });
815
876
  const language = (0, tree_sitter_1.getFullLanguageName)(currentFile);
816
- const query = await (0, tree_sitter_1.getQueryForFile)(currentFile, path.join(__dirname, "tree-sitter-files", "queries", "relevant-types-queries", `${language}-extract-identifiers.scm`));
877
+ const queryPath = require.resolve(`@jpoly1219/context-extractor/src/tree-sitter-files/queries/relevant-types-queries/${language}-extract-identifiers.scm`);
878
+ const query = await (0, tree_sitter_1.getQueryForFile)(currentFile, queryPath
879
+ // path.join(
880
+ // __dirname,
881
+ // "tree-sitter-files",
882
+ // "queries",
883
+ // "relevant-types-queries",
884
+ // `${language}-extract-identifiers.scm`,
885
+ // )
886
+ );
817
887
  if (!query) {
818
888
  throw new Error(`failed to get query for file ${currentFile} and language ${language}`);
819
889
  }
@@ -824,14 +894,16 @@ class TypeScriptDriver {
824
894
  try {
825
895
  const typeDefinitionResult = await lspClient.typeDefinition({
826
896
  textDocument: {
827
- uri: currentFile
897
+ uri: currentFile,
828
898
  },
829
899
  position: {
830
900
  character: node.startPosition.column,
831
- line: startLine + node.startPosition.row
832
- }
901
+ line: startLine + node.startPosition.row,
902
+ },
833
903
  });
834
- if (typeDefinitionResult && typeDefinitionResult instanceof Array && typeDefinitionResult.length != 0) {
904
+ if (typeDefinitionResult &&
905
+ typeDefinitionResult instanceof Array &&
906
+ typeDefinitionResult.length != 0) {
835
907
  const tdLocation = typeDefinitionResult[0];
836
908
  let content = "";
837
909
  if (foundContents.has(tdLocation.uri.slice(7))) {
@@ -879,9 +951,22 @@ class TypeScriptDriver {
879
951
  if (!ast) {
880
952
  throw new Error(`failed to get ast for file ${currentFile}`);
881
953
  }
882
- foundSoFar.set(typeName, { typeSpan: fullHoverResult, sourceFile: currentFile.slice(7), ast: ast });
954
+ foundSoFar.set(typeName, {
955
+ typeSpan: fullHoverResult,
956
+ sourceFile: currentFile.slice(7),
957
+ ast: ast,
958
+ });
883
959
  const language = (0, tree_sitter_1.getFullLanguageName)(currentFile);
884
- const query = await (0, tree_sitter_1.getQueryForFile)(currentFile, path.join(__dirname, "tree-sitter-files", "queries", "relevant-headers-queries", `${language}-extract-identifiers.scm`));
960
+ const queryPath = require.resolve(`@jpoly1219/context-extractor/src/tree-sitter-files/queries/relevant-headers-queries/${language}-extract-identifiers.scm`);
961
+ const query = await (0, tree_sitter_1.getQueryForFile)(currentFile, queryPath
962
+ // path.join(
963
+ // __dirname,
964
+ // "tree-sitter-files",
965
+ // "queries",
966
+ // "relevant-headers-queries",
967
+ // `${language}-extract-identifiers.scm`,
968
+ // )
969
+ );
885
970
  if (!query) {
886
971
  throw new Error(`failed to get query for file ${currentFile} and language ${language}`);
887
972
  }
@@ -893,8 +978,8 @@ class TypeScriptDriver {
893
978
  filepath: currentFile,
894
979
  position: {
895
980
  character: node.startPosition.column,
896
- line: startLine + node.startPosition.row
897
- }
981
+ line: startLine + node.startPosition.row,
982
+ },
898
983
  });
899
984
  if (typeDefinitionResult.length != 0) {
900
985
  const tdLocation = typeDefinitionResult[0];
@@ -1079,14 +1164,16 @@ class TypeScriptDriver {
1079
1164
  this.generateTargetTypesHelper(relevantTypes, rettype.text, targetTypes, program, checker);
1080
1165
  }
1081
1166
  else if (this.typeChecker.isTuple2(typeAnalysisResult)) {
1082
- typeAnalysisResult.constituents.forEach(constituent => {
1167
+ typeAnalysisResult.constituents.forEach((constituent) => {
1083
1168
  targetTypes.add(constituent.text);
1084
1169
  this.generateTargetTypesHelper(relevantTypes, constituent.text, targetTypes, program, checker);
1085
1170
  });
1086
1171
  }
1087
1172
  else {
1088
1173
  if (relevantTypes.has(currType)) {
1089
- const definition = relevantTypes.get(currType).typeSpan.split(" = ")[1];
1174
+ const definition = relevantTypes
1175
+ .get(currType)
1176
+ .typeSpan.split(" = ")[1];
1090
1177
  this.generateTargetTypesHelper(relevantTypes, definition, targetTypes, program, checker);
1091
1178
  }
1092
1179
  }
@@ -1134,7 +1221,7 @@ class TypeScriptDriver {
1134
1221
  else {
1135
1222
  typeAnalysisResult = foundTypeAnalysisResults.get(source + ":" + typeSpan);
1136
1223
  }
1137
- targetTypes.forEach(typ => {
1224
+ targetTypes.forEach((typ) => {
1138
1225
  if (this.isTypeEquivalent(typeSpan, typ, relevantTypes, foundNormalForms, program, checker)) {
1139
1226
  // NOTE: This checks for dupes. ctx is an object so you need to check for each field.
1140
1227
  // relevantContext.add({ typeSpan: line, sourceFile: source });
@@ -1146,7 +1233,7 @@ class TypeScriptDriver {
1146
1233
  this.extractRelevantHeadersHelper(rettype.text, targetTypes, relevantTypes, relevantContext, line, source, relevantContextMap, tag, trace, foundNormalForms, foundTypeAnalysisResults, program, checker);
1147
1234
  }
1148
1235
  else if (this.typeChecker.isTuple2(typeAnalysisResult)) {
1149
- typeAnalysisResult.constituents.forEach(constituent => {
1236
+ typeAnalysisResult.constituents.forEach((constituent) => {
1150
1237
  this.extractRelevantHeadersHelper(constituent.text, targetTypes, relevantTypes, relevantContext, line, source, relevantContextMap, tag, trace, foundNormalForms, foundTypeAnalysisResults, program, checker);
1151
1238
  });
1152
1239
  }
@@ -1212,10 +1299,12 @@ class TypeScriptDriver {
1212
1299
  // console.log(`isObject: ${typeSpan}`)
1213
1300
  const elements = typeSpan.slice(1, typeSpan.length - 2).split(";");
1214
1301
  normalForm += "{";
1215
- elements.forEach(element => {
1302
+ elements.forEach((element) => {
1216
1303
  if (element !== "") {
1217
1304
  const kv = element.split(": ");
1218
- normalForm += kv[0].slice(1, kv[0].length), ": ", this.normalize(kv[1], relevantTypes);
1305
+ (normalForm += kv[0].slice(1, kv[0].length)),
1306
+ ": ",
1307
+ this.normalize(kv[1], relevantTypes);
1219
1308
  normalForm += "; ";
1220
1309
  }
1221
1310
  });
@@ -1293,10 +1382,12 @@ class TypeScriptDriver {
1293
1382
  // console.log(`isObject: ${typeSpan}`)
1294
1383
  const elements = typeSpan.slice(1, typeSpan.length - 2).split(";");
1295
1384
  normalForm += "{";
1296
- elements.forEach(element => {
1385
+ elements.forEach((element) => {
1297
1386
  if (element !== "") {
1298
1387
  const kv = element.split(": ");
1299
- normalForm += kv[0].slice(1, kv[0].length), ": ", this.normalize2(kv[1], relevantTypes, program, checker);
1388
+ (normalForm += kv[0].slice(1, kv[0].length)),
1389
+ ": ",
1390
+ this.normalize2(kv[1], relevantTypes, program, checker);
1300
1391
  normalForm += "; ";
1301
1392
  }
1302
1393
  });
@@ -1351,7 +1442,9 @@ class TypeScriptDriver {
1351
1442
  if (!relevantTypes.has(analysisResult.text)) {
1352
1443
  return typeSpan;
1353
1444
  }
1354
- const typ = relevantTypes.get(analysisResult.text).typeSpan.split(" = ")[1];
1445
+ const typ = relevantTypes
1446
+ .get(analysisResult.text)
1447
+ .typeSpan.split(" = ")[1];
1355
1448
  if (typ === undefined) {
1356
1449
  return typeSpan;
1357
1450
  }
@@ -1378,7 +1471,7 @@ class TypeScriptDriver {
1378
1471
  else {
1379
1472
  typeAnalysisResult = foundTypeAnalysisResults.get(source + ":" + typeSpan);
1380
1473
  }
1381
- targetTypes.forEach(typ => {
1474
+ targetTypes.forEach((typ) => {
1382
1475
  // if (declText.includes("getBookings")) {
1383
1476
  // if (declText.slice(0, 11) === "getBookings") {
1384
1477
  // console.log("innermost", declText, "-=-=-", typeSpan)
@@ -1397,7 +1490,7 @@ class TypeScriptDriver {
1397
1490
  foundTypeAnalysisResults;
1398
1491
  }
1399
1492
  else if (this.typeChecker.isTuple2(typeAnalysisResult)) {
1400
- typeAnalysisResult.constituents.forEach(constituent => {
1493
+ typeAnalysisResult.constituents.forEach((constituent) => {
1401
1494
  this.extractRelevantHeadersHelper2(declText, constituent.text, targetTypes, relevantTypes, relevantContext, source, relevantContextMap, trace, foundNormalForms, foundTypeAnalysisResults, program, checker);
1402
1495
  });
1403
1496
  }
@@ -1427,8 +1520,8 @@ class TypeScriptDriver {
1427
1520
  // pattern 0 is let/const, 1 is var, 2 is fun
1428
1521
  // if (!seenDecls.has(JSON.stringify()) {
1429
1522
  const originalDeclText = tld.pattern === 2
1430
- ? tld.captures.find(d => d.name === "top.fn.decl").node.text
1431
- : tld.captures.find(d => d.name === "top.var.decl").node.text;
1523
+ ? tld.captures.find((d) => d.name === "top.fn.decl").node.text
1524
+ : tld.captures.find((d) => d.name === "top.var.decl").node.text;
1432
1525
  if (tld.pattern === 2) {
1433
1526
  // build a type span
1434
1527
  const funcType = (0, tree_sitter_1.extractFunctionTypeFromDecl)(tld);
@@ -1448,7 +1541,7 @@ class TypeScriptDriver {
1448
1541
  await this.extractRelevantHeadersWithTreesitterHelper(originalDeclText, baseNode, targetTypes, relevantTypes, relevantContext, relevantContextMap, foundNormalForms, source);
1449
1542
  }
1450
1543
  else {
1451
- const varTypNode = tld.captures.find(d => d.name === "top.var.type").node;
1544
+ const varTypNode = tld.captures.find((d) => d.name === "top.var.type").node;
1452
1545
  await this.extractRelevantHeadersWithTreesitterHelper(originalDeclText, varTypNode, targetTypes, relevantTypes, relevantContext, relevantContextMap, foundNormalForms, source);
1453
1546
  }
1454
1547
  }
@@ -1465,7 +1558,7 @@ class TypeScriptDriver {
1465
1558
  relevantContextMap.set(JSON.stringify(ctx), ctx);
1466
1559
  }
1467
1560
  if (node.type === "function_type") {
1468
- const retTypeNode = node.namedChildren.find(c => c && c.type === "return_type");
1561
+ const retTypeNode = node.namedChildren.find((c) => c && c.type === "return_type");
1469
1562
  if (retTypeNode) {
1470
1563
  this.extractRelevantHeadersWithTreesitterHelper(originalDeclText, retTypeNode, targetTypes, relevantTypes, relevantContext, relevantContextMap, foundNormalForms, source);
1471
1564
  }
@@ -1499,12 +1592,23 @@ class TypeScriptDriver {
1499
1592
  return targetTypes;
1500
1593
  }
1501
1594
  unwrapToBaseType(node) {
1502
- if (["function_type", "tuple_type", "type_identifier", "predefined_type"].includes(node.type)) {
1595
+ if ([
1596
+ "function_type",
1597
+ "tuple_type",
1598
+ "type_identifier",
1599
+ "predefined_type",
1600
+ ].includes(node.type)) {
1503
1601
  return node;
1504
1602
  }
1505
1603
  for (const child of node.namedChildren) {
1506
1604
  const unwrapped = this.unwrapToBaseType(child);
1507
- if (unwrapped !== child || ["function_type", "tuple_type", "type_identifier", "predefined_type"].includes(unwrapped.type)) {
1605
+ if (unwrapped !== child ||
1606
+ [
1607
+ "function_type",
1608
+ "tuple_type",
1609
+ "type_identifier",
1610
+ "predefined_type",
1611
+ ].includes(unwrapped.type)) {
1508
1612
  return unwrapped;
1509
1613
  }
1510
1614
  }
@@ -1589,16 +1693,17 @@ class TypeScriptDriver {
1589
1693
  case "function_type": {
1590
1694
  const params = node.child(0); // formal_parameters
1591
1695
  const returnType = node.childForFieldName("type") || node.namedChildren[1]; // function_type → parameters, =>, return
1592
- const paramTypes = (params === null || params === void 0 ? void 0 : params.namedChildren.map(param => this.normalizeWithTreesitter(param.childForFieldName("type") || param.namedChildren.at(-1), relevantTypes)).join(", ")) || "";
1696
+ const paramTypes = (params === null || params === void 0 ? void 0 : params.namedChildren.map((param) => this.normalizeWithTreesitter(param.childForFieldName("type") ||
1697
+ param.namedChildren.at(-1), relevantTypes)).join(", ")) || "";
1593
1698
  const ret = this.normalizeWithTreesitter(returnType, relevantTypes);
1594
1699
  return `(${paramTypes}) => ${ret}`;
1595
1700
  }
1596
1701
  case "tuple_type": {
1597
- const elements = node.namedChildren.map(c => this.normalizeWithTreesitter(c, relevantTypes));
1702
+ const elements = node.namedChildren.map((c) => this.normalizeWithTreesitter(c, relevantTypes));
1598
1703
  return `[${elements.join(", ")}]`;
1599
1704
  }
1600
1705
  case "union_type": {
1601
- const parts = node.namedChildren.map(c => this.normalizeWithTreesitter(c, relevantTypes));
1706
+ const parts = node.namedChildren.map((c) => this.normalizeWithTreesitter(c, relevantTypes));
1602
1707
  return parts.join(" | ");
1603
1708
  }
1604
1709
  case "type_identifier": {
@@ -1608,7 +1713,8 @@ class TypeScriptDriver {
1608
1713
  // Parse the alias's type span
1609
1714
  const wrapped = `type __TMP = ${alias};`;
1610
1715
  const tree = await (0, ast_1.getAst)("file.ts", wrapped);
1611
- const valueNode = (_a = tree.rootNode.descendantsOfType("type_alias_declaration")[0]) === null || _a === void 0 ? void 0 : _a.childForFieldName("value");
1716
+ const valueNode = (_a = tree.rootNode
1717
+ .descendantsOfType("type_alias_declaration")[0]) === null || _a === void 0 ? void 0 : _a.childForFieldName("value");
1612
1718
  return this.normalizeWithTreesitter(valueNode, relevantTypes);
1613
1719
  }
1614
1720
  case "predefined_type":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jpoly1219/context-extractor",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "description": "Extract relevant context from an incomplete program sketch.",
5
5
  "repository": {
6
6
  "type": "git",