@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,5 +1,5 @@
1
1
  import * as ts from 'typescript';
2
- import { TypeChecker, TypeAnalysis } from "./types";
2
+ import { TypeChecker, TypeAnalysis, VarFuncDecls } from "./types";
3
3
  export declare class TypeScriptTypeChecker implements TypeChecker {
4
4
  getIdentifierFromDecl(typeDecl: string): string;
5
5
  getTypeContextFromDecl(typeDecl: string): {
@@ -52,7 +52,7 @@ export declare class TypeScriptTypeChecker implements TypeChecker {
52
52
  parseTypeArrayString(typeStr: string): string[];
53
53
  handleMembers(members: ts.NodeArray<ts.TypeElement> | ts.NodeArray<ts.ClassElement>, checker: ts.TypeChecker): TypeAnalysis[];
54
54
  analyzeTypeNode(typeNode: ts.TypeNode, checker: ts.TypeChecker): TypeAnalysis;
55
- analyzeTypeString(typeString: string, program?: ts.Program): TypeAnalysis;
55
+ analyzeTypeString(typeString: string, program: ts.Program | undefined, checker: ts.TypeChecker): TypeAnalysis;
56
56
  createProgramFromSource(content: string): ts.Program;
57
57
  isPrimitive2(typeAnalysisResult: TypeAnalysis): RegExpMatchArray | null;
58
58
  isFunction2(typeAnalysisResult: TypeAnalysis): boolean;
@@ -77,4 +77,8 @@ export declare class TypeScriptTypeChecker implements TypeChecker {
77
77
  column: number;
78
78
  }[]): void;
79
79
  findDeclarationForIdentifier(sourceCode: string, targetLine: number, targetCharStart: number, targetCharEnd: number): string | null;
80
+ findTopLevelDeclarations(program: ts.Program, checker: ts.TypeChecker, fileName: string): VarFuncDecls[];
81
+ createTsCompilerProgram(repo: string[], projectRoot: string): ts.Program;
82
+ getCompilerOptionsFromTsconfig(projectRoot: string): ts.ParsedCommandLine | null;
83
+ replaceTypeAnnotationColonWithArrow(typeStr: string): string;
80
84
  }
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
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
+ })();
25
35
  Object.defineProperty(exports, "__esModule", { value: true });
26
36
  exports.TypeScriptTypeChecker = void 0;
27
37
  const ts = __importStar(require("typescript"));
@@ -467,7 +477,7 @@ class TypeScriptTypeChecker {
467
477
  text: typeNode.getText()
468
478
  };
469
479
  }
