@jpoly1219/context-extractor 0.2.10 → 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.
@@ -37,6 +37,24 @@ async function getParserForFile(filepath) {
37
37
  try {
38
38
  await web_tree_sitter_1.default.init();
39
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);
40
58
  const language = await getLanguageForFile(filepath);
41
59
  if (!language) {
42
60
  return undefined;
@@ -91,7 +109,7 @@ async function getQueryForFile(filepath, queryPath) {
91
109
  return query;
92
110
  }
93
111
  async function loadLanguageForFileExt(fileExtension) {
94
- const wasmPath = require.resolve(`./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`);
95
113
  // const wasmPath = path.join(
96
114
  // __dirname,
97
115
  // "tree-sitter-files",
@@ -223,7 +241,7 @@ async function extractTopLevelDecls(currentFile) {
223
241
  throw new Error(`failed to get ast for file ${currentFile}`);
224
242
  }
225
243
  const language = (0, exports.getFullLanguageName)(currentFile);
226
- const queryPath = require.resolve(`./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`);
227
245
  const query = await getQueryForFile(currentFile, queryPath
228
246
  // path.join(
229
247
  // __dirname,
@@ -245,7 +263,7 @@ async function extractTopLevelDeclsWithFormatting(currentFile) {
245
263
  throw new Error(`failed to get ast for file ${currentFile}`);
246
264
  }
247
265
  const language = (0, exports.getFullLanguageName)(currentFile);
248
- const queryPath = require.resolve(`./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`);
249
267
  const query = await getQueryForFile(currentFile, queryPath
250
268
  // path.join(
251
269
  // __dirname,
@@ -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,7 @@ 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 queryPath = require.resolve(`./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`);
394
416
  const query = await (0, tree_sitter_1.getQueryForFile)(sketchFilePath, queryPath
395
417
  // path.join(
396
418
  // __dirname,
@@ -423,10 +445,13 @@ class TypeScriptDriver {
423
445
  characterPosition: 0,
424
446
  holeTypeDefLinePos: 0,
425
447
  holeTypeDefCharPos: "declare function _(): ".length,
426
- 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
+ },
427
452
  // range: (sketchSymbol![0] as SymbolInformation).location.range,
428
453
  source: `file://${sketchFilePath}`,
429
- trueHoleFunction: ""
454
+ trueHoleFunction: "",
430
455
  };
431
456
  for (const c of captures) {
432
457
  const { name, node } = c;
@@ -448,7 +473,7 @@ class TypeScriptDriver {
448
473
  end: {
449
474
  line: node.endPosition.row,
450
475
  character: node.endPosition.column,
451
- }
476
+ },
452
477
  };
453
478
  }
454
479
  }
@@ -461,32 +486,39 @@ class TypeScriptDriver {
461
486
  // outputFile: fs.WriteStream,
462
487
  ) {
463
488
  if (!foundSoFar.has(typeName)) {
464
- foundSoFar.set(typeName, { typeSpan: fullHoverResult, sourceFile: currentFile.slice(7) });
489
+ foundSoFar.set(typeName, {
490
+ typeSpan: fullHoverResult,
491
+ sourceFile: currentFile.slice(7),
492
+ });
465
493
  // outputFile.write(`${fullHoverResult};\n`);
466
494
  const content = fs.readFileSync(currentFile.slice(7), "utf8");
467
495
  for (let linePos = startLine; linePos <= endLine; ++linePos) {
468
496
  // TODO: use a platform-agnostic command here
469
- 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());
470
500
  const numOfCharsInLine2 = content.split("\n")[linePos].length;
471
- 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;
472
502
  // console.log(numOfCharsInLine === numOfCharsInLine2, content.split("\n")[linePos], numOfCharsInLine, numOfCharsInLine2, numOfCharsInLine3)
473
503
  // console.time(`===loop ${content.split("\n")[linePos]}===`);
474
504
  for (let charPos = 0; charPos < numOfCharsInLine2; ++charPos) {
475
505
  try {
476
506
  const typeDefinitionResult = await lspClient.typeDefinition({
477
507
  textDocument: {
478
- uri: currentFile
508
+ uri: currentFile,
479
509
  },
480
510
  position: {
481
511
  character: charPos,
482
- line: linePos
483
- }
512
+ line: linePos,
513
+ },
484
514
  });
485
515
  // if (content.split("\n")[linePos] === `type Action = AddBooking | CancelBooking | ClearBookings;`) {
486
516
  // console.dir(typeDefinitionResult, { depth: null })
487
517
  // console.log(charPos)
488
518
  // }
489
- if (typeDefinitionResult && typeDefinitionResult instanceof Array && typeDefinitionResult.length != 0) {
519
+ if (typeDefinitionResult &&
520
+ typeDefinitionResult instanceof Array &&
521
+ typeDefinitionResult.length != 0) {
490
522
  const tdResultStr = JSON.stringify(typeDefinitionResult);
491
523
  if (!foundTypeDefinitions.has(tdResultStr)) {
492
524
  foundTypeDefinitions.set(tdResultStr, typeDefinitionResult);
@@ -501,17 +533,18 @@ class TypeScriptDriver {
501
533
  documentSymbolResult = foundSymbols.get(tdUri);
502
534
  }
503
535
  else {
504
- documentSymbolResult = await lspClient.documentSymbol({
536
+ documentSymbolResult = (await lspClient.documentSymbol({
505
537
  textDocument: {
506
- uri: typeDefinitionResult[0].uri
507
- }
508
- });
538
+ uri: typeDefinitionResult[0].uri,
539
+ },
540
+ }));
509
541
  foundSymbols.set(tdUri, documentSymbolResult);
510
542
  }
511
543
  // console.timeEnd("docSymbol")
512
544
  // console.time("dsMap")
513
545
  const dsMap = documentSymbolResult.reduce((m, obj) => {
514
- m.set(obj.location.range.start.line, obj.location.range);
546
+ m.set(obj.location.range.start.line, obj.location
547
+ .range);
515
548
  return m;
516
549
  }, new Map());
517
550
  // console.timeEnd("dsMap")
@@ -526,7 +559,9 @@ class TypeScriptDriver {
526
559
  // }, new Map<number, Range>());
527
560
  const matchingSymbolRange = dsMap.get(typeDefinitionResult[0].range.start.line);
528
561
  if (matchingSymbolRange) {
529
- 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);
530
565
  // TODO: this can potentially be its own method. the driver would require some way to get type context.
531
566
  // potentially, this type checker can be its own class.
532
567
  const identifier = this.typeChecker.getIdentifierFromDecl(snippetInRange);
@@ -577,7 +612,10 @@ class TypeScriptDriver {
577
612
  // Split the type span into identifiers, where each include the text, line number, and character range.
578
613
  // For each identifier, invoke go to type definition.
579
614
  if (!foundSoFar.has(typeName)) {
580
- foundSoFar.set(typeName, { typeSpan: fullHoverResult, sourceFile: currentFile.slice(7) });
615
+ foundSoFar.set(typeName, {
616
+ typeSpan: fullHoverResult,
617
+ sourceFile: currentFile.slice(7),
618
+ });
581
619
  // console.log(fullHoverResult)
582
620
  const identifiers = this.typeChecker.extractIdentifiers(fullHoverResult);
583
621
  // DEBUG: REMOVE
@@ -599,12 +637,12 @@ class TypeScriptDriver {
599
637
  // const start = performance.now()
600
638
  const typeDefinitionResult = await lspClient.typeDefinition({
601
639
  textDocument: {
602
- uri: currentFile
640
+ uri: currentFile,
603
641
  },
604
642
  position: {
605
643
  character: identifier.start,
606
- line: startLine + identifier.line - 1 // startLine is already 1-indexed
607
- }
644
+ line: startLine + identifier.line - 1, // startLine is already 1-indexed
645
+ },
608
646
  });
609
647
  // const end = performance.now()
610
648
  // console.log(end - start)
@@ -612,7 +650,9 @@ class TypeScriptDriver {
612
650
  // console.log(identifier)
613
651
  // console.dir(typeDefinitionResult, { depth: null })
614
652
  // }
615
- if (typeDefinitionResult && typeDefinitionResult instanceof Array && typeDefinitionResult.length != 0) {
653
+ if (typeDefinitionResult &&
654
+ typeDefinitionResult instanceof Array &&
655
+ typeDefinitionResult.length != 0) {
616
656
  const tdLocation = typeDefinitionResult[0];
617
657
  let content = "";
618
658
  if (foundContents.has(tdLocation.uri.slice(7))) {
@@ -654,7 +694,10 @@ class TypeScriptDriver {
654
694
  else {
655
695
  // TODO: Test this.
656
696
  if (!foundSoFar.has(typeName)) {
657
- foundSoFar.set(typeName, { typeSpan: fullHoverResult, sourceFile: currentFile.slice(7) });
697
+ foundSoFar.set(typeName, {
698
+ typeSpan: fullHoverResult,
699
+ sourceFile: currentFile.slice(7),
700
+ });
658
701
  const identifiers = this.typeChecker.extractIdentifiers(fullHoverResult);
659
702
  for (const identifier of identifiers) {
660
703
  if (!foundSoFar.has(identifier.name)) {
@@ -663,8 +706,8 @@ class TypeScriptDriver {
663
706
  filepath: currentFile,
664
707
  position: {
665
708
  line: startLine + identifier.line - 1,
666
- character: identifier.start
667
- }
709
+ character: identifier.start,
710
+ },
668
711
  });
669
712
  if (typeDefinitionResult.length != 0) {
670
713
  const tdLocation = typeDefinitionResult[0];
@@ -717,7 +760,10 @@ class TypeScriptDriver {
717
760
  // Split the type span into identifiers, where each include the text, line number, and character range.
718
761
  // For each identifier, invoke go to type definition.
719
762
  if (!foundSoFar.has(typeName)) {
720
- foundSoFar.set(typeName, { typeSpan: fullHoverResult, sourceFile: currentFile.slice(7) });
763
+ foundSoFar.set(typeName, {
764
+ typeSpan: fullHoverResult,
765
+ sourceFile: currentFile.slice(7),
766
+ });
721
767
  const identifiers = this.typeChecker.extractIdentifiers(fullHoverResult);
722
768
  const sourceFile = this.tsCompilerProgram.getSourceFile(currentFile.slice(7));
723
769
  for (const identifier of identifiers) {
@@ -742,7 +788,9 @@ class TypeScriptDriver {
742
788
  }
743
789
  function findIdentifierAtPosition(sourceFile, position) {
744
790
  function find(node) {
745
- if (ts.isIdentifier(node) && position >= node.getStart() && position <= node.getEnd()) {
791
+ if (ts.isIdentifier(node) &&
792
+ position >= node.getStart() &&
793
+ position <= node.getEnd()) {
746
794
  return node;
747
795
  }
748
796
  return ts.forEachChild(node, find);
@@ -820,9 +868,13 @@ class TypeScriptDriver {
820
868
  if (!ast) {
821
869
  throw new Error(`failed to get ast for file ${currentFile}`);
822
870
  }
823
- 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
+ });
824
876
  const language = (0, tree_sitter_1.getFullLanguageName)(currentFile);
825
- const queryPath = require.resolve(`./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`);
826
878
  const query = await (0, tree_sitter_1.getQueryForFile)(currentFile, queryPath
827
879
  // path.join(
828
880
  // __dirname,
@@ -842,14 +894,16 @@ class TypeScriptDriver {
842
894
  try {
843
895
  const typeDefinitionResult = await lspClient.typeDefinition({
844
896
  textDocument: {
845
- uri: currentFile
897
+ uri: currentFile,
846
898
  },
847
899
  position: {
848
900
  character: node.startPosition.column,
849
- line: startLine + node.startPosition.row
850
- }
901
+ line: startLine + node.startPosition.row,
902
+ },
851
903
  });
852
- if (typeDefinitionResult && typeDefinitionResult instanceof Array && typeDefinitionResult.length != 0) {
904
+ if (typeDefinitionResult &&
905
+ typeDefinitionResult instanceof Array &&
906
+ typeDefinitionResult.length != 0) {
853
907
  const tdLocation = typeDefinitionResult[0];
854
908
  let content = "";
855
909
  if (foundContents.has(tdLocation.uri.slice(7))) {
@@ -897,9 +951,13 @@ class TypeScriptDriver {
897
951
  if (!ast) {
898
952
  throw new Error(`failed to get ast for file ${currentFile}`);
899
953
  }
900
- 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
+ });
901
959
  const language = (0, tree_sitter_1.getFullLanguageName)(currentFile);
902
- const queryPath = require.resolve(`./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`);
903
961
  const query = await (0, tree_sitter_1.getQueryForFile)(currentFile, queryPath
904
962
  // path.join(
905
963
  // __dirname,
@@ -920,8 +978,8 @@ class TypeScriptDriver {
920
978
  filepath: currentFile,
921
979
  position: {
922
980
  character: node.startPosition.column,
923
- line: startLine + node.startPosition.row
924
- }
981
+ line: startLine + node.startPosition.row,
982
+ },
925
983
  });
926
984
  if (typeDefinitionResult.length != 0) {
927
985
  const tdLocation = typeDefinitionResult[0];
@@ -1106,14 +1164,16 @@ class TypeScriptDriver {
1106
1164
  this.generateTargetTypesHelper(relevantTypes, rettype.text, targetTypes, program, checker);
1107
1165
  }
1108
1166
  else if (this.typeChecker.isTuple2(typeAnalysisResult)) {
1109
- typeAnalysisResult.constituents.forEach(constituent => {
1167
+ typeAnalysisResult.constituents.forEach((constituent) => {
1110
1168
  targetTypes.add(constituent.text);
1111
1169
  this.generateTargetTypesHelper(relevantTypes, constituent.text, targetTypes, program, checker);
1112
1170
  });
1113
1171
  }
1114
1172
  else {
1115
1173
  if (relevantTypes.has(currType)) {
1116
- const definition = relevantTypes.get(currType).typeSpan.split(" = ")[1];
1174
+ const definition = relevantTypes
1175
+ .get(currType)
1176
+ .typeSpan.split(" = ")[1];
1117
1177
  this.generateTargetTypesHelper(relevantTypes, definition, targetTypes, program, checker);
1118
1178
  }
1119
1179
  }
@@ -1161,7 +1221,7 @@ class TypeScriptDriver {
1161
1221
  else {
1162
1222
  typeAnalysisResult = foundTypeAnalysisResults.get(source + ":" + typeSpan);
1163
1223
  }
1164
- targetTypes.forEach(typ => {
1224
+ targetTypes.forEach((typ) => {
1165
1225
  if (this.isTypeEquivalent(typeSpan, typ, relevantTypes, foundNormalForms, program, checker)) {
1166
1226
  // NOTE: This checks for dupes. ctx is an object so you need to check for each field.
1167
1227
  // relevantContext.add({ typeSpan: line, sourceFile: source });
@@ -1173,7 +1233,7 @@ class TypeScriptDriver {
1173
1233
  this.extractRelevantHeadersHelper(rettype.text, targetTypes, relevantTypes, relevantContext, line, source, relevantContextMap, tag, trace, foundNormalForms, foundTypeAnalysisResults, program, checker);
1174
1234
  }
1175
1235
  else if (this.typeChecker.isTuple2(typeAnalysisResult)) {
1176
- typeAnalysisResult.constituents.forEach(constituent => {
1236
+ typeAnalysisResult.constituents.forEach((constituent) => {
1177
1237
  this.extractRelevantHeadersHelper(constituent.text, targetTypes, relevantTypes, relevantContext, line, source, relevantContextMap, tag, trace, foundNormalForms, foundTypeAnalysisResults, program, checker);
1178
1238
  });
1179
1239
  }
@@ -1239,10 +1299,12 @@ class TypeScriptDriver {
1239
1299
  // console.log(`isObject: ${typeSpan}`)
1240
1300
  const elements = typeSpan.slice(1, typeSpan.length - 2).split(";");
1241
1301
  normalForm += "{";
1242
- elements.forEach(element => {
1302
+ elements.forEach((element) => {
1243
1303
  if (element !== "") {
1244
1304
  const kv = element.split(": ");
1245
- 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);
1246
1308
  normalForm += "; ";
1247
1309
  }
1248
1310
  });
@@ -1320,10 +1382,12 @@ class TypeScriptDriver {
1320
1382
  // console.log(`isObject: ${typeSpan}`)
1321
1383
  const elements = typeSpan.slice(1, typeSpan.length - 2).split(";");
1322
1384
  normalForm += "{";
1323
- elements.forEach(element => {
1385
+ elements.forEach((element) => {
1324
1386
  if (element !== "") {
1325
1387
  const kv = element.split(": ");
1326
- 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);
1327
1391
  normalForm += "; ";
1328
1392
  }
1329
1393
  });
@@ -1378,7 +1442,9 @@ class TypeScriptDriver {
1378
1442
  if (!relevantTypes.has(analysisResult.text)) {
1379
1443
  return typeSpan;
1380
1444
  }
1381
- const typ = relevantTypes.get(analysisResult.text).typeSpan.split(" = ")[1];
1445
+ const typ = relevantTypes
1446
+ .get(analysisResult.text)
1447
+ .typeSpan.split(" = ")[1];
1382
1448
  if (typ === undefined) {
1383
1449
  return typeSpan;
1384
1450
  }
@@ -1405,7 +1471,7 @@ class TypeScriptDriver {
1405
1471
  else {
1406
1472
  typeAnalysisResult = foundTypeAnalysisResults.get(source + ":" + typeSpan);
1407
1473
  }
1408
- targetTypes.forEach(typ => {
1474
+ targetTypes.forEach((typ) => {
1409
1475
  // if (declText.includes("getBookings")) {
1410
1476
  // if (declText.slice(0, 11) === "getBookings") {
1411
1477
  // console.log("innermost", declText, "-=-=-", typeSpan)
@@ -1424,7 +1490,7 @@ class TypeScriptDriver {
1424
1490
  foundTypeAnalysisResults;
1425
1491
  }
1426
1492
  else if (this.typeChecker.isTuple2(typeAnalysisResult)) {
1427
- typeAnalysisResult.constituents.forEach(constituent => {
1493
+ typeAnalysisResult.constituents.forEach((constituent) => {
1428
1494
  this.extractRelevantHeadersHelper2(declText, constituent.text, targetTypes, relevantTypes, relevantContext, source, relevantContextMap, trace, foundNormalForms, foundTypeAnalysisResults, program, checker);
1429
1495
  });
1430
1496
  }
@@ -1454,8 +1520,8 @@ class TypeScriptDriver {
1454
1520
  // pattern 0 is let/const, 1 is var, 2 is fun
1455
1521
  // if (!seenDecls.has(JSON.stringify()) {
1456
1522
  const originalDeclText = tld.pattern === 2
1457
- ? tld.captures.find(d => d.name === "top.fn.decl").node.text
1458
- : 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;
1459
1525
  if (tld.pattern === 2) {
1460
1526
  // build a type span
1461
1527
  const funcType = (0, tree_sitter_1.extractFunctionTypeFromDecl)(tld);
@@ -1475,7 +1541,7 @@ class TypeScriptDriver {
1475
1541
  await this.extractRelevantHeadersWithTreesitterHelper(originalDeclText, baseNode, targetTypes, relevantTypes, relevantContext, relevantContextMap, foundNormalForms, source);
1476
1542
  }
1477
1543
  else {
1478
- 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;
1479
1545
  await this.extractRelevantHeadersWithTreesitterHelper(originalDeclText, varTypNode, targetTypes, relevantTypes, relevantContext, relevantContextMap, foundNormalForms, source);
1480
1546
  }
1481
1547
  }
@@ -1492,7 +1558,7 @@ class TypeScriptDriver {
1492
1558
  relevantContextMap.set(JSON.stringify(ctx), ctx);
1493
1559
  }
1494
1560
  if (node.type === "function_type") {
1495
- const retTypeNode = node.namedChildren.find(c => c && c.type === "return_type");
1561
+ const retTypeNode = node.namedChildren.find((c) => c && c.type === "return_type");
1496
1562
  if (retTypeNode) {
1497
1563
  this.extractRelevantHeadersWithTreesitterHelper(originalDeclText, retTypeNode, targetTypes, relevantTypes, relevantContext, relevantContextMap, foundNormalForms, source);
1498
1564
  }
@@ -1526,12 +1592,23 @@ class TypeScriptDriver {
1526
1592
  return targetTypes;
1527
1593
  }
1528
1594
  unwrapToBaseType(node) {
1529
- 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)) {
1530
1601
  return node;
1531
1602
  }
1532
1603
  for (const child of node.namedChildren) {
1533
1604
  const unwrapped = this.unwrapToBaseType(child);
1534
- 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)) {
1535
1612
  return unwrapped;
1536
1613
  }
1537
1614
  }
@@ -1616,16 +1693,17 @@ class TypeScriptDriver {
1616
1693
  case "function_type": {
1617
1694
  const params = node.child(0); // formal_parameters
1618
1695
  const returnType = node.childForFieldName("type") || node.namedChildren[1]; // function_type → parameters, =>, return
1619
- 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(", ")) || "";
1620
1698
  const ret = this.normalizeWithTreesitter(returnType, relevantTypes);
1621
1699
  return `(${paramTypes}) => ${ret}`;
1622
1700
  }
1623
1701
  case "tuple_type": {
1624
- const elements = node.namedChildren.map(c => this.normalizeWithTreesitter(c, relevantTypes));
1702
+ const elements = node.namedChildren.map((c) => this.normalizeWithTreesitter(c, relevantTypes));
1625
1703
  return `[${elements.join(", ")}]`;
1626
1704
  }
1627
1705
  case "union_type": {
1628
- const parts = node.namedChildren.map(c => this.normalizeWithTreesitter(c, relevantTypes));
1706
+ const parts = node.namedChildren.map((c) => this.normalizeWithTreesitter(c, relevantTypes));
1629
1707
  return parts.join(" | ");
1630
1708
  }
1631
1709
  case "type_identifier": {
@@ -1635,7 +1713,8 @@ class TypeScriptDriver {
1635
1713
  // Parse the alias's type span
1636
1714
  const wrapped = `type __TMP = ${alias};`;
1637
1715
  const tree = await (0, ast_1.getAst)("file.ts", wrapped);
1638
- 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");
1639
1718
  return this.normalizeWithTreesitter(valueNode, relevantTypes);
1640
1719
  }
1641
1720
  case "predefined_type":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jpoly1219/context-extractor",
3
- "version": "0.2.10",
3
+ "version": "0.2.11",
4
4
  "description": "Extract relevant context from an incomplete program sketch.",
5
5
  "repository": {
6
6
  "type": "git",