bare-script 3.8.2 → 3.8.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/lib/model.js +52 -0
- package/lib/runtimeAsync.js +6 -6
- package/package.json +1 -1
package/lib/model.js
CHANGED
|
@@ -433,9 +433,15 @@ export function lintScript(script, globals = null) {
|
|
|
433
433
|
// Iterate function statements
|
|
434
434
|
const fnLabelsDefined = {};
|
|
435
435
|
const fnLabelsUsed = {};
|
|
436
|
+
let hasAsyncStatement = false;
|
|
436
437
|
for (const [ixFnStatement, fnStatement] of fnStatements.entries()) {
|
|
437
438
|
const [fnStatementKey] = Object.keys(fnStatement);
|
|
438
439
|
|
|
440
|
+
// Any async statements?
|
|
441
|
+
if (globals !== null) {
|
|
442
|
+
hasAsyncStatement ||= isAsyncStatement(fnStatement, globals, statement.function.async ?? false);
|
|
443
|
+
}
|
|
444
|
+
|
|
439
445
|
// Function expression statement checks
|
|
440
446
|
if (fnStatementKey === 'expr') {
|
|
441
447
|
// Pointless function expression statement?
|
|
@@ -478,6 +484,15 @@ export function lintScript(script, globals = null) {
|
|
|
478
484
|
}
|
|
479
485
|
}
|
|
480
486
|
|
|
487
|
+
// Async function issues?
|
|
488
|
+
if (globals !== null) {
|
|
489
|
+
if (statement.function.async && !hasAsyncStatement) {
|
|
490
|
+
lintScriptWarning(warnings, script, statement, `Unecessary async function "${statement.function.name}"`);
|
|
491
|
+
} else if (!statement.function.async && hasAsyncStatement) {
|
|
492
|
+
lintScriptWarning(warnings, script, statement, `Function "${statement.function.name}" requires async`);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
481
496
|
// Global expression statement checks
|
|
482
497
|
} else if (statementKey === 'expr') {
|
|
483
498
|
// Pointless global expression statement?
|
|
@@ -549,6 +564,43 @@ function isPointlessExpression(expr) {
|
|
|
549
564
|
}
|
|
550
565
|
|
|
551
566
|
|
|
567
|
+
// Helper function to determine if a statement requires async
|
|
568
|
+
function isAsyncStatement(statement, globals, isAsync) {
|
|
569
|
+
const [statementKey] = Object.keys(statement);
|
|
570
|
+
if (statementKey === 'expr') {
|
|
571
|
+
return isAsyncExpression(statement.expr.expr, globals, isAsync);
|
|
572
|
+
} else if (statementKey === 'jump') {
|
|
573
|
+
return 'expr' in statement.jump ? isAsyncExpression(statement.jump.expr, globals, isAsync) : false;
|
|
574
|
+
} else if (statementKey === 'return') {
|
|
575
|
+
return 'expr' in statement.return ? isAsyncExpression(statement.return.expr, globals, isAsync) : false;
|
|
576
|
+
}
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
// Helper function to determine if an expression statement requires async
|
|
582
|
+
function isAsyncExpression(expr, globals, isAsync) {
|
|
583
|
+
const [exprKey] = Object.keys(expr);
|
|
584
|
+
if (exprKey === 'function') {
|
|
585
|
+
// Global function not exist? Assume its OK for the scope
|
|
586
|
+
const funcValue = globals[expr.function.name] ?? null;
|
|
587
|
+
if (funcValue === null) {
|
|
588
|
+
return isAsync;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// Is function async?
|
|
592
|
+
return typeof funcValue === 'function' && funcValue.constructor.name === 'AsyncFunction';
|
|
593
|
+
} else if (exprKey === 'binary') {
|
|
594
|
+
return isAsyncExpression(expr.binary.left, globals, isAsync) || isAsyncExpression(expr.binary.right, globals, isAsync);
|
|
595
|
+
} else if (exprKey === 'unary') {
|
|
596
|
+
return isAsyncExpression(expr.unary.expr, globals, isAsync);
|
|
597
|
+
} else if (exprKey === 'group') {
|
|
598
|
+
return isAsyncExpression(expr.group, globals, isAsync);
|
|
599
|
+
}
|
|
600
|
+
return false;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
|
|
552
604
|
// Helper function to set variable assignments/uses for a statements array
|
|
553
605
|
function getVariableAssignmentsAndUses(statements, assigns, uses) {
|
|
554
606
|
for (const [ixStatement, statement] of statements.entries()) {
|
package/lib/runtimeAsync.js
CHANGED
|
@@ -187,9 +187,14 @@ async function executeScriptHelperAsync(script, statements, options, locals) {
|
|
|
187
187
|
includeScript.system = true;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
// Execute the include script
|
|
191
|
+
const includeOptions = {...options};
|
|
192
|
+
includeOptions.urlFn = (url) => urlFileRelative(includeURL, url);
|
|
193
|
+
await executeScriptHelperAsync(includeScript, includeScript.statements, includeOptions, null);
|
|
194
|
+
|
|
190
195
|
// Run the bare-script linter?
|
|
191
196
|
if ('logFn' in options && options.debug) {
|
|
192
|
-
const warnings = lintScript(includeScript);
|
|
197
|
+
const warnings = lintScript(includeScript, globals);
|
|
193
198
|
const warningPrefix = `BareScript: Include "${includeURL}" static analysis...`;
|
|
194
199
|
if (warnings.length) {
|
|
195
200
|
options.logFn(`${warningPrefix} ${warnings.length} warning${warnings.length > 1 ? 's' : ''}:`);
|
|
@@ -198,11 +203,6 @@ async function executeScriptHelperAsync(script, statements, options, locals) {
|
|
|
198
203
|
}
|
|
199
204
|
}
|
|
200
205
|
}
|
|
201
|
-
|
|
202
|
-
// Execute the include script
|
|
203
|
-
const includeOptions = {...options};
|
|
204
|
-
includeOptions.urlFn = (url) => urlFileRelative(includeURL, url);
|
|
205
|
-
await executeScriptHelperAsync(includeScript, includeScript.statements, includeOptions, null);
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
}
|