470
- analyzeTypeString(typeString, program = this.createProgramFromSource("")) {
480
+ analyzeTypeString(typeString, program = this.createProgramFromSource(""), checker) {
471
481
  const sourceFile = ts.createSourceFile('temp.ts', `type T = ${typeString};`, ts.ScriptTarget.Latest, true);
472
482
  let typeNode;
473
483
  ts.forEachChild(sourceFile, node => {
@@ -478,7 +488,7 @@ class TypeScriptTypeChecker {
478
488
  if (!typeNode) {
479
489
  throw new Error('Failed to parse type string');
480
490
  }
481
- const checker = program.getTypeChecker();
491
+ // const checker = program.getTypeChecker();
482
492
  return this.analyzeTypeNode(typeNode, checker);
483
493
  }
484
494
  createProgramFromSource(content) {
@@ -511,6 +521,15 @@ class TypeScriptTypeChecker {
511
521
  isTypeAlias2(typeAnalysisResult) {
512
522
  return typeAnalysisResult.kind === "TypeReference";
513
523
  }
524
+ // Extract identifiers from a given code string.
525
+ // For example:
526
+ // type Model = [BookingFormData, Booking[], BookingID];
527
+ // [
528
+ // { name: 'Model', start: 5, end: 10, line: 1, column: 6 },
529
+ // { name: 'BookingFormData', start: 14, end: 29, line: 1, column: 15 },
530
+ // { name: 'Booking', start: 31, end: 38, line: 1, column: 32 },
531
+ // { name: 'BookingID', start: 42, end: 51, line: 1, column: 43 }
532
+ // ]
514
533
  extractIdentifiers(code) {
515
534
  const sourceFile = ts.createSourceFile("sample.ts", code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
516
535
  const identifiers = [];
@@ -531,8 +550,8 @@ class TypeScriptTypeChecker {
531
550
  node.forEachChild(child => this.extractIdentifiersHelper(child, identifiers));
532
551
  }
533
552
  extractIdentifiersWithPosHelper(sourceFile, node, identifiers) {
553
+ // console.log(`iter on ${node.getText()} =*= ${node.kind}`)
534
554
  if (ts.isIdentifier(node)) {
535
- // console.log(node.kind, node.text)
536
555
  if (ts.isTypeReferenceNode(node.parent) ||
537
556
  ts.isTypeAliasDeclaration(node.parent) ||
538
557
  ts.isInterfaceDeclaration(node.parent) ||
@@ -548,8 +567,31 @@ class TypeScriptTypeChecker {
548
567
  });
549
568
  }
550
569
  }
570
+ else if (
571
+ // Handle keywords such as SyntaxKind.BooleanKeyword (boolean)
572
+ node.kind == ts.SyntaxKind.BooleanKeyword ||
573
+ node.kind == ts.SyntaxKind.StringKeyword ||
574
+ node.kind == ts.SyntaxKind.NumberKeyword ||
575
+ node.kind == ts.SyntaxKind.UndefinedKeyword ||
576
+ node.kind == ts.SyntaxKind.NullKeyword
577
+ // NOTE: this might be too all-encompassing.
578
+ // node.kind >= 83 && node.kind <= 165
579
+ ) {
580
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
581
+ identifiers.push({
582
+ name: node.getText(),
583
+ start: node.getStart(),
584
+ end: node.getEnd(),
585
+ line: line + 1, // Convert 0-based to 1-based
586
+ column: character + 1 // Convert 0-based to 1-based
587
+ });
588
+ }
551
589
  node.forEachChild(child => this.extractIdentifiersWithPosHelper(sourceFile, child, identifiers));
552
590
  }
591
+ // Find Declaration given an identifier.
592
+ //
593
+ // For example:
594
+ // Decl: type Booking = [Time, User, BookingID]; || Identifier: Booking
553
595
  findDeclarationForIdentifier(sourceCode, targetLine, targetCharStart, targetCharEnd) {
554
596
  const sourceFile = ts.createSourceFile("sample.ts", sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
555
597
  function findDeclarationForIdentifierHelper(node) {
@@ -577,5 +619,175 @@ class TypeScriptTypeChecker {
577
619
  return null;
578
620
  }
579
621
  }
622
+ // findTopLevelDeclarations(sourceCode: string, fileName = "temp.ts") {
623
+ findTopLevelDeclarations(program, checker, fileName) {
624
+ // const compilerOptions: ts.CompilerOptions = { target: ts.ScriptTarget.ESNext };
625
+ // NOTE: This is only necessary when you are passing the code string only.
626
+ // This is a nifty trick to create a temporary file to store your code string literal.
627
+ // In this case the function should accept (sourceCode: string, fileName = "temp.ts").
628
+ // If you know what file you need to read, then there is no need for this.
629
+ // const host = ts.createCompilerHost(compilerOptions);
630
+ // host.getSourceFile = (fileName, languageVersion) =>
631
+ // ts.createSourceFile(fileName, sourceCode, languageVersion, true);
632
+ // const program = ts.createProgram([fileName], compilerOptions, host);
633
+ // const program = ts.createProgram([fileName], compilerOptions);
634
+ const sourceFile = program.getSourceFile(fileName);
635
+ // const checker = program.getTypeChecker();
636
+ const results = [];
637
+ function getLineChar(pos) {
638
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(pos);
639
+ return { line: line + 1, character: character + 1 }; // 1-based
640
+ }
641
+ function visit(node) {
642
+ var _a;
643
+ // Only look at top-level nodes
644
+ if (node.parent && node.parent.kind !== ts.SyntaxKind.SourceFile)
645
+ return;
646
+ if (ts.isFunctionDeclaration(node) && node.name) {
647
+ // const symbol = checker.getSymbolAtLocation(node.name);
648
+ // const type = symbol && checker.getTypeOfSymbolAtLocation(symbol, node);
649
+ // const typeString = type ? checker.typeToString(type) : "unknown";
650
+ const signature = checker.getSignatureFromDeclaration(node);
651
+ const signatureString = signature ? checker.signatureToString(signature) : "unknown";
652
+ const returnType = signature ? checker.typeToString(signature.getReturnType()) : null;
653
+ let result = {
654
+ kind: "function",
655
+ name: node.name.text,
656
+ type: signatureString,
657
+ position: getLineChar(node.getStart()),
658
+ declarationText: node.getText(sourceFile),
659
+ sourceFile: fileName
660
+ };
661
+ if (returnType) {
662
+ result = Object.assign(Object.assign({}, result), { returnType: returnType });
663
+ }
664
+ results.push(result);
665
+ }
666
+ if (ts.isVariableStatement(node)) {
667
+ for (const decl of node.declarationList.declarations) {
668
+ if (!ts.isIdentifier(decl.name))
669
+ continue;
670
+ const name = decl.name.text;
671
+ const type = checker.getTypeAtLocation(decl);
672
+ let kind = "variable";
673
+ let returnType = null;
674
+ if (decl.initializer && ts.isArrowFunction(decl.initializer)) {
675
+ kind =
676
+ decl.initializer && ts.isArrowFunction(decl.initializer)
677
+ ? "arrowFunction"
678
+ : "variable";
679
+ const arrowFunc = decl.initializer;
680
+ const signature = checker.getSignatureFromDeclaration(arrowFunc);
681
+ if (signature) {
682
+ const returnTypeSymbol = checker.getReturnTypeOfSignature(signature);
683
+ // NOTE: debugging
684
+ // console.log(">=>", name)
685
+ // console.log(ts.TypeFlags[returnTypeSymbol.flags]);
686
+ // const apparent = checker.getApparentType(returnTypeSymbol);
687
+ // const returnTypeApparent = checker.typeToString(apparent);
688
+ // NOTE: debugging
689
+ // console.log(returnTypeApparent)
690
+ // console.log(returnTypeSymbol.getSymbol()?.getName());
691
+ // NOTE: debugging
692
+ // console.log({
693
+ // isArray: checker.isArrayType(returnTypeSymbol),
694
+ // symbol: returnTypeSymbol.symbol?.name,
695
+ // });
696
+ if (checker.isArrayType(returnTypeSymbol)) {
697
+ // NOTE: debugging
698
+ // console.log(">=>", name, "isArrayType")
699
+ const elementType = (_a = returnTypeSymbol.typeArguments) === null || _a === void 0 ? void 0 : _a[0];
700
+ const inner = elementType ? checker.typeToString(elementType) : 'unknown';
701
+ returnType = `${inner}[]`;
702
+ }
703
+ else {
704
+ returnType = checker.typeToString(returnTypeSymbol);
705
+ }
706
+ }
707
+ }
708
+ let result = {
709
+ kind,
710
+ name,
711
+ type: checker.typeToString(type),
712
+ position: getLineChar(decl.getStart()),
713
+ declarationText: decl.getText(sourceFile),
714
+ sourceFile: fileName
715
+ };
716
+ if (returnType) {
717
+ result = Object.assign(Object.assign({}, result), { returnType: returnType });
718
+ }
719
+ results.push(result);
720
+ }
721
+ }
722
+ if (ts.isClassDeclaration(node) && node.name) {
723
+ for (const member of node.members) {
724
+ if (ts.isMethodDeclaration(member) && member.name && ts.isIdentifier(member.name)) {
725
+ const symbol = checker.getSymbolAtLocation(member.name);
726
+ const type = symbol && checker.getTypeOfSymbolAtLocation(symbol, member);
727
+ results.push({
728
+ kind: "classMethod",
729
+ name: `${node.name.text}.${member.name.text}`,
730
+ type: type ? checker.typeToString(type) : "unknown",
731
+ position: getLineChar(member.getStart()),
732
+ declarationText: member.getText(sourceFile),
733
+ sourceFile: fileName
734
+ });
735
+ }
736
+ }
737
+ }
738
+ }
739
+ ts.forEachChild(sourceFile, visit);
740
+ return results;
741
+ }
742
+ createTsCompilerProgram(repo, projectRoot) {
743
+ // NOTE: This was an attempt to use an existing TS type system.
744
+ const existingConfig = this.getCompilerOptionsFromTsconfig(projectRoot);
745
+ // NOTE: debugging
746
+ // console.log(existingConfig)
747
+ if (existingConfig) {
748
+ const program = ts.createProgram({
749
+ rootNames: existingConfig.fileNames,
750
+ options: existingConfig.options
751
+ });
752
+ // NOTE: debugging
753
+ // console.log(program.getSourceFiles().map(f => f.fileName));
754
+ return program;
755
+ }
756
+ const compilerOptions = {
757
+ target: ts.ScriptTarget.ESNext,
758
+ module: ts.ModuleKind.CommonJS,
759
+ moduleResolution: ts.ModuleResolutionKind.NodeJs,
760
+ esModuleInterop: true,
761
+ strict: true,
762
+ skipLibCheck: true,
763
+ baseUrl: projectRoot, // Optional but useful for consistent resolution
764
+ paths: { "*": ["node_modules/*"] }, // Optional fallback
765
+ };
766
+ const program = ts.createProgram(repo, compilerOptions);
767
+ return program;
768
+ }
769
+ getCompilerOptionsFromTsconfig(projectRoot) {
770
+ const configPath = ts.findConfigFile(projectRoot, ts.sys.fileExists, "tsconfig.json");
771
+ // NOTE: debugging
772
+ // console.log(configPath)
773
+ if (!configPath)
774
+ return null;
775
+ const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
776
+ const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys,
777
+ // path.dirname(configPath)
778
+ projectRoot);
779
+ return parsedConfig;
780
+ }
781
+ replaceTypeAnnotationColonWithArrow(typeStr) {
782
+ const regex = /^([\(\[][^)]*\)?)(?:\s*:\s*)(.*)$/;
783
+ const match = typeStr.match(regex);
784
+ if (!match) {
785
+ console.log('Invalid function type signature');
786
+ return "";
787
+ }
788
+ const params = match[1].trim();
789
+ const returnType = match[2].trim();
790
+ return `${params} => ${returnType}`;
791
+ }
580
792
  }
581
793
  exports.TypeScriptTypeChecker = TypeScriptTypeChecker;
@@ -1,4 +1,5 @@
1
1
  import { relevantTypeObject, varsObject, typesObject, typesQueryResult, varsQueryResult, relevantTypeQueryResult, typesAndLocationsQueryResult, Language } from "./types";
2
+ declare const isUri: (str: string) => boolean;
2
3
  declare const indexOfRegexGroup: (match: RegExpMatchArray, n: number) => number;
3
4
  declare const formatTypeSpan: (typeSpan: string) => string;
4
5
  declare const extractSnippet: (documentContent: string, start: {
@@ -37,4 +38,13 @@ declare const isQLIdentifier: (typeQLClass: string) => boolean;
37
38
  declare const supportsHole: (lang: Language) => boolean;
38
39
  declare const getAllTSFiles: (dirPath: string, arrayOfFiles?: string[]) => string[];
39
40
  declare const getAllOCamlFiles: (dirPath: string, arrayOfFiles?: string[]) => string[];
40
- export { indexOfRegexGroup, formatTypeSpan, extractSnippet, isTuple, isUnion, isArray, isObject, isFunction, isPrimitive, isTypeAlias, escapeQuotes, parseTypeArrayString, removeLines, parseCodeQLRelevantTypes, parseCodeQLVars, parseCodeQLTypes, parseCodeQLLocationsAndTypes, parseCodeQLTypesAndLocations, isQLFunction, isQLTuple, isQLUnion, isQLArray, isQLInterface, isQLLocalTypeAccess, isQLPredefined, isQLLiteral, isQLKeyword, isQLLabel, isQLIdentifier, supportsHole, getAllTSFiles, getAllOCamlFiles };
41
+ declare const getTimestampForFilename: () => string;
42
+ declare const insertAtPosition: (contents: string, cursorPosition: {
43
+ line: number;
44
+ character: number;
45
+ }, insertText: string) => string;
46
+ declare function getCleanUriPath(uri: string): string;
47
+ declare function getUriPathBasename(uri: string): string;
48
+ declare function getFileExtensionFromBasename(basename: string): string;
49
+ declare function getUriFileExtension(uri: string): string;
50
+ export { isUri, indexOfRegexGroup, formatTypeSpan, extractSnippet, isTuple, isUnion, isArray, isObject, isFunction, isPrimitive, isTypeAlias, escapeQuotes, parseTypeArrayString, removeLines, parseCodeQLRelevantTypes, parseCodeQLVars, parseCodeQLTypes, parseCodeQLLocationsAndTypes, parseCodeQLTypesAndLocations, isQLFunction, isQLTuple, isQLUnion, isQLArray, isQLInterface, isQLLocalTypeAccess, isQLPredefined, isQLLiteral, isQLKeyword, isQLLabel, isQLIdentifier, supportsHole, getAllTSFiles, getAllOCamlFiles, getTimestampForFilename, insertAtPosition, getCleanUriPath, getUriPathBasename, getFileExtensionFromBasename, getUriFileExtension, };
package/dist/src/utils.js CHANGED
@@ -15,18 +15,42 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
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
+ })();
25
35
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.getAllOCamlFiles = exports.getAllTSFiles = exports.supportsHole = exports.isQLIdentifier = exports.isQLLabel = exports.isQLKeyword = exports.isQLLiteral = exports.isQLPredefined = exports.isQLLocalTypeAccess = exports.isQLInterface = exports.isQLArray = exports.isQLUnion = exports.isQLTuple = exports.isQLFunction = exports.parseCodeQLTypesAndLocations = exports.parseCodeQLLocationsAndTypes = exports.parseCodeQLTypes = exports.parseCodeQLVars = exports.parseCodeQLRelevantTypes = exports.removeLines = exports.parseTypeArrayString = exports.escapeQuotes = exports.isTypeAlias = exports.isPrimitive = exports.isFunction = exports.isObject = exports.isArray = exports.isUnion = exports.isTuple = exports.extractSnippet = exports.formatTypeSpan = exports.indexOfRegexGroup = void 0;
36
+ exports.insertAtPosition = exports.getTimestampForFilename = exports.getAllOCamlFiles = exports.getAllTSFiles = exports.supportsHole = exports.isQLIdentifier = exports.isQLLabel = exports.isQLKeyword = exports.isQLLiteral = exports.isQLPredefined = exports.isQLLocalTypeAccess = exports.isQLInterface = exports.isQLArray = exports.isQLUnion = exports.isQLTuple = exports.isQLFunction = exports.parseCodeQLTypesAndLocations = exports.parseCodeQLLocationsAndTypes = exports.parseCodeQLTypes = exports.parseCodeQLVars = exports.parseCodeQLRelevantTypes = exports.removeLines = exports.parseTypeArrayString = exports.escapeQuotes = exports.isTypeAlias = exports.isPrimitive = exports.isFunction = exports.isObject = exports.isArray = exports.isUnion = exports.isTuple = exports.extractSnippet = exports.formatTypeSpan = exports.indexOfRegexGroup = exports.isUri = void 0;
37
+ exports.getCleanUriPath = getCleanUriPath;
38
+ exports.getUriPathBasename = getUriPathBasename;
39
+ exports.getFileExtensionFromBasename = getFileExtensionFromBasename;
40
+ exports.getUriFileExtension = getUriFileExtension;
41
+ const URI = __importStar(require("uri-js"));
27
42
  const fs = __importStar(require("fs"));
28
43
  const path = __importStar(require("path"));
29
- const types_1 = require("./types");
44
+ const isUri = (str) => {
45
+ try {
46
+ const url = new URL(str);
47
+ return true;
48
+ }
49
+ catch (_a) {
50
+ return false;
51
+ }
52
+ };
53
+ exports.isUri = isUri;
30
54
  const indexOfRegexGroup = (match, n) => {
31
55
  return match.reduce((acc, curr, i) => {
32
56
  if (i < 1 || i >= n)
@@ -316,11 +340,14 @@ const isQLIdentifier = (typeQLClass) => {
316
340
  };
317
341
  exports.isQLIdentifier = isQLIdentifier;
318
342
  const supportsHole = (lang) => {
319
- const supportedLangs = [types_1.Language.OCaml];
343
+ const supportedLangs = ["ocaml"];
320
344
  return supportedLangs.includes(lang);
321
345
  };
322
346
  exports.supportsHole = supportsHole;
323
347
  const getAllTSFiles = (dirPath, arrayOfFiles = []) => {
348
+ if (dirPath.slice(0, 7) === "file://") {
349
+ dirPath = dirPath.slice(7);
350
+ }
324
351
  const files = fs.readdirSync(dirPath);
325
352
  files.forEach((file) => {
326
353
  const filePath = path.join(dirPath, file);
@@ -348,3 +375,53 @@ const getAllOCamlFiles = (dirPath, arrayOfFiles = []) => {
348
375
  return arrayOfFiles;
349
376
  };
350
377
  exports.getAllOCamlFiles = getAllOCamlFiles;
378
+ const getTimestampForFilename = () => {
379
+ const now = new Date();
380
+ const year = now.getFullYear();
381
+ const month = String(now.getMonth() + 1).padStart(2, "0"); // Months are 0-based
382
+ const day = String(now.getDate()).padStart(2, "0");
383
+ const hours = String(now.getHours()).padStart(2, "0");
384
+ const minutes = String(now.getMinutes()).padStart(2, "0");
385
+ const seconds = String(now.getSeconds()).padStart(2, "0");
386
+ return `${year}${month}${day}_${hours}${minutes}${seconds}`;
387
+ };
388
+ exports.getTimestampForFilename = getTimestampForFilename;
389
+ const insertAtPosition = (contents, cursorPosition, insertText) => {
390
+ const lines = contents.split(/\r?\n/); // Handle both LF and CRLF line endings
391
+ const { line, character } = cursorPosition;
392
+ if (line < 0 || line >= lines.length) {
393
+ throw new Error("Invalid line number");
394
+ }
395
+ const targetLine = lines[line];
396
+ if (character < 0 || character > targetLine.length) {
397
+ throw new Error("Invalid character index");
398
+ }
399
+ // Insert the text
400
+ lines[line] = targetLine.slice(0, character) + insertText + targetLine.slice(character);
401
+ return lines.join("\n"); // Reconstruct the file
402
+ };
403
+ exports.insertAtPosition = insertAtPosition;
404
+ function getCleanUriPath(uri) {
405
+ var _a;
406
+ const path = (_a = URI.parse(uri).path) !== null && _a !== void 0 ? _a : "";
407
+ let clean = path.replace(/^\//, ""); // remove start slash
408
+ clean = clean.replace(/\/$/, ""); // remove end slash
409
+ return clean;
410
+ }
411
+ function getUriPathBasename(uri) {
412
+ const path = getCleanUriPath(uri);
413
+ const basename = path.split("/").pop() || "";
414
+ return decodeURIComponent(basename);
415
+ }
416
+ function getFileExtensionFromBasename(basename) {
417
+ var _a;
418
+ const parts = basename.split(".");
419
+ if (parts.length < 2) {
420
+ return "";
421
+ }
422
+ return ((_a = parts.slice(-1)[0]) !== null && _a !== void 0 ? _a : "").toLowerCase();
423
+ }
424
+ function getUriFileExtension(uri) {
425
+ const baseName = getUriPathBasename(uri);
426
+ return getFileExtensionFromBasename(baseName);
427
+ }
@@ -0,0 +1,29 @@
1
+ export declare namespace VsCode {
2
+ interface Hover {
3
+ text: string;
4
+ }
5
+ interface DocumentSymbol extends RangeInFile {
6
+ name: string;
7
+ selectionRange: Range;
8
+ }
9
+ interface RangeInFile {
10
+ filepath: string;
11
+ range: Range;
12
+ }
13
+ interface Range {
14
+ start: Position;
15
+ end: Position;
16
+ }
17
+ interface Location {
18
+ filepath: string;
19
+ position: Position;
20
+ }
21
+ interface Position {
22
+ line: number;
23
+ character: number;
24
+ }
25
+ export function hover(location: Location): Promise<Hover>;
26
+ export function gotoTypeDefinition(location: Location): Promise<RangeInFile[]>;
27
+ export function getDocumentSymbols(location: Omit<Location, "position">): Promise<DocumentSymbol[]>;
28
+ export {};
29
+ }
@@ -0,0 +1,161 @@
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
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.VsCode = void 0;
37
+ const vscode = __importStar(require("vscode"));
38
+ var VsCode;
39
+ (function (VsCode) {
40
+ const MAX_CACHE_SIZE = 50;
41
+ const lspCache = new Map();
42
+ function gotoInputKey(input) {
43
+ return `${input.name}${input.uri.toString()}${input.line}${input.character}`;
44
+ }
45
+ async function hover(location) {
46
+ const result = await executeHoverProvider({
47
+ uri: vscode.Uri.parse(location.filepath),
48
+ line: location.position.line,
49
+ character: location.position.character,
50
+ name: "vscode.executeHoverProvider",
51
+ });
52
+ return result;
53
+ }
54
+ VsCode.hover = hover;
55
+ async function gotoTypeDefinition(location) {
56
+ const result = await executeGotoProvider({
57
+ uri: vscode.Uri.parse(location.filepath),
58
+ line: location.position.line,
59
+ character: location.position.character,
60
+ name: "vscode.executeTypeDefinitionProvider",
61
+ });
62
+ return result;
63
+ }
64
+ VsCode.gotoTypeDefinition = gotoTypeDefinition;
65
+ async function getDocumentSymbols(location) {
66
+ const result = await executeDocumentSymbolProvider({
67
+ uri: vscode.Uri.parse(location.filepath),
68
+ name: "vscode.executeDocumentSymbolProvider",
69
+ });
70
+ return result;
71
+ }
72
+ VsCode.getDocumentSymbols = getDocumentSymbols;
73
+ // Core logic for executing vscode providers.
74
+ async function executeGotoProvider(input) {
75
+ // Check the cache before executing vscode command.
76
+ const cacheKey = gotoInputKey(input);
77
+ const cached = lspCache.get(cacheKey);
78
+ if (cached) {
79
+ return cached;
80
+ }
81
+ try {
82
+ const definitions = (await vscode.commands.executeCommand(input.name, input.uri, new vscode.Position(input.line, input.character)));
83
+ const results = definitions
84
+ .filter((d) => (d.targetUri || d.uri) && (d.targetRange || d.range))
85
+ .map((d) => ({
86
+ filepath: (d.targetUri || d.uri).toString(),
87
+ range: d.targetRange || d.range,
88
+ }));
89
+ // Update the cache via LRU.
90
+ if (lspCache.size >= MAX_CACHE_SIZE) {
91
+ const oldestKey = lspCache.keys().next().value;
92
+ if (oldestKey) {
93
+ lspCache.delete(oldestKey);
94
+ }
95
+ }
96
+ lspCache.set(cacheKey, results);
97
+ return results;
98
+ }
99
+ catch (e) {
100
+ console.warn(`Error executing ${input.name}:`, e);
101
+ return [];
102
+ }
103
+ }
104
+ async function executeHoverProvider(input) {
105
+ // Check the cache before executing vscode command.
106
+ const cacheKey = gotoInputKey(input);
107
+ const cached = lspCache.get(cacheKey);
108
+ if (cached) {
109
+ return cached;
110
+ }
111
+ try {
112
+ const definitions = (await vscode.commands.executeCommand(input.name, input.uri, new vscode.Position(input.line, input.character)));
113
+ const result = definitions[0].contents[0].value;
114
+ // Update the cache via LRU.
115
+ if (lspCache.size >= MAX_CACHE_SIZE) {
116
+ const oldestKey = lspCache.keys().next().value;
117
+ if (oldestKey) {
118
+ lspCache.delete(oldestKey);
119
+ }
120
+ }
121
+ lspCache.set(cacheKey, result);
122
+ return result;
123
+ }
124
+ catch (e) {
125
+ console.warn(`Error executing ${input.name}:`, e);
126
+ return { text: "" };
127
+ }
128
+ }
129
+ async function executeDocumentSymbolProvider(input) {
130
+ // Check the cache before executing vscode command.
131
+ const cacheKey = gotoInputKey(input);
132
+ const cached = lspCache.get(cacheKey);
133
+ if (cached) {
134
+ return cached;
135
+ }
136
+ try {
137
+ const definitions = (await vscode.commands.executeCommand(input.name, input.uri));
138
+ const results = definitions
139
+ .filter((d) => d.location && d.location.uri && d.range && d.selectionRange && d.name)
140
+ .map((d) => ({
141
+ filepath: (d.location.uri).toString(),
142
+ range: d.range,
143
+ selectionRange: d.selectionRange,
144
+ name: d.name
145
+ }));
146
+ // Update the cache via LRU.
147
+ if (lspCache.size >= MAX_CACHE_SIZE) {
148
+ const oldestKey = lspCache.keys().next().value;
149
+ if (oldestKey) {
150
+ lspCache.delete(oldestKey);
151
+ }
152
+ }
153
+ lspCache.set(cacheKey, results);
154
+ return results;
155
+ }
156
+ catch (e) {
157
+ console.warn(`Error executing ${input.name}:`, e);
158
+ return [];
159
+ }
160
+ }
161
+ })(VsCode || (exports.VsCode = VsCode = {}));