@jpoly1219/context-extractor 0.2.0 → 0.2.2
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/app.d.ts +27 -0
- package/dist/app.js +285 -0
- package/dist/codeql.d.ts +17 -0
- package/dist/codeql.js +1341 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.js +62 -0
- package/dist/core.d.ts +20 -0
- package/dist/core.js +576 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +7 -0
- package/dist/main.d.ts +13 -0
- package/dist/main.js +255 -0
- package/dist/ocaml-driver.d.ts +30 -0
- package/dist/ocaml-driver.js +394 -0
- package/dist/ocaml-type-checker.d.ts +52 -0
- package/dist/ocaml-type-checker.js +286 -0
- package/dist/runner.d.ts +1 -0
- package/dist/runner.js +52 -0
- package/dist/types.d.ts +134 -0
- package/dist/types.js +14 -0
- package/dist/typescript-driver.d.ts +27 -0
- package/dist/typescript-driver.js +542 -0
- package/dist/typescript-type-checker.d.ts +64 -0
- package/dist/typescript-type-checker.js +512 -0
- package/dist/utils.d.ts +40 -0
- package/dist/utils.js +350 -0
- package/package.json +1 -1
@@ -0,0 +1,512 @@
|
|
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 (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
|
+
};
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
26
|
+
exports.TypeScriptTypeChecker = void 0;
|
27
|
+
const ts = __importStar(require("typescript"));
|
28
|
+
const utils_1 = require("./utils");
|
29
|
+
class TypeScriptTypeChecker {
|
30
|
+
getIdentifierFromDecl(typeDecl) {
|
31
|
+
const declRe = /(.+ )(.+)( = )(.+)/;
|
32
|
+
const match = typeDecl.match(declRe);
|
33
|
+
if (!match)
|
34
|
+
return "";
|
35
|
+
return match[2];
|
36
|
+
}
|
37
|
+
getTypeContextFromDecl(typeDecl) {
|
38
|
+
if (this.checkHole(typeDecl)) {
|
39
|
+
return this.checkHole(typeDecl);
|
40
|
+
}
|
41
|
+
else if (this.checkParameter(typeDecl)) {
|
42
|
+
return this.checkParameter(typeDecl);
|
43
|
+
}
|
44
|
+
else if (this.checkFunction(typeDecl)) {
|
45
|
+
return this.checkFunction(typeDecl);
|
46
|
+
}
|
47
|
+
else if (this.checkUnion(typeDecl)) {
|
48
|
+
return this.checkUnion(typeDecl);
|
49
|
+
}
|
50
|
+
else if (this.checkObject(typeDecl)) {
|
51
|
+
return this.checkObject(typeDecl);
|
52
|
+
}
|
53
|
+
else if (this.checkImports(typeDecl)) {
|
54
|
+
return this.checkImports(typeDecl);
|
55
|
+
}
|
56
|
+
else if (this.checkModule(typeDecl)) {
|
57
|
+
return this.checkModule(typeDecl);
|
58
|
+
}
|
59
|
+
else {
|
60
|
+
return this.checkPrimitive(typeDecl);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
// pattern matching
|
64
|
+
// attempts to match strings to corresponding types, then returns an object containing the name, type span, and an interesting index
|
65
|
+
// base case - type can no longer be stepped into
|
66
|
+
// boolean, number, string, enum, unknown, any, void, null, undefined, never
|
67
|
+
// ideally this should be checked for before we do the for loop
|
68
|
+
// return typeSpan;
|
69
|
+
// check if hover result is from a primitive type
|
70
|
+
checkPrimitive(typeDecl) {
|
71
|
+
// type _ = boolean
|
72
|
+
const primitivePattern = /(type )(.+)( = )(.+)/;
|
73
|
+
const primitiveMatch = typeDecl.match(primitivePattern);
|
74
|
+
let primitiveInterestingIndex = -1;
|
75
|
+
if (primitiveMatch) {
|
76
|
+
primitiveInterestingIndex = (0, utils_1.indexOfRegexGroup)(primitiveMatch, 4);
|
77
|
+
}
|
78
|
+
if (primitiveInterestingIndex != -1) {
|
79
|
+
const typeName = primitiveMatch[2];
|
80
|
+
const typeSpan = primitiveMatch[4];
|
81
|
+
return { identifier: typeName, span: typeSpan, interestingIndex: primitiveInterestingIndex };
|
82
|
+
}
|
83
|
+
return null;
|
84
|
+
}
|
85
|
+
// check if hover result is from an import
|
86
|
+
checkImports(typeDecl) {
|
87
|
+
// import { _, _ };
|
88
|
+
const importPattern = /(import )(\{.+\})/;
|
89
|
+
const importMatch = typeDecl.match(importPattern);
|
90
|
+
let importInterestingIndex = -1;
|
91
|
+
if (importMatch) {
|
92
|
+
importInterestingIndex = (0, utils_1.indexOfRegexGroup)(importMatch, 2);
|
93
|
+
}
|
94
|
+
// import _;
|
95
|
+
const defaultImportPattern = /(import )(.+)/;
|
96
|
+
const defaultImportMatch = typeDecl.match(defaultImportPattern);
|
97
|
+
let defaultImportInterestingIndex = -1;
|
98
|
+
if (defaultImportMatch) {
|
99
|
+
defaultImportInterestingIndex = (0, utils_1.indexOfRegexGroup)(defaultImportMatch, 2);
|
100
|
+
}
|
101
|
+
if (importInterestingIndex != -1) {
|
102
|
+
const typeName = importMatch[2];
|
103
|
+
const typeSpan = importMatch[2];
|
104
|
+
return { identifier: typeName, span: typeSpan, interestingIndex: importInterestingIndex };
|
105
|
+
}
|
106
|
+
else if (defaultImportInterestingIndex != -1) {
|
107
|
+
const typeName = defaultImportMatch[2];
|
108
|
+
const typeSpan = defaultImportMatch[2];
|
109
|
+
return { identifier: typeName, span: typeSpan, interestingIndex: defaultImportInterestingIndex };
|
110
|
+
}
|
111
|
+
return null;
|
112
|
+
}
|
113
|
+
// check if hover result is from a module
|
114
|
+
checkModule(typeDecl) {
|
115
|
+
// module "path/to/module"
|
116
|
+
const modulePattern = /(module )(.+)/;
|
117
|
+
const moduleMatch = typeDecl.match(modulePattern);
|
118
|
+
let moduleInterestingIndex = -1;
|
119
|
+
if (moduleMatch) {
|
120
|
+
moduleInterestingIndex = (0, utils_1.indexOfRegexGroup)(moduleMatch, 2);
|
121
|
+
}
|
122
|
+
if (moduleInterestingIndex != -1) {
|
123
|
+
const typeName = moduleMatch[2];
|
124
|
+
const typeSpan = moduleMatch[2];
|
125
|
+
return { identifier: typeName, span: typeSpan, interestingIndex: moduleInterestingIndex };
|
126
|
+
}
|
127
|
+
return null;
|
128
|
+
}
|
129
|
+
// check if hover result is from an object
|
130
|
+
checkObject(typeDecl) {
|
131
|
+
// type _ = {
|
132
|
+
// _: t1;
|
133
|
+
// _: t2;
|
134
|
+
// }
|
135
|
+
const objectTypeDefPattern = /(type )(.+)( = )(\{.+\})/;
|
136
|
+
const objectTypeDefMatch = typeDecl.match(objectTypeDefPattern);
|
137
|
+
let objectTypeDefInterestingIndex = -1;
|
138
|
+
if (objectTypeDefMatch) {
|
139
|
+
objectTypeDefInterestingIndex = (0, utils_1.indexOfRegexGroup)(objectTypeDefMatch, 4);
|
140
|
+
}
|
141
|
+
if (objectTypeDefInterestingIndex != -1) {
|
142
|
+
const typeName = objectTypeDefMatch[2];
|
143
|
+
const typeSpan = objectTypeDefMatch[4];
|
144
|
+
return { identifier: typeName, span: typeSpan, interestingIndex: objectTypeDefInterestingIndex };
|
145
|
+
}
|
146
|
+
return null;
|
147
|
+
}
|
148
|
+
// check if hover result is from a union
|
149
|
+
checkUnion(typeDecl) {
|
150
|
+
// type _ = A | B | C
|
151
|
+
const unionPattern = /(type )(.+)( = )((.+ | )+.+)/;
|
152
|
+
const unionMatch = typeDecl.match(unionPattern);
|
153
|
+
let unionInterestingIndex = -1;
|
154
|
+
if (unionMatch) {
|
155
|
+
unionInterestingIndex = (0, utils_1.indexOfRegexGroup)(unionMatch, 4);
|
156
|
+
}
|
157
|
+
if (unionInterestingIndex != -1) {
|
158
|
+
const typeName = unionMatch[2];
|
159
|
+
const typeSpan = unionMatch[4];
|
160
|
+
return { identifier: typeName, span: typeSpan, interestingIndex: unionInterestingIndex };
|
161
|
+
}
|
162
|
+
return null;
|
163
|
+
}
|
164
|
+
// check if hover result is from a function
|
165
|
+
checkFunction(typeDecl) {
|
166
|
+
// const myFunc : (arg1: typ1, ...) => _
|
167
|
+
const es6AnnotatedFunctionPattern = /(const )(.+)(: )(\(.+\) => .+)/;
|
168
|
+
const es6AnnotatedFunctionMatch = typeDecl.match(es6AnnotatedFunctionPattern);
|
169
|
+
let es6AnnotatedFunctionInterestingIndex = -1;
|
170
|
+
if (es6AnnotatedFunctionMatch) {
|
171
|
+
es6AnnotatedFunctionInterestingIndex = (0, utils_1.indexOfRegexGroup)(es6AnnotatedFunctionMatch, 4);
|
172
|
+
}
|
173
|
+
// type _ = (_: t1) => t2
|
174
|
+
const es6FunctionTypeDefPattern = /(type )(.+)( = )(\(.+\) => .+)/;
|
175
|
+
const es6FunctionTypeDefPatternMatch = typeDecl.match(es6FunctionTypeDefPattern);
|
176
|
+
let es6FunctionTypeDefInterestingIndex = -1;
|
177
|
+
if (es6FunctionTypeDefPatternMatch) {
|
178
|
+
es6FunctionTypeDefInterestingIndex = (0, utils_1.indexOfRegexGroup)(es6FunctionTypeDefPatternMatch, 4);
|
179
|
+
}
|
180
|
+
// function myFunc<T>(args: types, genarg: T): returntype
|
181
|
+
const genericFunctionTypePattern = /(function )(.+)(\<.+\>\(.*\))(: )(.+)/;
|
182
|
+
const genericFunctionTypeMatch = typeDecl.match(genericFunctionTypePattern);
|
183
|
+
let genericFunctionTypeInterestingIndex = -1;
|
184
|
+
if (genericFunctionTypeMatch) {
|
185
|
+
genericFunctionTypeInterestingIndex = (0, utils_1.indexOfRegexGroup)(genericFunctionTypeMatch, 3);
|
186
|
+
}
|
187
|
+
// function myFunc(args: types): returntype
|
188
|
+
const functionTypePattern = /(function )(.+)(\(.*\))(: )(.+)/;
|
189
|
+
const functionTypeMatch = typeDecl.match(functionTypePattern);
|
190
|
+
let functionTypeInterestingIndex = -1;
|
191
|
+
if (functionTypeMatch) {
|
192
|
+
functionTypeInterestingIndex = (0, utils_1.indexOfRegexGroup)(functionTypeMatch, 3);
|
193
|
+
}
|
194
|
+
if (es6AnnotatedFunctionInterestingIndex != -1) {
|
195
|
+
const typeName = es6AnnotatedFunctionMatch[2];
|
196
|
+
const typeSpan = es6AnnotatedFunctionMatch[4];
|
197
|
+
return { identifier: typeName, span: typeSpan, interestingIndex: es6AnnotatedFunctionInterestingIndex };
|
198
|
+
}
|
199
|
+
else if (es6FunctionTypeDefInterestingIndex != -1) {
|
200
|
+
const typeName = es6FunctionTypeDefPatternMatch[2];
|
201
|
+
const typeSpan = es6FunctionTypeDefPatternMatch[4];
|
202
|
+
return { identifier: typeName, span: typeSpan, interestingIndex: es6FunctionTypeDefInterestingIndex };
|
203
|
+
}
|
204
|
+
else if (genericFunctionTypeInterestingIndex != -1) {
|
205
|
+
const typeName = genericFunctionTypeMatch[2];
|
206
|
+
const typeSpan = genericFunctionTypeMatch[3] + genericFunctionTypeMatch[4] + genericFunctionTypeMatch[5];
|
207
|
+
return { identifier: typeName, span: typeSpan, interestingIndex: genericFunctionTypeInterestingIndex };
|
208
|
+
}
|
209
|
+
else if (functionTypeInterestingIndex != -1) {
|
210
|
+
const typeName = functionTypeMatch[2];
|
211
|
+
const typeSpan = functionTypeMatch[3] + functionTypeMatch[4] + functionTypeMatch[5];
|
212
|
+
return { identifier: typeName, span: typeSpan, interestingIndex: functionTypeInterestingIndex };
|
213
|
+
}
|
214
|
+
return null;
|
215
|
+
}
|
216
|
+
// check if hover result is from a hole
|
217
|
+
checkHole(typeDecl) {
|
218
|
+
// (type parameter) T in _<T>(): T
|
219
|
+
const holePattern = /(\(type parameter\) T in _\<T\>\(\): T)/;
|
220
|
+
const match = typeDecl.match(holePattern);
|
221
|
+
if (match) {
|
222
|
+
const typeName = "hole function";
|
223
|
+
const typeSpan = match[1];
|
224
|
+
return { identifier: typeName, span: typeSpan };
|
225
|
+
}
|
226
|
+
return null;
|
227
|
+
}
|
228
|
+
// check if hover result is from a parameter
|
229
|
+
checkParameter(typeDecl) {
|
230
|
+
// (parameter) name: type
|
231
|
+
// const parameterPattern = /(\(parameter\) )(.+)(: )(.+))/;
|
232
|
+
// const parameterMatch = typeDecl.match(parameterPattern);
|
233
|
+
// let parameterInterestingIndex = -1;
|
234
|
+
// if (parameterMatch) {
|
235
|
+
// parameterInterestingIndex = indexOfRegexGroup(parameterMatch, 4);
|
236
|
+
// }
|
237
|
+
//
|
238
|
+
// if (parameterInterestingIndex != -1) {
|
239
|
+
// const typeName = parameterMatch[2];
|
240
|
+
// const typeSpan = parameterMatch[4];
|
241
|
+
// return { typeName: typeName, typeSpan: typeSpan, interestingIndex: parameterInterestingIndex }
|
242
|
+
// }
|
243
|
+
return null;
|
244
|
+
}
|
245
|
+
isTuple(typeSpan) {
|
246
|
+
return typeSpan[0] === "[" && typeSpan[typeSpan.length - 1] === "]";
|
247
|
+
}
|
248
|
+
isUnion(typeSpan) {
|
249
|
+
return typeSpan.includes(" | ");
|
250
|
+
}
|
251
|
+
isArray(typeSpan) {
|
252
|
+
return typeSpan.slice(-2) === "[]";
|
253
|
+
}
|
254
|
+
isObject(typeSpan) {
|
255
|
+
return typeSpan[0] === "{" && typeSpan[typeSpan.length - 1] === "}";
|
256
|
+
}
|
257
|
+
// this is a very rudimentary check, so it should be expanded upon
|
258
|
+
isFunction(typeSpan) {
|
259
|
+
return typeSpan.includes("=>");
|
260
|
+
}
|
261
|
+
isPrimitive(typeSpan) {
|
262
|
+
const primitives = ["string", "number", "boolean"];
|
263
|
+
return primitives.includes(typeSpan);
|
264
|
+
}
|
265
|
+
isTypeAlias(typeSpan) {
|
266
|
+
const caps = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
267
|
+
return caps.includes(typeSpan[0]);
|
268
|
+
}
|
269
|
+
escapeQuotes(typeSpan) {
|
270
|
+
return typeSpan.replace(/"/g, `\\"`);
|
271
|
+
}
|
272
|
+
parseTypeArrayString(typeStr) {
|
273
|
+
// Remove all spaces
|
274
|
+
const cleaned = typeStr.replace(/\s/g, '');
|
275
|
+
// Remove the outermost square brackets
|
276
|
+
const inner = cleaned.slice(1, -1);
|
277
|
+
// const inner = cleaned.slice(-1) === ";" ? cleaned.slice(1, -2) : cleaned.slice(1, -1);
|
278
|
+
// Split the string, respecting nested structures
|
279
|
+
const result = [];
|
280
|
+
let currentItem = '';
|
281
|
+
let nestLevel = 0;
|
282
|
+
for (const char of inner) {
|
283
|
+
if (char === '[')
|
284
|
+
nestLevel++;
|
285
|
+
if (char === ']')
|
286
|
+
nestLevel--;
|
287
|
+
if (char === ',' && nestLevel === 0) {
|
288
|
+
// check if currentItem is a name: type pair or just type
|
289
|
+
if (currentItem.includes(":")) {
|
290
|
+
result.push(currentItem.split(":")[1]);
|
291
|
+
}
|
292
|
+
else {
|
293
|
+
result.push(currentItem);
|
294
|
+
}
|
295
|
+
currentItem = '';
|
296
|
+
}
|
297
|
+
else {
|
298
|
+
currentItem += char;
|
299
|
+
}
|
300
|
+
}
|
301
|
+
if (currentItem.includes(":")) {
|
302
|
+
result.push(currentItem.split(":")[1]);
|
303
|
+
}
|
304
|
+
else {
|
305
|
+
result.push(currentItem);
|
306
|
+
}
|
307
|
+
return result;
|
308
|
+
}
|
309
|
+
/* Version 2, using TypeScript Compiler API */
|
310
|
+
handleMembers(members, checker) {
|
311
|
+
return members.map(member => {
|
312
|
+
if (ts.isPropertySignature(member) || ts.isPropertyDeclaration(member)) {
|
313
|
+
const propertyType = member.type ? this.analyzeTypeNode(member.type, checker) : { kind: 'Any', text: 'any' };
|
314
|
+
return {
|
315
|
+
kind: 'Property',
|
316
|
+
text: member.getText(),
|
317
|
+
constituents: [propertyType]
|
318
|
+
};
|
319
|
+
}
|
320
|
+
else if (ts.isMethodSignature(member) || ts.isMethodDeclaration(member)) {
|
321
|
+
const parameters = member.parameters.map(param => ({
|
322
|
+
name: param.name.getText(),
|
323
|
+
optional: !!param.questionToken,
|
324
|
+
type: param.type ? this.analyzeTypeNode(param.type, checker) : { kind: 'Any', text: 'any' }
|
325
|
+
}));
|
326
|
+
const returnType = member.type ? this.analyzeTypeNode(member.type, checker) : { kind: 'Any', text: 'any' };
|
327
|
+
return {
|
328
|
+
kind: 'Method',
|
329
|
+
text: member.getText(),
|
330
|
+
parameters,
|
331
|
+
returnType
|
332
|
+
};
|
333
|
+
}
|
334
|
+
else {
|
335
|
+
return {
|
336
|
+
kind: "Unknown",
|
337
|
+
text: member.getText()
|
338
|
+
};
|
339
|
+
}
|
340
|
+
});
|
341
|
+
}
|
342
|
+
analyzeTypeNode(typeNode, checker) {
|
343
|
+
switch (typeNode.kind) {
|
344
|
+
case ts.SyntaxKind.NumericLiteral: {
|
345
|
+
return {
|
346
|
+
kind: 'NumericLiteral',
|
347
|
+
text: typeNode.getText(),
|
348
|
+
};
|
349
|
+
}
|
350
|
+
case ts.SyntaxKind.StringLiteral: {
|
351
|
+
return {
|
352
|
+
kind: 'StringLiteral',
|
353
|
+
text: typeNode.getText(),
|
354
|
+
};
|
355
|
+
}
|
356
|
+
case ts.SyntaxKind.FunctionType: {
|
357
|
+
const tn = typeNode;
|
358
|
+
return {
|
359
|
+
kind: "Function",
|
360
|
+
text: tn.getText(),
|
361
|
+
parameters: tn.parameters.map(parameter => {
|
362
|
+
return {
|
363
|
+
name: parameter.name.getText(),
|
364
|
+
optional: !!parameter.questionToken,
|
365
|
+
type: parameter.type ? this.analyzeTypeNode(parameter.type, checker) : { kind: "Any", text: "any" }
|
366
|
+
};
|
367
|
+
}),
|
368
|
+
returnType: tn.type ? this.analyzeTypeNode(tn.type, checker) : undefined
|
369
|
+
};
|
370
|
+
}
|
371
|
+
case ts.SyntaxKind.ArrayType: {
|
372
|
+
const tn = typeNode;
|
373
|
+
return {
|
374
|
+
kind: 'Array',
|
375
|
+
text: typeNode.getText(),
|
376
|
+
constituents: [this.analyzeTypeNode(tn.elementType, checker)]
|
377
|
+
};
|
378
|
+
}
|
379
|
+
case ts.SyntaxKind.TupleType: {
|
380
|
+
const tn = typeNode;
|
381
|
+
const elements = tn.elements.map(element => {
|
382
|
+
if (ts.isRestTypeNode(element)) {
|
383
|
+
return {
|
384
|
+
kind: 'RestElement',
|
385
|
+
text: element.getText(),
|
386
|
+
type: this.analyzeTypeNode(element.type, checker)
|
387
|
+
};
|
388
|
+
}
|
389
|
+
else {
|
390
|
+
return this.analyzeTypeNode(element, checker);
|
391
|
+
}
|
392
|
+
});
|
393
|
+
return {
|
394
|
+
kind: 'Tuple',
|
395
|
+
text: typeNode.getText(),
|
396
|
+
constituents: elements
|
397
|
+
};
|
398
|
+
}
|
399
|
+
case ts.SyntaxKind.UnionType: {
|
400
|
+
const tn = typeNode;
|
401
|
+
return {
|
402
|
+
kind: "Union",
|
403
|
+
text: tn.getText(),
|
404
|
+
constituents: tn.types.map(typ => {
|
405
|
+
return this.analyzeTypeNode(typ, checker);
|
406
|
+
})
|
407
|
+
};
|
408
|
+
}
|
409
|
+
case ts.SyntaxKind.IntersectionType: {
|
410
|
+
const tn = typeNode;
|
411
|
+
return {
|
412
|
+
kind: "Intersection",
|
413
|
+
text: tn.getText(),
|
414
|
+
constituents: tn.types.map(typ => {
|
415
|
+
return this.analyzeTypeNode(typ, checker);
|
416
|
+
})
|
417
|
+
};
|
418
|
+
}
|
419
|
+
case ts.SyntaxKind.TypeLiteral: {
|
420
|
+
const tn = typeNode;
|
421
|
+
return {
|
422
|
+
kind: "Object",
|
423
|
+
text: tn.getText(),
|
424
|
+
constituents: this.handleMembers(tn.members, checker)
|
425
|
+
};
|
426
|
+
}
|
427
|
+
case ts.SyntaxKind.TypeReference: {
|
428
|
+
const tn = typeNode;
|
429
|
+
const symbol = checker.getSymbolAtLocation(tn.typeName);
|
430
|
+
let typeAliasAnalysis = { kind: 'TypeReference', text: typeNode.getText() };
|
431
|
+
if (symbol && symbol.declarations) {
|
432
|
+
const declaration = symbol.declarations[0];
|
433
|
+
if (ts.isTypeAliasDeclaration(declaration)) {
|
434
|
+
const typeAlias = declaration;
|
435
|
+
if (typeAlias.type) {
|
436
|
+
typeAliasAnalysis = Object.assign(Object.assign({}, typeAliasAnalysis), { kind: `TypeReference of TypeAliasDeclaration`, constituents: [this.analyzeTypeNode(typeAlias.type, checker)] });
|
437
|
+
}
|
438
|
+
}
|
439
|
+
else if (ts.isInterfaceDeclaration(declaration)) {
|
440
|
+
const interfaceDecl = declaration;
|
441
|
+
if (interfaceDecl.members) {
|
442
|
+
typeAliasAnalysis = Object.assign(Object.assign({}, typeAliasAnalysis), { kind: `TypeReference of InterfaceDeclaration`, constituents: this.handleMembers(interfaceDecl.members, checker) });
|
443
|
+
}
|
444
|
+
}
|
445
|
+
else if (ts.isClassDeclaration(declaration)) {
|
446
|
+
const classDecl = declaration;
|
447
|
+
if (classDecl.members) {
|
448
|
+
typeAliasAnalysis = Object.assign(Object.assign({}, typeAliasAnalysis), { kind: `TypeReference of ClassDeclaration`, constituents: this.handleMembers(classDecl.members, checker) });
|
449
|
+
if (classDecl.heritageClauses) {
|
450
|
+
typeAliasAnalysis = Object.assign(Object.assign({}, typeAliasAnalysis), { heritage: classDecl.heritageClauses.map(heritageClause => {
|
451
|
+
return heritageClause.types.map(typ => {
|
452
|
+
return this.analyzeTypeNode(typ, checker);
|
453
|
+
});
|
454
|
+
}) });
|
455
|
+
}
|
456
|
+
}
|
457
|
+
}
|
458
|
+
}
|
459
|
+
return typeAliasAnalysis;
|
460
|
+
}
|
461
|
+
}
|
462
|
+
return {
|
463
|
+
kind: ts.SyntaxKind[typeNode.kind],
|
464
|
+
text: typeNode.getText()
|
465
|
+
};
|
466
|
+
}
|
467
|
+
analyzeTypeString(typeString, program = this.createProgramFromSource("")) {
|
468
|
+
const sourceFile = ts.createSourceFile('temp.ts', `type T = ${typeString};`, ts.ScriptTarget.Latest, true);
|
469
|
+
let typeNode;
|
470
|
+
ts.forEachChild(sourceFile, node => {
|
471
|
+
if (ts.isTypeAliasDeclaration(node)) {
|
472
|
+
typeNode = node.type;
|
473
|
+
}
|
474
|
+
});
|
475
|
+
if (!typeNode) {
|
476
|
+
throw new Error('Failed to parse type string');
|
477
|
+
}
|
478
|
+
const checker = program.getTypeChecker();
|
479
|
+
return this.analyzeTypeNode(typeNode, checker);
|
480
|
+
}
|
481
|
+
createProgramFromSource(content) {
|
482
|
+
const fileName = 'test.ts';
|
483
|
+
const sourceFile = ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true);
|
484
|
+
const host = ts.createCompilerHost({});
|
485
|
+
host.getSourceFile = (fileName) => (fileName === 'test.ts' ? sourceFile : undefined);
|
486
|
+
const program = ts.createProgram([fileName], {}, host);
|
487
|
+
return program;
|
488
|
+
}
|
489
|
+
isPrimitive2(typeAnalysisResult) {
|
490
|
+
const re = /(.*)Keyword/;
|
491
|
+
return typeAnalysisResult.kind.match(re);
|
492
|
+
}
|
493
|
+
isFunction2(typeAnalysisResult) {
|
494
|
+
return typeAnalysisResult.kind === "Function";
|
495
|
+
}
|
496
|
+
isTuple2(typeAnalysisResult) {
|
497
|
+
return typeAnalysisResult.kind === "Tuple";
|
498
|
+
}
|
499
|
+
isObject2(typeAnalysisResult) {
|
500
|
+
return typeAnalysisResult.kind === "Object";
|
501
|
+
}
|
502
|
+
isUnion2(typeAnalysisResult) {
|
503
|
+
return typeAnalysisResult.kind === "Union";
|
504
|
+
}
|
505
|
+
isArray2(typeAnalysisResult) {
|
506
|
+
return typeAnalysisResult.kind === "Array";
|
507
|
+
}
|
508
|
+
isTypeAlias2(typeAnalysisResult) {
|
509
|
+
return typeAnalysisResult.kind === "TypeReference";
|
510
|
+
}
|
511
|
+
}
|
512
|
+
exports.TypeScriptTypeChecker = TypeScriptTypeChecker;
|
package/dist/utils.d.ts
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
import { relevantTypeObject, varsObject, typesObject, typesQueryResult, varsQueryResult, relevantTypeQueryResult, typesAndLocationsQueryResult, Language } from "./types";
|
2
|
+
declare const indexOfRegexGroup: (match: RegExpMatchArray, n: number) => number;
|
3
|
+
declare const formatTypeSpan: (typeSpan: string) => string;
|
4
|
+
declare const extractSnippet: (documentContent: string, start: {
|
5
|
+
line: number;
|
6
|
+
character: number;
|
7
|
+
}, end: {
|
8
|
+
line: number;
|
9
|
+
character: number;
|
10
|
+
}) => string;
|
11
|
+
declare const isTuple: (typeSpan: string) => boolean;
|
12
|
+
declare const isUnion: (typeSpan: string) => boolean;
|
13
|
+
declare const isArray: (typeSpan: string) => boolean;
|
14
|
+
declare const isObject: (typeSpan: string) => boolean;
|
15
|
+
declare const isFunction: (typeSpan: string) => boolean;
|
16
|
+
declare const isPrimitive: (typeSpan: string) => boolean;
|
17
|
+
declare const isTypeAlias: (typeSpan: string) => boolean;
|
18
|
+
declare const escapeQuotes: (typeSpan: string) => string;
|
19
|
+
declare const parseTypeArrayString: (typeStr: string) => string[];
|
20
|
+
declare const removeLines: (fileContent: string) => string[];
|
21
|
+
declare const parseCodeQLRelevantTypes: (table: relevantTypeQueryResult) => Map<string, relevantTypeObject>;
|
22
|
+
declare const parseCodeQLVars: (table: varsQueryResult) => Map<string, varsObject>;
|
23
|
+
declare const parseCodeQLTypes: (table: typesQueryResult) => typesObject[];
|
24
|
+
declare const parseCodeQLLocationsAndTypes: (table: typesAndLocationsQueryResult) => Map<string, string[]>;
|
25
|
+
declare const parseCodeQLTypesAndLocations: (table: typesAndLocationsQueryResult) => Map<string, string>;
|
26
|
+
declare const isQLFunction: (typeQLClass: string) => boolean;
|
27
|
+
declare const isQLTuple: (typeQLClass: string) => boolean;
|
28
|
+
declare const isQLUnion: (typeQLClass: string) => boolean;
|
29
|
+
declare const isQLArray: (typeQLClass: string) => boolean;
|
30
|
+
declare const isQLInterface: (typeQLClass: string) => boolean;
|
31
|
+
declare const isQLLocalTypeAccess: (typeQLClass: string) => boolean;
|
32
|
+
declare const isQLPredefined: (typeQLClass: string) => boolean;
|
33
|
+
declare const isQLLiteral: (typeQLClass: string) => boolean;
|
34
|
+
declare const isQLKeyword: (typeQLClass: string) => boolean;
|
35
|
+
declare const isQLLabel: (typeQLClass: string) => boolean;
|
36
|
+
declare const isQLIdentifier: (typeQLClass: string) => boolean;
|
37
|
+
declare const supportsHole: (lang: Language) => boolean;
|
38
|
+
declare const getAllTSFiles: (dirPath: string, arrayOfFiles?: string[]) => string[];
|
39
|
+
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 };
|