@@ -256,6 +256,12 @@ export class Parser {
256256 this . errorHandler . tolerate ( this . unexpectedTokenError ( token , message ) ) ;
257257 }
258258
259+ tolerateInvalidLoopStatement ( ) {
260+ if ( this . matchKeyword ( "class" ) || this . matchKeyword ( "function" ) ) {
261+ this . tolerateError ( this . lookahead ) ;
262+ }
263+ }
264+
259265 collectComments ( ) {
260266 if ( ! this . config . comment ) {
261267 this . scanner . scanComments ( ) ;
@@ -772,8 +778,7 @@ export class Parser {
772778 return body ;
773779 }
774780
775- parsePropertyMethodFunction ( ) : Node . FunctionExpression {
776- const isGenerator = false ;
781+ parsePropertyMethodFunction ( isGenerator : boolean ) : Node . FunctionExpression {
777782 const node = this . createNode ( ) ;
778783
779784 const previousAllowYield = this . context . allowYield ;
@@ -785,19 +790,24 @@ export class Parser {
785790 return this . finalize ( node , new Node . FunctionExpression ( null , params . params , method , isGenerator ) ) ;
786791 }
787792
788- parsePropertyMethodAsyncFunction ( ) : Node . FunctionExpression {
793+ parsePropertyMethodAsyncFunction ( isGenerator : boolean ) : Node . FunctionExpression {
789794 const node = this . createNode ( ) ;
790795
791796 const previousAllowYield = this . context . allowYield ;
792797 const previousAwait = this . context . await ;
793798 this . context . allowYield = false ;
794799 this . context . await = true ;
800+
795801 const params = this . parseFormalParameters ( ) ;
802+ if ( params . message === Messages . StrictParamDupe ) {
803+ this . throwError ( Messages . DuplicateParameter ) ;
804+ }
805+
796806 const method = this . parsePropertyMethod ( params ) ;
797807 this . context . allowYield = previousAllowYield ;
798808 this . context . await = previousAwait ;
799809
800- return this . finalize ( node , new Node . AsyncFunctionExpression ( null , params . params , method ) ) ;
810+ return this . finalize ( node , new Node . AsyncFunctionExpression ( null , params . params , method , isGenerator ) ) ;
801811 }
802812
803813 parseObjectPropertyKey ( ) : Node . PropertyKey {
@@ -855,13 +865,18 @@ export class Parser {
855865 let method = false ;
856866 let shorthand = false ;
857867 let isAsync = false ;
868+ let isGenerator = false ;
858869
859870 if ( token . type === Token . Identifier ) {
860871 const id = token . value ;
861872 this . nextToken ( ) ;
862873 computed = this . match ( '[' ) ;
863874 isAsync = ! this . hasLineTerminator && ( id === 'async' ) &&
864- ! this . match ( ':' ) && ! this . match ( '(' ) && ! this . match ( '*' ) && ! this . match ( ',' ) ;
875+ ! this . match ( ':' ) && ! this . match ( '(' ) && ! this . match ( ',' ) ;
876+ isGenerator = this . match ( '*' ) ;
877+ if ( isGenerator ) {
878+ this . nextToken ( ) ;
879+ }
865880 key = isAsync ? this . parseObjectPropertyKey ( ) : this . finalize ( node , new Node . Identifier ( id ) ) ;
866881 } else if ( this . match ( '*' ) ) {
867882 this . nextToken ( ) ;
@@ -908,7 +923,7 @@ export class Parser {
908923 value = this . inheritCoverGrammar ( this . parseAssignmentExpression ) ;
909924
910925 } else if ( this . match ( '(' ) ) {
911- value = isAsync ? this . parsePropertyMethodAsyncFunction ( ) : this . parsePropertyMethodFunction ( ) ;
926+ value = isAsync ? this . parsePropertyMethodAsyncFunction ( isGenerator ) : this . parsePropertyMethodFunction ( isGenerator ) ;
912927 method = true ;
913928
914929 } else if ( token . type === Token . Identifier ) {
@@ -2125,7 +2140,7 @@ export class Parser {
21252140 return this . finalize ( node , new Node . Property ( 'init' , key , computed , value , method , shorthand ) ) ;
21262141 }
21272142
2128- parseRestProperty ( params , kind ) : Node . RestElement {
2143+ parseRestProperty ( params ) : Node . RestElement {
21292144 const node = this . createNode ( ) ;
21302145 this . expect ( '...' ) ;
21312146 const arg = this . parsePattern ( params ) ;
@@ -2144,7 +2159,7 @@ export class Parser {
21442159
21452160 this . expect ( '{' ) ;
21462161 while ( ! this . match ( '}' ) ) {
2147- properties . push ( this . match ( '...' ) ? this . parseRestProperty ( params , kind ) : this . parsePropertyPattern ( params , kind ) ) ;
2162+ properties . push ( this . match ( '...' ) ? this . parseRestProperty ( params ) : this . parsePropertyPattern ( params , kind ) ) ;
21482163 if ( ! this . match ( '}' ) ) {
21492164 this . expect ( ',' ) ;
21502165 }
@@ -2316,6 +2331,8 @@ export class Parser {
23162331 const node = this . createNode ( ) ;
23172332 this . expectKeyword ( 'do' ) ;
23182333
2334+ this . tolerateInvalidLoopStatement ( ) ;
2335+
23192336 const previousInIteration = this . context . inIteration ;
23202337 this . context . inIteration = true ;
23212338 const body = this . parseStatement ( ) ;
@@ -2519,6 +2536,7 @@ export class Parser {
25192536 body = this . finalize ( this . createNode ( ) , new Node . EmptyStatement ( ) ) ;
25202537 } else {
25212538 this . expect ( ')' ) ;
2539+ this . tolerateInvalidLoopStatement ( ) ;
25222540
25232541 const previousInIteration = this . context . inIteration ;
25242542 this . context . inIteration = true ;
@@ -3046,12 +3064,15 @@ export class Parser {
30463064
30473065 const isAsync = this . matchContextualKeyword ( 'async' ) ;
30483066 if ( isAsync ) {
3067+ if ( this . context . inIteration ) {
3068+ this . tolerateError ( Messages . AsyncFunctionInSingleStatementContext ) ;
3069+ }
30493070 this . nextToken ( ) ;
30503071 }
30513072
30523073 this . expectKeyword ( 'function' ) ;
30533074
3054- const isGenerator = isAsync ? false : this . match ( '*' ) ;
3075+ const isGenerator = this . match ( '*' ) ;
30553076 if ( isGenerator ) {
30563077 this . nextToken ( ) ;
30573078 }
@@ -3084,6 +3105,10 @@ export class Parser {
30843105 this . context . allowYield = ! isGenerator ;
30853106
30863107 const formalParameters = this . parseFormalParameters ( firstRestricted ) ;
3108+ if ( isGenerator && formalParameters . message === Messages . StrictParamDupe ) {
3109+ this . throwError ( Messages . DuplicateParameter ) ;
3110+ }
3111+
30873112 const params = formalParameters . params ;
30883113 const stricted = formalParameters . stricted ;
30893114 firstRestricted = formalParameters . firstRestricted ;
@@ -3107,8 +3132,9 @@ export class Parser {
31073132 this . context . await = previousAllowAwait ;
31083133 this . context . allowYield = previousAllowYield ;
31093134
3110- return isAsync ? this . finalize ( node , new Node . AsyncFunctionDeclaration ( id , params , body ) ) :
3111- this . finalize ( node , new Node . FunctionDeclaration ( id , params , body , isGenerator ) ) ;
3135+ return isAsync
3136+ ? this . finalize ( node , new Node . AsyncFunctionDeclaration ( id , params , body , isGenerator ) )
3137+ : this . finalize ( node , new Node . FunctionDeclaration ( id , params , body , isGenerator ) ) ;
31123138 }
31133139
31143140 parseFunctionExpression ( ) : Node . AsyncFunctionExpression | Node . FunctionExpression {
@@ -3121,7 +3147,7 @@ export class Parser {
31213147
31223148 this . expectKeyword ( 'function' ) ;
31233149
3124- const isGenerator = isAsync ? false : this . match ( '*' ) ;
3150+ const isGenerator = this . match ( '*' ) ;
31253151 if ( isGenerator ) {
31263152 this . nextToken ( ) ;
31273153 }
@@ -3154,6 +3180,10 @@ export class Parser {
31543180 }
31553181
31563182 const formalParameters = this . parseFormalParameters ( firstRestricted ) ;
3183+ if ( isGenerator && formalParameters . message === Messages . StrictParamDupe ) {
3184+ this . throwError ( Messages . DuplicateParameter ) ;
3185+ }
3186+
31573187 const params = formalParameters . params ;
31583188 const stricted = formalParameters . stricted ;
31593189 firstRestricted = formalParameters . firstRestricted ;
@@ -3176,8 +3206,9 @@ export class Parser {
31763206 this . context . await = previousAllowAwait ;
31773207 this . context . allowYield = previousAllowYield ;
31783208
3179- return isAsync ? this . finalize ( node , new Node . AsyncFunctionExpression ( id , params , body ) ) :
3180- this . finalize ( node , new Node . FunctionExpression ( id , params , body , isGenerator ) ) ;
3209+ return isAsync
3210+ ? this . finalize ( node , new Node . AsyncFunctionExpression ( id , params , body , isGenerator ) )
3211+ : this . finalize ( node , new Node . FunctionExpression ( id , params , body , isGenerator ) ) ;
31813212 }
31823213
31833214 // https://tc39.github.io/ecma262/#sec-directive-prologues-and-the-use-strict-directive
@@ -3360,6 +3391,7 @@ export class Parser {
33603391 let method = false ;
33613392 let isStatic = false ;
33623393 let isAsync = false ;
3394+ let isGenerator = false ;
33633395
33643396 if ( this . match ( '*' ) ) {
33653397 this . nextToken ( ) ;
@@ -3379,8 +3411,12 @@ export class Parser {
33793411 }
33803412 if ( ( token . type === Token . Identifier ) && ! this . hasLineTerminator && ( token . value === 'async' ) ) {
33813413 const punctuator = this . lookahead . value ;
3382- if ( punctuator !== ':' && punctuator !== '(' && punctuator !== '*' ) {
3414+ if ( punctuator !== ':' && punctuator !== '(' ) {
33833415 isAsync = true ;
3416+ isGenerator = this . match ( "*" ) ;
3417+ if ( isGenerator ) {
3418+ this . nextToken ( ) ;
3419+ }
33843420 token = this . lookahead ;
33853421 computed = this . match ( '[' ) ;
33863422 key = this . parseObjectPropertyKey ( ) ;
@@ -3415,7 +3451,7 @@ export class Parser {
34153451
34163452 if ( ! kind && key && this . match ( '(' ) ) {
34173453 kind = 'init' ;
3418- value = isAsync ? this . parsePropertyMethodAsyncFunction ( ) : this . parsePropertyMethodFunction ( ) ;
3454+ value = isAsync ? this . parsePropertyMethodAsyncFunction ( isGenerator ) : this . parsePropertyMethodFunction ( isGenerator ) ;
34193455 method = true ;
34203456 }
34213457
0 commit comments