bulltrackers-module 1.0.636 → 1.0.637
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.
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Comprehensive Computation Validator
|
|
3
3
|
* Validates computation structure, metadata, and code compliance during build
|
|
4
|
+
* UPDATED: Added Static Dependency Verification to prove context.computed access.
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
const acorn = require('acorn');
|
|
@@ -134,7 +135,8 @@ class ComputationValidator {
|
|
|
134
135
|
this.validateDependencies(dependencies, name);
|
|
135
136
|
|
|
136
137
|
// 4. Code Analysis (AST)
|
|
137
|
-
|
|
138
|
+
// UPDATED: Passing dependencies to enable context.computed verification
|
|
139
|
+
this.validateCode(CalcClass, name, metadata, dependencies);
|
|
138
140
|
|
|
139
141
|
// 5. Schema Validation (if present)
|
|
140
142
|
if (typeof CalcClass.getSchema === 'function') {
|
|
@@ -305,7 +307,7 @@ class ComputationValidator {
|
|
|
305
307
|
/**
|
|
306
308
|
* 4. Code Analysis (AST-based)
|
|
307
309
|
*/
|
|
308
|
-
validateCode(CalcClass, name, metadata) {
|
|
310
|
+
validateCode(CalcClass, name, metadata, dependencies) {
|
|
309
311
|
const processSource = CalcClass.prototype.process.toString();
|
|
310
312
|
|
|
311
313
|
// Parse AST
|
|
@@ -336,6 +338,8 @@ class ComputationValidator {
|
|
|
336
338
|
this.analyzeContextUsage(ast, name, metadata);
|
|
337
339
|
this.analyzeLayerUsage(ast, name);
|
|
338
340
|
this.analyzeResultAssignment(ast, name, metadata);
|
|
341
|
+
// UPDATED: Analyze Dependency Validity
|
|
342
|
+
this.analyzeDependencyUsage(ast, name, dependencies);
|
|
339
343
|
}
|
|
340
344
|
|
|
341
345
|
analyzeContextUsage(ast, name, metadata) {
|
|
@@ -386,6 +390,52 @@ class ComputationValidator {
|
|
|
386
390
|
});
|
|
387
391
|
}
|
|
388
392
|
|
|
393
|
+
/**
|
|
394
|
+
* [NEW] Analyzes usage of context.computed to ensure variables exist
|
|
395
|
+
*/
|
|
396
|
+
analyzeDependencyUsage(ast, name, dependencies) {
|
|
397
|
+
const declaredSet = new Set(dependencies);
|
|
398
|
+
const self = this;
|
|
399
|
+
|
|
400
|
+
walk.simple(ast, {
|
|
401
|
+
MemberExpression(node) {
|
|
402
|
+
// Look for: context.computed['Key'] OR context.computed.Key
|
|
403
|
+
if (node.object.type === 'MemberExpression' &&
|
|
404
|
+
node.object.object.type === 'Identifier' &&
|
|
405
|
+
node.object.object.name === 'context' &&
|
|
406
|
+
node.object.property.name === 'computed') {
|
|
407
|
+
|
|
408
|
+
let accessedKey = null;
|
|
409
|
+
|
|
410
|
+
// Case 1: Dot notation (context.computed.SomeDep)
|
|
411
|
+
if (!node.computed && node.property.type === 'Identifier') {
|
|
412
|
+
accessedKey = node.property.name;
|
|
413
|
+
}
|
|
414
|
+
// Case 2: Bracket notation with string literal (context.computed['SomeDep'])
|
|
415
|
+
else if (node.computed && node.property.type === 'Literal') {
|
|
416
|
+
accessedKey = node.property.value;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (accessedKey) {
|
|
420
|
+
if (!declaredSet.has(accessedKey)) {
|
|
421
|
+
// Check for casing mismatches to give helpful errors
|
|
422
|
+
const caseInsensitiveMatch = dependencies.find(d => d.toLowerCase() === accessedKey.toLowerCase());
|
|
423
|
+
|
|
424
|
+
if (caseInsensitiveMatch) {
|
|
425
|
+
self.errors.push(`[${name}] Dependency Casing Mismatch: Accessed '${accessedKey}' but declared '${caseInsensitiveMatch}'. Keys are case-sensitive.`);
|
|
426
|
+
} else {
|
|
427
|
+
self.errors.push(`[${name}] Accessing undeclared dependency: '${accessedKey}'. Add it to getDependencies() or fix the typo.`);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
} else if (node.computed) {
|
|
431
|
+
// Dynamic access (e.g. context.computed[someVar])
|
|
432
|
+
self.warnings.push(`[${name}] Dynamic access to context.computed detected. Cannot statically verify dependency existence.`);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
|
|
389
439
|
analyzeResultAssignment(ast, name, metadata) {
|
|
390
440
|
let assignsToResults = false;
|
|
391
441
|
let hasReturn = false;
|