@eventra_dev/eventra-cli 0.3.1 → 0.3.3
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/README.md +2 -13
- package/dist/analysis/cache/evaluationCache.js +1 -3
- package/dist/analysis/cache/resolvedCallCache.js +1 -3
- package/dist/analysis/cache/resolvedExportCache.js +1 -3
- package/dist/analysis/cache/returnPropagationCache.js +19 -0
- package/dist/analysis/cache/symbolInvalidation.js +8 -2
- package/dist/analysis/extractor/extractor.js +5 -13
- package/dist/analysis/extractor/propagationExtractor.js +55 -14
- package/dist/analysis/resolver/callResolver.js +10 -52
- package/dist/analysis/resolver/exportResolver.js +4 -19
- package/dist/analysis/resolver/resolver.js +148 -29
- package/dist/analysis/scanner/analyzer/propagationAnalyzer.js +19 -48
- package/dist/analysis/scanner/analyzer/returnPropagationAnalyzer.js +2 -13
- package/dist/analysis/scanner/scanner.js +16 -44
- package/dist/analysis/scanner/sinkDetector.js +10 -44
- package/dist/analysis/shared/evaluationContext.js +0 -1
- package/dist/analysis/symbols/symbolUtils.js +6 -29
- package/dist/analysis/symbols/wrapperRegistry.js +25 -25
- package/dist/cli/check.js +8 -10
- package/dist/cli/init.js +18 -82
- package/dist/cli/send.js +7 -5
- package/dist/cli/sync.js +4 -39
- package/dist/cli/watch.js +42 -40
- package/dist/compiler/compilerContext.js +18 -41
- package/dist/compiler/documentRegistry.js +5 -15
- package/dist/compiler/importGraph.js +4 -8
- package/dist/compiler/scheduler.js +1 -3
- package/dist/config/config.js +9 -19
- package/dist/core/EventraEngine.js +37 -101
- package/dist/core/projectScanner.js +7 -6
- package/dist/filesystem/processFile.js +1 -4
- package/dist/shared/buildSyntheticTsx.js +1 -2
- package/package.json +1 -1
- package/dist/analysis/cache/semanticDependencyGraph.js +0 -25
- package/dist/analysis/pipeline/semanticPass.js +0 -2
package/README.md
CHANGED
|
@@ -9,17 +9,6 @@
|
|
|
9
9
|
[](https://www.typescriptlang.org/)
|
|
10
10
|
[]()
|
|
11
11
|
|
|
12
|
-
<p align="center">
|
|
13
|
-
<img src="./assets/eventra-icon-animated.svg" width="120">
|
|
14
|
-
</p>
|
|
15
|
-
|
|
16
|
-
# Eventra CLI
|
|
17
|
-
|
|
18
|
-
[](https://www.npmjs.com/package/@eventra_dev/eventra-cli)
|
|
19
|
-
[](https://www.npmjs.com/package/@eventra_dev/eventra-cli)
|
|
20
|
-
[](https://www.typescriptlang.org/)
|
|
21
|
-
[]()
|
|
22
|
-
|
|
23
12
|
Eventra CLI automatically discovers and tracks event usage across your codebase — even through abstractions like wrappers, propagation chains, variables, and cross-file calls.
|
|
24
13
|
|
|
25
14
|
---
|
|
@@ -28,7 +17,7 @@ Eventra CLI automatically discovers and tracks event usage across your codebase
|
|
|
28
17
|
|
|
29
18
|
Eventra scans your JavaScript and TypeScript codebase using a TypeScript-powered semantic engine and extracts analytics event usage statically.
|
|
30
19
|
|
|
31
|
-
It supports
|
|
20
|
+
It supports semantic parameter propagation, return propagation, cross-file resolution, and incremental dependency-aware analysis.
|
|
32
21
|
|
|
33
22
|
No runtime instrumentation required.
|
|
34
23
|
|
|
@@ -150,7 +139,7 @@ function trackFeature(name: string) {
|
|
|
150
139
|
trackFeature("click")
|
|
151
140
|
```
|
|
152
141
|
|
|
153
|
-
#####
|
|
142
|
+
##### Semantic parameter propagation
|
|
154
143
|
|
|
155
144
|
```ts
|
|
156
145
|
function trackEvent(props: {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/analysis/cache/evaluationCache.ts
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.EvaluationCache = void 0;
|
|
5
4
|
class EvaluationCache {
|
|
@@ -14,8 +13,7 @@ class EvaluationCache {
|
|
|
14
13
|
this.cache.delete(symbol);
|
|
15
14
|
}
|
|
16
15
|
clear() {
|
|
17
|
-
this.cache =
|
|
18
|
-
new WeakMap();
|
|
16
|
+
this.cache = new WeakMap();
|
|
19
17
|
}
|
|
20
18
|
}
|
|
21
19
|
exports.EvaluationCache = EvaluationCache;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/analysis/cache/resolvedCallCache.ts
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.ResolvedCallCache = void 0;
|
|
5
4
|
class ResolvedCallCache {
|
|
@@ -14,8 +13,7 @@ class ResolvedCallCache {
|
|
|
14
13
|
this.cache.delete(symbol);
|
|
15
14
|
}
|
|
16
15
|
clear() {
|
|
17
|
-
this.cache =
|
|
18
|
-
new WeakMap();
|
|
16
|
+
this.cache = new WeakMap();
|
|
19
17
|
}
|
|
20
18
|
}
|
|
21
19
|
exports.ResolvedCallCache = ResolvedCallCache;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/analysis/cache/resolvedExportCache.ts
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.ResolvedExportCache = void 0;
|
|
5
4
|
class ResolvedExportCache {
|
|
@@ -14,8 +13,7 @@ class ResolvedExportCache {
|
|
|
14
13
|
this.cache.delete(symbol);
|
|
15
14
|
}
|
|
16
15
|
clear() {
|
|
17
|
-
this.cache =
|
|
18
|
-
new WeakMap();
|
|
16
|
+
this.cache = new WeakMap();
|
|
19
17
|
}
|
|
20
18
|
}
|
|
21
19
|
exports.ResolvedExportCache = ResolvedExportCache;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReturnPropagationCache = void 0;
|
|
4
|
+
class ReturnPropagationCache {
|
|
5
|
+
cache = new WeakMap();
|
|
6
|
+
get(declaration) {
|
|
7
|
+
return this.cache.get(declaration);
|
|
8
|
+
}
|
|
9
|
+
set(declaration, value) {
|
|
10
|
+
this.cache.set(declaration, value);
|
|
11
|
+
}
|
|
12
|
+
delete(declaration) {
|
|
13
|
+
this.cache.delete(declaration);
|
|
14
|
+
}
|
|
15
|
+
clear() {
|
|
16
|
+
this.cache = new WeakMap();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.ReturnPropagationCache = ReturnPropagationCache;
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/analysis/cache/symbolInvalidation.ts
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
6
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
6
|
exports.invalidateSourceFileSymbols = invalidateSourceFileSymbols;
|
|
8
7
|
const typescript_1 = __importDefault(require("typescript"));
|
|
9
|
-
function
|
|
8
|
+
function isFunctionLike(node) {
|
|
9
|
+
return (typescript_1.default.isFunctionDeclaration(node) || typescript_1.default.isMethodDeclaration(node) || typescript_1.default.isArrowFunction(node) || typescript_1.default.isFunctionExpression(node));
|
|
10
|
+
}
|
|
11
|
+
function invalidateSourceFileSymbols(sourceFile, checker, evaluationCache, resolvedCallCache, resolvedExportCache, returnPropagationCache, wrapperRegistry) {
|
|
10
12
|
function visit(node) {
|
|
11
13
|
const symbol = checker.getSymbolAtLocation(node);
|
|
12
14
|
if (symbol) {
|
|
13
15
|
evaluationCache.delete(symbol);
|
|
14
16
|
resolvedCallCache.delete(symbol);
|
|
15
17
|
resolvedExportCache.delete(symbol);
|
|
18
|
+
wrapperRegistry.delete(symbol);
|
|
19
|
+
}
|
|
20
|
+
if (isFunctionLike(node)) {
|
|
21
|
+
returnPropagationCache.delete(node);
|
|
16
22
|
}
|
|
17
23
|
typescript_1.default.forEachChild(node, visit);
|
|
18
24
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/analysis/extractor/extractor.ts
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -10,18 +9,14 @@ const resolver_1 = require("../resolver/resolver");
|
|
|
10
9
|
const evaluationContext_1 = require("../shared/evaluationContext");
|
|
11
10
|
const propagationExtractor_1 = require("./propagationExtractor");
|
|
12
11
|
function isValidEvent(value) {
|
|
13
|
-
return (value.length > 0
|
|
14
|
-
&& value.length < 160
|
|
15
|
-
&& /^[a-zA-Z0-9:_./-]+$/.test(value));
|
|
12
|
+
return (value.length > 0 && value.length < 160 && /^[a-zA-Z0-9:_./-]+$/.test(value));
|
|
16
13
|
}
|
|
17
|
-
function extractEvents(index, checker, _config, evaluationCache, exportCache, resolvedCallCache, wrapperRegistry) {
|
|
14
|
+
function extractEvents(index, checker, _config, evaluationCache, exportCache, resolvedCallCache, returnPropagationCache, wrapperRegistry) {
|
|
18
15
|
const events = new Set();
|
|
19
|
-
//
|
|
20
16
|
// direct track sinks
|
|
21
|
-
//
|
|
22
17
|
for (const call of index.trackCalls) {
|
|
23
18
|
for (const argument of call.trackedArguments) {
|
|
24
|
-
const resolved = (0, resolver_1.resolveNodeValue)(argument, checker, (0, evaluationContext_1.createEvaluationContext)(), new Set(), evaluationCache, resolvedCallCache, exportCache);
|
|
19
|
+
const resolved = (0, resolver_1.resolveNodeValue)(argument, checker, (0, evaluationContext_1.createEvaluationContext)(), new Set(), evaluationCache, resolvedCallCache, returnPropagationCache, exportCache);
|
|
25
20
|
for (const value of resolved.values) {
|
|
26
21
|
if (isValidEvent(value)) {
|
|
27
22
|
events.add(value);
|
|
@@ -29,12 +24,10 @@ function extractEvents(index, checker, _config, evaluationCache, exportCache, re
|
|
|
29
24
|
}
|
|
30
25
|
}
|
|
31
26
|
}
|
|
32
|
-
|
|
33
|
-
// wrapper propagation
|
|
34
|
-
//
|
|
27
|
+
const propagationVisited = new Set();
|
|
35
28
|
function visit(node) {
|
|
36
29
|
if (typescript_1.default.isCallExpression(node)) {
|
|
37
|
-
(0, propagationExtractor_1.extractPropagationEvents)(node, checker, wrapperRegistry, resolvedCallCache, evaluationCache, exportCache, events,
|
|
30
|
+
(0, propagationExtractor_1.extractPropagationEvents)(node, checker, wrapperRegistry, resolvedCallCache, returnPropagationCache, evaluationCache, exportCache, events, propagationVisited);
|
|
38
31
|
}
|
|
39
32
|
typescript_1.default.forEachChild(node, visit);
|
|
40
33
|
}
|
|
@@ -42,6 +35,5 @@ function extractEvents(index, checker, _config, evaluationCache, exportCache, re
|
|
|
42
35
|
return {
|
|
43
36
|
events,
|
|
44
37
|
detectedFunctionWrappers: new Set(index.wrappers.map(wrapper => wrapper.symbol.getName())),
|
|
45
|
-
detectedComponentWrappers: new Map(),
|
|
46
38
|
};
|
|
47
39
|
}
|
|
@@ -1,21 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
3
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
6
|
exports.extractPropagationEvents = extractPropagationEvents;
|
|
7
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
5
8
|
const callResolver_1 = require("../resolver/callResolver");
|
|
6
9
|
const resolver_1 = require("../resolver/resolver");
|
|
7
10
|
const evaluationContext_1 = require("../shared/evaluationContext");
|
|
8
11
|
function isValidEvent(value) {
|
|
9
|
-
return (value.length > 0
|
|
10
|
-
&& value.length < 160
|
|
11
|
-
&& /^[a-zA-Z0-9:_./-]+$/.test(value));
|
|
12
|
+
return (value.length > 0 && value.length < 160 && /^[a-zA-Z0-9:_./-]+$/.test(value));
|
|
12
13
|
}
|
|
13
|
-
function
|
|
14
|
+
function resolveObjectPath(expression, path) {
|
|
15
|
+
let current = expression;
|
|
16
|
+
for (const segment of path) {
|
|
17
|
+
if (!typescript_1.default.isObjectLiteralExpression(current)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
let matched = null;
|
|
21
|
+
for (const property of current.properties) {
|
|
22
|
+
if (!typescript_1.default.isPropertyAssignment(property) && !typescript_1.default.isShorthandPropertyAssignment(property)) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const propertyName = typescript_1.default.isIdentifier(property.name) ? property.name.text : typescript_1.default.isStringLiteral(property.name) ? property.name.text : property.name.getText();
|
|
26
|
+
if (propertyName !== segment) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
matched = typescript_1.default.isShorthandPropertyAssignment(property) ? property.name : property.initializer;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
if (!matched) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
current = matched;
|
|
36
|
+
}
|
|
37
|
+
return current;
|
|
38
|
+
}
|
|
39
|
+
function extractPropagationEvents(call, checker, wrapperRegistry, resolvedCallCache, returnPropagationCache, evaluationCache, exportCache, events, visited) {
|
|
14
40
|
const resolved = (0, callResolver_1.resolveFunctionFromCall)(call.expression, checker, resolvedCallCache, exportCache);
|
|
15
41
|
if (!resolved) {
|
|
16
42
|
return;
|
|
17
43
|
}
|
|
18
|
-
const semantic = wrapperRegistry.get(resolved
|
|
44
|
+
const semantic = wrapperRegistry.get(resolved);
|
|
19
45
|
if (!semantic) {
|
|
20
46
|
return;
|
|
21
47
|
}
|
|
@@ -27,23 +53,38 @@ function extractPropagationEvents(call, checker, wrapperRegistry, resolvedCallCa
|
|
|
27
53
|
return;
|
|
28
54
|
}
|
|
29
55
|
visited.add(signature);
|
|
30
|
-
|
|
31
|
-
|
|
56
|
+
try {
|
|
57
|
+
for (const propagation of semantic.propagations) {
|
|
58
|
+
extractPropagation(propagation, call, checker, evaluationCache, resolvedCallCache, returnPropagationCache, exportCache, events);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
visited.delete(signature);
|
|
32
63
|
}
|
|
33
64
|
}
|
|
34
|
-
function extractPropagation(propagation, call, checker, evaluationCache, resolvedCallCache, exportCache, events) {
|
|
35
|
-
|
|
65
|
+
function extractPropagation(propagation, call, checker, evaluationCache, resolvedCallCache, returnPropagationCache, exportCache, events) {
|
|
66
|
+
let argument = call.arguments[propagation.sourceParameterIndex];
|
|
36
67
|
if (!argument) {
|
|
37
68
|
return;
|
|
38
69
|
}
|
|
70
|
+
// wrapper({
|
|
71
|
+
// nested: {
|
|
72
|
+
// event: "x"
|
|
73
|
+
// }
|
|
74
|
+
// })
|
|
75
|
+
if (propagation.propertyPath.length > 0) {
|
|
76
|
+
const resolvedPath = resolveObjectPath(argument, propagation.propertyPath);
|
|
77
|
+
if (!resolvedPath) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
argument = resolvedPath;
|
|
81
|
+
}
|
|
39
82
|
const context = (0, evaluationContext_1.createEvaluationContext)();
|
|
40
|
-
const parameterSymbol = checker.getSymbolAtLocation(propagation
|
|
41
|
-
.sourceParameter
|
|
42
|
-
.name);
|
|
83
|
+
const parameterSymbol = checker.getSymbolAtLocation(propagation.sourceParameter.name);
|
|
43
84
|
if (parameterSymbol) {
|
|
44
85
|
context.parameterBindings.set(parameterSymbol, argument);
|
|
45
86
|
}
|
|
46
|
-
const resolved = (0, resolver_1.resolveNodeValue)(propagation.targetNode, checker, context, new Set(), evaluationCache, resolvedCallCache, exportCache);
|
|
87
|
+
const resolved = (0, resolver_1.resolveNodeValue)(propagation.targetNode, checker, context, new Set(), evaluationCache, resolvedCallCache, returnPropagationCache, exportCache);
|
|
47
88
|
for (const value of resolved.values) {
|
|
48
89
|
if (isValidEvent(value)) {
|
|
49
90
|
events.add(value);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/analysis/resolver/callResolver.ts
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -8,59 +7,37 @@ exports.resolveFunctionFromCall = resolveFunctionFromCall;
|
|
|
8
7
|
const typescript_1 = __importDefault(require("typescript"));
|
|
9
8
|
const exportResolver_1 = require("./exportResolver");
|
|
10
9
|
function isFunctionLike(node) {
|
|
11
|
-
return (typescript_1.default.isFunctionDeclaration(node)
|
|
12
|
-
|| typescript_1.default.isMethodDeclaration(node)
|
|
13
|
-
|| typescript_1.default.isArrowFunction(node)
|
|
14
|
-
|| typescript_1.default.isFunctionExpression(node));
|
|
10
|
+
return (typescript_1.default.isFunctionDeclaration(node) || typescript_1.default.isMethodDeclaration(node) || typescript_1.default.isArrowFunction(node) || typescript_1.default.isFunctionExpression(node));
|
|
15
11
|
}
|
|
16
12
|
function resolveDeclaration(declaration) {
|
|
17
|
-
//
|
|
18
13
|
// function foo() {}
|
|
19
|
-
//
|
|
20
14
|
if (isFunctionLike(declaration)) {
|
|
21
15
|
return declaration;
|
|
22
16
|
}
|
|
23
|
-
//
|
|
24
17
|
// const foo = () => {}
|
|
25
|
-
|
|
26
|
-
if (typescript_1.default.isVariableDeclaration(declaration)
|
|
27
|
-
&& declaration.initializer
|
|
28
|
-
&& isFunctionLike(declaration.initializer)) {
|
|
18
|
+
if (typescript_1.default.isVariableDeclaration(declaration) && declaration.initializer && isFunctionLike(declaration.initializer)) {
|
|
29
19
|
return declaration.initializer;
|
|
30
20
|
}
|
|
31
|
-
//
|
|
32
21
|
// class field = () => {}
|
|
33
|
-
|
|
34
|
-
if (typescript_1.default.isPropertyDeclaration(declaration)
|
|
35
|
-
&& declaration.initializer
|
|
36
|
-
&& isFunctionLike(declaration.initializer)) {
|
|
22
|
+
if (typescript_1.default.isPropertyDeclaration(declaration) && declaration.initializer && isFunctionLike(declaration.initializer)) {
|
|
37
23
|
return declaration.initializer;
|
|
38
24
|
}
|
|
39
25
|
return null;
|
|
40
26
|
}
|
|
41
27
|
function getExpressionSymbol(expression, checker) {
|
|
42
|
-
//
|
|
43
28
|
// analytics.track()
|
|
44
|
-
//
|
|
45
29
|
if (typescript_1.default.isPropertyAccessExpression(expression)) {
|
|
46
30
|
return checker.getSymbolAtLocation(expression.name);
|
|
47
31
|
}
|
|
48
|
-
//
|
|
49
32
|
// analytics?.track()
|
|
50
|
-
//
|
|
51
33
|
if (typescript_1.default.isPropertyAccessChain(expression)) {
|
|
52
34
|
return checker.getSymbolAtLocation(expression.name);
|
|
53
35
|
}
|
|
54
|
-
//
|
|
55
36
|
// analytics["track"]()
|
|
56
|
-
|
|
57
|
-
if (typescript_1.default.isElementAccessExpression(expression)
|
|
58
|
-
&& expression.argumentExpression) {
|
|
37
|
+
if (typescript_1.default.isElementAccessExpression(expression) && expression.argumentExpression) {
|
|
59
38
|
return checker.getSymbolAtLocation(expression.argumentExpression);
|
|
60
39
|
}
|
|
61
|
-
//
|
|
62
40
|
// track()
|
|
63
|
-
//
|
|
64
41
|
return checker.getSymbolAtLocation(expression);
|
|
65
42
|
}
|
|
66
43
|
function resolveFunctionFromCall(expression, checker, callCache, exportCache) {
|
|
@@ -68,32 +45,19 @@ function resolveFunctionFromCall(expression, checker, callCache, exportCache) {
|
|
|
68
45
|
if (!symbol) {
|
|
69
46
|
return null;
|
|
70
47
|
}
|
|
71
|
-
//
|
|
72
48
|
// export unwrap
|
|
73
|
-
|
|
74
|
-
symbol =
|
|
75
|
-
(0, exportResolver_1.resolveExportedSymbol)(symbol, checker, exportCache)
|
|
76
|
-
?? symbol;
|
|
77
|
-
//
|
|
49
|
+
symbol = (0, exportResolver_1.resolveExportedSymbol)(symbol, checker, exportCache) ?? symbol;
|
|
78
50
|
// alias unwrap
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
& typescript_1.default.SymbolFlags.Alias) {
|
|
82
|
-
symbol =
|
|
83
|
-
checker.getAliasedSymbol(symbol);
|
|
51
|
+
if (symbol.flags & typescript_1.default.SymbolFlags.Alias) {
|
|
52
|
+
symbol = checker.getAliasedSymbol(symbol);
|
|
84
53
|
}
|
|
85
|
-
//
|
|
86
54
|
// cache
|
|
87
|
-
//
|
|
88
55
|
const cached = callCache.get(symbol);
|
|
89
56
|
if (cached !== undefined) {
|
|
90
57
|
return cached;
|
|
91
58
|
}
|
|
92
|
-
//
|
|
93
59
|
// declaration resolution
|
|
94
|
-
|
|
95
|
-
const declarations = symbol.getDeclarations()
|
|
96
|
-
?? [];
|
|
60
|
+
const declarations = symbol.getDeclarations() ?? [];
|
|
97
61
|
for (const declaration of declarations) {
|
|
98
62
|
const resolved = resolveDeclaration(declaration);
|
|
99
63
|
if (!resolved) {
|
|
@@ -102,24 +66,18 @@ function resolveFunctionFromCall(expression, checker, callCache, exportCache) {
|
|
|
102
66
|
callCache.set(symbol, resolved);
|
|
103
67
|
return resolved;
|
|
104
68
|
}
|
|
105
|
-
//
|
|
106
69
|
// fallback:
|
|
107
70
|
// type signatures
|
|
108
|
-
|
|
109
|
-
const type = checker.getTypeOfSymbolAtLocation(symbol, declarations[0]
|
|
110
|
-
?? expression);
|
|
71
|
+
const type = checker.getTypeOfSymbolAtLocation(symbol, declarations[0] ?? expression);
|
|
111
72
|
const signatures = checker.getSignaturesOfType(type, typescript_1.default.SignatureKind.Call);
|
|
112
73
|
for (const signature of signatures) {
|
|
113
74
|
const declaration = signature.declaration;
|
|
114
|
-
if (declaration
|
|
115
|
-
&& isFunctionLike(declaration)) {
|
|
75
|
+
if (declaration && isFunctionLike(declaration)) {
|
|
116
76
|
callCache.set(symbol, declaration);
|
|
117
77
|
return declaration;
|
|
118
78
|
}
|
|
119
79
|
}
|
|
120
|
-
//
|
|
121
80
|
// unresolved
|
|
122
|
-
//
|
|
123
81
|
callCache.set(symbol, null);
|
|
124
82
|
return null;
|
|
125
83
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// src/analysis/resolver/exportResolver.ts
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -17,54 +16,40 @@ function isConcreteDeclaration(node) {
|
|
|
17
16
|
|| typescript_1.default.isPropertyDeclaration(node));
|
|
18
17
|
}
|
|
19
18
|
function resolveExportedSymbol(symbol, checker, cache, visited) {
|
|
20
|
-
const seen = visited
|
|
21
|
-
?? new Set();
|
|
19
|
+
const seen = visited ?? new Set();
|
|
22
20
|
const cached = cache.get(symbol);
|
|
23
21
|
if (cached !== undefined) {
|
|
24
22
|
return cached;
|
|
25
23
|
}
|
|
26
|
-
//
|
|
27
24
|
// cycle guard
|
|
28
|
-
//
|
|
29
25
|
if (seen.has(symbol)) {
|
|
30
26
|
cache.set(symbol, null);
|
|
31
27
|
return null;
|
|
32
28
|
}
|
|
33
29
|
seen.add(symbol);
|
|
34
|
-
//
|
|
35
30
|
// alias unwrap
|
|
36
|
-
|
|
37
|
-
if (symbol.flags
|
|
38
|
-
& typescript_1.default.SymbolFlags.Alias) {
|
|
31
|
+
if (symbol.flags & typescript_1.default.SymbolFlags.Alias) {
|
|
39
32
|
const aliased = checker.getAliasedSymbol(symbol);
|
|
40
33
|
const resolved = resolveExportedSymbol(aliased, checker, cache, seen);
|
|
41
34
|
cache.set(symbol, resolved);
|
|
42
35
|
return resolved;
|
|
43
36
|
}
|
|
44
|
-
//
|
|
45
37
|
// export unwrap
|
|
46
|
-
//
|
|
47
38
|
const exportSymbol = checker.getExportSymbolOfSymbol(symbol);
|
|
48
|
-
if (exportSymbol
|
|
49
|
-
&& exportSymbol !== symbol) {
|
|
39
|
+
if (exportSymbol && exportSymbol !== symbol) {
|
|
50
40
|
const resolved = resolveExportedSymbol(exportSymbol, checker, cache, seen);
|
|
51
41
|
cache.set(symbol, resolved);
|
|
52
42
|
return resolved;
|
|
53
43
|
}
|
|
54
|
-
//
|
|
55
44
|
// declaration existence
|
|
56
|
-
|
|
57
|
-
const declarations = symbol.getDeclarations()
|
|
58
|
-
?? [];
|
|
45
|
+
const declarations = symbol.getDeclarations() ?? [];
|
|
59
46
|
for (const declaration of declarations) {
|
|
60
47
|
if (isConcreteDeclaration(declaration)) {
|
|
61
48
|
cache.set(symbol, symbol);
|
|
62
49
|
return symbol;
|
|
63
50
|
}
|
|
64
51
|
}
|
|
65
|
-
//
|
|
66
52
|
// final validation
|
|
67
|
-
//
|
|
68
53
|
const valid = declarations.some(isConcreteDeclaration);
|
|
69
54
|
if (valid) {
|
|
70
55
|
cache.set(symbol, symbol);
|