@komaci/static-analyzer 242.1.5 → 242.1.7
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/index.d.ts +1 -0
- package/build/index.js +1 -0
- package/build/invariantFunctions/returnStatementInvariantFunctions.d.ts +16 -0
- package/build/invariantFunctions/returnStatementInvariantFunctions.js +60 -1
- package/build/rules.js +18 -0
- package/build/validateGetter.d.ts +8 -0
- package/build/validateGetter.js +4 -3
- package/build/validateRenderFunction.d.ts +15 -0
- package/build/validateRenderFunction.js +64 -0
- package/package.json +7 -5
package/build/index.d.ts
CHANGED
|
@@ -4,4 +4,5 @@ export { AnalyzerInput, PrimingDiagnostic, Range, Position } from './types';
|
|
|
4
4
|
export { isSupportedNamespace, isImageComposition } from './shared';
|
|
5
5
|
export { diagnosticMessages, getPrimingDiagnostic } from './rules';
|
|
6
6
|
export * from './validateGetter';
|
|
7
|
+
export * from './validateRenderFunction';
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.js
CHANGED
|
@@ -34,4 +34,5 @@ var rules_1 = require("./rules");
|
|
|
34
34
|
Object.defineProperty(exports, "diagnosticMessages", { enumerable: true, get: function () { return rules_1.diagnosticMessages; } });
|
|
35
35
|
Object.defineProperty(exports, "getPrimingDiagnostic", { enumerable: true, get: function () { return rules_1.getPrimingDiagnostic; } });
|
|
36
36
|
__exportStar(require("./validateGetter"), exports);
|
|
37
|
+
__exportStar(require("./validateRenderFunction"), exports);
|
|
37
38
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NodePath } from '@babel/traverse';
|
|
2
2
|
import * as t from '@babel/types';
|
|
3
3
|
import { PrimingDiagnostic } from '../types';
|
|
4
|
+
import { ModuleMetadata } from '@komaci/common-shared';
|
|
4
5
|
/**
|
|
5
6
|
* Invariant function for checking if an getter defined in an external module has only a
|
|
6
7
|
* statement in it, a return statement.
|
|
@@ -9,4 +10,19 @@ import { PrimingDiagnostic } from '../types';
|
|
|
9
10
|
* @returns PrimingDiagnostic of the BlockStatement if the invariant is detected, or undefined if the invariant wasn't found
|
|
10
11
|
*/
|
|
11
12
|
export declare function checkExternalModuleGetterReturnStatement(blockStatement: NodePath<t.BlockStatement>, statements: NodePath<t.Statement>[]): PrimingDiagnostic | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Invariant function for checking if an render function defined in an external module has only a
|
|
15
|
+
* statement in it, a return statement.
|
|
16
|
+
* @param blockStatement the babel path object for the BlockStatement representing the contents of the render function.
|
|
17
|
+
* @param statements the babel path object array for all of the Statements in the render function.
|
|
18
|
+
* @returns PrimingDiagnostic of the BlockStatement if the invariant is detected, or undefined if the invariant wasn't found
|
|
19
|
+
*/
|
|
20
|
+
export declare function checkExternalModuleRenderReturnStatement(blockStatement: NodePath<t.BlockStatement>, statements: NodePath<t.Statement>[]): PrimingDiagnostic | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Function to validate the render function, returns a priming diagnost if an invariant is found.
|
|
23
|
+
* @param returnStmt the return satement node
|
|
24
|
+
* @param moduleMetadata the module metadata obj
|
|
25
|
+
* @returns a priming diagnostic or undefined.
|
|
26
|
+
*/
|
|
27
|
+
export declare function checkRenderFunctionReturnValues(returnStmt: t.ReturnStatement, moduleMetadata: ModuleMetadata): PrimingDiagnostic | undefined;
|
|
12
28
|
//# sourceMappingURL=returnStatementInvariantFunctions.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkExternalModuleGetterReturnStatement = void 0;
|
|
3
|
+
exports.checkRenderFunctionReturnValues = exports.checkExternalModuleRenderReturnStatement = exports.checkExternalModuleGetterReturnStatement = void 0;
|
|
4
4
|
const shared_1 = require("../shared");
|
|
5
5
|
const rules_1 = require("../rules");
|
|
6
6
|
/**
|
|
@@ -20,4 +20,63 @@ function checkExternalModuleGetterReturnStatement(blockStatement, statements) {
|
|
|
20
20
|
return undefined;
|
|
21
21
|
}
|
|
22
22
|
exports.checkExternalModuleGetterReturnStatement = checkExternalModuleGetterReturnStatement;
|
|
23
|
+
/**
|
|
24
|
+
* Invariant function for checking if an render function defined in an external module has only a
|
|
25
|
+
* statement in it, a return statement.
|
|
26
|
+
* @param blockStatement the babel path object for the BlockStatement representing the contents of the render function.
|
|
27
|
+
* @param statements the babel path object array for all of the Statements in the render function.
|
|
28
|
+
* @returns PrimingDiagnostic of the BlockStatement if the invariant is detected, or undefined if the invariant wasn't found
|
|
29
|
+
*/
|
|
30
|
+
function checkExternalModuleRenderReturnStatement(blockStatement, statements) {
|
|
31
|
+
// the render function doesn't only have a return method as expected. Skip traversal, then return from this method here
|
|
32
|
+
if (!(statements.length === 1 && statements[0].isReturnStatement())) {
|
|
33
|
+
if (blockStatement.node.loc) {
|
|
34
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_RENDER_FUNCTION_CONTAINS_MORE_THAN_RETURN_STATEMENT, shared_1.LLSRange.fromBabelSourceLocation(blockStatement.node.loc), []);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
exports.checkExternalModuleRenderReturnStatement = checkExternalModuleRenderReturnStatement;
|
|
40
|
+
/**
|
|
41
|
+
* Function to validate the render function, returns a priming diagnost if an invariant is found.
|
|
42
|
+
* @param returnStmt the return satement node
|
|
43
|
+
* @param moduleMetadata the module metadata obj
|
|
44
|
+
* @returns a priming diagnostic or undefined.
|
|
45
|
+
*/
|
|
46
|
+
function checkRenderFunctionReturnValues(returnStmt, moduleMetadata) {
|
|
47
|
+
//eg. return child1;
|
|
48
|
+
if (returnStmt.argument && returnStmt.argument.type == 'Identifier') {
|
|
49
|
+
const identifierName = returnStmt.argument.name;
|
|
50
|
+
const importedTemplateMetadata = moduleMetadata.importsByName.get(identifierName);
|
|
51
|
+
//the identifier that is being returned was not found in the imports by name array.
|
|
52
|
+
if (importedTemplateMetadata) {
|
|
53
|
+
if (!importedTemplateMetadata.templateKomaciDoc) {
|
|
54
|
+
if (returnStmt.loc) {
|
|
55
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_RENDER_FUNCTION_RETURN_STATEMENT_NOT_RETURNING_IMPORTED_TEMPLATE, shared_1.LLSRange.fromBabelSourceLocation(returnStmt.loc), []);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if (returnStmt.argument &&
|
|
61
|
+
returnStmt.argument.type == 'ConditionalExpression') {
|
|
62
|
+
const conditionalExpr = returnStmt.argument;
|
|
63
|
+
const consequence = conditionalExpr.consequent;
|
|
64
|
+
const alternate = conditionalExpr.alternate;
|
|
65
|
+
const consequenceTemplateImport = moduleMetadata.importsByName.get(consequence.name);
|
|
66
|
+
const alternateTemplateImport = moduleMetadata.importsByName.get(alternate.name);
|
|
67
|
+
if (!consequenceTemplateImport.templateKomaciDoc &&
|
|
68
|
+
!alternateTemplateImport.templateKomaciDoc) {
|
|
69
|
+
if (returnStmt.loc) {
|
|
70
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_RENDER_FUNCTION_RETURN_STATEMENT_NOT_RETURNING_IMPORTED_TEMPLATE, shared_1.LLSRange.fromBabelSourceLocation(returnStmt.loc), []);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
if (returnStmt.loc) {
|
|
76
|
+
return (0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_RENDER_FUNCTION_RETURN_STATEMENT_NOT_RETURNING_IMPORTED_TEMPLATE, shared_1.LLSRange.fromBabelSourceLocation(returnStmt.loc), []);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
exports.checkRenderFunctionReturnValues = checkRenderFunctionReturnValues;
|
|
23
82
|
//# sourceMappingURL=returnStatementInvariantFunctions.js.map
|
package/build/rules.js
CHANGED
|
@@ -192,6 +192,24 @@ exports.diagnosticMessages = {
|
|
|
192
192
|
message: 'Supported getters can only contain a return statement',
|
|
193
193
|
source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
|
|
194
194
|
},
|
|
195
|
+
NO_RENDER_FUNCTION_CONTAINS_MORE_THAN_RETURN_STATEMENT: {
|
|
196
|
+
code: `${MESSAGE_CODE_PREFIX}1025`,
|
|
197
|
+
severity: SEVERITY.ERROR,
|
|
198
|
+
message: 'Supported render functions in custom components can only contain a return statement',
|
|
199
|
+
source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
|
|
200
|
+
},
|
|
201
|
+
NO_RENDER_FUNCTION_RETURN_STATEMENT: {
|
|
202
|
+
code: `${MESSAGE_CODE_PREFIX}1025`,
|
|
203
|
+
severity: SEVERITY.ERROR,
|
|
204
|
+
message: 'Supported render functions need to contain a return statement',
|
|
205
|
+
source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
|
|
206
|
+
},
|
|
207
|
+
NO_RENDER_FUNCTION_RETURN_STATEMENT_NOT_RETURNING_IMPORTED_TEMPLATE: {
|
|
208
|
+
code: `${MESSAGE_CODE_PREFIX}1025`,
|
|
209
|
+
severity: SEVERITY.ERROR,
|
|
210
|
+
message: 'Supported render functions can only return supported imported templates',
|
|
211
|
+
source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
|
|
212
|
+
},
|
|
195
213
|
NO_EXPRESSION_CONTAINS_MODULE_LEVEL_VARIABLE_REF: {
|
|
196
214
|
code: `${MESSAGE_CODE_PREFIX}1026`,
|
|
197
215
|
severity: SEVERITY.ERROR,
|
|
@@ -33,6 +33,14 @@ export declare function checkFunctionalPurity(path: NodePath<t.ClassMethod | t.C
|
|
|
33
33
|
* least one invariant check failed. If no invariant checks failed, an empty Array<InvariantDetail> is returned.
|
|
34
34
|
*/
|
|
35
35
|
export declare function validateGetter(getterMethodPath: NodePath<t.ClassMethod>, adgIndex: number, moduleMetadata: ModuleMetadata, moduleContext: ModuleContext, returnSourceLocation?: boolean): boolean | Array<PrimingDiagnostic>;
|
|
36
|
+
/**
|
|
37
|
+
* Given a set of results from invariant checks. we want to filter out any no-op values and put meaningful
|
|
38
|
+
* results into the list of allInvalidLocations
|
|
39
|
+
* @param allInvalidLocations PrimingDiagnostic[] containing all invariants that occurred so far
|
|
40
|
+
* @param results the Array<PrimingDiagnostic | undefined> containing what is return by calling invariant checker method.
|
|
41
|
+
* @returns array of PrimingDiagnostic filtered of no-op values/non-meaningful results.
|
|
42
|
+
*/
|
|
43
|
+
export declare function processLocationInfo(allInvalidLocations: PrimingDiagnostic[], results: Array<PrimingDiagnostic | undefined>): PrimingDiagnostic[];
|
|
36
44
|
/**
|
|
37
45
|
* Validate template strings for purity. Variable declarations are not valid inside of a template expression so we do not have to support that use case here.
|
|
38
46
|
* Template string processing is essentially a subset of what we do for getter functions. The only diff is that we don't have to do the extra "only a return statement"
|
package/build/validateGetter.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validateTemplateString = exports.validateGetter = exports.checkFunctionalPurity = void 0;
|
|
3
|
+
exports.validateTemplateString = exports.processLocationInfo = exports.validateGetter = exports.checkFunctionalPurity = void 0;
|
|
4
4
|
const memberExpressionInvariantFunctions_1 = require("./invariantFunctions/memberExpressionInvariantFunctions");
|
|
5
5
|
const callExpressionInvariantFunctions_1 = require("./invariantFunctions/callExpressionInvariantFunctions");
|
|
6
6
|
const assignmentExpressionInvariantFunctions_1 = require("./invariantFunctions/assignmentExpressionInvariantFunctions");
|
|
@@ -104,8 +104,8 @@ exports.checkFunctionalPurity = checkFunctionalPurity;
|
|
|
104
104
|
* least one invariant check failed. If no invariant checks failed, an empty Array<InvariantDetail> is returned.
|
|
105
105
|
*/
|
|
106
106
|
function validateGetter(getterMethodPath, adgIndex, moduleMetadata, moduleContext, returnSourceLocation = false) {
|
|
107
|
-
const getterDeclaredVars = (0, common_shared_1.
|
|
108
|
-
const thisAliases = (0, common_shared_1.
|
|
107
|
+
const getterDeclaredVars = (0, common_shared_1.getVariablesDeclaredInFunction)(getterMethodPath);
|
|
108
|
+
const thisAliases = (0, common_shared_1.getThisAliasDeclaredInFunction)(getterMethodPath);
|
|
109
109
|
let primingDiagnostics = checkFunctionalPurity(getterMethodPath, adgIndex, moduleMetadata, moduleContext, {
|
|
110
110
|
thisAliases,
|
|
111
111
|
declaredVariables: getterDeclaredVars,
|
|
@@ -138,6 +138,7 @@ function processLocationInfo(allInvalidLocations, results) {
|
|
|
138
138
|
// concat method returns a new array from the original array + the arrays to concatenate
|
|
139
139
|
return allInvalidLocations.concat(results.filter((result) => result !== undefined));
|
|
140
140
|
}
|
|
141
|
+
exports.processLocationInfo = processLocationInfo;
|
|
141
142
|
/**
|
|
142
143
|
* Validate template strings for purity. Variable declarations are not valid inside of a template expression so we do not have to support that use case here.
|
|
143
144
|
* Template string processing is essentially a subset of what we do for getter functions. The only diff is that we don't have to do the extra "only a return statement"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { NodePath } from '@babel/core';
|
|
3
|
+
import { ModuleContext, ModuleMetadata } from '@komaci/common-shared';
|
|
4
|
+
import { PrimingDiagnostic } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Function to validate a components render function.
|
|
7
|
+
* @param renderFunction the render function to validate
|
|
8
|
+
* @param adgIndex the adg index
|
|
9
|
+
* @param moduleMetadata the moduleMeta data object
|
|
10
|
+
* @param moduleContext the module context
|
|
11
|
+
* @param returnSourceLocation a bool if we want to return the source location
|
|
12
|
+
* @returns true or false if the function is valid or a priming diagnostic
|
|
13
|
+
*/
|
|
14
|
+
export declare function validateRenderFunction(renderFunction: NodePath<t.ClassMethod>, adgIndex: number, moduleMetadata: ModuleMetadata, moduleContext: ModuleContext, returnSourceLocation?: boolean): boolean | Array<PrimingDiagnostic>;
|
|
15
|
+
//# sourceMappingURL=validateRenderFunction.d.ts.map
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateRenderFunction = void 0;
|
|
4
|
+
const common_shared_1 = require("@komaci/common-shared");
|
|
5
|
+
const returnStatementInvariantFunctions_1 = require("./invariantFunctions/returnStatementInvariantFunctions");
|
|
6
|
+
const validateGetter_1 = require("./validateGetter");
|
|
7
|
+
const rules_1 = require("./rules");
|
|
8
|
+
const shared_1 = require("./shared");
|
|
9
|
+
/**
|
|
10
|
+
* Function to validate a components render function.
|
|
11
|
+
* @param renderFunction the render function to validate
|
|
12
|
+
* @param adgIndex the adg index
|
|
13
|
+
* @param moduleMetadata the moduleMeta data object
|
|
14
|
+
* @param moduleContext the module context
|
|
15
|
+
* @param returnSourceLocation a bool if we want to return the source location
|
|
16
|
+
* @returns true or false if the function is valid or a priming diagnostic
|
|
17
|
+
*/
|
|
18
|
+
function validateRenderFunction(renderFunction, adgIndex, moduleMetadata, moduleContext, returnSourceLocation = false) {
|
|
19
|
+
let primingDiagnostics = [];
|
|
20
|
+
const declaredVars = (0, common_shared_1.getVariablesDeclaredInFunction)(renderFunction);
|
|
21
|
+
const thisAliases = (0, common_shared_1.getThisAliasDeclaredInFunction)(renderFunction);
|
|
22
|
+
//First Check the functional Purity of the render function
|
|
23
|
+
primingDiagnostics = (0, validateGetter_1.checkFunctionalPurity)(renderFunction, adgIndex, moduleMetadata, moduleContext, {
|
|
24
|
+
thisAliases,
|
|
25
|
+
declaredVariables: declaredVars,
|
|
26
|
+
});
|
|
27
|
+
const blockStatement = renderFunction.get('body');
|
|
28
|
+
const statements = blockStatement.get('body');
|
|
29
|
+
let hasReturnStatement = false;
|
|
30
|
+
//Visitor object to look at each return statement in the render function and validate it.
|
|
31
|
+
const Vistior = {
|
|
32
|
+
ReturnStatement(path) {
|
|
33
|
+
//Check the if the return statement is valid.
|
|
34
|
+
hasReturnStatement = true;
|
|
35
|
+
primingDiagnostics = (0, validateGetter_1.processLocationInfo)(primingDiagnostics, [
|
|
36
|
+
(0, returnStatementInvariantFunctions_1.checkRenderFunctionReturnValues)(path.node, moduleMetadata),
|
|
37
|
+
]);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
renderFunction.traverse(Vistior);
|
|
41
|
+
//we don't have a return statement in the render function.
|
|
42
|
+
if (!hasReturnStatement) {
|
|
43
|
+
if (renderFunction.node.loc) {
|
|
44
|
+
primingDiagnostics = (0, validateGetter_1.processLocationInfo)(primingDiagnostics, [
|
|
45
|
+
(0, rules_1.getPrimingDiagnostic)(rules_1.diagnosticMessages.NO_RENDER_FUNCTION_RETURN_STATEMENT, shared_1.LLSRange.fromBabelSourceLocation(renderFunction.node.loc), []),
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// if render function was defined in an external module
|
|
50
|
+
if (moduleContext.isExternal) {
|
|
51
|
+
// the render function doesn't only have a return method as expected. Skip traversal, then return from this method here
|
|
52
|
+
primingDiagnostics = (0, validateGetter_1.processLocationInfo)(primingDiagnostics, [
|
|
53
|
+
(0, returnStatementInvariantFunctions_1.checkExternalModuleRenderReturnStatement)(blockStatement, statements),
|
|
54
|
+
]);
|
|
55
|
+
// If checkExternalModuleGetterReturnStatement() fails we should just return. There's no use in
|
|
56
|
+
// validating a function that is already foundationally invalid
|
|
57
|
+
if (primingDiagnostics.length > 0) {
|
|
58
|
+
return returnSourceLocation ? primingDiagnostics : false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return returnSourceLocation ? primingDiagnostics : primingDiagnostics.length === 0;
|
|
62
|
+
}
|
|
63
|
+
exports.validateRenderFunction = validateRenderFunction;
|
|
64
|
+
//# sourceMappingURL=validateRenderFunction.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@komaci/static-analyzer",
|
|
3
|
-
"version": "242.1.
|
|
3
|
+
"version": "242.1.7",
|
|
4
4
|
"description": "Komaci Diagnostics API",
|
|
5
5
|
"homepage": "https://komaci.dev/",
|
|
6
6
|
"repository": {
|
|
@@ -28,12 +28,14 @@
|
|
|
28
28
|
"!**/RULES.todo.md"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@komaci/common-shared": "242.1.
|
|
32
|
-
"@lwc/metadata": "2.22.0-0",
|
|
33
|
-
"@lwc/sfdc-compiler-utils": "2.22.0-0"
|
|
31
|
+
"@komaci/common-shared": "242.1.7"
|
|
34
32
|
},
|
|
35
33
|
"devDependencies": {
|
|
36
34
|
"@babel/types": "^7.9.0",
|
|
37
|
-
"@komaci/types": "242.1.
|
|
35
|
+
"@komaci/types": "242.1.7"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@lwc/metadata": "2.22.0-0",
|
|
39
|
+
"@lwc/sfdc-compiler-utils": "2.22.0-0"
|
|
38
40
|
}
|
|
39
41
|
}
|