@@ -2899,7 +2899,35 @@ 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 . 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
+
2903
2931
switch ( token ) {
2904
2932
case Token . Break : {
2905
2933
statement = this . parseBreak ( tn ) ;
@@ -2914,11 +2942,11 @@ export class Parser extends DiagnosticEmitter {
2914
2942
break ;
2915
2943
}
2916
2944
case Token . Do : {
2917
- statement = this . parseDoStatement ( tn ) ;
2945
+ statement = this . parseDoStatement ( tn , label ) ;
2918
2946
break ;
2919
2947
}
2920
2948
case Token . For : {
2921
- statement = this . parseForStatement ( tn ) ;
2949
+ statement = this . parseForStatement ( tn , label ) ;
2922
2950
break ;
2923
2951
}
2924
2952
case Token . If : {
@@ -2934,7 +2962,7 @@ export class Parser extends DiagnosticEmitter {
2934
2962
break ;
2935
2963
}
2936
2964
case Token . OpenBrace : {
2937
- statement = this . parseBlockStatement ( tn , topLevel ) ;
2965
+ statement = this . parseBlockStatement ( tn , topLevel , label ) ;
2938
2966
break ;
2939
2967
}
2940
2968
case Token . Return : {
@@ -2951,7 +2979,7 @@ export class Parser extends DiagnosticEmitter {
2951
2979
return Node . createEmptyStatement ( tn . range ( tn . tokenPos ) ) ;
2952
2980
}
2953
2981
case Token . Switch : {
2954
- statement = this . parseSwitchStatement ( tn ) ;
2982
+ statement = this . parseSwitchStatement ( tn , label ) ;
2955
2983
break ;
2956
2984
}
2957
2985
case Token . Throw : {
@@ -2967,7 +2995,7 @@ export class Parser extends DiagnosticEmitter {
2967
2995
break ;
2968
2996
}
2969
2997
case Token . While : {
2970
- statement = this . parseWhileStatement ( tn ) ;
2998
+ statement = this . parseWhileStatement ( tn , label ) ;
2971
2999
break ;
2972
3000
}
2973
3001
case Token . Type : { // also identifier
@@ -2994,7 +3022,8 @@ export class Parser extends DiagnosticEmitter {
2994
3022
2995
3023
parseBlockStatement (
2996
3024
tn : Tokenizer ,
2997
- topLevel : bool
3025
+ topLevel : bool ,
3026
+ label : IdentifierExpression | null = null
2998
3027
) : BlockStatement | null {
2999
3028
3000
3029
// at '{': Statement* '}' ';'?
@@ -3013,7 +3042,7 @@ export class Parser extends DiagnosticEmitter {
3013
3042
statements . push ( statement ) ;
3014
3043
}
3015
3044
}
3016
- let ret = Node . createBlockStatement ( statements , tn . range ( startPos , tn . pos ) ) ;
3045
+ let ret = Node . createBlockStatement ( statements , label , tn . range ( startPos , tn . pos ) ) ;
3017
3046
if ( topLevel ) tn . skip ( Token . Semicolon ) ;
3018
3047
return ret ;
3019
3048
}
@@ -3051,7 +3080,8 @@ export class Parser extends DiagnosticEmitter {
3051
3080
}
3052
3081
3053
3082
parseDoStatement (
3054
- tn : Tokenizer
3083
+ tn : Tokenizer ,
3084
+ label : IdentifierExpression | null
3055
3085
) : DoStatement | null {
3056
3086
3057
3087
// at 'do': Statement 'while' '(' Expression ')' ';'?
@@ -3067,7 +3097,7 @@ export class Parser extends DiagnosticEmitter {
3067
3097
if ( ! condition ) return null ;
3068
3098
3069
3099
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 ) ) ;
3071
3101
tn . skip ( Token . Semicolon ) ;
3072
3102
return ret ;
3073
3103
} else {
@@ -3106,7 +3136,8 @@ export class Parser extends DiagnosticEmitter {
3106
3136
}
3107
3137
3108
3138
parseForStatement (
3109
- tn : Tokenizer
3139
+ tn : Tokenizer ,
3140
+ label : IdentifierExpression | null
3110
3141
) : Statement | null {
3111
3142
3112
3143
// at 'for': '(' Statement? Expression? ';' Expression? ')' Statement
@@ -3139,7 +3170,7 @@ export class Parser extends DiagnosticEmitter {
3139
3170
) ;
3140
3171
return null ;
3141
3172
}
3142
- return this . parseForOfStatement ( tn , startPos , initializer ) ;
3173
+ return this . parseForOfStatement ( tn , startPos , initializer , label ) ;
3143
3174
}
3144
3175
if ( initializer . kind == NodeKind . Variable ) {
3145
3176
let declarations = ( < VariableStatement > initializer ) . declarations ;
@@ -3153,7 +3184,7 @@ export class Parser extends DiagnosticEmitter {
3153
3184
) ; // recoverable
3154
3185
}
3155
3186
}
3156
- return this . parseForOfStatement ( tn , startPos , initializer ) ;
3187
+ return this . parseForOfStatement ( tn , startPos , initializer , label ) ;
3157
3188
}
3158
3189
this . error (
3159
3190
DiagnosticCode . Identifier_expected ,
@@ -3215,6 +3246,7 @@ export class Parser extends DiagnosticEmitter {
3215
3246
: null ,
3216
3247
incrementor ,
3217
3248
statement ,
3249
+ label ,
3218
3250
tn . range ( startPos , tn . pos )
3219
3251
) ;
3220
3252
@@ -3243,6 +3275,7 @@ export class Parser extends DiagnosticEmitter {
3243
3275
tn : Tokenizer ,
3244
3276
startPos : i32 ,
3245
3277
variable : Statement ,
3278
+ label : IdentifierExpression | null
3246
3279
) : ForOfStatement | null {
3247
3280
3248
3281
// at 'of': Expression ')' Statement
@@ -3265,6 +3298,7 @@ export class Parser extends DiagnosticEmitter {
3265
3298
variable ,
3266
3299
iterable ,
3267
3300
statement ,
3301
+ label ,
3268
3302
tn . range ( startPos , tn . pos )
3269
3303
) ;
3270
3304
}
@@ -3309,7 +3343,8 @@ export class Parser extends DiagnosticEmitter {
3309
3343
}
3310
3344
3311
3345
parseSwitchStatement (
3312
- tn : Tokenizer
3346
+ tn : Tokenizer ,
3347
+ label : IdentifierExpression | null
3313
3348
) : SwitchStatement | null {
3314
3349
3315
3350
// at 'switch': '(' Expression ')' '{' SwitchCase* '}' ';'?
@@ -3326,7 +3361,7 @@ export class Parser extends DiagnosticEmitter {
3326
3361
if ( ! switchCase ) return null ;
3327
3362
switchCases . push ( switchCase ) ;
3328
3363
}
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 ) ) ;
3330
3365
tn . skip ( Token . Semicolon ) ;
3331
3366
return ret ;
3332
3367
} else {
@@ -3609,7 +3644,8 @@ export class Parser extends DiagnosticEmitter {
3609
3644
}
3610
3645
3611
3646
parseWhileStatement (
3612
- tn : Tokenizer
3647
+ tn : Tokenizer ,
3648
+ label : IdentifierExpression | null
3613
3649
) : WhileStatement | null {
3614
3650
3615
3651
// at 'while': '(' Expression ')' Statement ';'?
@@ -3621,7 +3657,7 @@ export class Parser extends DiagnosticEmitter {
3621
3657
if ( tn . skip ( Token . CloseParen ) ) {
3622
3658
let statement = this . parseStatement ( tn ) ;
3623
3659
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 ) ) ;
3625
3661
tn . skip ( Token . Semicolon ) ;
3626
3662
return ret ;
3627
3663
} else {
0 commit comments