@@ -1395,7 +1395,7 @@ export class Parser extends DiagnosticEmitter {
1395
1395
1396
1396
var body : Statement | null ;
1397
1397
if ( isArrow ) {
1398
- body = this . parseStatement ( tn , false ) ;
1398
+ body = this . parseArrowFunctionBody ( tn ) ;
1399
1399
} else {
1400
1400
if ( ! tn . skip ( Token . OPENBRACE ) ) {
1401
1401
this . error (
@@ -1420,6 +1420,11 @@ export class Parser extends DiagnosticEmitter {
1420
1420
return Node . createFunctionExpression ( declaration ) ;
1421
1421
}
1422
1422
1423
+ private parseArrowFunctionBody ( tn : Tokenizer ) : Statement | null {
1424
+ // TODO: should parse an expression unless the next token is `{`.
1425
+ return this . parseStatement ( tn , false ) ;
1426
+ }
1427
+
1423
1428
parseClassOrInterface (
1424
1429
tn : Tokenizer ,
1425
1430
flags : CommonFlags ,
@@ -2965,80 +2970,7 @@ export class Parser extends DiagnosticEmitter {
2965
2970
2966
2971
// ParenthesizedExpression
2967
2972
// FunctionExpression
2968
- case Token . OPENPAREN : {
2969
-
2970
- // determine whether this is a function expression
2971
- if ( tn . skip ( Token . CLOSEPAREN ) ) { // must be a function expression (fast route)
2972
- return this . parseFunctionExpressionCommon (
2973
- tn ,
2974
- Node . createEmptyIdentifierExpression ( tn . range ( startPos ) ) ,
2975
- [ ] ,
2976
- true
2977
- ) ;
2978
- }
2979
- let state = tn . mark ( ) ;
2980
- let again = true ;
2981
- do {
2982
- switch ( tn . next ( IdentifierHandling . PREFER ) ) {
2983
-
2984
- // function expression
2985
- case Token . DOT_DOT_DOT : {
2986
- tn . reset ( state ) ;
2987
- return this . parseFunctionExpression ( tn ) ;
2988
- }
2989
- // can be both
2990
- case Token . IDENTIFIER : {
2991
- tn . readIdentifier ( ) ;
2992
- switch ( tn . next ( ) ) {
2993
-
2994
- // if we got here, check for arrow
2995
- case Token . CLOSEPAREN : {
2996
- if ( ! tn . skip ( Token . EQUALS_GREATERTHAN ) ) {
2997
- again = false ;
2998
- break ;
2999
- }
3000
- // fall-through
3001
- }
3002
- // function expression
3003
- case Token . COLON : { // type annotation
3004
- tn . reset ( state ) ;
3005
- return this . parseFunctionExpression ( tn ) ;
3006
- }
3007
- // can be both
3008
- case Token . QUESTION : // optional parameter or ternary
3009
- case Token . COMMA : {
3010
- break ; // continue
3011
- }
3012
- // parenthesized expression
3013
- // case Token.EQUALS: // missing type annotation for simplicity
3014
- default : {
3015
- again = false ;
3016
- break ;
3017
- }
3018
- }
3019
- break ;
3020
- }
3021
- // parenthesized expression
3022
- default : {
3023
- again = false ;
3024
- break ;
3025
- }
3026
- }
3027
- } while ( again ) ;
3028
- tn . reset ( state ) ;
3029
-
3030
- // parse parenthesized
3031
- expr = this . parseExpression ( tn ) ;
3032
- if ( ! expr ) return null ;
3033
- if ( ! tn . skip ( Token . CLOSEPAREN ) ) {
3034
- this . error (
3035
- DiagnosticCode . _0_expected ,
3036
- tn . range ( ) , ")"
3037
- ) ;
3038
- return null ;
3039
- }
3040
- return Node . createParenthesizedExpression ( expr , tn . range ( startPos , tn . pos ) ) ;
3041
- }
2973
+ case Token . OPENPAREN : return this . parseArrowFunctionOrParenthesizedExpression ( tn , startPos ) ;
3042
2974
// ArrayLiteralExpression
3043
2975
case Token . OPENBRACKET : {
3044
2976
let elementExpressions = new Array < Expression | null > ( ) ;
@@ -3133,7 +3065,24 @@ export class Parser extends DiagnosticEmitter {
3133
3065
) ;
3134
3066
}
3135
3067
case Token . IDENTIFIER : {
3136
- return Node . createIdentifierExpression ( tn . readIdentifier ( ) , tn . range ( startPos , tn . pos ) ) ;
3068
+ const name = tn . readIdentifier ( ) ;
3069
+ const range = tn . range ( startPos , tn . pos ) ;
3070
+ const id = Node . createIdentifierExpression ( name , range ) ;
3071
+ if ( ! tn . skip ( Token . EQUALS_GREATERTHAN ) ) return id ;
3072
+
3073
+ let param = new ParameterNode ( ) ;
3074
+ param . parameterKind = ParameterKind . DEFAULT ;
3075
+ param . name = id ;
3076
+ param . type = Node . createOmittedType ( range ) ;
3077
+ return Node . createFunctionExpression ( Node . createFunctionDeclaration (
3078
+ Node . createEmptyIdentifierExpression ( range ) ,
3079
+ null ,
3080
+ Node . createSignature ( [ param ] , Node . createOmittedType ( range ) , null , false , range ) ,
3081
+ this . parseArrowFunctionBody ( tn ) ,
3082
+ null ,
3083
+ CommonFlags . ARROW ,
3084
+ range
3085
+ ) ) ;
3137
3086
}
3138
3087
case Token . THIS : {
3139
3088
return Node . createThisExpression ( tn . range ( startPos , tn . pos ) ) ;
@@ -3193,6 +3142,66 @@ export class Parser extends DiagnosticEmitter {
3193
3142
}
3194
3143
}
3195
3144
3145
+ private parseArrowFunctionOrParenthesizedExpression ( tn : Tokenizer , startPos : number ) : Expression | null {
3146
+ if ( tn . skip ( Token . CLOSEPAREN ) ) { // must be a function expression (fast route)
3147
+ return this . parseFunctionExpressionCommon (
3148
+ tn ,
3149
+ Node . createEmptyIdentifierExpression ( tn . range ( startPos ) ) ,
3150
+ [ ] ,
3151
+ true
3152
+ ) ;
3153
+ }
3154
+
3155
+ var state = tn . mark ( ) ;
3156
+ var isArrow = this . lookAheadIsArrowFunction ( tn ) ;
3157
+ tn . reset ( state ) ;
3158
+ if ( isArrow ) {
3159
+ return this . parseFunctionExpression ( tn ) ;
3160
+ } else {
3161
+ // parse parenthesized
3162
+ const expr = this . parseExpression ( tn ) ;
3163
+ if ( ! expr ) return null ;
3164
+ if ( ! tn . skip ( Token . CLOSEPAREN ) ) {
3165
+ this . error (
3166
+ DiagnosticCode . _0_expected ,
3167
+ tn . range ( ) , ")"
3168
+ ) ;
3169
+ return null ;
3170
+ }
3171
+ return Node . createParenthesizedExpression ( expr , tn . range ( startPos , tn . pos ) ) ;
3172
+ }
3173
+ }
3174
+
3175
+ private lookAheadIsArrowFunction ( tn : Tokenizer ) : boolean {
3176
+ while ( true ) {
3177
+ switch ( tn . next ( IdentifierHandling . PREFER ) ) {
3178
+ case Token . DOT_DOT_DOT : return true ; // rest argument
3179
+ case Token . IDENTIFIER : {
3180
+ tn . readIdentifier ( ) ;
3181
+ switch ( tn . next ( ) ) {
3182
+ // if we got here, check for arrow
3183
+ case Token . CLOSEPAREN : {
3184
+ return tn . skip ( Token . EQUALS_GREATERTHAN ) || tn . skip ( Token . COLON ) ;
3185
+ }
3186
+ case Token . COLON : return true ; // type annotation
3187
+ case Token . QUESTION : { // optional parameter or ternary
3188
+ // Arrow function may be `(x?: i32) => 0`, `(x?, y) => 0`, or `(x?) => 0`.
3189
+ // Anything else is a conditional expression.
3190
+ return ( tn . skip ( Token . COLON ) || tn . skip ( Token . COMMA ) || tn . skip ( Token . CLOSEPAREN ) ) ;
3191
+ }
3192
+ case Token . COMMA : {
3193
+ break ; // continue
3194
+ }
3195
+ // case Token.EQUALS: // missing type annotation for simplicity
3196
+ default : return false ;
3197
+ }
3198
+ break ;
3199
+ }
3200
+ default : return false ;
3201
+ }
3202
+ }
3203
+ }
3204
+
3196
3205
tryParseTypeArgumentsBeforeArguments (
3197
3206
tn : Tokenizer
3198
3207
) : CommonTypeNode [ ] | null {
0 commit comments