@@ -2899,7 +2899,35 @@ 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 . Do :
2917+ case Token . For :
2918+ case Token . OpenBrace :
2919+ case Token . Switch :
2920+ case Token . While :
2921+ // Do nothing
2922+ break ;
2923+ default :
2924+ this . error ( DiagnosticCode . A_label_is_not_allowed_here , range ) ;
2925+ }
2926+ } else {
2927+ tn . reset ( preIdentifierState ) ;
2928+ }
2929+ }
2930+
29032931 switch ( token ) {
29042932 case Token . Break : {
29052933 statement = this . parseBreak ( tn ) ;
@@ -2914,11 +2942,11 @@ export class Parser extends DiagnosticEmitter {
29142942 break ;
29152943 }
29162944 case Token . Do : {
2917- statement = this . parseDoStatement ( tn ) ;
2945+ statement = this . parseDoStatement ( tn , label ) ;
29182946 break ;
29192947 }
29202948 case Token . For : {
2921- statement = this . parseForStatement ( tn ) ;
2949+ statement = this . parseForStatement ( tn , label ) ;
29222950 break ;
29232951 }
29242952 case Token . If : {
@@ -2934,7 +2962,7 @@ export class Parser extends DiagnosticEmitter {
29342962 break ;
29352963 }
29362964 case Token . OpenBrace : {
2937- statement = this . parseBlockStatement ( tn , topLevel ) ;
2965+ statement = this . parseBlockStatement ( tn , topLevel , label ) ;
29382966 break ;
29392967 }
29402968 case Token . Return : {
@@ -2951,7 +2979,7 @@ export class Parser extends DiagnosticEmitter {
29512979 return Node . createEmptyStatement ( tn . range ( tn . tokenPos ) ) ;
29522980 }
29532981 case Token . Switch : {
2954- statement = this . parseSwitchStatement ( tn ) ;
2982+ statement = this . parseSwitchStatement ( tn , label ) ;
29552983 break ;
29562984 }
29572985 case Token . Throw : {
@@ -2967,7 +2995,7 @@ export class Parser extends DiagnosticEmitter {
29672995 break ;
29682996 }
29692997 case Token . While : {
2970- statement = this . parseWhileStatement ( tn ) ;
2998+ statement = this . parseWhileStatement ( tn , label ) ;
29712999 break ;
29723000 }
29733001 case Token . Type : { // also identifier
@@ -2994,7 +3022,8 @@ export class Parser extends DiagnosticEmitter {
29943022
29953023 parseBlockStatement (
29963024 tn : Tokenizer ,
2997- topLevel : bool
3025+ topLevel : bool ,
3026+ label : IdentifierExpression | null = null
29983027 ) : BlockStatement | null {
29993028
30003029 // at '{': Statement* '}' ';'?
@@ -3013,7 +3042,7 @@ export class Parser extends DiagnosticEmitter {
30133042 statements . push ( statement ) ;
30143043 }
30153044 }
3016- let ret = Node . createBlockStatement ( statements , tn . range ( startPos , tn . pos ) ) ;
3045+ let ret = Node . createBlockStatement ( statements , label , tn . range ( startPos , tn . pos ) ) ;
30173046 if ( topLevel ) tn . skip ( Token . Semicolon ) ;
30183047 return ret ;
30193048 }
@@ -3051,7 +3080,8 @@ export class Parser extends DiagnosticEmitter {
30513080 }
30523081
30533082 parseDoStatement (
3054- tn : Tokenizer
3083+ tn : Tokenizer ,
3084+ label : IdentifierExpression | null
30553085 ) : DoStatement | null {
30563086
30573087 // at 'do': Statement 'while' '(' Expression ')' ';'?
@@ -3067,7 +3097,7 @@ export class Parser extends DiagnosticEmitter {
30673097 if ( ! condition ) return null ;
30683098
30693099 if ( tn . skip ( Token . CloseParen ) ) {
3070- let ret = Node . createDoStatement ( statement , condition , tn . range ( startPos , tn . pos ) ) ;
3100+ let ret = Node . createDoStatement ( statement , condition , label , tn . range ( startPos , tn . pos ) ) ;
30713101 tn . skip ( Token . Semicolon ) ;
30723102 return ret ;
30733103 } else {
@@ -3106,7 +3136,8 @@ export class Parser extends DiagnosticEmitter {
31063136 }
31073137
31083138 parseForStatement (
3109- tn : Tokenizer
3139+ tn : Tokenizer ,
3140+ label : IdentifierExpression | null
31103141 ) : Statement | null {
31113142
31123143 // at 'for': '(' Statement? Expression? ';' Expression? ')' Statement
@@ -3139,7 +3170,7 @@ export class Parser extends DiagnosticEmitter {
31393170 ) ;
31403171 return null ;
31413172 }
3142- return this . parseForOfStatement ( tn , startPos , initializer ) ;
3173+ return this . parseForOfStatement ( tn , startPos , initializer , label ) ;
31433174 }
31443175 if ( initializer . kind == NodeKind . Variable ) {
31453176 let declarations = ( < VariableStatement > initializer ) . declarations ;
@@ -3153,7 +3184,7 @@ export class Parser extends DiagnosticEmitter {
31533184 ) ; // recoverable
31543185 }
31553186 }
3156- return this . parseForOfStatement ( tn , startPos , initializer ) ;
3187+ return this . parseForOfStatement ( tn , startPos , initializer , label ) ;
31573188 }
31583189 this . error (
31593190 DiagnosticCode . Identifier_expected ,
@@ -3215,6 +3246,7 @@ export class Parser extends DiagnosticEmitter {
32153246 : null ,
32163247 incrementor ,
32173248 statement ,
3249+ label ,
32183250 tn . range ( startPos , tn . pos )
32193251 ) ;
32203252
@@ -3243,6 +3275,7 @@ export class Parser extends DiagnosticEmitter {
32433275 tn : Tokenizer ,
32443276 startPos : i32 ,
32453277 variable : Statement ,
3278+ label : IdentifierExpression | null
32463279 ) : ForOfStatement | null {
32473280
32483281 // at 'of': Expression ')' Statement
@@ -3265,6 +3298,7 @@ export class Parser extends DiagnosticEmitter {
32653298 variable ,
32663299 iterable ,
32673300 statement ,
3301+ label ,
32683302 tn . range ( startPos , tn . pos )
32693303 ) ;
32703304 }
@@ -3309,7 +3343,8 @@ export class Parser extends DiagnosticEmitter {
33093343 }
33103344
33113345 parseSwitchStatement (
3312- tn : Tokenizer
3346+ tn : Tokenizer ,
3347+ label : IdentifierExpression | null
33133348 ) : SwitchStatement | null {
33143349
33153350 // at 'switch': '(' Expression ')' '{' SwitchCase* '}' ';'?
@@ -3326,7 +3361,7 @@ export class Parser extends DiagnosticEmitter {
33263361 if ( ! switchCase ) return null ;
33273362 switchCases . push ( switchCase ) ;
33283363 }
3329- let ret = Node . createSwitchStatement ( condition , switchCases , tn . range ( startPos , tn . pos ) ) ;
3364+ let ret = Node . createSwitchStatement ( condition , switchCases , label , tn . range ( startPos , tn . pos ) ) ;
33303365 tn . skip ( Token . Semicolon ) ;
33313366 return ret ;
33323367 } else {
@@ -3609,7 +3644,8 @@ export class Parser extends DiagnosticEmitter {
36093644 }
36103645
36113646 parseWhileStatement (
3612- tn : Tokenizer
3647+ tn : Tokenizer ,
3648+ label : IdentifierExpression | null
36133649 ) : WhileStatement | null {
36143650
36153651 // at 'while': '(' Expression ')' Statement ';'?
@@ -3621,7 +3657,7 @@ export class Parser extends DiagnosticEmitter {
36213657 if ( tn . skip ( Token . CloseParen ) ) {
36223658 let statement = this . parseStatement ( tn ) ;
36233659 if ( ! statement ) return null ;
3624- let ret = Node . createWhileStatement ( expression , statement , tn . range ( startPos , tn . pos ) ) ;
3660+ let ret = Node . createWhileStatement ( expression , statement , label , tn . range ( startPos , tn . pos ) ) ;
36253661 tn . skip ( Token . Semicolon ) ;
36263662 return ret ;
36273663 } else {
0 commit comments