@@ -27,6 +27,7 @@ interface Context {
2727 inFunctionBody : boolean ;
2828 inIteration : boolean ;
2929 inSwitch : boolean ;
30+ inClassConstructor : boolean ;
3031 labelSet : any ;
3132 strict : boolean ;
3233}
@@ -153,6 +154,7 @@ export class Parser {
153154 inFunctionBody : false ,
154155 inIteration : false ,
155156 inSwitch : false ,
157+ inClassConstructor : false ,
156158 labelSet : { } ,
157159 strict : false
158160 } ;
@@ -256,6 +258,12 @@ export class Parser {
256258 this . errorHandler . tolerate ( this . unexpectedTokenError ( token , message ) ) ;
257259 }
258260
261+ tolerateInvalidLoopStatement ( ) {
262+ if ( this . matchKeyword ( "class" ) || this . matchKeyword ( "function" ) ) {
263+ this . tolerateError ( Messages . UnexpectedToken , this . lookahead ) ;
264+ }
265+ }
266+
259267 collectComments ( ) {
260268 if ( ! this . config . comment ) {
261269 this . scanner . scanComments ( ) ;
@@ -772,8 +780,7 @@ export class Parser {
772780 return body ;
773781 }
774782
775- parsePropertyMethodFunction ( ) : Node . FunctionExpression {
776- const isGenerator = false ;
783+ parsePropertyMethodFunction ( isGenerator : boolean ) : Node . FunctionExpression {
777784 const node = this . createNode ( ) ;
778785
779786 const previousAllowYield = this . context . allowYield ;
@@ -785,19 +792,24 @@ export class Parser {
785792 return this . finalize ( node , new Node . FunctionExpression ( null , params . params , method , isGenerator ) ) ;
786793 }
787794
788- parsePropertyMethodAsyncFunction ( ) : Node . FunctionExpression {
795+ parsePropertyMethodAsyncFunction ( isGenerator : boolean ) : Node . FunctionExpression {
789796 const node = this . createNode ( ) ;
790797
791798 const previousAllowYield = this . context . allowYield ;
792799 const previousAwait = this . context . await ;
793800 this . context . allowYield = false ;
794801 this . context . await = true ;
802+
795803 const params = this . parseFormalParameters ( ) ;
804+ if ( params . message === Messages . StrictParamDupe ) {
805+ this . throwError ( Messages . DuplicateParameter ) ;
806+ }
807+
796808 const method = this . parsePropertyMethod ( params ) ;
797809 this . context . allowYield = previousAllowYield ;
798810 this . context . await = previousAwait ;
799811
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 ) ) ;
801813 }
802814
803815 parseObjectPropertyKey ( ) : Node . PropertyKey {
@@ -855,13 +867,18 @@ export class Parser {
855867 let method = false ;
856868 let shorthand = false ;
857869 let isAsync = false ;
870+ let isGenerator = false ;
858871
859872 if ( token . type === Token . Identifier ) {
860873 const id = token . value ;
861874 this . nextToken ( ) ;
862875 computed = this . match ( '[' ) ;
863876 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+ }
865882 key = isAsync ? this . parseObjectPropertyKey ( ) : this . finalize ( node , new Node . Identifier ( id ) ) ;
866883 } else if ( this . match ( '*' ) ) {
867884 this . nextToken ( ) ;
@@ -908,7 +925,7 @@ export class Parser {
908925 value = this . inheritCoverGrammar ( this . parseAssignmentExpression ) ;
909926
910927 } else if ( this . match ( '(' ) ) {
911- value = isAsync ? this . parsePropertyMethodAsyncFunction ( ) : this . parsePropertyMethodFunction ( ) ;
928+ value = isAsync ? this . parsePropertyMethodAsyncFunction ( isGenerator ) : this . parsePropertyMethodFunction ( isGenerator ) ;
912929 method = true ;
913930
914931 } else if ( token . type === Token . Identifier ) {
@@ -1331,7 +1348,8 @@ export class Parser {
13311348 this . context . allowIn = true ;
13321349
13331350 let expr ;
1334- if ( this . matchKeyword ( 'super' ) && this . context . inFunctionBody ) {
1351+ const isSuper = this . matchKeyword ( 'super' ) ;
1352+ if ( isSuper && this . context . inFunctionBody ) {
13351353 expr = this . createNode ( ) ;
13361354 this . nextToken ( ) ;
13371355 expr = this . finalize ( expr , new Node . Super ( ) ) ;
@@ -1342,6 +1360,10 @@ export class Parser {
13421360 expr = this . inheritCoverGrammar ( this . matchKeyword ( 'new' ) ? this . parseNewExpression : this . parsePrimaryExpression ) ;
13431361 }
13441362
1363+ if ( isSuper && this . match ( '(' ) && ! this . context . inClassConstructor ) {
1364+ this . tolerateError ( Messages . UnexpectedSuper ) ;
1365+ }
1366+
13451367 let hasOptional = false ;
13461368 while ( true ) {
13471369 let optional = false ;
@@ -1426,8 +1448,11 @@ export class Parser {
14261448 assert ( this . context . allowIn , 'callee of new expression always allow in keyword.' ) ;
14271449
14281450 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 ) ;
14311456
14321457 let hasOptional = false ;
14331458 while ( true ) {
@@ -2125,7 +2150,7 @@ export class Parser {
21252150 return this . finalize ( node , new Node . Property ( 'init' , key , computed , value , method , shorthand ) ) ;
21262151 }
21272152
2128- parseRestProperty ( params , kind ) : Node . RestElement {
2153+ parseRestProperty ( params ) : Node . RestElement {
21292154 const node = this . createNode ( ) ;
21302155 this . expect ( '...' ) ;
21312156 const arg = this . parsePattern ( params ) ;
@@ -2144,7 +2169,7 @@ export class Parser {
21442169
21452170 this . expect ( '{' ) ;
21462171 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 ) ) ;
21482173 if ( ! this . match ( '}' ) ) {
21492174 this . expect ( ',' ) ;
21502175 }
@@ -2316,6 +2341,8 @@ export class Parser {
23162341 const node = this . createNode ( ) ;
23172342 this . expectKeyword ( 'do' ) ;
23182343
2344+ this . tolerateInvalidLoopStatement ( ) ;
2345+
23192346 const previousInIteration = this . context . inIteration ;
23202347 this . context . inIteration = true ;
23212348 const body = this . parseStatement ( ) ;
@@ -2519,6 +2546,7 @@ export class Parser {
25192546 body = this . finalize ( this . createNode ( ) , new Node . EmptyStatement ( ) ) ;
25202547 } else {
25212548 this . expect ( ')' ) ;
2549+ this . tolerateInvalidLoopStatement ( ) ;
25222550
25232551 const previousInIteration = this . context . inIteration ;
25242552 this . context . inIteration = true ;
@@ -3046,12 +3074,15 @@ export class Parser {
30463074
30473075 const isAsync = this . matchContextualKeyword ( 'async' ) ;
30483076 if ( isAsync ) {
3077+ if ( this . context . inIteration ) {
3078+ this . tolerateError ( Messages . AsyncFunctionInSingleStatementContext ) ;
3079+ }
30493080 this . nextToken ( ) ;
30503081 }
30513082
30523083 this . expectKeyword ( 'function' ) ;
30533084
3054- const isGenerator = isAsync ? false : this . match ( '*' ) ;
3085+ const isGenerator = this . match ( '*' ) ;
30553086 if ( isGenerator ) {
30563087 this . nextToken ( ) ;
30573088 }
@@ -3084,6 +3115,10 @@ export class Parser {
30843115 this . context . allowYield = ! isGenerator ;
30853116
30863117 const formalParameters = this . parseFormalParameters ( firstRestricted ) ;
3118+ if ( isGenerator && formalParameters . message === Messages . StrictParamDupe ) {
3119+ this . throwError ( Messages . DuplicateParameter ) ;
3120+ }
3121+
30873122 const params = formalParameters . params ;
30883123 const stricted = formalParameters . stricted ;
30893124 firstRestricted = formalParameters . firstRestricted ;
@@ -3107,8 +3142,9 @@ export class Parser {
31073142 this . context . await = previousAllowAwait ;
31083143 this . context . allowYield = previousAllowYield ;
31093144
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 ) ) ;
31123148 }
31133149
31143150 parseFunctionExpression ( ) : Node . AsyncFunctionExpression | Node . FunctionExpression {
@@ -3121,7 +3157,7 @@ export class Parser {
31213157
31223158 this . expectKeyword ( 'function' ) ;
31233159
3124- const isGenerator = isAsync ? false : this . match ( '*' ) ;
3160+ const isGenerator = this . match ( '*' ) ;
31253161 if ( isGenerator ) {
31263162 this . nextToken ( ) ;
31273163 }
@@ -3154,6 +3190,12 @@ export class Parser {
31543190 }
31553191
31563192 const formalParameters = this . parseFormalParameters ( firstRestricted ) ;
3193+ if ( formalParameters . message === Messages . StrictParamDupe ) {
3194+ if ( isGenerator || isAsync ) {
3195+ this . throwError ( Messages . DuplicateParameter ) ;
3196+ }
3197+ }
3198+
31573199 const params = formalParameters . params ;
31583200 const stricted = formalParameters . stricted ;
31593201 firstRestricted = formalParameters . firstRestricted ;
@@ -3176,8 +3218,9 @@ export class Parser {
31763218 this . context . await = previousAllowAwait ;
31773219 this . context . allowYield = previousAllowYield ;
31783220
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 ) ) ;
31813224 }
31823225
31833226 // https://tc39.github.io/ecma262/#sec-directive-prologues-and-the-use-strict-directive
@@ -3360,6 +3403,7 @@ export class Parser {
33603403 let method = false ;
33613404 let isStatic = false ;
33623405 let isAsync = false ;
3406+ let isGenerator = false ;
33633407
33643408 if ( this . match ( '*' ) ) {
33653409 this . nextToken ( ) ;
@@ -3379,8 +3423,12 @@ export class Parser {
33793423 }
33803424 if ( ( token . type === Token . Identifier ) && ! this . hasLineTerminator && ( token . value === 'async' ) ) {
33813425 const punctuator = this . lookahead . value ;
3382- if ( punctuator !== ':' && punctuator !== '(' && punctuator !== '*' ) {
3426+ if ( punctuator !== ':' && punctuator !== '(' ) {
33833427 isAsync = true ;
3428+ isGenerator = this . match ( "*" ) ;
3429+ if ( isGenerator ) {
3430+ this . nextToken ( ) ;
3431+ }
33843432 token = this . lookahead ;
33853433 computed = this . match ( '[' ) ;
33863434 key = this . parseObjectPropertyKey ( ) ;
@@ -3414,8 +3462,11 @@ export class Parser {
34143462 }
34153463
34163464 if ( ! kind && key && this . match ( '(' ) ) {
3465+ const previousInClassConstructor = this . context . inClassConstructor ;
3466+ this . context . inClassConstructor = token . value === 'constructor' ;
34173467 kind = 'init' ;
3418- value = isAsync ? this . parsePropertyMethodAsyncFunction ( ) : this . parsePropertyMethodFunction ( ) ;
3468+ value = isAsync ? this . parsePropertyMethodAsyncFunction ( isGenerator ) : this . parsePropertyMethodFunction ( isGenerator ) ;
3469+ this . context . inClassConstructor = previousInClassConstructor ;
34193470 method = true ;
34203471 }
34213472
0 commit comments