@@ -2685,7 +2685,8 @@ namespace ts {
2685
2685
// 2) LeftHandSideExpression = AssignmentExpression[?in,?yield]
2686
2686
// 3) LeftHandSideExpression AssignmentOperator AssignmentExpression[?in,?yield]
2687
2687
// 4) ArrowFunctionExpression[?in,?yield]
2688
- // 5) [+Yield] YieldExpression[?In]
2688
+ // 5) AsyncArrowFunctionExpression[in,yield,await]
2689
+ // 6) [+Yield] YieldExpression[?In]
2689
2690
//
2690
2691
// Note: for ease of implementation we treat productions '2' and '3' as the same thing.
2691
2692
// (i.e. they're both BinaryExpressions with an assignment operator in it).
@@ -2695,11 +2696,18 @@ namespace ts {
2695
2696
return parseYieldExpression ( ) ;
2696
2697
}
2697
2698
2698
- // Then, check if we have an arrow function (production '4') that starts with a parenthesized
2699
- // parameter list. If we do, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is
2699
+ // Then, check if we have an arrow function (production '4' and '5') that starts with a parenthesized
2700
+ // parameter list or is an async arrow function.
2701
+ // AsyncArrowFunctionExpression:
2702
+ // 1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In]
2703
+ // 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In]
2704
+ // Production (1) of AsyncArrowFunctionExpression is parsed in "tryParseAsyncSimpleArrowFunctionExpression".
2705
+ // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression".
2706
+ //
2707
+ // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is
2700
2708
// not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done
2701
2709
// with AssignmentExpression if we see one.
2702
- const arrowExpression = tryParseParenthesizedArrowFunctionExpression ( ) ;
2710
+ const arrowExpression = tryParseParenthesizedArrowFunctionExpression ( ) || tryParseAsyncSimpleArrowFunctionExpression ( ) ;
2703
2711
if ( arrowExpression ) {
2704
2712
return arrowExpression ;
2705
2713
}
@@ -2791,10 +2799,17 @@ namespace ts {
2791
2799
}
2792
2800
}
2793
2801
2794
- function parseSimpleArrowFunctionExpression ( identifier : Identifier ) : Expression {
2802
+ function parseSimpleArrowFunctionExpression ( identifier : Identifier , asyncModifier ?: ModifiersArray ) : ArrowFunction {
2795
2803
Debug . assert ( token === SyntaxKind . EqualsGreaterThanToken , "parseSimpleArrowFunctionExpression should only have been called if we had a =>" ) ;
2796
2804
2797
- const node = < ArrowFunction > createNode ( SyntaxKind . ArrowFunction , identifier . pos ) ;
2805
+ let node : ArrowFunction ;
2806
+ if ( asyncModifier ) {
2807
+ node = < ArrowFunction > createNode ( SyntaxKind . ArrowFunction , asyncModifier . pos ) ;
2808
+ setModifiers ( node , asyncModifier ) ;
2809
+ }
2810
+ else {
2811
+ node = < ArrowFunction > createNode ( SyntaxKind . ArrowFunction , identifier . pos ) ;
2812
+ }
2798
2813
2799
2814
const parameter = < ParameterDeclaration > createNode ( SyntaxKind . Parameter , identifier . pos ) ;
2800
2815
parameter . name = identifier ;
@@ -2805,7 +2820,7 @@ namespace ts {
2805
2820
node . parameters . end = parameter . end ;
2806
2821
2807
2822
node . equalsGreaterThanToken = parseExpectedToken ( SyntaxKind . EqualsGreaterThanToken , /*reportAtCurrentPosition*/ false , Diagnostics . _0_expected , "=>" ) ;
2808
- node . body = parseArrowFunctionExpressionBody ( /*isAsync*/ false ) ;
2823
+ node . body = parseArrowFunctionExpressionBody ( /*isAsync*/ ! ! asyncModifier ) ;
2809
2824
2810
2825
return finishNode ( node ) ;
2811
2826
}
@@ -2973,6 +2988,32 @@ namespace ts {
2973
2988
return parseParenthesizedArrowFunctionExpressionHead ( /*allowAmbiguity*/ false ) ;
2974
2989
}
2975
2990
2991
+ function tryParseAsyncSimpleArrowFunctionExpression ( ) : ArrowFunction {
2992
+ const isUnParenthesizedAsyncArrowFunction = lookAhead ( isUnParenthesizedAsyncArrowFunctionWorker ) ;
2993
+ if ( isUnParenthesizedAsyncArrowFunction === Tristate . True ) {
2994
+ const asyncModifier = parseModifiersForArrowFunction ( ) ;
2995
+ const expr = parseBinaryExpressionOrHigher ( /*precedence*/ 0 ) ;
2996
+ return parseSimpleArrowFunctionExpression ( < Identifier > expr , asyncModifier ) ;
2997
+ }
2998
+ return undefined ;
2999
+ }
3000
+
3001
+ function isUnParenthesizedAsyncArrowFunctionWorker ( ) : Tristate {
3002
+ if ( token === SyntaxKind . AsyncKeyword ) {
3003
+ nextToken ( ) ;
3004
+ if ( scanner . hasPrecedingLineBreak ( ) ) {
3005
+ return Tristate . False ;
3006
+ }
3007
+ // Check for un-parenthesized AsyncArrowFunction
3008
+ const expr = parseBinaryExpressionOrHigher ( /*precedence*/ 0 ) ;
3009
+ if ( ! scanner . hasPrecedingLineBreak ( ) && expr . kind === SyntaxKind . Identifier && token === SyntaxKind . EqualsGreaterThanToken ) {
3010
+ return Tristate . True ;
3011
+ }
3012
+ }
3013
+
3014
+ return Tristate . False ;
3015
+ }
3016
+
2976
3017
function parseParenthesizedArrowFunctionExpressionHead ( allowAmbiguity : boolean ) : ArrowFunction {
2977
3018
const node = < ArrowFunction > createNode ( SyntaxKind . ArrowFunction ) ;
2978
3019
setModifiers ( node , parseModifiersForArrowFunction ( ) ) ;
0 commit comments