@@ -2899,7 +2899,34 @@ export class Parser extends DiagnosticEmitter {
2899
2899
2900
2900
let state = tn . mark ( ) ;
2901
2901
let token = tn . next ( ) ;
2902
+ let label : IdentifierExpression | null = null ;
2902
2903
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
+
2903
2930
switch ( token ) {
2904
2931
case Token . Break : {
2905
2932
statement = this . parseBreak ( tn ) ;
@@ -2914,11 +2941,11 @@ export class Parser extends DiagnosticEmitter {
2914
2941
break ;
2915
2942
}
2916
2943
case Token . Do : {
2917
- statement = this . parseDoStatement ( tn ) ;
2944
+ statement = this . parseDoStatement ( tn , label ) ;
2918
2945
break ;
2919
2946
}
2920
2947
case Token . For : {
2921
- statement = this . parseForStatement ( tn ) ;
2948
+ statement = this . parseForStatement ( tn , label ) ;
2922
2949
break ;
2923
2950
}
2924
2951
case Token . If : {
@@ -2934,7 +2961,7 @@ export class Parser extends DiagnosticEmitter {
2934
2961
break ;
2935
2962
}
2936
2963
case Token . OpenBrace : {
2937
- statement = this . parseBlockStatement ( tn , topLevel ) ;
2964
+ statement = this . parseBlockStatement ( tn , topLevel , label ) ;
2938
2965
break ;
2939
2966
}
2940
2967
case Token . Return : {
@@ -2967,7 +2994,7 @@ export class Parser extends DiagnosticEmitter {
2967
2994
break ;
2968
2995
}
2969
2996
case Token . While : {
2970
- statement = this . parseWhileStatement ( tn ) ;
2997
+ statement = this . parseWhileStatement ( tn , label ) ;
2971
2998
break ;
2972
2999
}
2973
3000
case Token . Type : { // also identifier
@@ -2994,7 +3021,8 @@ export class Parser extends DiagnosticEmitter {
2994
3021
2995
3022
parseBlockStatement (
2996
3023
tn : Tokenizer ,
2997
- topLevel : bool
3024
+ topLevel : bool ,
3025
+ label : IdentifierExpression | null = null
2998
3026
) : BlockStatement | null {
2999
3027
3000
3028
// at '{': Statement* '}' ';'?
@@ -3013,7 +3041,7 @@ export class Parser extends DiagnosticEmitter {
3013
3041
statements . push ( statement ) ;
3014
3042
}
3015
3043
}
3016
- let ret = Node . createBlockStatement ( statements , tn . range ( startPos , tn . pos ) ) ;
3044
+ let ret = Node . createBlockStatement ( statements , label , tn . range ( startPos , tn . pos ) ) ;
3017
3045
if ( topLevel ) tn . skip ( Token . Semicolon ) ;
3018
3046
return ret ;
3019
3047
}
@@ -3051,7 +3079,8 @@ export class Parser extends DiagnosticEmitter {
3051
3079
}
3052
3080
3053
3081
parseDoStatement (
3054
- tn : Tokenizer
3082
+ tn : Tokenizer ,
3083
+ label : IdentifierExpression | null
3055
3084
) : DoStatement | null {
3056
3085
3057
3086
// at 'do': Statement 'while' '(' Expression ')' ';'?
@@ -3067,7 +3096,7 @@ export class Parser extends DiagnosticEmitter {
3067
3096
if ( ! condition ) return null ;
3068
3097
3069
3098
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 ) ) ;
3071
3100
tn . skip ( Token . Semicolon ) ;
3072
3101
return ret ;
3073
3102
} else {
@@ -3106,7 +3135,8 @@ export class Parser extends DiagnosticEmitter {
3106
3135
}
3107
3136
3108
3137
parseForStatement (
3109
- tn : Tokenizer
3138
+ tn : Tokenizer ,
3139
+ label : IdentifierExpression | null
3110
3140
) : Statement | null {
3111
3141
3112
3142
// at 'for': '(' Statement? Expression? ';' Expression? ')' Statement
@@ -3139,7 +3169,7 @@ export class Parser extends DiagnosticEmitter {
3139
3169
) ;
3140
3170
return null ;
3141
3171
}
3142
- return this . parseForOfStatement ( tn , startPos , initializer ) ;
3172
+ return this . parseForOfStatement ( tn , startPos , initializer , label ) ;
3143
3173
}
3144
3174
if ( initializer . kind == NodeKind . Variable ) {
3145
3175
let declarations = ( < VariableStatement > initializer ) . declarations ;
@@ -3153,7 +3183,7 @@ export class Parser extends DiagnosticEmitter {
3153
3183
) ; // recoverable
3154
3184
}
3155
3185
}
3156
- return this . parseForOfStatement ( tn , startPos , initializer ) ;
3186
+ return this . parseForOfStatement ( tn , startPos , initializer , label ) ;
3157
3187
}
3158
3188
this . error (
3159
3189
DiagnosticCode . Identifier_expected ,
@@ -3215,6 +3245,7 @@ export class Parser extends DiagnosticEmitter {
3215
3245
: null ,
3216
3246
incrementor ,
3217
3247
statement ,
3248
+ label ,
3218
3249
tn . range ( startPos , tn . pos )
3219
3250
) ;
3220
3251
@@ -3243,6 +3274,7 @@ export class Parser extends DiagnosticEmitter {
3243
3274
tn : Tokenizer ,
3244
3275
startPos : i32 ,
3245
3276
variable : Statement ,
3277
+ label : IdentifierExpression | null
3246
3278
) : ForOfStatement | null {
3247
3279
3248
3280
// at 'of': Expression ')' Statement
@@ -3265,6 +3297,7 @@ export class Parser extends DiagnosticEmitter {
3265
3297
variable ,
3266
3298
iterable ,
3267
3299
statement ,
3300
+ label ,
3268
3301
tn . range ( startPos , tn . pos )
3269
3302
) ;
3270
3303
}
@@ -3609,7 +3642,8 @@ export class Parser extends DiagnosticEmitter {
3609
3642
}
3610
3643
3611
3644
parseWhileStatement (
3612
- tn : Tokenizer
3645
+ tn : Tokenizer ,
3646
+ label : IdentifierExpression | null
3613
3647
) : WhileStatement | null {
3614
3648
3615
3649
// at 'while': '(' Expression ')' Statement ';'?
@@ -3621,7 +3655,7 @@ export class Parser extends DiagnosticEmitter {
3621
3655
if ( tn . skip ( Token . CloseParen ) ) {
3622
3656
let statement = this . parseStatement ( tn ) ;
3623
3657
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 ) ) ;
3625
3659
tn . skip ( Token . Semicolon ) ;
3626
3660
return ret ;
3627
3661
} else {
0 commit comments