@@ -2685,7 +2685,8 @@ namespace ts {
26852685 // 2) LeftHandSideExpression = AssignmentExpression[?in,?yield]
26862686 // 3) LeftHandSideExpression AssignmentOperator AssignmentExpression[?in,?yield]
26872687 // 4) ArrowFunctionExpression[?in,?yield]
2688- // 5) [+Yield] YieldExpression[?In]
2688+ // 5) AsyncArrowFunctionExpression[in,yield,await]
2689+ // 6) [+Yield] YieldExpression[?In]
26892690 //
26902691 // Note: for ease of implementation we treat productions '2' and '3' as the same thing.
26912692 // (i.e. they're both BinaryExpressions with an assignment operator in it).
@@ -2695,11 +2696,18 @@ namespace ts {
26952696 return parseYieldExpression ( ) ;
26962697 }
26972698
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
27002708 // not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done
27012709 // with AssignmentExpression if we see one.
2702- const arrowExpression = tryParseParenthesizedArrowFunctionExpression ( ) ;
2710+ const arrowExpression = tryParseParenthesizedArrowFunctionExpression ( ) || tryParseAsyncSimpleArrowFunctionExpression ( ) ;
27032711 if ( arrowExpression ) {
27042712 return arrowExpression ;
27052713 }
@@ -2791,10 +2799,17 @@ namespace ts {
27912799 }
27922800 }
27932801
2794- function parseSimpleArrowFunctionExpression ( identifier : Identifier ) : Expression {
2802+ function parseSimpleArrowFunctionExpression ( identifier : Identifier , asyncModifier ?: ModifiersArray ) : ArrowFunction {
27952803 Debug . assert ( token === SyntaxKind . EqualsGreaterThanToken , "parseSimpleArrowFunctionExpression should only have been called if we had a =>" ) ;
27962804
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+ }
27982813
27992814 const parameter = < ParameterDeclaration > createNode ( SyntaxKind . Parameter , identifier . pos ) ;
28002815 parameter . name = identifier ;
@@ -2805,7 +2820,7 @@ namespace ts {
28052820 node . parameters . end = parameter . end ;
28062821
28072822 node . equalsGreaterThanToken = parseExpectedToken ( SyntaxKind . EqualsGreaterThanToken , /*reportAtCurrentPosition*/ false , Diagnostics . _0_expected , "=>" ) ;
2808- node . body = parseArrowFunctionExpressionBody ( /*isAsync*/ false ) ;
2823+ node . body = parseArrowFunctionExpressionBody ( /*isAsync*/ ! ! asyncModifier ) ;
28092824
28102825 return finishNode ( node ) ;
28112826 }
@@ -2973,6 +2988,32 @@ namespace ts {
29732988 return parseParenthesizedArrowFunctionExpressionHead ( /*allowAmbiguity*/ false ) ;
29742989 }
29752990
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+
29763017 function parseParenthesizedArrowFunctionExpressionHead ( allowAmbiguity : boolean ) : ArrowFunction {
29773018 const node = < ArrowFunction > createNode ( SyntaxKind . ArrowFunction ) ;
29783019 setModifiers ( node , parseModifiersForArrowFunction ( ) ) ;
0 commit comments