@jpoly1219/context-extractor 0.2.8 → 0.2.9
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.
- package/dist/src/app.d.ts +7 -3
- package/dist/src/app.js +304 -101
- package/dist/src/ast.d.ts +6 -0
- package/dist/src/ast.js +80 -0
- package/dist/src/codeql.js +17 -7
- package/dist/src/constants.js +17 -7
- package/dist/src/core.d.ts +0 -1
- package/dist/src/core.js +17 -7
- package/dist/src/main.d.ts +8 -2
- package/dist/src/main.js +51 -13
- package/dist/src/ocaml-driver.d.ts +55 -5
- package/dist/src/ocaml-driver.js +295 -190
- package/dist/src/ocaml-utils/_build/default/test_parser.bc.cjs +194658 -0
- package/dist/src/runner.js +118 -3
- package/dist/src/tree-sitter-files/queries/hole-queries/typescript.scm +36 -0
- package/dist/src/tree-sitter-files/queries/relevant-headers-queries/typescript-get-toplevel-headers.scm +22 -0
- package/dist/src/tree-sitter-files/queries/relevant-types-queries/typescript-extract-identifiers.scm +10 -0
- package/dist/src/tree-sitter-files/queries/relevant-types-queries/typescript-find-typedecl-given-typeidentifier.scm +11 -0
- package/dist/src/tree-sitter-files/wasms/tree-sitter-ocaml.wasm +0 -0
- package/dist/src/tree-sitter-files/wasms/tree-sitter-typescript.wasm +0 -0
- package/dist/src/tree-sitter-files/wasms/tree-sitter.wasm +0 -0
- package/dist/src/tree-sitter.d.ts +40 -0
- package/dist/src/tree-sitter.js +311 -0
- package/dist/src/types.d.ts +79 -9
- package/dist/src/types.js +1 -6
- package/dist/src/typescript-driver.d.ts +81 -13
- package/dist/src/typescript-driver.js +1123 -237
- package/dist/src/typescript-type-checker.d.ts +6 -2
- package/dist/src/typescript-type-checker.js +222 -10
- package/dist/src/utils.d.ts +11 -1
- package/dist/src/utils.js +87 -10
- package/dist/src/vscode-ide.d.ts +29 -0
- package/dist/src/vscode-ide.js +161 -0
- 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
|
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 (
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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;
|
package/dist/src/utils.d.ts
CHANGED
@@ -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
|
-
|
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 (
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
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 = [
|
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 = {}));
|