@@ -27,6 +27,7 @@ interface Context {
27
27
inFunctionBody : boolean ;
28
28
inIteration : boolean ;
29
29
inSwitch : boolean ;
30
+ inClassConstructor : boolean ;
30
31
labelSet : any ;
31
32
strict : boolean ;
32
33
}
@@ -153,6 +154,7 @@ export class Parser {
153
154
inFunctionBody : false ,
154
155
inIteration : false ,
155
156
inSwitch : false ,
157
+ inClassConstructor : false ,
156
158
labelSet : { } ,
157
159
strict : false
158
160
} ;
@@ -256,6 +258,12 @@ export class Parser {
256
258
this . errorHandler . tolerate ( this . unexpectedTokenError ( token , message ) ) ;
257
259
}
258
260
261
+ tolerateInvalidLoopStatement ( ) {
262
+ if ( this . matchKeyword ( "class" ) || this . matchKeyword ( "function" ) ) {
263
+ this . tolerateError ( Messages . UnexpectedToken , this . lookahead ) ;
264
+ }
265
+ }
266
+
259
267
collectComments ( ) {
260
268
if ( ! this . config . comment ) {
261
269
this . scanner . scanComments ( ) ;
@@ -772,8 +780,7 @@ export class Parser {
772
780
return body ;
773
781
}
774
782
775
- parsePropertyMethodFunction ( ) : Node . FunctionExpression {
776
- const isGenerator = false ;
783
+ parsePropertyMethodFunction ( isGenerator : boolean ) : Node . FunctionExpression {
777
784
const node = this . createNode ( ) ;
778
785
779
786
const previousAllowYield = this . context . allowYield ;
@@ -785,19 +792,24 @@ export class Parser {
785
792
return this . finalize ( node , new Node . FunctionExpression ( null , params . params , method , isGenerator ) ) ;
786
793
}
787
794
788
- parsePropertyMethodAsyncFunction ( ) : Node . FunctionExpression {
795
+ parsePropertyMethodAsyncFunction ( isGenerator : boolean ) : Node . FunctionExpression {
789
796
const node = this . createNode ( ) ;
790
797
791
798
const previousAllowYield = this . context . allowYield ;
792
799
const previousAwait = this . context . await ;
793
800
this . context . allowYield = false ;
794
801
this . context . await = true ;
802
+
795
803
const params = this . parseFormalParameters ( ) ;
804
+ if ( params . message === Messages . StrictParamDupe ) {
805
+ this . throwError ( Messages . DuplicateParameter ) ;
806
+ }
807
+
796
808
const method = this . parsePropertyMethod ( params ) ;
797
809
this . context . allowYield = previousAllowYield ;
798
810
this . context . await = previousAwait ;
799
811
800
- return this . finalize ( node , new Node . AsyncFunctionExpression ( null , params . params , method ) ) ;
812
+ return this . finalize ( node , new Node . AsyncFunctionExpression ( null , params . params , method , isGenerator ) ) ;
801
813
}
802
814
803
815
parseObjectPropertyKey ( ) : Node . PropertyKey {
@@ -855,13 +867,18 @@ export class Parser {
855
867
let method = false ;
856
868
let shorthand = false ;
857
869
let isAsync = false ;
870
+ let isGenerator = false ;
858
871
859
872
if ( token . type === Token . Identifier ) {
860
873
const id = token . value ;
861
874
this . nextToken ( ) ;
862
875
computed = this . match ( '[' ) ;
863
876
isAsync = ! this . hasLineTerminator && ( id === 'async' ) &&
864
- ! this . match ( ':' ) && ! this . match ( '(' ) && ! this . match ( '*' ) && ! this . match ( ',' ) ;
877
+ ! this . match ( ':' ) && ! this . match ( '(' ) && ! this . match ( ',' ) ;
878
+ isGenerator = this . match ( '*' ) ;
879
+ if ( isGenerator ) {
880
+ this . nextToken ( ) ;
881
+ }
865
882
key = isAsync ? this . parseObjectPropertyKey ( ) : this . finalize ( node , new Node . Identifier ( id ) ) ;
866
883
} else if ( this . match ( '*' ) ) {
867
884
this . nextToken ( ) ;
@@ -908,7 +925,7 @@ export class Parser {
908
925
value = this . inheritCoverGrammar ( this . parseAssignmentExpression ) ;
909
926
910
927
} else if ( this . match ( '(' ) ) {
911
- value = isAsync ? this . parsePropertyMethodAsyncFunction ( ) : this . parsePropertyMethodFunction ( ) ;
928
+ value = isAsync ? this . parsePropertyMethodAsyncFunction ( isGenerator ) : this . parsePropertyMethodFunction ( isGenerator ) ;
912
929
method = true ;
913
930
914
931
} else if ( token . type === Token . Identifier ) {
@@ -1331,7 +1348,8 @@ export class Parser {
1331
1348
this . context . allowIn = true ;
1332
1349
1333
1350
let expr ;
1334
- if ( this . matchKeyword ( 'super' ) && this . context . inFunctionBody ) {
1351
+ const isSuper = this . matchKeyword ( 'super' ) ;
1352
+ if ( isSuper && this . context . inFunctionBody ) {
1335
1353
expr = this . createNode ( ) ;
1336
1354
this . nextToken ( ) ;
1337
1355
expr = this . finalize ( expr , new Node . Super ( ) ) ;
@@ -1342,6 +1360,10 @@ export class Parser {
1342
1360
expr = this . inheritCoverGrammar ( this . matchKeyword ( 'new' ) ? this . parseNewExpression : this . parsePrimaryExpression ) ;
1343
1361
}
1344
1362
1363
+ if ( isSuper && this . match ( '(' ) && ! this . context . inClassConstructor ) {
1364
+ this . tolerateError ( Messages . UnexpectedSuper ) ;
1365
+ }
1366
+
1345
1367
let hasOptional = false ;
1346
1368
while ( true ) {
1347
1369
let optional = false ;
@@ -1426,8 +1448,11 @@ export class Parser {
1426
1448
assert ( this . context . allowIn , 'callee of new expression always allow in keyword.' ) ;
1427
1449
1428
1450
const node = this . startNode ( this . lookahead ) ;
1429
- let expr = ( this . matchKeyword ( 'super' ) && this . context . inFunctionBody ) ? this . parseSuper ( ) :
1430
- this . inheritCoverGrammar ( this . matchKeyword ( 'new' ) ? this . parseNewExpression : this . parsePrimaryExpression ) ;
1451
+ let expr = ( this . matchKeyword ( 'super' ) && this . context . inFunctionBody )
1452
+ ? this . parseSuper ( )
1453
+ : this . inheritCoverGrammar ( this . matchKeyword ( 'new' )
1454
+ ? this . parseNewExpression
1455
+ : this . parsePrimaryExpression ) ;
1431
1456
1432
1457
let hasOptional = false ;
1433
1458
while ( true ) {
@@ -2125,7 +2150,7 @@ export class Parser {
2125
2150
return this . finalize ( node , new Node . Property ( 'init' , key , computed , value , method , shorthand ) ) ;
2126
2151
}
2127
2152
2128
- parseRestProperty ( params , kind ) : Node . RestElement {
2153
+ parseRestProperty ( params ) : Node . RestElement {
2129
2154
const node = this . createNode ( ) ;
2130
2155
this . expect ( '...' ) ;
2131
2156
const arg = this . parsePattern ( params ) ;
@@ -2144,7 +2169,7 @@ export class Parser {
2144
2169
2145
2170
this . expect ( '{' ) ;
2146
2171
while ( ! this . match ( '}' ) ) {
2147
- properties . push ( this . match ( '...' ) ? this . parseRestProperty ( params , kind ) : this . parsePropertyPattern ( params , kind ) ) ;
2172
+ properties . push ( this . match ( '...' ) ? this . parseRestProperty ( params ) : this . parsePropertyPattern ( params , kind ) ) ;
2148
2173
if ( ! this . match ( '}' ) ) {
2149
2174
this . expect ( ',' ) ;
2150
2175
}
@@ -2316,6 +2341,8 @@ export class Parser {
2316
2341
const node = this . createNode ( ) ;
2317
2342
this . expectKeyword ( 'do' ) ;
2318
2343
2344
+ this . tolerateInvalidLoopStatement ( ) ;
2345
+
2319
2346
const previousInIteration = this . context . inIteration ;
2320
2347
this . context . inIteration = true ;
2321
2348
const body = this . parseStatement ( ) ;
@@ -2519,6 +2546,7 @@ export class Parser {
2519
2546
body = this . finalize ( this . createNode ( ) , new Node . EmptyStatement ( ) ) ;
2520
2547
} else {
2521
2548
this . expect ( ')' ) ;
2549
+ this . tolerateInvalidLoopStatement ( ) ;
2522
2550
2523
2551
const previousInIteration = this . context . inIteration ;
2524
2552
this . context . inIteration = true ;
@@ -3046,12 +3074,15 @@ export class Parser {
3046
3074
3047
3075
const isAsync = this . matchContextualKeyword ( 'async' ) ;
3048
3076
if ( isAsync ) {
3077
+ if ( this . context . inIteration ) {
3078
+ this . tolerateError ( Messages . AsyncFunctionInSingleStatementContext ) ;
3079
+ }
3049
3080
this . nextToken ( ) ;
3050
3081
}
3051
3082
3052
3083
this . expectKeyword ( 'function' ) ;
3053
3084
3054
- const isGenerator = isAsync ? false : this . match ( '*' ) ;
3085
+ const isGenerator = this . match ( '*' ) ;
3055
3086
if ( isGenerator ) {
3056
3087
this . nextToken ( ) ;
3057
3088
}
@@ -3084,6 +3115,10 @@ export class Parser {
3084
3115
this . context . allowYield = ! isGenerator ;
3085
3116
3086
3117
const formalParameters = this . parseFormalParameters ( firstRestricted ) ;
3118
+ if ( isGenerator && formalParameters . message === Messages . StrictParamDupe ) {
3119
+ this . throwError ( Messages . DuplicateParameter ) ;
3120
+ }
3121
+
3087
3122
const params = formalParameters . params ;
3088
3123
const stricted = formalParameters . stricted ;
3089
3124
firstRestricted = formalParameters . firstRestricted ;
@@ -3107,8 +3142,9 @@ export class Parser {
3107
3142
this . context . await = previousAllowAwait ;
3108
3143
this . context . allowYield = previousAllowYield ;
3109
3144
3110
- return isAsync ? this . finalize ( node , new Node . AsyncFunctionDeclaration ( id , params , body ) ) :
3111
- this . finalize ( node , new Node . FunctionDeclaration ( id , params , body , isGenerator ) ) ;
3145
+ return isAsync
3146
+ ? this . finalize ( node , new Node . AsyncFunctionDeclaration ( id , params , body , isGenerator ) )
3147
+ : this . finalize ( node , new Node . FunctionDeclaration ( id , params , body , isGenerator ) ) ;
3112
3148
}
3113
3149
3114
3150
parseFunctionExpression ( ) : Node . AsyncFunctionExpression | Node . FunctionExpression {
@@ -3121,7 +3157,7 @@ export class Parser {
3121
3157
3122
3158
this . expectKeyword ( 'function' ) ;
3123
3159
3124
- const isGenerator = isAsync ? false : this . match ( '*' ) ;
3160
+ const isGenerator = this . match ( '*' ) ;
3125
3161
if ( isGenerator ) {
3126
3162
this . nextToken ( ) ;
3127
3163
}
@@ -3154,6 +3190,12 @@ export class Parser {
3154
3190
}
3155
3191
3156
3192
const formalParameters = this . parseFormalParameters ( firstRestricted ) ;
3193
+ if ( formalParameters . message === Messages . StrictParamDupe ) {
3194
+ if ( isGenerator || isAsync ) {
3195
+ this . throwError ( Messages . DuplicateParameter ) ;
3196
+ }
3197
+ }
3198
+
3157
3199
const params = formalParameters . params ;
3158
3200
const stricted = formalParameters . stricted ;
3159
3201
firstRestricted = formalParameters . firstRestricted ;
@@ -3176,8 +3218,9 @@ export class Parser {
3176
3218
this . context . await = previousAllowAwait ;
3177
3219
this . context . allowYield = previousAllowYield ;
3178
3220
3179
- return isAsync ? this . finalize ( node , new Node . AsyncFunctionExpression ( id , params , body ) ) :
3180
- this . finalize ( node , new Node . FunctionExpression ( id , params , body , isGenerator ) ) ;
3221
+ return isAsync
3222
+ ? this . finalize ( node , new Node . AsyncFunctionExpression ( id , params , body , isGenerator ) )
3223
+ : this . finalize ( node , new Node . FunctionExpression ( id , params , body , isGenerator ) ) ;
3181
3224
}
3182
3225
3183
3226
// https://tc39.github.io/ecma262/#sec-directive-prologues-and-the-use-strict-directive
@@ -3360,6 +3403,7 @@ export class Parser {
3360
3403
let method = false ;
3361
3404
let isStatic = false ;
3362
3405
let isAsync = false ;
3406
+ let isGenerator = false ;
3363
3407
3364
3408
if ( this . match ( '*' ) ) {
3365
3409
this . nextToken ( ) ;
@@ -3379,8 +3423,12 @@ export class Parser {
3379
3423
}
3380
3424
if ( ( token . type === Token . Identifier ) && ! this . hasLineTerminator && ( token . value === 'async' ) ) {
3381
3425
const punctuator = this . lookahead . value ;
3382
- if ( punctuator !== ':' && punctuator !== '(' && punctuator !== '*' ) {
3426
+ if ( punctuator !== ':' && punctuator !== '(' ) {
3383
3427
isAsync = true ;
3428
+ isGenerator = this . match ( "*" ) ;
3429
+ if ( isGenerator ) {
3430
+ this . nextToken ( ) ;
3431
+ }
3384
3432
token = this . lookahead ;
3385
3433
computed = this . match ( '[' ) ;
3386
3434
key = this . parseObjectPropertyKey ( ) ;
@@ -3414,8 +3462,11 @@ export class Parser {
3414
3462
}
3415
3463
3416
3464
if ( ! kind && key && this . match ( '(' ) ) {
3465
+ const previousInClassConstructor = this . context . inClassConstructor ;
3466
+ this . context . inClassConstructor = token . value === 'constructor' ;
3417
3467
kind = 'init' ;
3418
- value = isAsync ? this . parsePropertyMethodAsyncFunction ( ) : this . parsePropertyMethodFunction ( ) ;
3468
+ value = isAsync ? this . parsePropertyMethodAsyncFunction ( isGenerator ) : this . parsePropertyMethodFunction ( isGenerator ) ;
3469
+ this . context . inClassConstructor = previousInClassConstructor ;
3419
3470
method = true ;
3420
3471
}
3421
3472
0 commit comments