@@ -2899,7 +2899,34 @@ export class Parser extends DiagnosticEmitter {
28992899
29002900 let state = tn . mark ( ) ;
29012901 let token = tn . next ( ) ;
2902+ let label : IdentifierExpression | null = null ;
29022903 let statement : Statement | null = null ;
2904+
2905+ // Detect labeled statements
2906+ if ( token == Token . Identifier ) {
2907+ const preIdentifierState = tn . mark ( ) ;
2908+ const identifier = tn . readIdentifier ( ) ;
2909+ const range = tn . range ( ) ;
2910+
2911+ if ( tn . skip ( Token . Colon ) ) {
2912+ label = Node . createIdentifierExpression ( identifier , range ) ;
2913+ token = tn . next ( ) ;
2914+
2915+ switch ( token ) {
2916+ case Token . For :
2917+ case Token . While :
2918+ case Token . Do :
2919+ case Token . OpenBrace :
2920+ // Do nothing
2921+ break ;
2922+ default :
2923+ this . error ( DiagnosticCode . A_label_is_not_allowed_here , range ) ;
2924+ }
2925+ } else {
2926+ tn . reset ( preIdentifierState ) ;
2927+ }
2928+ }
2929+
29032930 switch ( token ) {
29042931 case Token . Break : {
29052932 statement = this . parseBreak ( tn ) ;
@@ -2914,11 +2941,11 @@ export class Parser extends DiagnosticEmitter {
29142941 break ;
29152942 }
29162943 case Token . Do : {
2917- statement = this . parseDoStatement ( tn ) ;
2944+ statement = this . parseDoStatement ( tn , label ) ;
29182945 break ;
29192946 }
29202947 case Token . For : {
2921- statement = this . parseForStatement ( tn ) ;
2948+ statement = this . parseForStatement ( tn , label ) ;
29222949 break ;
29232950 }
29242951 case Token . If : {
@@ -2934,7 +2961,7 @@ export class Parser extends DiagnosticEmitter {
29342961 break ;
29352962 }
29362963 case Token . OpenBrace : {
2937- statement = this . parseBlockStatement ( tn , topLevel ) ;
2964+ statement = this . parseBlockStatement ( tn , topLevel , label ) ;
29382965 break ;
29392966 }
29402967 case Token . Return : {
@@ -2967,7 +2994,7 @@ export class Parser extends DiagnosticEmitter {
29672994 break ;
29682995 }
29692996 case Token . While : {
2970- statement = this . parseWhileStatement ( tn ) ;
2997+ statement = this . parseWhileStatement ( tn , label ) ;
29712998 break ;
29722999 }
29733000 case Token . Type : { // also identifier
@@ -2994,7 +3021,8 @@ export class Parser extends DiagnosticEmitter {
29943021
29953022 parseBlockStatement (
29963023 tn : Tokenizer ,
2997- topLevel : bool
3024+ topLevel : bool ,
3025+ label : IdentifierExpression | null = null
29983026 ) : BlockStatement | null {
29993027
30003028 // at '{': Statement* '}' ';'?
@@ -3013,7 +3041,7 @@ export class Parser extends DiagnosticEmitter {
30133041 statements . push ( statement ) ;
30143042 }
30153043 }
3016- let ret = Node . createBlockStatement ( statements , tn . range ( startPos , tn . pos ) ) ;
3044+ let ret = Node . createBlockStatement ( statements , label , tn . range ( startPos , tn . pos ) ) ;
30173045 if ( topLevel ) tn . skip ( Token . Semicolon ) ;
30183046 return ret ;
30193047 }
@@ -3051,7 +3079,8 @@ export class Parser extends DiagnosticEmitter {
30513079 }
30523080
30533081 parseDoStatement (
3054- tn : Tokenizer
3082+ tn : Tokenizer ,
3083+ label : IdentifierExpression | null
30553084 ) : DoStatement | null {
30563085
30573086 // at 'do': Statement 'while' '(' Expression ')' ';'?
@@ -3067,7 +3096,7 @@ export class Parser extends DiagnosticEmitter {
30673096 if ( ! condition ) return null ;
30683097
30693098 if ( tn . skip ( Token . CloseParen ) ) {
3070- let ret = Node . createDoStatement ( statement , condition , tn . range ( startPos , tn . pos ) ) ;
3099+ let ret = Node . createDoStatement ( statement , condition , label , tn . range ( startPos , tn . pos ) ) ;
30713100 tn . skip ( Token . Semicolon ) ;
30723101 return ret ;
30733102 } else {
@@ -3106,7 +3135,8 @@ export class Parser extends DiagnosticEmitter {
31063135 }
31073136
31083137 parseForStatement (
3109- tn : Tokenizer
3138+ tn : Tokenizer ,
3139+ label : IdentifierExpression | null
31103140 ) : Statement | null {
31113141
31123142 // at 'for': '(' Statement? Expression? ';' Expression? ')' Statement
@@ -3139,7 +3169,7 @@ export class Parser extends DiagnosticEmitter {
31393169 ) ;
31403170 return null ;
31413171 }
3142- return this . parseForOfStatement ( tn , startPos , initializer ) ;
3172+ return this . parseForOfStatement ( tn , startPos , initializer , label ) ;
31433173 }
31443174 if ( initializer . kind == NodeKind . Variable ) {
31453175 let declarations = ( < VariableStatement > initializer ) . declarations ;
@@ -3153,7 +3183,7 @@ export class Parser extends DiagnosticEmitter {
31533183 ) ; // recoverable
31543184 }
31553185 }
3156- return this . parseForOfStatement ( tn , startPos , initializer ) ;
3186+ return this . parseForOfStatement ( tn , startPos , initializer , label ) ;
31573187 }
31583188 this . error (
31593189 DiagnosticCode . Identifier_expected ,
@@ -3215,6 +3245,7 @@ export class Parser extends DiagnosticEmitter {
32153245 : null ,
32163246 incrementor ,
32173247 statement ,
3248+ label ,
32183249 tn . range ( startPos , tn . pos )
32193250 ) ;
32203251
@@ -3243,6 +3274,7 @@ export class Parser extends DiagnosticEmitter {
32433274 tn : Tokenizer ,
32443275 startPos : i32 ,
32453276 variable : Statement ,
3277+ label : IdentifierExpression | null
32463278 ) : ForOfStatement | null {
32473279
32483280 // at 'of': Expression ')' Statement
@@ -3265,6 +3297,7 @@ export class Parser extends DiagnosticEmitter {
32653297 variable ,
32663298 iterable ,
32673299 statement ,
3300+ label ,
32683301 tn . range ( startPos , tn . pos )
32693302 ) ;
32703303 }
@@ -3609,7 +3642,8 @@ export class Parser extends DiagnosticEmitter {
36093642 }
36103643
36113644 parseWhileStatement (
3612- tn : Tokenizer
3645+ tn : Tokenizer ,
3646+ label : IdentifierExpression | null
36133647 ) : WhileStatement | null {
36143648
36153649 // at 'while': '(' Expression ')' Statement ';'?
@@ -3621,7 +3655,7 @@ export class Parser extends DiagnosticEmitter {
36213655 if ( tn . skip ( Token . CloseParen ) ) {
36223656 let statement = this . parseStatement ( tn ) ;
36233657 if ( ! statement ) return null ;
3624- let ret = Node . createWhileStatement ( expression , statement , tn . range ( startPos , tn . pos ) ) ;
3658+ let ret = Node . createWhileStatement ( expression , statement , label , tn . range ( startPos , tn . pos ) ) ;
36253659 tn . skip ( Token . Semicolon ) ;
36263660 return ret ;
36273661 } else {
0 commit comments