@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.
Files changed (36) hide show
  1. package/build/WireGraph.d.ts +34 -0
  2. package/build/WireGraph.js +82 -0
  3. package/build/__mocks__/@babel/parser.d.ts +2 -0
  4. package/build/__mocks__/@babel/parser.js +6 -0
  5. package/build/adaptersMapping.d.ts +3 -0
  6. package/build/adaptersMapping.js +25 -0
  7. package/build/allowlistAdapters.d.ts +6 -0
  8. package/build/allowlistAdapters.js +10 -0
  9. package/build/index.d.ts +7 -0
  10. package/build/index.js +35 -0
  11. package/build/invariantFunctions/assignmentExpressionInvariantFunctions.d.ts +16 -0
  12. package/build/invariantFunctions/assignmentExpressionInvariantFunctions.js +34 -0
  13. package/build/invariantFunctions/callExpressionInvariantFunctions.d.ts +33 -0
  14. package/build/invariantFunctions/callExpressionInvariantFunctions.js +87 -0
  15. package/build/invariantFunctions/functionExpressionInvariantFunctions.d.ts +31 -0
  16. package/build/invariantFunctions/functionExpressionInvariantFunctions.js +69 -0
  17. package/build/invariantFunctions/identifierInvariantFunctions.d.ts +28 -0
  18. package/build/invariantFunctions/identifierInvariantFunctions.js +56 -0
  19. package/build/invariantFunctions/memberExpressionInvariantFunctions.d.ts +50 -0
  20. package/build/invariantFunctions/memberExpressionInvariantFunctions.js +146 -0
  21. package/build/invariantFunctions/returnStatementInvariantFunctions.d.ts +12 -0
  22. package/build/invariantFunctions/returnStatementInvariantFunctions.js +23 -0
  23. package/build/invariantFunctions/taggedTemplateExpressionInvariantFunctions.d.ts +12 -0
  24. package/build/invariantFunctions/taggedTemplateExpressionInvariantFunctions.js +25 -0
  25. package/build/komaci-mapping.json +288 -0
  26. package/build/rules.d.ts +22 -0
  27. package/build/rules.js +310 -0
  28. package/build/shared.d.ts +52 -0
  29. package/build/shared.js +184 -0
  30. package/build/staticAnalyzer.d.ts +100 -0
  31. package/build/staticAnalyzer.js +822 -0
  32. package/build/types.d.ts +102 -0
  33. package/build/types.js +3 -0
  34. package/build/validateGetter.d.ts +46 -0
  35. package/build/validateGetter.js +154 -0
  36. package/package.json +39 -0
