@komaci/static-analyzer 240.1.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/build/WireGraph.d.ts +34 -0
- package/build/WireGraph.js +82 -0
- package/build/__mocks__/@babel/parser.d.ts +2 -0
- package/build/__mocks__/@babel/parser.js +6 -0
- package/build/adaptersMapping.d.ts +3 -0
- package/build/adaptersMapping.js +25 -0
- package/build/allowlistAdapters.d.ts +6 -0
- package/build/allowlistAdapters.js +10 -0
- package/build/index.d.ts +7 -0
- package/build/index.js +35 -0
- package/build/invariantFunctions/assignmentExpressionInvariantFunctions.d.ts +16 -0
- package/build/invariantFunctions/assignmentExpressionInvariantFunctions.js +34 -0
- package/build/invariantFunctions/callExpressionInvariantFunctions.d.ts +33 -0
- package/build/invariantFunctions/callExpressionInvariantFunctions.js +87 -0
- package/build/invariantFunctions/functionExpressionInvariantFunctions.d.ts +31 -0
- package/build/invariantFunctions/functionExpressionInvariantFunctions.js +69 -0
- package/build/invariantFunctions/identifierInvariantFunctions.d.ts +28 -0
- package/build/invariantFunctions/identifierInvariantFunctions.js +56 -0
- package/build/invariantFunctions/memberExpressionInvariantFunctions.d.ts +50 -0
- package/build/invariantFunctions/memberExpressionInvariantFunctions.js +146 -0
- package/build/invariantFunctions/returnStatementInvariantFunctions.d.ts +12 -0
- package/build/invariantFunctions/returnStatementInvariantFunctions.js +23 -0
- package/build/invariantFunctions/taggedTemplateExpressionInvariantFunctions.d.ts +12 -0
- package/build/invariantFunctions/taggedTemplateExpressionInvariantFunctions.js +25 -0
- package/build/komaci-mapping.json +288 -0
- package/build/rules.d.ts +22 -0
- package/build/rules.js +310 -0
- package/build/shared.d.ts +52 -0
- package/build/shared.js +184 -0
- package/build/staticAnalyzer.d.ts +100 -0
- package/build/staticAnalyzer.js +822 -0
- package/build/types.d.ts +102 -0
- package/build/types.js +3 -0
- package/build/validateGetter.d.ts +46 -0
- package/build/validateGetter.js +154 -0
- package/package.json +39 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { WireInfo } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Class that represent a WireInfo graph of a wire dependencies. This data structure is needed to detect dependency cycles,
|
|
4
|
+
* so that they can be reported to the user as a PrimingDiagnostic
|
|
5
|
+
*/
|
|
6
|
+
export declare class WireGraph {
|
|
7
|
+
private vertices;
|
|
8
|
+
private wireWithCycle;
|
|
9
|
+
private cycleVertices;
|
|
10
|
+
constructor(vertices?: Array<WireInfo>);
|
|
11
|
+
/**
|
|
12
|
+
* Detects a cycle in the directed WireGraph, even if it is disconnected graph (we can't reach all nodes from any one node)
|
|
13
|
+
* @returns true if cycle is detected in this directed WireGraph, false otherwise
|
|
14
|
+
*/
|
|
15
|
+
hasCycle(): boolean;
|
|
16
|
+
private hasCycleInternal;
|
|
17
|
+
/**
|
|
18
|
+
* Gets the wire whose child results in a cycle in the graph.
|
|
19
|
+
* @returns WireInfo if a cycle was detected, undefined otherwise
|
|
20
|
+
*/
|
|
21
|
+
getWireThatCycles(): WireInfo | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Returns the top of the "stack" which has the first dependency in the dependency chain
|
|
24
|
+
* @returns name of the property that starts the dependency chain, which we can include in the error message,
|
|
25
|
+
* or blank string if the stack if empty (no cycle found)
|
|
26
|
+
*/
|
|
27
|
+
getWireCycleProperty(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Returns the dependency chain as a string
|
|
30
|
+
* @returns string representing the wire configuration dependency chain
|
|
31
|
+
*/
|
|
32
|
+
getWireCycleString(): string;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=WireGraph.d.ts.map
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WireGraph = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Class that represent a WireInfo graph of a wire dependencies. This data structure is needed to detect dependency cycles,
|
|
6
|
+
* so that they can be reported to the user as a PrimingDiagnostic
|
|
7
|
+
*/
|
|
8
|
+
class WireGraph {
|
|
9
|
+
constructor(vertices = []) {
|
|
10
|
+
this.cycleVertices = [];
|
|
11
|
+
this.vertices = vertices;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Detects a cycle in the directed WireGraph, even if it is disconnected graph (we can't reach all nodes from any one node)
|
|
15
|
+
* @returns true if cycle is detected in this directed WireGraph, false otherwise
|
|
16
|
+
*/
|
|
17
|
+
hasCycle() {
|
|
18
|
+
for (const vertex of this.vertices) {
|
|
19
|
+
if (!vertex.visited && this.hasCycleInternal(vertex)) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
this.wireWithCycle = undefined;
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
hasCycleInternal(sourceWire) {
|
|
27
|
+
sourceWire.beingVisited = true;
|
|
28
|
+
for (const wire of sourceWire.dependentWires) {
|
|
29
|
+
if (wire.beingVisited) {
|
|
30
|
+
this.wireWithCycle = wire; // track wire whose child resulted in a cycle detection
|
|
31
|
+
if (wire.propName) {
|
|
32
|
+
this.cycleVertices.push(wire.propName); // track traversal so we can print out dependency chain later
|
|
33
|
+
}
|
|
34
|
+
return true; // backward edge exists, cycle detected (base case, return from recursive calls)
|
|
35
|
+
}
|
|
36
|
+
else if (!wire.visited && this.hasCycleInternal(wire)) {
|
|
37
|
+
// DFS recursion of child
|
|
38
|
+
if (wire.propName) {
|
|
39
|
+
this.cycleVertices.push(wire.propName); // track traversal so we can print out dependency chain later
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
sourceWire.beingVisited = false;
|
|
45
|
+
sourceWire.visited = true;
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Gets the wire whose child results in a cycle in the graph.
|
|
50
|
+
* @returns WireInfo if a cycle was detected, undefined otherwise
|
|
51
|
+
*/
|
|
52
|
+
getWireThatCycles() {
|
|
53
|
+
return this.wireWithCycle;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Returns the top of the "stack" which has the first dependency in the dependency chain
|
|
57
|
+
* @returns name of the property that starts the dependency chain, which we can include in the error message,
|
|
58
|
+
* or blank string if the stack if empty (no cycle found)
|
|
59
|
+
*/
|
|
60
|
+
getWireCycleProperty() {
|
|
61
|
+
return this.cycleVertices.length > 0
|
|
62
|
+
? this.cycleVertices[this.cycleVertices.length - 1]
|
|
63
|
+
: '';
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns the dependency chain as a string
|
|
67
|
+
* @returns string representing the wire configuration dependency chain
|
|
68
|
+
*/
|
|
69
|
+
getWireCycleString() {
|
|
70
|
+
let wireCycleString = '';
|
|
71
|
+
const lastIndex = this.cycleVertices.length - 1;
|
|
72
|
+
for (let index = lastIndex; index >= 0; index -= 1) {
|
|
73
|
+
wireCycleString += this.cycleVertices[index] + '->';
|
|
74
|
+
if (index == 0) {
|
|
75
|
+
wireCycleString += this.cycleVertices[lastIndex];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return wireCycleString;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.WireGraph = WireGraph;
|
|
82
|
+
//# sourceMappingURL=WireGraph.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.wireAdaptersMap = void 0;
|
|
23
|
+
const wireAdapterImport = __importStar(require("./komaci-mapping.json"));
|
|
24
|
+
exports.wireAdaptersMap = wireAdapterImport;
|
|
25
|
+
//# sourceMappingURL=adaptersMapping.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.allowlistResourceNamesExact = exports.allowlistResourceNamesStartsWith = exports.allowlistAdapters = void 0;
|
|
4
|
+
exports.allowlistAdapters = {
|
|
5
|
+
'lightning/navigation': ['CurrentPageReference'],
|
|
6
|
+
}; // these must match the resourceName and one or more of the wire adapter names (export names), exactly
|
|
7
|
+
// these can have any wire adapter name (export name)
|
|
8
|
+
exports.allowlistResourceNamesStartsWith = ['@salesforce/apex']; // resourceName can start with
|
|
9
|
+
exports.allowlistResourceNamesExact = ['laf/transformWire']; // resourceName must exactly match this
|
|
10
|
+
//# sourceMappingURL=allowlistAdapters.js.map
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AnalyzerInput, PrimingDiagnostic } from './types';
|
|
2
|
+
export declare function generatePrimingDiagnosticsModule(input: AnalyzerInput): PrimingDiagnostic[];
|
|
3
|
+
export { AnalyzerInput, PrimingDiagnostic, Range, Position, PrimingAdapterDefinition, } from './types';
|
|
4
|
+
export { getPrimingAdapter, isSupportedNamespace, isSupportedWireAdapter, isImageComposition, } from './shared';
|
|
5
|
+
export { diagnosticMessages, getPrimingDiagnostic } from './rules';
|
|
6
|
+
export * from './validateGetter';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
package/build/index.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.getPrimingDiagnostic = exports.diagnosticMessages = exports.isImageComposition = exports.isSupportedWireAdapter = exports.isSupportedNamespace = exports.getPrimingAdapter = exports.generatePrimingDiagnosticsModule = void 0;
|
|
14
|
+
const staticAnalyzer_1 = require("./staticAnalyzer");
|
|
15
|
+
function generatePrimingDiagnosticsModule(input) {
|
|
16
|
+
const analyzer = new staticAnalyzer_1.StaticAnalyzer();
|
|
17
|
+
if (input.type === 'bundle') {
|
|
18
|
+
return analyzer.analyzeBundle(input);
|
|
19
|
+
}
|
|
20
|
+
if (input.type === 'file') {
|
|
21
|
+
return analyzer.analyzeScript(input);
|
|
22
|
+
}
|
|
23
|
+
throw new Error('input type was neither file or bundle');
|
|
24
|
+
}
|
|
25
|
+
exports.generatePrimingDiagnosticsModule = generatePrimingDiagnosticsModule;
|
|
26
|
+
var shared_1 = require("./shared");
|
|
27
|
+
Object.defineProperty(exports, "getPrimingAdapter", { enumerable: true, get: function () { return shared_1.getPrimingAdapter; } });
|
|
28
|
+
Object.defineProperty(exports, "isSupportedNamespace", { enumerable: true, get: function () { return shared_1.isSupportedNamespace; } });
|
|
29
|
+
Object.defineProperty(exports, "isSupportedWireAdapter", { enumerable: true, get: function () { return shared_1.isSupportedWireAdapter; } });
|
|
30
|
+
Object.defineProperty(exports, "isImageComposition", { enumerable: true, get: function () { return shared_1.isImageComposition; } });
|
|
31
|
+
var rules_1 = require("./rules");
|
|
32
|
+
Object.defineProperty(exports, "diagnosticMessages", { enumerable: true, get: function () { return rules_1.diagnosticMessages; } });
|
|
33
|
+
Object.defineProperty(exports, "getPrimingDiagnostic", { enumerable: true, get: function () { return rules_1.getPrimingDiagnostic; } });
|
|
34
|
+
__exportStar(require("./validateGetter"), exports);
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { NodePath } from '@babel/traverse';
|
|
2
|
+
import * as t from '@babel/types';
|
|
3
|
+
import { PrimingDiagnostic } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Invariant function for checking if a member variable get a value assigned to it.
|
|
6
|
+
* @param path the babel path object for the current Assignment Expressoin.
|
|
7
|
+
* @returns undefined if NO member variable is assigned a value, location object if a member variable is assigned a value.
|
|
8
|
+
*/
|
|
9
|
+
export declare function checkForNoMemberVariableAssignments(path: NodePath<t.AssignmentExpression>): PrimingDiagnostic | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Function to check external components for an Assignment Expression.
|
|
12
|
+
* @param path the node path for an assignemnt expression
|
|
13
|
+
* @returns a PrimingDiagnostic if there is an Assignment Expression, undefined if not.
|
|
14
|
+
*/
|
|
15
|
+
export declare function checkExternalComponentForAssignmentExpr(path: NodePath<t.AssignmentExpression>): PrimingDiagnostic | undefined;
|
|
16
|
+
//# sourceMappingURL=assignmentExpressionInvariantFunctions.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkExternalComponentForAssignmentExpr = exports.checkForNoMemberVariableAssignments = void 0;
|
|
4
|
+
const rules_1 = require("../rules");
|
|
5
|
+
const shared_1 = require("../shared");
|
|
6
|
+
/**
|
|
7
|
+
* Invariant function for checking if a member variable get a value assigned to it.
|
|
8
|
+
* @param path the babel path object for the current Assignment Expressoin.
|
|
9
|
+
* @returns undefined if NO member variable is assigned a value, location object if a member variable is assigned a value.
|
|
10
|
+
*/
|
|
11
|
+
function checkForNoMemberVariableAssignments(path) {
|
|
12
|
+
const assignmentExpr = path.node;
|
|
13
|
+
const leftNode = assignmentExpr.left;
|
|
14
|
+
if (leftNode.object?.type === 'ThisExpression') {
|
|
15
|
+
if (leftNode.loc !== null) {
|
|
16
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_ASSIGNMENT_EXPRESSION_ASSIGNS_VALUE_TO_MEMBER_VARIABLE, shared_1.LLSRange.fromBabelSourceLocation(leftNode.loc), [leftNode.property.name]);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
exports.checkForNoMemberVariableAssignments = checkForNoMemberVariableAssignments;
|
|
22
|
+
/**
|
|
23
|
+
* Function to check external components for an Assignment Expression.
|
|
24
|
+
* @param path the node path for an assignemnt expression
|
|
25
|
+
* @returns a PrimingDiagnostic if there is an Assignment Expression, undefined if not.
|
|
26
|
+
*/
|
|
27
|
+
function checkExternalComponentForAssignmentExpr(path) {
|
|
28
|
+
const assignmentExpr = path.node;
|
|
29
|
+
if (assignmentExpr.loc !== null) {
|
|
30
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_ASSIGNMENT_EXPRESSION_FOR_EXTERNAL_COMPONENTS, shared_1.LLSRange.fromBabelSourceLocation(assignmentExpr.loc), []);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.checkExternalComponentForAssignmentExpr = checkExternalComponentForAssignmentExpr;
|
|
34
|
+
//# sourceMappingURL=assignmentExpressionInvariantFunctions.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { NodePath } from '@babel/traverse';
|
|
2
|
+
import * as t from '@babel/types';
|
|
3
|
+
import { PrimingDiagnostic } from '../types';
|
|
4
|
+
import { ImportDeclarationInfo } from '@komaci/common-shared';
|
|
5
|
+
/**
|
|
6
|
+
* Invariant function for checking if call expressions references an unsupported import.
|
|
7
|
+
* @param path the babel path object for the current call expression.
|
|
8
|
+
* @param importReferences a set of supported import references.
|
|
9
|
+
* @returns undefined if a call expression does NOT reference an unspoorted import, locatoin object if a call expression references an unsupported import.
|
|
10
|
+
*/
|
|
11
|
+
export declare function checkCallExpressionForNonSupportedNamespaceRefs(path: NodePath<t.CallExpression>, importReferences: Map<string, ImportDeclarationInfo>): PrimingDiagnostic | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Validates whether a CallExpression Node on the AST adheres to a portability invariant (whether it doesn't
|
|
14
|
+
* contain 'eval()' call).
|
|
15
|
+
* @param path NodePath<CallExpression> containing a CallExpression to analyze for the invariant
|
|
16
|
+
* @returns PrimingDiagnostic of the CallExpression if an invariant is detected, or undefined if none was found
|
|
17
|
+
*/
|
|
18
|
+
export declare function checkNoUsageOfEval(path: NodePath<t.CallExpression>): PrimingDiagnostic | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Function that checks if there are any references to other functions that are defined on the class.
|
|
21
|
+
* @param path the current call expression node.
|
|
22
|
+
* @param classFunctions a collection of function names that are defined on the class.
|
|
23
|
+
* @returns {PrimingDiagnostic} a PrimingDiagnostic if there is a reference to another class function, undefined if no reference.
|
|
24
|
+
*/
|
|
25
|
+
export declare function checkForNoReferenceToClassFunctions(path: NodePath<t.CallExpression>, classFunctions: string[]): PrimingDiagnostic | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Function that checks if there are any references to other functions that are defined on the module.
|
|
28
|
+
* @param path the current call expression node.
|
|
29
|
+
* @param classFunctions a collection of function names that are defined on the module.
|
|
30
|
+
* @returns PrimingDiagnostic object if there is a reference to another module function, undefined if no reference.
|
|
31
|
+
*/
|
|
32
|
+
export declare function checkForNoReferenceToModuleFunctions(path: NodePath<t.CallExpression>, moduleFunctions: string[]): PrimingDiagnostic | undefined;
|
|
33
|
+
//# sourceMappingURL=callExpressionInvariantFunctions.d.ts.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkForNoReferenceToModuleFunctions = exports.checkForNoReferenceToClassFunctions = exports.checkNoUsageOfEval = exports.checkCallExpressionForNonSupportedNamespaceRefs = void 0;
|
|
4
|
+
const shared_1 = require("../shared");
|
|
5
|
+
const rules_1 = require("../rules");
|
|
6
|
+
/**
|
|
7
|
+
* Invariant function for checking if call expressions references an unsupported import.
|
|
8
|
+
* @param path the babel path object for the current call expression.
|
|
9
|
+
* @param importReferences a set of supported import references.
|
|
10
|
+
* @returns undefined if a call expression does NOT reference an unspoorted import, locatoin object if a call expression references an unsupported import.
|
|
11
|
+
*/
|
|
12
|
+
function checkCallExpressionForNonSupportedNamespaceRefs(path, importReferences) {
|
|
13
|
+
const callExprNode = path.node;
|
|
14
|
+
const callee = callExprNode.callee;
|
|
15
|
+
if (importReferences.get(callee.name)) {
|
|
16
|
+
if (!importReferences.get(callee.name)?.isSupported) {
|
|
17
|
+
if (callee.loc != null) {
|
|
18
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_CALL_EXPRESSION_REFERENCES_UNSUPPORTED_NAMESPACE, shared_1.LLSRange.fromBabelSourceLocation(callee.loc), [callee.name]);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
exports.checkCallExpressionForNonSupportedNamespaceRefs = checkCallExpressionForNonSupportedNamespaceRefs;
|
|
25
|
+
/**
|
|
26
|
+
* Validates whether a CallExpression Node on the AST adheres to a portability invariant (whether it doesn't
|
|
27
|
+
* contain 'eval()' call).
|
|
28
|
+
* @param path NodePath<CallExpression> containing a CallExpression to analyze for the invariant
|
|
29
|
+
* @returns PrimingDiagnostic of the CallExpression if an invariant is detected, or undefined if none was found
|
|
30
|
+
*/
|
|
31
|
+
function checkNoUsageOfEval(path) {
|
|
32
|
+
const callExpr = path.node;
|
|
33
|
+
if (callExpr.callee.type === 'Identifier' && callExpr.callee.name === 'eval') {
|
|
34
|
+
if (callExpr.callee.loc !== null) {
|
|
35
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_EVAL_USAGE, shared_1.LLSRange.fromBabelSourceLocation(callExpr.callee.loc), [callExpr.callee.name]);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
exports.checkNoUsageOfEval = checkNoUsageOfEval;
|
|
41
|
+
/**
|
|
42
|
+
* Function that checks if there are any references to other functions that are defined on the class.
|
|
43
|
+
* @param path the current call expression node.
|
|
44
|
+
* @param classFunctions a collection of function names that are defined on the class.
|
|
45
|
+
* @returns {PrimingDiagnostic} a PrimingDiagnostic if there is a reference to another class function, undefined if no reference.
|
|
46
|
+
*/
|
|
47
|
+
function checkForNoReferenceToClassFunctions(path, classFunctions) {
|
|
48
|
+
const callExpr = path.node;
|
|
49
|
+
if (callExpr.callee.type === 'MemberExpression') {
|
|
50
|
+
const memberExpr = callExpr.callee;
|
|
51
|
+
if (memberExpr.object.type === 'ThisExpression') {
|
|
52
|
+
if (memberExpr.object.loc !== null) {
|
|
53
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_REFERENCE_TO_CLASS_FUNCTIONS, shared_1.LLSRange.fromBabelSourceLocation(memberExpr.object.loc), [memberExpr.property.name]);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (callExpr.callee.type === 'Identifier') {
|
|
58
|
+
const identifier = callExpr.callee;
|
|
59
|
+
if (classFunctions.includes(identifier.name)) {
|
|
60
|
+
if (callExpr.callee.loc !== null) {
|
|
61
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_REFERENCE_TO_CLASS_FUNCTIONS, shared_1.LLSRange.fromBabelSourceLocation(callExpr.callee.loc), [callExpr.callee.name]);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
exports.checkForNoReferenceToClassFunctions = checkForNoReferenceToClassFunctions;
|
|
68
|
+
/**
|
|
69
|
+
* Function that checks if there are any references to other functions that are defined on the module.
|
|
70
|
+
* @param path the current call expression node.
|
|
71
|
+
* @param classFunctions a collection of function names that are defined on the module.
|
|
72
|
+
* @returns PrimingDiagnostic object if there is a reference to another module function, undefined if no reference.
|
|
73
|
+
*/
|
|
74
|
+
function checkForNoReferenceToModuleFunctions(path, moduleFunctions) {
|
|
75
|
+
const callExpr = path.node;
|
|
76
|
+
if (callExpr.callee.type === 'Identifier') {
|
|
77
|
+
const identifier = callExpr.callee;
|
|
78
|
+
if (moduleFunctions.includes(identifier.name)) {
|
|
79
|
+
if (callExpr.callee.loc !== null) {
|
|
80
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_REFERENCE_TO_MODULE_FUNCTIONS, shared_1.LLSRange.fromBabelSourceLocation(callExpr.callee.loc), [callExpr.callee.name]);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
exports.checkForNoReferenceToModuleFunctions = checkForNoReferenceToModuleFunctions;
|
|
87
|
+
//# sourceMappingURL=callExpressionInvariantFunctions.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { NodePath } from '@babel/traverse';
|
|
2
|
+
import * as t from '@babel/types';
|
|
3
|
+
import { ModuleContext } from '@komaci/common-shared';
|
|
4
|
+
import { PrimingDiagnostic } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* Checks whether a getter contains an unnamed function declaration (anonymous FunctionExpression or ArrowFunctionExpression),
|
|
7
|
+
* as well named FunctionExpression, NodePaths in the AST. None of these are allowed for external components.
|
|
8
|
+
* @param {NodePath<t.FunctionExpression> | NodePath<t.ArrowFunctionExpression>} path NodePath containing a
|
|
9
|
+
* {FunctionExpression | ArrowFunctionExpression} to analyze
|
|
10
|
+
* @returns PrimingDiagnostic of the FunctionExpression or ArrowFunctionExpression if the invariant is detected, or
|
|
11
|
+
* undefined if none was found
|
|
12
|
+
*/
|
|
13
|
+
export declare function checkForFunctionExpression(path: NodePath<t.FunctionExpression> | NodePath<t.ArrowFunctionExpression>): PrimingDiagnostic | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Checks for the presence of an Anonymous Function Expression or ArrowFunctionExpression in the context of an external component
|
|
16
|
+
* (where it is not allowed).
|
|
17
|
+
* @param {ModuelContext} moduleContext which can tell if we are in the context of an external component or not
|
|
18
|
+
* @param {NodePath<t.FunctionExpression> | NodePath<t.ArrowFunctionExpression>} path the NodePath of the FunctionExpression or
|
|
19
|
+
* ArrowFunctionExpression to be evaluated
|
|
20
|
+
* @returns PrimingDiagnostic if anonymous function expression is found in the context of an external component, or undefined if none was found
|
|
21
|
+
* or if one was detected within the context of an internal component
|
|
22
|
+
*/
|
|
23
|
+
export declare function checkForFunctionExpressionIfExternalComponent(moduleContext: ModuleContext, path: NodePath<t.FunctionExpression> | NodePath<t.ArrowFunctionExpression>): PrimingDiagnostic | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Checks whether a getter contains an named function declaration NodePath (as an ObjectMethod) on the AST
|
|
26
|
+
* @param {ModuelContext} moduleContext which can tell if we are in the context of an external component or not
|
|
27
|
+
* @param {NodePath<ObjectMethod>} path NodePath containing a {ObjectMethod} to analyze
|
|
28
|
+
* @returns PrimingDiagnostic of the first ObjectMethod invariant encountered is detected, or undefined if none was found
|
|
29
|
+
*/
|
|
30
|
+
export declare function checkForObjectMethodFunctionDeclarations(moduleContext: ModuleContext, path: NodePath<t.ObjectMethod>): PrimingDiagnostic | undefined;
|
|
31
|
+
//# sourceMappingURL=functionExpressionInvariantFunctions.d.ts.map
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkForObjectMethodFunctionDeclarations = exports.checkForFunctionExpressionIfExternalComponent = exports.checkForFunctionExpression = void 0;
|
|
4
|
+
const shared_1 = require("../shared");
|
|
5
|
+
const rules_1 = require("../rules");
|
|
6
|
+
/**
|
|
7
|
+
* Checks whether a getter contains an unnamed function declaration (anonymous FunctionExpression or ArrowFunctionExpression),
|
|
8
|
+
* as well named FunctionExpression, NodePaths in the AST. None of these are allowed for external components.
|
|
9
|
+
* @param {NodePath<t.FunctionExpression> | NodePath<t.ArrowFunctionExpression>} path NodePath containing a
|
|
10
|
+
* {FunctionExpression | ArrowFunctionExpression} to analyze
|
|
11
|
+
* @returns PrimingDiagnostic of the FunctionExpression or ArrowFunctionExpression if the invariant is detected, or
|
|
12
|
+
* undefined if none was found
|
|
13
|
+
*/
|
|
14
|
+
function checkForFunctionExpression(path) {
|
|
15
|
+
const expr = path.node;
|
|
16
|
+
if (expr.type === 'FunctionExpression') {
|
|
17
|
+
const funcExpr = expr;
|
|
18
|
+
if (funcExpr.id === null) {
|
|
19
|
+
if (funcExpr.loc !== null) {
|
|
20
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_FUNCTIONS_DECLARED_WITHIN_GETTER_METHOD, shared_1.LLSRange.fromBabelSourceLocation(funcExpr.loc), []);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
if (funcExpr.loc !== null) {
|
|
25
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_FUNCTIONS_DECLARED_WITHIN_GETTER_METHOD, shared_1.LLSRange.fromBabelSourceLocation(funcExpr.loc), []);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else if (expr.type === 'ArrowFunctionExpression') {
|
|
30
|
+
const arrowFuncExpr = expr;
|
|
31
|
+
if (arrowFuncExpr.loc !== null) {
|
|
32
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_FUNCTIONS_DECLARED_WITHIN_GETTER_METHOD, shared_1.LLSRange.fromBabelSourceLocation(arrowFuncExpr.loc), []);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
exports.checkForFunctionExpression = checkForFunctionExpression;
|
|
38
|
+
/**
|
|
39
|
+
* Checks for the presence of an Anonymous Function Expression or ArrowFunctionExpression in the context of an external component
|
|
40
|
+
* (where it is not allowed).
|
|
41
|
+
* @param {ModuelContext} moduleContext which can tell if we are in the context of an external component or not
|
|
42
|
+
* @param {NodePath<t.FunctionExpression> | NodePath<t.ArrowFunctionExpression>} path the NodePath of the FunctionExpression or
|
|
43
|
+
* ArrowFunctionExpression to be evaluated
|
|
44
|
+
* @returns PrimingDiagnostic if anonymous function expression is found in the context of an external component, or undefined if none was found
|
|
45
|
+
* or if one was detected within the context of an internal component
|
|
46
|
+
*/
|
|
47
|
+
function checkForFunctionExpressionIfExternalComponent(moduleContext, path) {
|
|
48
|
+
return moduleContext.isExternal ? checkForFunctionExpression(path) : undefined;
|
|
49
|
+
}
|
|
50
|
+
exports.checkForFunctionExpressionIfExternalComponent = checkForFunctionExpressionIfExternalComponent;
|
|
51
|
+
/**
|
|
52
|
+
* Checks whether a getter contains an named function declaration NodePath (as an ObjectMethod) on the AST
|
|
53
|
+
* @param {ModuelContext} moduleContext which can tell if we are in the context of an external component or not
|
|
54
|
+
* @param {NodePath<ObjectMethod>} path NodePath containing a {ObjectMethod} to analyze
|
|
55
|
+
* @returns PrimingDiagnostic of the first ObjectMethod invariant encountered is detected, or undefined if none was found
|
|
56
|
+
*/
|
|
57
|
+
function checkForObjectMethodFunctionDeclarations(moduleContext, path) {
|
|
58
|
+
const objMethod = path.node;
|
|
59
|
+
if (moduleContext.isExternal) {
|
|
60
|
+
if (objMethod.type === 'ObjectMethod') {
|
|
61
|
+
if (objMethod.loc !== null) {
|
|
62
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_FUNCTIONS_DECLARED_WITHIN_GETTER_METHOD, shared_1.LLSRange.fromBabelSourceLocation(objMethod.loc), []);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
exports.checkForObjectMethodFunctionDeclarations = checkForObjectMethodFunctionDeclarations;
|
|
69
|
+
//# sourceMappingURL=functionExpressionInvariantFunctions.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { NodePath } from '@babel/traverse';
|
|
2
|
+
import * as t from '@babel/types';
|
|
3
|
+
import { ImportDeclarationInfo } from '@komaci/common-shared';
|
|
4
|
+
import { PrimingDiagnostic } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* Invariant function to check for no references to module varaibles.
|
|
7
|
+
* @param path the babel path for the identifier.
|
|
8
|
+
* @param moduleVars a collection of module variables.
|
|
9
|
+
* @param classVariables a collection of variables defined within the a getter.
|
|
10
|
+
* @returns a locatoin object if there are references to a module variable, undefined if not.
|
|
11
|
+
*/
|
|
12
|
+
export declare function checkForNoReferenceToModuleVariables(path: NodePath<t.Identifier>, moduleVars: string[], classVariables: string[]): PrimingDiagnostic | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Invariant function to check if an identifier references an unsupported import.
|
|
15
|
+
*
|
|
16
|
+
* We ignore identifiers in specific usecases for this check predominantly bc of situational awareness:
|
|
17
|
+
* - Decorator parent: out of scope for this check
|
|
18
|
+
* - This Expression Parent: this.anything will never be an import ref
|
|
19
|
+
* - MemberExpression, CallExpression, TaggedTemplateExpression: similar checks done by other invariants so don't have to do them here.
|
|
20
|
+
*
|
|
21
|
+
* @param path the babel path object for the current member expression
|
|
22
|
+
* @param supportedImportRefs a set of supported import references.
|
|
23
|
+
* @param declaredVariables list of variables declared in the function to manage scoping collisions
|
|
24
|
+
* @returns undefined if a member expression does NOT reference an unsuppoerted import, PrimingDiagnostic object
|
|
25
|
+
* if an unsupported import is reference.
|
|
26
|
+
*/
|
|
27
|
+
export declare function checkIdentifierForNonSupportedNamespaceRefs(path: NodePath<t.Identifier>, importReferences: Map<string, ImportDeclarationInfo>, declaredVariables: string[]): PrimingDiagnostic | undefined;
|
|
28
|
+
//# sourceMappingURL=identifierInvariantFunctions.d.ts.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkIdentifierForNonSupportedNamespaceRefs = exports.checkForNoReferenceToModuleVariables = void 0;
|
|
4
|
+
const rules_1 = require("../rules");
|
|
5
|
+
const shared_1 = require("../shared");
|
|
6
|
+
/**
|
|
7
|
+
* Invariant function to check for no references to module varaibles.
|
|
8
|
+
* @param path the babel path for the identifier.
|
|
9
|
+
* @param moduleVars a collection of module variables.
|
|
10
|
+
* @param classVariables a collection of variables defined within the a getter.
|
|
11
|
+
* @returns a locatoin object if there are references to a module variable, undefined if not.
|
|
12
|
+
*/
|
|
13
|
+
function checkForNoReferenceToModuleVariables(path, moduleVars, classVariables) {
|
|
14
|
+
const identifier = path.node;
|
|
15
|
+
if (moduleVars.includes(identifier.name)) {
|
|
16
|
+
if (!classVariables.includes(identifier.name)) {
|
|
17
|
+
if (identifier.loc != null) {
|
|
18
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_EXPRESSION_CONTAINS_MODULE_LEVEL_VARIABLE_REF, shared_1.LLSRange.fromBabelSourceLocation(identifier.loc), [identifier.name]);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
exports.checkForNoReferenceToModuleVariables = checkForNoReferenceToModuleVariables;
|
|
25
|
+
/**
|
|
26
|
+
* Invariant function to check if an identifier references an unsupported import.
|
|
27
|
+
*
|
|
28
|
+
* We ignore identifiers in specific usecases for this check predominantly bc of situational awareness:
|
|
29
|
+
* - Decorator parent: out of scope for this check
|
|
30
|
+
* - This Expression Parent: this.anything will never be an import ref
|
|
31
|
+
* - MemberExpression, CallExpression, TaggedTemplateExpression: similar checks done by other invariants so don't have to do them here.
|
|
32
|
+
*
|
|
33
|
+
* @param path the babel path object for the current member expression
|
|
34
|
+
* @param supportedImportRefs a set of supported import references.
|
|
35
|
+
* @param declaredVariables list of variables declared in the function to manage scoping collisions
|
|
36
|
+
* @returns undefined if a member expression does NOT reference an unsuppoerted import, PrimingDiagnostic object
|
|
37
|
+
* if an unsupported import is reference.
|
|
38
|
+
*/
|
|
39
|
+
function checkIdentifierForNonSupportedNamespaceRefs(path, importReferences, declaredVariables) {
|
|
40
|
+
const identifier = path.node;
|
|
41
|
+
if (path.parent.type !== 'Decorator' &&
|
|
42
|
+
path.parent.type !== 'MemberExpression' &&
|
|
43
|
+
path.parent.type !== 'CallExpression' &&
|
|
44
|
+
path.parent.type !== 'TaggedTemplateExpression' &&
|
|
45
|
+
path.parent.type !== 'ThisExpression' &&
|
|
46
|
+
importReferences.get(identifier.name) &&
|
|
47
|
+
!importReferences.get(identifier.name)?.isSupported &&
|
|
48
|
+
!declaredVariables.includes(identifier.name)) {
|
|
49
|
+
if (identifier.loc !== null) {
|
|
50
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_REFERENCE_TO_UNSUPPORTED_NAMESPACE_REFERENCE, shared_1.LLSRange.fromBabelSourceLocation(identifier.loc), [identifier.name]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
exports.checkIdentifierForNonSupportedNamespaceRefs = checkIdentifierForNonSupportedNamespaceRefs;
|
|
56
|
+
//# sourceMappingURL=identifierInvariantFunctions.js.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { NodePath } from '@babel/traverse';
|
|
2
|
+
import * as t from '@babel/types';
|
|
3
|
+
import { PrimingDiagnostic } from '../types';
|
|
4
|
+
import { ClassPropertyInfo, ImportDeclarationInfo, AstContext } from '@komaci/common-shared';
|
|
5
|
+
/**
|
|
6
|
+
* Invariant function for checking if a member expression references a non decorated member var.
|
|
7
|
+
* @param path the babel path object for the current member expressoin
|
|
8
|
+
* @param memberVars a set of approved member variable names.
|
|
9
|
+
* @returns undefined if the member expression does NOT reference an unsupported member var, PrimingDiagnostic object if an unsuppported
|
|
10
|
+
* member variable is referenced
|
|
11
|
+
*/
|
|
12
|
+
export declare function checkForNonSupportedMemberRefs(path: NodePath<t.MemberExpression>, memberVars: ClassPropertyInfo[]): PrimingDiagnostic | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Invariant function for checking if a member expression references a non-existent member property variable
|
|
15
|
+
* @param {NodePath<MemberExpression>} path babel/types path object representing the current member expression
|
|
16
|
+
* @param {string[]} memberVars an string[] of member variable names
|
|
17
|
+
* @param {Set<string>} thisAliases a Set of the aliases of `this` used. ex: in `let that = this;`, `that` would be an alias.
|
|
18
|
+
* @returns {(PrimingDiagnostic | undefined)} undefined if the member expression does NOT reference a non-existent member property variable. Returns a
|
|
19
|
+
* PrimingDiagnostic object if a non-existent member property variable is referenced
|
|
20
|
+
*/
|
|
21
|
+
export declare function checkForNonExistentMemberRefs(path: NodePath<t.MemberExpression>, memberVars: ClassPropertyInfo[], thisAliases: Set<string>): PrimingDiagnostic | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Invariant function to check if a member expression references an unsupported import.
|
|
24
|
+
* @param path the babel path object for the current member expression
|
|
25
|
+
* @param supportedImportRefs a set of supported import references.
|
|
26
|
+
* @returns undefined if a member expression does NOT reference an unsuppoerted import, PrimingDiagnostic object
|
|
27
|
+
* if an unsupported import is reference.
|
|
28
|
+
*/
|
|
29
|
+
export declare function checkMemberExpressionForNonSupportedNamespaceRefs(path: NodePath<t.MemberExpression>, importReferences: Map<string, ImportDeclarationInfo>): PrimingDiagnostic | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Validates whether a MemberExpression Node on the AST adheres to a portability invariant (whether it doesn't
|
|
32
|
+
* contain 'document', 'window' indentifiers within an expression).
|
|
33
|
+
* @param path NodePath<MemberExpression> containing a MemberExpression to analyze for invariants
|
|
34
|
+
* @returns PrimingDiagnostic of the MemberExpression if an invariant is detected, or undefined if none was found
|
|
35
|
+
*/
|
|
36
|
+
export declare function checkNoUsageOfDocumentOrWindow(path: NodePath<t.MemberExpression>): PrimingDiagnostic | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Invariant function to check weather a member expression contains a call to super.
|
|
39
|
+
* @param path the babel path object for the current member expressoin
|
|
40
|
+
* @returns undefined if the member expressoin does NOT contain a reference to a super var or function. Location object if there is a super reference.
|
|
41
|
+
*/
|
|
42
|
+
export declare function checkForNoUseOfSuper(path: NodePath<t.MemberExpression>): PrimingDiagnostic | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Function to check if there is an reference to an unsupported global reference.
|
|
45
|
+
* @param path the member expression path node
|
|
46
|
+
* @param astContext the ast context that holds meta data about the scr code.
|
|
47
|
+
* @returns a Priming Diagnostic if there is a global reference undefined if none
|
|
48
|
+
*/
|
|
49
|
+
export declare function checkForUnsupportedGlobalRef(path: NodePath<t.MemberExpression>, astContext: AstContext, declaredGetterVars: string[]): PrimingDiagnostic | undefined;
|
|
50
|
+
//# sourceMappingURL=memberExpressionInvariantFunctions.d.ts.map
|