zuzu-js 0.1.2 → 0.3.0
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/README.md +0 -6
- package/dist/zuzu-browser-worker.js +384 -84
- package/dist/zuzu-browser.js +388 -88
- package/lib/cli.js +1 -1
- package/lib/runtime-helpers.js +49 -0
- package/lib/runtime.js +42 -5
- package/lib/transpiler-new/codegen.js +66 -23
- package/lib/transpiler-new/parser.js +5 -9
- package/lib/transpiler-new/validate-bindings.js +21 -1
- package/package.json +1 -1
- package/stdlib/modules/test/parser.zzm +13 -2
package/lib/cli.js
CHANGED
|
@@ -254,7 +254,7 @@ function stripShebang( source ) {
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
function printVersion( runtime, verbose ) {
|
|
257
|
-
process.stdout.write( 'zuzu-js version 0.
|
|
257
|
+
process.stdout.write( 'zuzu-js version 0.3.0\n' );
|
|
258
258
|
if ( verbose ) {
|
|
259
259
|
process.stdout.write( '\nlib search paths:\n' );
|
|
260
260
|
for ( const p of runtime.getModuleSearchRoots() ) {
|
package/lib/runtime-helpers.js
CHANGED
|
@@ -251,6 +251,8 @@ function collectTopLevelDeclarations( source, stripPod ) {
|
|
|
251
251
|
let inSingle = false;
|
|
252
252
|
let inDouble = false;
|
|
253
253
|
let inBacktick = false;
|
|
254
|
+
let inRegex = false;
|
|
255
|
+
let inRegexClass = false;
|
|
254
256
|
let inLineComment = false;
|
|
255
257
|
let inBlockComment = false;
|
|
256
258
|
let escape = false;
|
|
@@ -280,6 +282,35 @@ function collectTopLevelDeclarations( source, stripPod ) {
|
|
|
280
282
|
masked.push( ch === '\n' ? '\n' : ' ' );
|
|
281
283
|
continue;
|
|
282
284
|
}
|
|
285
|
+
if ( inRegex ) {
|
|
286
|
+
if ( escape ) {
|
|
287
|
+
escape = false;
|
|
288
|
+
masked.push( ' ' );
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
if ( ch === '\\' ) {
|
|
292
|
+
escape = true;
|
|
293
|
+
masked.push( ' ' );
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
if ( ch === '[' ) {
|
|
297
|
+
inRegexClass = true;
|
|
298
|
+
masked.push( ' ' );
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
if ( ch === ']' ) {
|
|
302
|
+
inRegexClass = false;
|
|
303
|
+
masked.push( ' ' );
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
if ( ch === '/' && !inRegexClass ) {
|
|
307
|
+
inRegex = false;
|
|
308
|
+
masked.push( ' ' );
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
masked.push( ch === '\n' ? '\n' : ' ' );
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
283
314
|
if ( inSingle || inDouble || inBacktick ) {
|
|
284
315
|
if ( escape ) {
|
|
285
316
|
escape = false;
|
|
@@ -318,6 +349,12 @@ function collectTopLevelDeclarations( source, stripPod ) {
|
|
|
318
349
|
masked.push( ' ' );
|
|
319
350
|
continue;
|
|
320
351
|
}
|
|
352
|
+
if ( ch === '/' && looksLikeRegexLiteralStart( stripped, i ) ) {
|
|
353
|
+
inRegex = true;
|
|
354
|
+
inRegexClass = false;
|
|
355
|
+
masked.push( ' ' );
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
321
358
|
if ( ch === '\'' ) {
|
|
322
359
|
inSingle = true;
|
|
323
360
|
masked.push( ' ' );
|
|
@@ -391,6 +428,18 @@ function collectTopLevelDeclarations( source, stripPod ) {
|
|
|
391
428
|
return [ ...names ];
|
|
392
429
|
}
|
|
393
430
|
|
|
431
|
+
function looksLikeRegexLiteralStart( source, index ) {
|
|
432
|
+
let pos = index - 1;
|
|
433
|
+
while ( pos >= 0 && /\s/u.test( source[pos] ) ) {
|
|
434
|
+
pos--;
|
|
435
|
+
}
|
|
436
|
+
if ( pos < 0 ) {
|
|
437
|
+
return true;
|
|
438
|
+
}
|
|
439
|
+
const previous = source[pos];
|
|
440
|
+
return /[({[=,:;!~?&|+\-*%^<>]/u.test( previous );
|
|
441
|
+
}
|
|
442
|
+
|
|
394
443
|
function collectTopLevelUnpackDeclarationNames( source, topLevelMask ) {
|
|
395
444
|
const names = [];
|
|
396
445
|
const rx = /(?:^|[;\n])\s*(?:export\s+)?(?:let|const)\b/gm;
|
package/lib/runtime.js
CHANGED
|
@@ -53,6 +53,28 @@ const textEncoder = new TextEncoder();
|
|
|
53
53
|
const utf8Decoder = new TextDecoder( 'utf-8', { fatal: true } );
|
|
54
54
|
const ZUZU_SKIP_BUILD = Symbol.for( 'zuzu.skip_build' );
|
|
55
55
|
|
|
56
|
+
const runtimeVersion = (() => {
|
|
57
|
+
if ( typeof globalThis === 'object' && globalThis !== null ) {
|
|
58
|
+
const globalVersion = globalThis.__ZUZU_RUNTIME_VERSION;
|
|
59
|
+
if ( typeof globalVersion === 'string' && globalVersion.trim() ) {
|
|
60
|
+
return String( globalVersion );
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if ( typeof process === 'object' && process && process.versions ) {
|
|
64
|
+
try {
|
|
65
|
+
const packageMetadata = require( '../package.json' );
|
|
66
|
+
const packageVersion = packageMetadata && packageMetadata.version;
|
|
67
|
+
if ( packageVersion ) {
|
|
68
|
+
return String( packageVersion );
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch ( err ) {
|
|
72
|
+
return 'dev';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return 'dev';
|
|
76
|
+
})();
|
|
77
|
+
|
|
56
78
|
function defaultModuleSearchRoots( host, repoRoot, includePaths ) {
|
|
57
79
|
if ( host.name === 'browser' ) {
|
|
58
80
|
return [
|
|
@@ -1283,7 +1305,11 @@ function defineZuzuClass( name, base, spec = {} ) {
|
|
|
1283
1305
|
zuzuStoreField( this, field, value );
|
|
1284
1306
|
}
|
|
1285
1307
|
let named = null;
|
|
1286
|
-
|
|
1308
|
+
const lastArg = ctorArgs[ctorArgs.length - 1];
|
|
1309
|
+
if (
|
|
1310
|
+
ctorArgs.length === 1
|
|
1311
|
+
&& isPairListLike( ctorArgs[0] )
|
|
1312
|
+
) {
|
|
1287
1313
|
named = ctorArgs[0];
|
|
1288
1314
|
}
|
|
1289
1315
|
else if (
|
|
@@ -1294,6 +1320,20 @@ function defineZuzuClass( name, base, spec = {} ) {
|
|
|
1294
1320
|
) {
|
|
1295
1321
|
named = ctorArgs[0];
|
|
1296
1322
|
}
|
|
1323
|
+
else if (
|
|
1324
|
+
ctorArgs.length > 1
|
|
1325
|
+
&& isPairListLike( lastArg )
|
|
1326
|
+
) {
|
|
1327
|
+
named = lastArg;
|
|
1328
|
+
}
|
|
1329
|
+
else if (
|
|
1330
|
+
ctorArgs.length > 1
|
|
1331
|
+
&& lastArg
|
|
1332
|
+
&& typeof lastArg === 'object'
|
|
1333
|
+
&& !Array.isArray( lastArg )
|
|
1334
|
+
) {
|
|
1335
|
+
named = lastArg;
|
|
1336
|
+
}
|
|
1297
1337
|
const releaseTemporaryNamed = !skipBuild
|
|
1298
1338
|
&& isPairListLike( named )
|
|
1299
1339
|
&& named.__zuzu_temporary_call_args === true;
|
|
@@ -1459,9 +1499,6 @@ function zuzuCallMember( object, property, ...args ) {
|
|
|
1459
1499
|
if ( dictMethod ) {
|
|
1460
1500
|
return dictMethod( ...args );
|
|
1461
1501
|
}
|
|
1462
|
-
if ( args.length === 0 ) {
|
|
1463
|
-
return value;
|
|
1464
|
-
}
|
|
1465
1502
|
throw new TypeError( `${String( property )} is not a function` );
|
|
1466
1503
|
}
|
|
1467
1504
|
|
|
@@ -2421,7 +2458,7 @@ class ZuzuScript {
|
|
|
2421
2458
|
const systemGlobalSeed = {
|
|
2422
2459
|
language_version: 0,
|
|
2423
2460
|
runtime: 'zuzu-js',
|
|
2424
|
-
runtime_version:
|
|
2461
|
+
runtime_version: runtimeVersion,
|
|
2425
2462
|
platform: this.host.name,
|
|
2426
2463
|
inc: Object.freeze( moduleSearchRoots.slice() ),
|
|
2427
2464
|
deny_fs: capabilityFlags.fs ? false : true,
|
|
@@ -609,6 +609,8 @@ function extractSpecialPreludeNames( signature ) {
|
|
|
609
609
|
return [ '__zuzu_call_args', signature.headName, signature.restName, signature.namedName, '__i', '__a' ];
|
|
610
610
|
case 'scalar_pairlist':
|
|
611
611
|
return [ '__zuzu_call_args', signature.headName, signature.namedName, '__i', '__a' ];
|
|
612
|
+
case 'scalar_pairlist_array':
|
|
613
|
+
return [ '__zuzu_call_args', signature.headName, signature.namedName, signature.restName, '__i', '__a' ];
|
|
612
614
|
case 'variadic':
|
|
613
615
|
return [ '__zuzu_call_args', signature.headName, signature.restName, '__i', '__a' ];
|
|
614
616
|
default:
|
|
@@ -694,6 +696,22 @@ function analyzeSpecialSignature( params ) {
|
|
|
694
696
|
namedName: params[1].name,
|
|
695
697
|
};
|
|
696
698
|
}
|
|
699
|
+
if (
|
|
700
|
+
params.length === 3
|
|
701
|
+
&& params[0].type === 'Parameter'
|
|
702
|
+
&& params[1].type === 'SpecialParameter'
|
|
703
|
+
&& params[1].special === 'rest_only'
|
|
704
|
+
&& params[1].containerType === 'PairList'
|
|
705
|
+
&& params[2].type === 'Parameter'
|
|
706
|
+
&& ( params[2].typeName === 'Array' || params[2].typeName == null )
|
|
707
|
+
) {
|
|
708
|
+
return {
|
|
709
|
+
kind: 'scalar_pairlist_array',
|
|
710
|
+
headName: params[0].name,
|
|
711
|
+
namedName: params[1].name,
|
|
712
|
+
restName: params[2].name,
|
|
713
|
+
};
|
|
714
|
+
}
|
|
697
715
|
if (
|
|
698
716
|
params.length === 1
|
|
699
717
|
&& params[0].type === 'SpecialParameter'
|
|
@@ -729,7 +747,7 @@ function emitFunctionPreamble( params, signature = null ) {
|
|
|
729
747
|
for ( const param of params ) {
|
|
730
748
|
if ( param.type === 'SpecialParameter' ) {
|
|
731
749
|
if ( param.special === 'lead_rest' ) {
|
|
732
|
-
lines.push( `
|
|
750
|
+
lines.push( `const ${param.leadName} = arguments[${argIndex}];` );
|
|
733
751
|
argIndex++;
|
|
734
752
|
lines.push( `const ${param.name} = Array.prototype.slice.call( arguments, ${argIndex} );` );
|
|
735
753
|
continue;
|
|
@@ -757,13 +775,13 @@ function emitFunctionPreamble( params, signature = null ) {
|
|
|
757
775
|
continue;
|
|
758
776
|
}
|
|
759
777
|
if ( param.defaultValue ) {
|
|
760
|
-
lines.push( `
|
|
778
|
+
lines.push( `const ${paramName} = __argc__ > ${argIndex} ? arguments[${argIndex}] : ${emitExpression( param.defaultValue )};` );
|
|
761
779
|
}
|
|
762
780
|
else if ( param.optional ) {
|
|
763
|
-
lines.push( `
|
|
781
|
+
lines.push( `const ${paramName} = __argc__ > ${argIndex} ? arguments[${argIndex}] : null;` );
|
|
764
782
|
}
|
|
765
783
|
else {
|
|
766
|
-
lines.push( `
|
|
784
|
+
lines.push( `const ${paramName} = arguments[${argIndex}];` );
|
|
767
785
|
}
|
|
768
786
|
if ( param.typeName ) {
|
|
769
787
|
lines.push(
|
|
@@ -780,62 +798,84 @@ function emitSpecialFunctionPreamble( signature ) {
|
|
|
780
798
|
case 'pairlist_only':
|
|
781
799
|
return [
|
|
782
800
|
`const __zuzu_call_args = Array.prototype.slice.call( arguments );`,
|
|
783
|
-
|
|
801
|
+
'let __zuzu_named_args = __zuzu_pairlist_literal( [] );',
|
|
784
802
|
'for ( const __a of __zuzu_call_args ) {',
|
|
785
|
-
|
|
803
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { throw new Exception( "named PairList parameter only accepts named arguments" ); }',
|
|
786
804
|
'}',
|
|
805
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
787
806
|
].join( '\n' );
|
|
788
807
|
case 'pairlist_rest_array':
|
|
789
808
|
case 'rest_array_pairlist':
|
|
790
809
|
return [
|
|
791
810
|
`const __zuzu_call_args = Array.prototype.slice.call( arguments );`,
|
|
792
|
-
|
|
793
|
-
|
|
811
|
+
'let __zuzu_named_args = __zuzu_pairlist_literal( [] );',
|
|
812
|
+
'const __zuzu_rest_args = [];',
|
|
794
813
|
'for ( const __a of __zuzu_call_args ) {',
|
|
795
|
-
|
|
814
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }',
|
|
796
815
|
'}',
|
|
816
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
817
|
+
`const ${signature.restName} = __zuzu_rest_args;`,
|
|
797
818
|
].join( '\n' );
|
|
798
819
|
case 'lead_pairlist':
|
|
799
820
|
return [
|
|
800
821
|
'const __zuzu_call_args = Array.prototype.slice.call( arguments );',
|
|
801
|
-
`
|
|
802
|
-
|
|
803
|
-
|
|
822
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
823
|
+
'let __zuzu_named_args = __zuzu_pairlist_literal( [] );',
|
|
824
|
+
'const __zuzu_rest_args = [];',
|
|
804
825
|
'for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {',
|
|
805
826
|
'const __a = __zuzu_call_args[__i];',
|
|
806
|
-
|
|
827
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }',
|
|
807
828
|
'}',
|
|
829
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
830
|
+
`const ${signature.restName} = __zuzu_rest_args;`,
|
|
808
831
|
].join( '\n' );
|
|
809
832
|
case 'trail_pairlist':
|
|
810
833
|
return [
|
|
811
834
|
'const __zuzu_call_args = Array.prototype.slice.call( arguments );',
|
|
812
|
-
`
|
|
813
|
-
|
|
814
|
-
|
|
835
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
836
|
+
'const __zuzu_rest_args = [];',
|
|
837
|
+
'let __zuzu_named_args = __zuzu_pairlist_literal( [] );',
|
|
815
838
|
'for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {',
|
|
816
839
|
'const __a = __zuzu_call_args[__i];',
|
|
817
|
-
|
|
840
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }',
|
|
818
841
|
'}',
|
|
842
|
+
`const ${signature.restName} = __zuzu_rest_args;`,
|
|
843
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
819
844
|
].join( '\n' );
|
|
820
845
|
case 'scalar_pairlist':
|
|
821
846
|
return [
|
|
822
847
|
'const __zuzu_call_args = Array.prototype.slice.call( arguments );',
|
|
823
|
-
`
|
|
824
|
-
|
|
848
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
849
|
+
'let __zuzu_named_args = __zuzu_pairlist_literal( [] );',
|
|
825
850
|
'for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {',
|
|
826
851
|
'const __a = __zuzu_call_args[__i];',
|
|
827
|
-
|
|
852
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { throw new Exception( "named arguments not allowed for this function" ); }',
|
|
828
853
|
'}',
|
|
854
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
855
|
+
].join( '\n' );
|
|
856
|
+
case 'scalar_pairlist_array':
|
|
857
|
+
return [
|
|
858
|
+
'const __zuzu_call_args = Array.prototype.slice.call( arguments );',
|
|
859
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
860
|
+
'let __zuzu_named_args = __zuzu_pairlist_literal( [] );',
|
|
861
|
+
'const __zuzu_rest_args = [];',
|
|
862
|
+
'for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {',
|
|
863
|
+
'const __a = __zuzu_call_args[__i];',
|
|
864
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }',
|
|
865
|
+
'}',
|
|
866
|
+
`const ${signature.restName} = __zuzu_rest_args;`,
|
|
867
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
829
868
|
].join( '\n' );
|
|
830
869
|
case 'variadic':
|
|
831
870
|
return [
|
|
832
871
|
'const __zuzu_call_args = Array.prototype.slice.call( arguments );',
|
|
833
|
-
`
|
|
834
|
-
|
|
872
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
873
|
+
'const __zuzu_rest_args = [];',
|
|
835
874
|
'for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {',
|
|
836
875
|
'const __a = __zuzu_call_args[__i];',
|
|
837
|
-
|
|
876
|
+
'if ( __zuzu_is_pairlist( __a ) ) { throw new Exception( "named arguments not allowed for this function" ); } __zuzu_rest_args.push( __a );',
|
|
838
877
|
'}',
|
|
878
|
+
`const ${signature.restName} = __zuzu_rest_args;`,
|
|
839
879
|
].join( '\n' );
|
|
840
880
|
default:
|
|
841
881
|
return '';
|
|
@@ -2154,6 +2194,9 @@ function emitAssignmentExpression( node ) {
|
|
|
2154
2194
|
: `${left} = __zuzu_assign_strong( ${left}, ${right} )`;
|
|
2155
2195
|
}
|
|
2156
2196
|
if ( node.left && node.left.type === 'MemberExpression' ) {
|
|
2197
|
+
if ( !node.left.computed ) {
|
|
2198
|
+
throw new UnsupportedSyntaxError( 'Invalid assignment target' );
|
|
2199
|
+
}
|
|
2157
2200
|
const object = emitExpression( node.left.object );
|
|
2158
2201
|
const objectTarget = emitAssignmentTarget( node.left.object );
|
|
2159
2202
|
const key = node.left.computed
|
|
@@ -55,26 +55,22 @@ function parse( tokens, options = {} ) {
|
|
|
55
55
|
return tokens[index - 1];
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
function
|
|
58
|
+
function canTerminateSimpleStatement() {
|
|
59
59
|
const token = current();
|
|
60
|
-
const prev = previous();
|
|
61
|
-
if ( !prev ) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
60
|
if ( token.type === 'punctuation' && token.value === '}' ) {
|
|
65
61
|
return true;
|
|
66
62
|
}
|
|
67
63
|
if ( token.type === 'eof' ) {
|
|
68
64
|
return true;
|
|
69
65
|
}
|
|
70
|
-
return
|
|
66
|
+
return false;
|
|
71
67
|
}
|
|
72
68
|
|
|
73
69
|
function consumeStatementTerminator(message) {
|
|
74
70
|
if ( match( 'punctuation', ';' ) ) {
|
|
75
71
|
return;
|
|
76
72
|
}
|
|
77
|
-
if (
|
|
73
|
+
if ( canTerminateSimpleStatement() ) {
|
|
78
74
|
return;
|
|
79
75
|
}
|
|
80
76
|
throw new TranspilerSyntaxError( message || 'Expected statement terminator', current() );
|
|
@@ -1313,7 +1309,7 @@ function parse( tokens, options = {} ) {
|
|
|
1313
1309
|
prefix: true,
|
|
1314
1310
|
}, keyword, endLocFromNode( test ) );
|
|
1315
1311
|
}
|
|
1316
|
-
|
|
1312
|
+
consumeStatementTerminator( semicolonMessage );
|
|
1317
1313
|
const consequent = withLoc( {
|
|
1318
1314
|
type: 'BlockStatement',
|
|
1319
1315
|
body: [ stmt ],
|
|
@@ -1330,7 +1326,7 @@ function parse( tokens, options = {} ) {
|
|
|
1330
1326
|
const keyword = current();
|
|
1331
1327
|
index++;
|
|
1332
1328
|
const iterable = parseExpression();
|
|
1333
|
-
|
|
1329
|
+
consumeStatementTerminator( semicolonMessage );
|
|
1334
1330
|
const body = withLoc( {
|
|
1335
1331
|
type: 'BlockStatement',
|
|
1336
1332
|
body: [ stmt ],
|
|
@@ -235,6 +235,7 @@ function validateExpression( node, scope ) {
|
|
|
235
235
|
}
|
|
236
236
|
return;
|
|
237
237
|
case 'UpdateExpression':
|
|
238
|
+
requireValidAssignmentTarget( node.argument );
|
|
238
239
|
if ( node.argument && node.argument.type === 'Identifier' ) {
|
|
239
240
|
requireMutable( node.argument, scope );
|
|
240
241
|
}
|
|
@@ -242,6 +243,23 @@ function validateExpression( node, scope ) {
|
|
|
242
243
|
validateExpression( node.argument, scope );
|
|
243
244
|
}
|
|
244
245
|
return;
|
|
246
|
+
case 'UnaryExpression':
|
|
247
|
+
if ( node.operator === '++' || node.operator === '--' ) {
|
|
248
|
+
requireValidAssignmentTarget( node.argument );
|
|
249
|
+
if ( node.argument && node.argument.type === 'Identifier' ) {
|
|
250
|
+
requireMutable( node.argument, scope );
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
validateExpression( node.argument, scope );
|
|
254
|
+
}
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
validateChildNodes( node, scope );
|
|
258
|
+
return;
|
|
259
|
+
case 'RefExpression':
|
|
260
|
+
requireValidAssignmentTarget( node.argument );
|
|
261
|
+
validateExpression( node.argument, scope );
|
|
262
|
+
return;
|
|
245
263
|
case 'FunctionExpression':
|
|
246
264
|
validateFunctionBody( node, scope );
|
|
247
265
|
return;
|
|
@@ -261,11 +279,13 @@ function requireValidAssignmentTarget( node ) {
|
|
|
261
279
|
}
|
|
262
280
|
if (
|
|
263
281
|
target.type === 'Identifier'
|
|
264
|
-
|| target.type === 'MemberExpression'
|
|
265
282
|
|| target.type === 'SliceExpression'
|
|
266
283
|
) {
|
|
267
284
|
return;
|
|
268
285
|
}
|
|
286
|
+
if ( target.type === 'MemberExpression' && target.computed ) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
269
289
|
if (
|
|
270
290
|
target.type === 'BinaryExpression'
|
|
271
291
|
&& [ '@', '@@', '@?' ].includes( target.operator )
|
package/package.json
CHANGED
|
@@ -158,6 +158,7 @@ function parse_lines ( Array lines ) {
|
|
|
158
158
|
let top_level := _new_counts();
|
|
159
159
|
let assertions := _new_counts();
|
|
160
160
|
let planned := null;
|
|
161
|
+
let plan_directive := "";
|
|
161
162
|
let tests := [];
|
|
162
163
|
|
|
163
164
|
for ( let line in lines ) {
|
|
@@ -170,8 +171,11 @@ function parse_lines ( Array lines ) {
|
|
|
170
171
|
|
|
171
172
|
if ( body ~ /^\d+\.\.\d+\b/ ) {
|
|
172
173
|
if ( is_top_level ) {
|
|
173
|
-
let
|
|
174
|
-
|
|
174
|
+
let plan_parts := split( body, "#", 2 );
|
|
175
|
+
let range_parts := split( trim( plan_parts[0] ), "..", 2 );
|
|
176
|
+
planned := trim( range_parts.get( 1, "" ) ) + 0;
|
|
177
|
+
plan_directive := trim( plan_parts.get( 1, "" ) )
|
|
178
|
+
if plan_parts.length() > 1;
|
|
175
179
|
}
|
|
176
180
|
next;
|
|
177
181
|
}
|
|
@@ -186,10 +190,17 @@ function parse_lines ( Array lines ) {
|
|
|
186
190
|
}
|
|
187
191
|
}
|
|
188
192
|
|
|
193
|
+
let skip_all_plan := false;
|
|
194
|
+
if ( planned ≡ 0 and plan_directive ~ /^skip\b/i ) {
|
|
195
|
+
skip_all_plan := true;
|
|
196
|
+
}
|
|
197
|
+
|
|
189
198
|
return {
|
|
190
199
|
top_level: top_level,
|
|
191
200
|
assertions: assertions,
|
|
192
201
|
planned: planned,
|
|
202
|
+
plan_directive: plan_directive,
|
|
203
|
+
skip_all: skip_all_plan,
|
|
193
204
|
tests: tests,
|
|
194
205
|
};
|
|
195
206
|
}
|