package/build/rules.js ADDED
@@ -0,0 +1,310 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.diagnosticMessages = exports.updatePrimingDiagnosticWithFileInfo = exports.getPrimingDiagnostic = void 0;
4
+ const MESSAGE_CODE_PREFIX = 'komaci';
5
+ const SOURCE_PREFIX_OFFLINE_CODE_ANALYZER = 'offline code analyzer';
6
+ var SEVERITY;
7
+ (function (SEVERITY) {
8
+ SEVERITY["ERROR"] = "error";
9
+ SEVERITY["WARNING"] = "warning";
10
+ SEVERITY["INFO"] = "info";
11
+ })(SEVERITY || (SEVERITY = {}));
12
+ const argReplaceRegExp = /\{([0-9]+)\}/g;
13
+ const DIAGNOSTIC_MSG_NOT_FOUND = 'The message for this diagnostic occurence was not found';
14
+ /**
15
+ * Returns the processed PrimingDiagnostic for a given DianosticMessage message key. If {args} are passed in, they will be substituted into
16
+ * the message string in the order of the array. If a {filename} is passed in, a {Uri} will be generated that will be included in the DiagnosticMessage
17
+ * in the format expected by the VSCode language server
18
+ * @param {DiagnosticMessage} diagnosticMessage the unprocessed diagnostic message (the caller of this method looks up the message with a key)
19
+ * @param {Range} range the line numbers and column numbers for the starting and endline line and starting and ending columns of the cause of the diagnostic
20
+ * message in the code, respectively.
21
+ * @param {Array<string>} args arguments to substitute into the message string
22
+ * @returns a new, processed instance of PrimingDiagnostic (with arguments substituted in, and Uri set) which is compatible with the VSCode language server
23
+ */
24
+ function getPrimingDiagnostic(diagnosticMessage, range, args) {
25
+ const primingDiagnostic = {
26
+ range: range,
27
+ ...diagnosticMessage,
28
+ };
29
+ if (!diagnosticMessage) {
30
+ primingDiagnostic.message = DIAGNOSTIC_MSG_NOT_FOUND;
31
+ }
32
+ // does argument substitution for message, if args exist
33
+ primingDiagnostic.message = primingDiagnostic.message.replace(argReplaceRegExp, (_, index) => {
34
+ return args && args[index] ? args[index] : '';
35
+ });
36
+ return primingDiagnostic;
37
+ }
38
+ exports.getPrimingDiagnostic = getPrimingDiagnostic;
39
+ /**
40
+ * This method augments the PrimingDiagnostic with filename information. It augments the
41
+ * object by reference and does not return a modified object.
42
+ * @param {PrimingDiagnostic} primingDiagnostic The PrimingDiagnostic that needs to be augmented with filename informations
43
+ * @param {string | undefined} filename The name of the file that the PrimingDiagnostic is for
44
+ * @returns {PrimingDiagnostic} a PrimingDiagnostic (this is optional to use)
45
+ */
46
+ function updatePrimingDiagnosticWithFileInfo(primingDiagnostic, filename) {
47
+ if (filename && filename.length > 0) {
48
+ const uri = {
49
+ scheme: 'file',
50
+ path: filename,
51
+ fragment: '',
52
+ query: '',
53
+ authority: '',
54
+ };
55
+ // convert the komaci field to one that supports file names, but only if it exists
56
+ if (primingDiagnostic.code) {
57
+ primingDiagnostic.code = {
58
+ target: uri,
59
+ value: primingDiagnostic.code,
60
+ };
61
+ }
62
+ }
63
+ return primingDiagnostic;
64
+ }
65
+ exports.updatePrimingDiagnosticWithFileInfo = updatePrimingDiagnosticWithFileInfo;
66
+ exports.diagnosticMessages = {
67
+ NO_UNRESOLVED_PARENT_CLASS_REFERENCE: {
68
+ code: `${MESSAGE_CODE_PREFIX}1001`,
69
+ severity: SEVERITY.ERROR,
70
+ message: 'This class refers to an unresolved parent class',
71
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
72
+ },
73
+ NO_MULTIPLE_TEMPLATE_FILES: {
74
+ code: `${MESSAGE_CODE_PREFIX}1002`,
75
+ severity: SEVERITY.WARNING,
76
+ message: 'This analyzer does not support LWCs which render multiple template files',
77
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
78
+ },
79
+ NO_PRIVATE_WIRE_CONFIG_PROPERTY: {
80
+ code: `${MESSAGE_CODE_PREFIX}1003`,
81
+ severity: SEVERITY.ERROR,
82
+ message: "This wire configuration uses a property '{0}' that is private",
83
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
84
+ },
85
+ NO_UNDEFINED_WIRE_CONFIG_PROPERTY: {
86
+ code: `${MESSAGE_CODE_PREFIX}1004`,
87
+ severity: SEVERITY.WARNING,
88
+ message: "This wire configuration uses a property '{0}' which is undefined",
89
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
90
+ },
91
+ NO_CONDITIONAL_USING_PROPERTY_FROM_UNRESOLVABLE_WIRE: {
92
+ code: `${MESSAGE_CODE_PREFIX}1005`,
93
+ severity: SEVERITY.ERROR,
94
+ message: "This conditional acts upon an unanalyzable property '{0}' that is wired by a unresolvable wire",
95
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
96
+ },
97
+ NO_WIRE_CONFIGURATION_PROPERTY_USING_OUTPUT_OF_NON_PRIMEABLE_WIRE: {
98
+ code: `${MESSAGE_CODE_PREFIX}1006`,
99
+ severity: SEVERITY.ERROR,
100
+ message: "The wire configuration uses a property '{0}' that is the output of a non-primeable wire, making this wire non-primeable",
101
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
102
+ },
103
+ NO_WIRE_ADAPTER_OF_RESOURCE_CANNOT_BE_PRIMED: {
104
+ code: `${MESSAGE_CODE_PREFIX}1007`,
105
+ severity: SEVERITY.ERROR,
106
+ message: "The wire adapter '{0}' of resource '{1}' cannot be primed",
107
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
108
+ },
109
+ NO_MISSING_RESOURCE_CANNOT_PRIME_WIRE_ADAPTER: {
110
+ code: `${MESSAGE_CODE_PREFIX}1008`,
111
+ severity: SEVERITY.ERROR,
112
+ message: 'The wire adapter cannot be primed because it refers to a missing resource',
113
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
114
+ },
115
+ NO_WIRE_CONFIG_PROPERTY_USES_GETTER_FUNCTION_RETURNING_NON_LITERAL: {
116
+ code: `${MESSAGE_CODE_PREFIX}1009`,
117
+ severity: SEVERITY.ERROR,
118
+ message: "This wire configuration uses a property from a getter function named '{0}' that returns a non-literal",
119
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
120
+ },
121
+ NO_WIRE_CONFIG_PROPERTY_USES_GETTER_FUNCTION_RETURNING_INACCESSIBLE_IMPORT: {
122
+ code: `${MESSAGE_CODE_PREFIX}1010`,
123
+ severity: SEVERITY.ERROR,
124
+ message: "This wire configuration uses a property from a getter function named '{0}' that returns an inaccessible import",
125
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
126
+ },
127
+ NO_CLASS_REFERS_TO_PARENT_CLASS_FROM_UNSUPPORTED_NAMESPACE: {
128
+ code: `${MESSAGE_CODE_PREFIX}1011`,
129
+ severity: SEVERITY.ERROR,
130
+ message: 'This class refers to a parent class from an unsupported namespace',
131
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
132
+ },
133
+ NO_WIRE_CONFIG_PROPERTY_USES_IMPORTED_ARTIFACT_FROM_UNSUPPORTED_NAMESPACE: {
134
+ code: `${MESSAGE_CODE_PREFIX}1012`,
135
+ severity: SEVERITY.ERROR,
136
+ message: "This wire configuration uses an imported artifact '{0}' from unsupported namespace '{1}'",
137
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
138
+ },
139
+ NO_WIRE_CONFIG_REFERENCES_NON_LOCAL_PROPERTY_REACTIVE_VALUE: {
140
+ code: `${MESSAGE_CODE_PREFIX}1013`,
141
+ severity: SEVERITY.WARNING,
142
+ message: "This wire configuration references a reactive value '{0}' that is not a local property",
143
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
144
+ },
145
+ NO_ITERATE_ON_UNANALYZABLE_PROPERTY_FROM_UNRESOLVABLE_WIRE: {
146
+ code: `${MESSAGE_CODE_PREFIX}1014`,
147
+ severity: SEVERITY.ERROR,
148
+ message: "This iterator iterates upon an unanalyzable property '{0}' that is wired by a unresolvable wire",
149
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
150
+ },
151
+ NO_ITERATE_ON_UNANALYZABLE_PROPERTY_FROM_NON_PUBLIC_PROPERTY: {
152
+ code: `${MESSAGE_CODE_PREFIX}1015`,
153
+ severity: SEVERITY.ERROR,
154
+ message: "This iterator iterates upon an unanalyzable property '{0}' that is not a public property",
155
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
156
+ },
157
+ NO_CONDITIONAL_ON_UNANALYZABLE_GETTER_PROPERTY: {
158
+ code: `${MESSAGE_CODE_PREFIX}1016`,
159
+ severity: SEVERITY.ERROR,
160
+ message: "This conditional acts upon an unanalyzable getter property '{0}'",
161
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
162
+ },
163
+ NO_CONDITIONAL_ON_UNANALYZABLE_NON_PUBLIC_GETTER_PROPERTY: {
164
+ code: `${MESSAGE_CODE_PREFIX}1017`,
165
+ severity: SEVERITY.ERROR,
166
+ message: "This conditional acts upon an unanalyzable getter property '{0}' that is not a public property",
167
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
168
+ },
169
+ NO_WIRE_CONFIG_PROPERTY_CIRCULAR_WIRE_DEPENDENCY: {
170
+ code: `${MESSAGE_CODE_PREFIX}1018`,
171
+ severity: SEVERITY.ERROR,
172
+ message: "The wire configuration input property '{0}' of this wire is part of a chain of circular wire " +
173
+ 'dependencies, and will result an infinite loop during runtime. Please refactor ' +
174
+ "code to remove the circular dependency. Dependency chain: '{1}'",
175
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
176
+ },
177
+ NO_ITERATE_ON_UNANALYZABLE_GETTER_PROPERTY: {
178
+ code: `${MESSAGE_CODE_PREFIX}1019`,
179
+ severity: SEVERITY.ERROR,
180
+ message: "This iterator iterates upon an unanalyzable getter property '{0}'",
181
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
182
+ },
183
+ NO_CONDITIONAL_USING_UNANALYZABLE_NON_PUBLIC_PROPERTY: {
184
+ code: `${MESSAGE_CODE_PREFIX}1020`,
185
+ severity: SEVERITY.ERROR,
186
+ message: "This conditional acts upon an unanalyzable property '{0}' that is not a public property",
187
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
188
+ },
189
+ NO_ITERATE_ON_UNANALYZABLE_PROPERTY: {
190
+ code: `${MESSAGE_CODE_PREFIX}1021`,
191
+ severity: SEVERITY.ERROR,
192
+ message: "This iterator iterates upon an unanalyzable property '{0}'",
193
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
194
+ },
195
+ NO_ASSIGNMENT_EXPRESSION_ASSIGNS_VALUE_TO_MEMBER_VARIABLE: {
196
+ code: `${MESSAGE_CODE_PREFIX}1022`,
197
+ severity: SEVERITY.ERROR,
198
+ message: "Assignment expression cannot assign a value to member variable '{0}'",
199
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
200
+ },
201
+ NO_ASSIGNMENT_EXPRESSION_FOR_EXTERNAL_COMPONENTS: {
202
+ code: `${MESSAGE_CODE_PREFIX}1023`,
203
+ severity: SEVERITY.ERROR,
204
+ message: 'Assignment Expressions are not supported for external components',
205
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
206
+ },
207
+ NO_TAGGED_TEMPLATE_EXPRESSION_CONTAINS_UNSUPPORTED_NAMESPACE: {
208
+ code: `${MESSAGE_CODE_PREFIX}1024`,
209
+ severity: SEVERITY.ERROR,
210
+ message: "Tagged Template Expression contains a reference to an unsupported namespace '{0}'",
211
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
212
+ },
213
+ NO_GETTER_CONTAINS_MORE_THAN_RETURN_STATEMENT: {
214
+ code: `${MESSAGE_CODE_PREFIX}1025`,
215
+ severity: SEVERITY.ERROR,
216
+ message: 'Supported getters can only contain a return statement',
217
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
218
+ },
219
+ NO_EXPRESSION_CONTAINS_MODULE_LEVEL_VARIABLE_REF: {
220
+ code: `${MESSAGE_CODE_PREFIX}1026`,
221
+ severity: SEVERITY.ERROR,
222
+ message: "Expression contains a reference to a variable at the module level: '{0}'",
223
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
224
+ },
225
+ NO_CALL_EXPRESSION_REFERENCES_UNSUPPORTED_NAMESPACE: {
226
+ code: `${MESSAGE_CODE_PREFIX}1027`,
227
+ severity: SEVERITY.ERROR,
228
+ message: "Call expression contains reference to an unsupported namespace '{0}'",
229
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
230
+ },
231
+ NO_EVAL_USAGE: {
232
+ code: `${MESSAGE_CODE_PREFIX}1028`,
233
+ severity: SEVERITY.ERROR,
234
+ message: "Call expression contains non-portable identifier '{0}'",
235
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
236
+ },
237
+ NO_REFERENCE_TO_CLASS_FUNCTIONS: {
238
+ code: `${MESSAGE_CODE_PREFIX}1029`,
239
+ severity: SEVERITY.ERROR,
240
+ message: "Call expression contains reference to function defined on the class '{0}'",
241
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
242
+ },
243
+ NO_REFERENCE_TO_MODULE_FUNCTIONS: {
244
+ code: `${MESSAGE_CODE_PREFIX}1030`,
245
+ severity: SEVERITY.ERROR,
246
+ message: "Call expression contains reference to function defined on the module '{0}'",
247
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
248
+ },
249
+ NO_FUNCTIONS_DECLARED_WITHIN_GETTER_METHOD: {
250
+ code: `${MESSAGE_CODE_PREFIX}1031`,
251
+ severity: SEVERITY.ERROR,
252
+ message: 'Functions may not be declared within a getter method',
253
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
254
+ },
255
+ NO_UNSUPPORTED_MEMBER_VARIABLE_IN_MEMBER_EXPRESSION: {
256
+ code: `${MESSAGE_CODE_PREFIX}1032`,
257
+ severity: SEVERITY.ERROR,
258
+ message: "Member expression contains reference to unsupported member variable '{0}'",
259
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
260
+ },
261
+ NO_MEMBER_EXPRESSION_REFERENCE_TO_NON_EXISTENT_MEMBER_VARIABLE: {
262
+ code: `${MESSAGE_CODE_PREFIX}1033`,
263
+ severity: SEVERITY.ERROR,
264
+ message: "Member expression contains reference to non-existent member variable '{0}'",
265
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
266
+ },
267
+ NO_MEMBER_EXPRESSION_REFERENCE_TO_UNSUPPORTED_NAMESPACE_REFERENCE: {
268
+ code: `${MESSAGE_CODE_PREFIX}1034`,
269
+ severity: SEVERITY.ERROR,
270
+ message: "Member expression contains reference to unsupported namespace reference: '{0}'",
271
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
272
+ },
273
+ NO_MEMBER_EXPRESSION_CONTAINS_NON_PORTABLE_IDENTIFIER: {
274
+ code: `${MESSAGE_CODE_PREFIX}1035`,
275
+ severity: SEVERITY.ERROR,
276
+ message: "Member expression contains non-portable identifier '{0}'",
277
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
278
+ },
279
+ NO_MEMBER_EXPRESSION_REFERENCE_TO_SUPER_CLASS: {
280
+ code: `${MESSAGE_CODE_PREFIX}1036`,
281
+ severity: SEVERITY.ERROR,
282
+ message: "Member expression contains reference to super class: '{0}'",
283
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
284
+ },
285
+ NO_MEMBER_EXPRESSION_REFERENCE_TO_UNSUPPORTED_GLOBAL: {
286
+ code: `${MESSAGE_CODE_PREFIX}1037`,
287
+ severity: SEVERITY.ERROR,
288
+ message: "Member expression contains reference to unsupported global: '{0}'",
289
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
290
+ },
291
+ NO_REFERENCE_TO_UNSUPPORTED_NAMESPACE_REFERENCE: {
292
+ code: `${MESSAGE_CODE_PREFIX}1038`,
293
+ severity: SEVERITY.ERROR,
294
+ message: "Reference to import '{0}' from an unsupported namespace is not allowed",
295
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
296
+ },
297
+ NO_IMAGE_REFERENCE_UNANALYZABLE_SOURCE_PROPERTY: {
298
+ code: `${MESSAGE_CODE_PREFIX}1039`,
299
+ severity: SEVERITY.ERROR,
300
+ message: "Image tag references in its source attribute the unanalyzable property '{0}'",
301
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
302
+ },
303
+ NO_IMAGE_REFERENCE_MISSING_SOURCE_PROPERTY: {
304
+ code: `${MESSAGE_CODE_PREFIX}1040`,
305
+ severity: SEVERITY.ERROR,
306
+ message: "Image tag references in its source attribute a property '{0}' which does not exist in the corresponding script file",
307
+ source: SOURCE_PREFIX_OFFLINE_CODE_ANALYZER,
308
+ },
309
+ };
310
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1,52 @@
1
+ import { ClassPropertyContexts } from '@komaci/common-shared';
2
+ import { GetPrimingAdapter } from './types';
3
+ import { SourceLocation } from '@babel/types';
4
+ import { PrimingDiagnostic, Range } from '.';
5
+ import { Composition, Image, SourceLocation as KomaciSourceLocation } from '@komaci/types';
6
+ export declare const WIRE_FUNCTION = "WireFunction";
7
+ export declare const ERROR_PREFIX = "[komaci static-analyzer] ";
8
+ /**
9
+ * Determine whether the wire adapter is supported
10
+ * @param resourceName the resource name of the Import, as a string
11
+ * @param adapterName the wire adapter variable name (import specifier export name) from a single
12
+ * Import statement (which can have more than one of these export names)
13
+ * @returns boolean true if the adapterName represents is a supported wire adapter (note that some
14
+ * resourceNames allow any adapterName as valid wire adapters)
15
+ */
16
+ export declare function isSupportedWireAdapter(resourceName: string | undefined, adapterName: string | undefined): boolean;
17
+ /**
18
+ * Determine whether the resource name is in a supported namespace
19
+ * @param resourceName the resource name of the Import, as a string
20
+ * @returns boolean true if the resource name is in a supported namespace
21
+ */
22
+ export declare function isSupportedNamespace(resourceName: string | undefined): boolean;
23
+ export declare const getPrimingAdapter: GetPrimingAdapter;
24
+ export declare const LLSRange: {
25
+ /**
26
+ * Converts an lwc-metadata SourceLocation (1-indexed for both line and column) into a Lightning Language
27
+ * Server-compatible Range object.
28
+ * @param {Location} location the SourceLocation, as represented by lwc-metadata, with komaci SourceLocation type
29
+ * @returns {Range} the komaci, Lightning Language Server-compatible Range object
30
+ */
31
+ fromLWCSourceLocation(location: KomaciSourceLocation | undefined): Range;
32
+ /**
33
+ * Converts a BabelJS SourceLocation (1-indexed for line, 0-indexed for column) into a Lightning Language
34
+ * Server-compatible Range object.
35
+ * @param {Location} location the SourceLocation, as represented by lwc-metadata, with komaci SourceLocation type
36
+ * @returns {Range} the komaci, Lightning Language Server-compatible Range object
37
+ */
38
+ fromBabelSourceLocation({ start, end }: SourceLocation): Range;
39
+ };
40
+ /**
41
+ * Function to analyze getter functions and collect any Priming Diagnostic info for invalid gettters.
42
+ * @param srcCode the source code to analyze.
43
+ * @param namespace the namespace of src file.
44
+ */
45
+ export declare function analyzeSrcForInvalidGetterFunctions(srcCode: string, namespace: string, properties: ClassPropertyContexts): PrimingDiagnostic[];
46
+ /**
47
+ * Type guard for the komaci Image type
48
+ * @param {Composition} composition the komaci Composition object
49
+ * @returns {boolean} true if the Composition is more specifically an Image, false if it is not an Image
50
+ */
51
+ export declare function isImageComposition(composition: Composition): composition is Image;
52
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isImageComposition = exports.analyzeSrcForInvalidGetterFunctions = exports.LLSRange = exports.getPrimingAdapter = exports.isSupportedNamespace = exports.isSupportedWireAdapter = exports.ERROR_PREFIX = exports.WIRE_FUNCTION = void 0;
4
+ const adaptersMapping_1 = require("./adaptersMapping");
5
+ const allowlistAdapters_1 = require("./allowlistAdapters");
6
+ const common_shared_1 = require("@komaci/common-shared");
7
+ const validateGetter_1 = require("./validateGetter");
8
+ // TODO: eventually refactor list consts into their own file
9
+ exports.WIRE_FUNCTION = 'WireFunction';
10
+ exports.ERROR_PREFIX = '[komaci static-analyzer] ';
11
+ const emptyRange = {
12
+ start: { line: 0, character: 0 },
13
+ end: { line: 0, character: 0 },
14
+ };
15
+ /**
16
+ * Determine whether the wire adapter is supported
17
+ * @param resourceName the resource name of the Import, as a string
18
+ * @param adapterName the wire adapter variable name (import specifier export name) from a single
19
+ * Import statement (which can have more than one of these export names)
20
+ * @returns boolean true if the adapterName represents is a supported wire adapter (note that some
21
+ * resourceNames allow any adapterName as valid wire adapters)
22
+ */
23
+ function isSupportedWireAdapter(resourceName, adapterName) {
24
+ if (!resourceName || !adapterName) {
25
+ return false;
26
+ }
27
+ // check if the resourceName is one of the types that can have any wire adapter name. If so, return true.
28
+ // allow list of ResourceName that can be a "starsWith" match
29
+ for (const allowedResourceNamePrefix of allowlistAdapters_1.allowlistResourceNamesStartsWith) {
30
+ if (resourceName.startsWith(allowedResourceNamePrefix)) {
31
+ return true;
32
+ }
33
+ }
34
+ // allow list of ResourceNames that need to be an exact match
35
+ for (const allowedResourceName of allowlistAdapters_1.allowlistResourceNamesExact) {
36
+ if (resourceName === allowedResourceName) {
37
+ return true;
38
+ }
39
+ }
40
+ // check the allowlist of wire adapters for certain various resourceNames that all start with "lightning".
41
+ for (const [resourceNameKey, adapterList] of Object.entries(allowlistAdapters_1.allowlistAdapters)) {
42
+ if (resourceNameKey === resourceName && adapterList.includes(adapterName)) {
43
+ return true;
44
+ }
45
+ }
46
+ // check if there's an associated LDS priming adapter.
47
+ if ((0, exports.getPrimingAdapter)(resourceName, adapterName)) {
48
+ return true;
49
+ }
50
+ return false;
51
+ }
52
+ exports.isSupportedWireAdapter = isSupportedWireAdapter;
53
+ /**
54
+ * Determine whether the resource name is in a supported namespace
55
+ * @param resourceName the resource name of the Import, as a string
56
+ * @returns boolean true if the resource name is in a supported namespace
57
+ */
58
+ function isSupportedNamespace(resourceName) {
59
+ // check for relative, null, or empty namespaces (which are not allowed)
60
+ // Ex: undefined, '', './app_const1', './parent.html'
61
+ if (!resourceName || resourceName === '' || resourceName.startsWith('./')) {
62
+ return false;
63
+ }
64
+ // imports where parent class is for a relative import.
65
+ // Ex: import { Foo } from './foo';
66
+ if (resourceName.startsWith('@salesforce/komaci/.')) {
67
+ return false;
68
+ }
69
+ return ((0, common_shared_1.isNamespaceInternal)((0, common_shared_1.getNamespaceFromImport)(resourceName)) &&
70
+ (0, common_shared_1.isLibraryValid)(resourceName));
71
+ }
72
+ exports.isSupportedNamespace = isSupportedNamespace;
73
+ const getPrimingAdapter = (importPath, identifier) => {
74
+ const adapterMap = adaptersMapping_1.wireAdaptersMap[importPath];
75
+ if (adapterMap === undefined) {
76
+ return null;
77
+ }
78
+ const primingAdapter = adapterMap[identifier];
79
+ if (primingAdapter === undefined) {
80
+ return null;
81
+ }
82
+ return primingAdapter;
83
+ };
84
+ exports.getPrimingAdapter = getPrimingAdapter;
85
+ /* Related utilty functions to convert Locations of various types into a Range format and indexing scheme supported by
86
+ the Lightning Language Server
87
+ (0-index based for lines and columns, and a specific format where `column` is called `character`) */
88
+ exports.LLSRange = {
89
+ /**
90
+ * Converts an lwc-metadata SourceLocation (1-indexed for both line and column) into a Lightning Language
91
+ * Server-compatible Range object.
92
+ * @param {Location} location the SourceLocation, as represented by lwc-metadata, with komaci SourceLocation type
93
+ * @returns {Range} the komaci, Lightning Language Server-compatible Range object
94
+ */
95
+ fromLWCSourceLocation(location) {
96
+ let range;
97
+ if (location === undefined) {
98
+ range = emptyRange;
99
+ }
100
+ else {
101
+ // switch from lwc-metadata 1-index based range to 0-index based range
102
+ // as required by lightning language server
103
+ const startPos = {
104
+ line: location.startLine - 1,
105
+ character: location.startColumn - 1,
106
+ };
107
+ const endPos = {
108
+ line: location.endLine - 1,
109
+ character: location.endColumn - 1,
110
+ };
111
+ range = {
112
+ start: startPos,
113
+ end: endPos,
114
+ };
115
+ }
116
+ return range;
117
+ },
118
+ /**
119
+ * Converts a BabelJS SourceLocation (1-indexed for line, 0-indexed for column) into a Lightning Language
120
+ * Server-compatible Range object.
121
+ * @param {Location} location the SourceLocation, as represented by lwc-metadata, with komaci SourceLocation type
122
+ * @returns {Range} the komaci, Lightning Language Server-compatible Range object
123
+ */
124
+ fromBabelSourceLocation({ start, end }) {
125
+ return {
126
+ start: {
127
+ line: start.line - 1,
128
+ character: start.column,
129
+ },
130
+ end: {
131
+ line: end.line - 1,
132
+ character: end.column,
133
+ },
134
+ };
135
+ },
136
+ };
137
+ /**
138
+ * Function to analyze getter functions and collect any Priming Diagnostic info for invalid gettters.
139
+ * @param srcCode the source code to analyze.
140
+ * @param namespace the namespace of src file.
141
+ */
142
+ function analyzeSrcForInvalidGetterFunctions(srcCode, namespace, properties) {
143
+ const rootAst = (0, common_shared_1.generateAstFromSrcCode)(srcCode);
144
+ const moduleContext = {
145
+ astContext: (0, common_shared_1.getAstContextObject)(rootAst),
146
+ isExternal: (0, common_shared_1.isExternalModule)(namespace),
147
+ };
148
+ const diagnostics = [];
149
+ const { getters } = (0, common_shared_1.getPropertyMetadataFromAst)(rootAst);
150
+ const identifiers = new Set();
151
+ const checkForPropertyReferences = {
152
+ // visitor for each type
153
+ MemberExpression(path) {
154
+ (0, common_shared_1.getMemberVarsFromGetter)(path, identifiers);
155
+ },
156
+ };
157
+ if (getters.length > 0) {
158
+ getters
159
+ .map((getter) => {
160
+ identifiers.clear();
161
+ getter.traverse(checkForPropertyReferences);
162
+ const name = (0, common_shared_1.getClassMethodName)(getter);
163
+ (0, common_shared_1.updatePropertyUsage)(name, Array.from(identifiers), properties, common_shared_1.PropertyTypes.GETTER);
164
+ return getter;
165
+ })
166
+ .forEach((func) => {
167
+ const res = (0, validateGetter_1.validateGetter)(func, moduleContext, true);
168
+ const getterDiagnostics = res;
169
+ diagnostics.push(...getterDiagnostics);
170
+ });
171
+ }
172
+ return diagnostics;
173
+ }
174
+ exports.analyzeSrcForInvalidGetterFunctions = analyzeSrcForInvalidGetterFunctions;
175
+ /**
176
+ * Type guard for the komaci Image type
177
+ * @param {Composition} composition the komaci Composition object
178
+ * @returns {boolean} true if the Composition is more specifically an Image, false if it is not an Image
179
+ */
180
+ function isImageComposition(composition) {
181
+ return composition.type === 'Image';
182
+ }
183
+ exports.isImageComposition = isImageComposition;
184
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1,100 @@
1
+ import { AnalyzerInput, PrimingDiagnostic, Range, Position, WireInfo } from './types';
2
+ export declare class StaticAnalyzer {
3
+ startPos: Position;
4
+ endPos: Position;
5
+ emptyRange: Range;
6
+ orderedWireInfos: WireInfo[];
7
+ wireInfoMap: Map<number, WireInfo>;
8
+ fileNamesMap: Map<string, string>;
9
+ /**
10
+ * Given a bundle of files of different types (html, js), this method will perform static analysis of the input source files,
11
+ * and will output the result of the analysis as an array of PrimingDiagnostic objects that are compliant with the lightning language server specifications.
12
+ * @param input AnalyzerInput object containing the source files, their types, and namespace information required for analysis.
13
+ * @returns array of PrimingDiagnostic, with each element containing the analysis message and location information for IDE syntax underlining.
14
+ */
15
+ analyzeBundle(input: AnalyzerInput): PrimingDiagnostic[];
16
+ /**
17
+ * Given a script (JS) file, this method will perform static analysis of the input source JS files,
18
+ * and will output the result of the analysis as an array of PrimingDiagnostic objects that are compliant with the lightning language server specifications.
19
+ * @param input AnalyzerInput object containing the source JS files, namespace and other information required for analysis.
20
+ * @returns array of PrimingDiagnostic, with each element containing the analysis message and location information for IDE syntax underlining.
21
+ */
22
+ analyzeScript(input: AnalyzerInput): PrimingDiagnostic[];
23
+ private processKomaciScriptDoc;
24
+ /**
25
+ * Given bundle komaciDocs, produce diagnostics for conditionals and iterators which are unanalyzable
26
+ * @param templateKomaciDoc KomaciDoc which provides composition information
27
+ * @param scriptKomaciDoc KomaciDoc which provides relevant adg information
28
+ * @returns array of PrimingDiagnostic, with each element containing the analysis message and location information for IDE syntax underlining.
29
+ */
30
+ private processKomaciTemplateDoc;
31
+ private findWireConfigsThatUsePrivateProperty;
32
+ /**
33
+ * Traverses direct dependencies of the input wire (represented by a WireInfo) to see if any
34
+ * are non-analyzable. If any are, the input wire is also marked as non-analyzable, and a PrimingDiagnostic
35
+ * is generated for each dependency that is non-analyzable.
36
+ * @param wireInfo the current WireInfo to evaluate
37
+ * @param orderedWireInfos an array of dependency-sorted WireInfo against which to check the
38
+ * state of dependencies of wireInfo
39
+ * @returns array of PrimingDiagnostic containing a diagnostic for all non-analyzable wires found.
40
+ */
41
+ private findPropagatedUnresolvedWireAdaptersFromConfigProp;
42
+ private findUnresolvableWireAdaptersFromImports;
43
+ private findWireConfigGetterReturningNonLiteral;
44
+ private findWireConfigForGetterReturningInaccessibleImports;
45
+ private findUnresolvedParentClass;
46
+ private findParentClassFromUnsupportedNS;
47
+ private findWiresWithReactivePropNameFromUnsupportedNS;
48
+ /**
49
+ * identify unsupported namespaces usage nested within wireConfig array property
50
+ */
51
+ private findNestedUnsupportedNSArray;
52
+ /**
53
+ * identify unsupported namespaces usage nested within wireConfig object property
54
+ */
55
+ private findNestedUnsupportedNSObject;
56
+ private findWireConfigReferenceNonExistProperty;
57
+ /**
58
+ * Produce diagnostics for iterators which iterate on unresolvable inputs, such as private properties
59
+ * or wired properties which associated to unresolvable wires
60
+ */
61
+ private findUnresolvableIterator;
62
+ /**
63
+ * Produce diagnostics for conditionals which act upon unresolvable inputs, such as private properties
64
+ * or wired properties which associated to unresolvable wires
65
+ */
66
+ private findUnresolvableConditional;
67
+ /**
68
+ * Produces diagnostic for images which refer to unresolvable `src` attributes within the `<img>` tag.
69
+ * Note that Images are a type of Composition
70
+ *
71
+ * @param {Composition} image the composition containing the Image
72
+ * @param {Adg[]} adgs an array of ADGs
73
+ * @returns {PrimingDiagnostic} a PrimingDiagnostic if an image with unresolvable `src` attribute is found. void otherwise
74
+ */
75
+ private findUnresolvableImage;
76
+ /**
77
+ * Convert array of Compositions into flattened array of Compositions,
78
+ * visiting top-level and nested children compositions
79
+ */
80
+ private compositionsToArray;
81
+ /**
82
+ * find Import name information (resourceName, importName) given komaciDoc imports and reference
83
+ */
84
+ private findImport;
85
+ private getMetadata;
86
+ private findWireConfigReferenceCircularDependency;
87
+ /**
88
+ * Given an input array of FunctionType function nodes, this method creates an array of WireInfo that is
89
+ * ordered in such a way that independent WireFunction nodes are placed towards the beginning of the array, and the
90
+ * most dependent ones are placed towards the end of the array, so that iterating the array from beginning to end
91
+ * while evaluating wire conditions without running into unencountered dependencies is actually possible
92
+ * @param adg Adg, containing needed properties for this method
93
+ * @param funcs Array of FunctionType, which correspond to WireInfos that this method creates
94
+ * @returns and array of WireInfo, which contain references to FunctionType nodes for Wires, and other important state
95
+ */
96
+ private reorderFunctionsByWireDependency;
97
+ private dependsOn;
98
+ private findWireInfo;
99
+ }
100
+ //# sourceMappingURL=staticAnalyzer.d.ts.map