From a1110c5d42b906c15de8df5f679b98e4776ce34a Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk Date: Sat, 17 Oct 2026 23:47:38 +0300 Subject: [PATCH 1/7] fix async and yield parsing --- tsc/internal/parser/parser.go | 111 +++-- tsc/internal/parser/parser_test.go | 455 ++++++++++++++++++ tsc/internal/parser/types.go | 14 +- .../parenthesizedAsyncArrowFunction.js | 79 +++ .../parenthesizedAsyncArrowFunction.symbols | 239 +++++++++ .../parenthesizedAsyncArrowFunction.types | 346 +++++++++++++ .../parenthesizedAsyncArrowFunctionJs.js | 49 ++ .../parenthesizedAsyncArrowFunctionJs.symbols | 75 +++ .../parenthesizedAsyncArrowFunctionJs.types | 108 +++++ .../asyncArrowFunction_allowJs.errors.txt | 16 +- .../asyncArrowFunction_allowJs.symbols | 38 ++ .../asyncArrowFunction_allowJs.types | 55 +++ .../parenthesizedAsyncArrowFunction.ts | 43 ++ .../parenthesizedAsyncArrowFunctionJs.ts | 24 + .../asyncArrowFunction_allowJs.ts | 15 +- 15 files changed, 1616 insertions(+), 51 deletions(-) create mode 100644 tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js create mode 100644 tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols create mode 100644 tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types create mode 100644 tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts diff --git a/tsc/internal/parser/parser.go b/tsc/internal/parser/parser.go index c670d64ad21c2..ce4899a68ab9a 100644 --- a/tsc/internal/parser/parser.go +++ b/tsc/internal/parser/parser.go @@ -342,8 +342,10 @@ type ParserState struct { contextFlags ast.NodeFlags diagnosticsLen int jsDiagnosticsLen int + jsdocDiagnosticsLen int jsdocInfosLen int reparsedClonesLen int + reparseList []*ast.Node statementHasAwaitIdentifier bool hasParseError bool } @@ -354,8 +356,10 @@ func (p *Parser) mark() ParserState { contextFlags: p.contextFlags, diagnosticsLen: len(p.diagnostics), jsDiagnosticsLen: len(p.jsDiagnostics), + jsdocDiagnosticsLen: len(p.jsdocDiagnostics), jsdocInfosLen: len(p.jsdocInfos), reparsedClonesLen: len(p.reparsedClones), + reparseList: p.reparseList, statementHasAwaitIdentifier: p.statementHasAwaitIdentifier, hasParseError: p.hasParseError, } @@ -367,8 +371,10 @@ func (p *Parser) rewind(state ParserState) { p.contextFlags = state.contextFlags p.diagnostics = p.diagnostics[0:state.diagnosticsLen] p.jsDiagnostics = p.jsDiagnostics[0:state.jsDiagnosticsLen] + p.jsdocDiagnostics = p.jsdocDiagnostics[0:state.jsdocDiagnosticsLen] p.jsdocInfos = p.jsdocInfos[0:state.jsdocInfosLen] p.reparsedClones = p.reparsedClones[0:state.reparsedClonesLen] + p.reparseList = state.reparseList p.statementHasAwaitIdentifier = state.statementHasAwaitIdentifier p.hasParseError = state.hasParseError } @@ -4149,10 +4155,10 @@ func (p *Parser) parseExpressionAllowIn() *ast.Expression { } func (p *Parser) parseAssignmentExpressionOrHigher() *ast.Expression { - return p.parseAssignmentExpressionOrHigherWorker(true /*allowReturnTypeInArrowFunction*/) + return p.parseAssignmentExpressionOrHigherWorker(ParseFlagsNone) } -func (p *Parser) parseAssignmentExpressionOrHigherWorker(allowReturnTypeInArrowFunction bool) *ast.Expression { +func (p *Parser) parseAssignmentExpressionOrHigherWorker(flags ParseFlags) *ast.Expression { // AssignmentExpression[in,yield]: // 1) ConditionalExpression[?in,?yield] // 2) LeftHandSideExpression = AssignmentExpression[?in,?yield] @@ -4165,7 +4171,7 @@ func (p *Parser) parseAssignmentExpressionOrHigherWorker(allowReturnTypeInArrowF // (i.e. they're both BinaryExpressions with an assignment operator in it). // First, do the simple check if we have a YieldExpression (production '6'). if p.isYieldExpression() { - return p.parseYieldExpression() + return p.parseYieldExpression(flags) } // Then, check if we have an arrow function (production '4' and '5') that starts with a parenthesized // parameter list or is an async arrow function. @@ -4178,15 +4184,15 @@ func (p *Parser) parseAssignmentExpressionOrHigherWorker(allowReturnTypeInArrowF // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is // not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done // with AssignmentExpression if we see one. - arrowExpression := p.tryParseParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction) + arrowExpression := p.tryParseParenthesizedArrowFunctionExpression(flags) if arrowExpression != nil { return arrowExpression } - arrowExpression = p.tryParseAsyncSimpleArrowFunctionExpression(allowReturnTypeInArrowFunction) + arrowExpression = p.tryParseAsyncSimpleArrowFunctionExpression(flags) if arrowExpression != nil { return arrowExpression } - // arrowExpression2 := p.tryParseAsyncSimpleArrowFunctionExpression(allowReturnTypeInArrowFunction) + // arrowExpression2 := p.tryParseAsyncSimpleArrowFunctionExpression(flags) // if arrowExpression2 != nil { // return arrowExpression2 // } @@ -4206,7 +4212,7 @@ func (p *Parser) parseAssignmentExpressionOrHigherWorker(allowReturnTypeInArrowF // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single // identifier and the current token is an arrow. if expr.Kind == ast.KindIdentifier && p.token == ast.KindEqualsGreaterThanToken { - return p.parseSimpleArrowFunctionExpression(pos, expr, allowReturnTypeInArrowFunction, jsdoc, nil /*asyncModifier*/) + return p.parseSimpleArrowFunctionExpression(pos, expr, flags, jsdoc, nil /*asyncModifier*/) } // Now see if we might be in cases '2' or '3'. // If the expression was a LHS expression, and we have an assignment operator, then @@ -4215,10 +4221,10 @@ func (p *Parser) parseAssignmentExpressionOrHigherWorker(allowReturnTypeInArrowF // Note: we call reScanGreaterToken so that we get an appropriately merged token // for cases like `> > =` becoming `>>=` if ast.IsLeftHandSideExpression(expr) && ast.IsAssignmentOperator(p.reScanGreaterThanToken()) { - return p.makeBinaryExpression(expr, p.parseTokenNode(), p.parseAssignmentExpressionOrHigherWorker(allowReturnTypeInArrowFunction), pos) + return p.makeBinaryExpression(expr, p.parseTokenNode(), p.parseAssignmentExpressionOrHigherWorker(flags), pos) } // It wasn't an assignment or a lambda. This is a conditional expression: - return p.parseConditionalExpressionRest(expr, pos, allowReturnTypeInArrowFunction) + return p.parseConditionalExpressionRest(expr, pos, flags) } func (p *Parser) isYieldExpression() bool { @@ -4248,7 +4254,7 @@ func (p *Parser) isYieldExpression() bool { return false } -func (p *Parser) parseYieldExpression() *ast.Node { +func (p *Parser) parseYieldExpression(flags ParseFlags) *ast.Node { pos := p.nodePos() // YieldExpression[In] : // yield @@ -4257,7 +4263,7 @@ func (p *Parser) parseYieldExpression() *ast.Node { p.nextToken() var result *ast.Node if !p.hasPrecedingLineBreak() && (p.token == ast.KindAsteriskToken || p.isStartOfExpression()) { - result = p.factory.NewYieldExpression(p.parseOptionalToken(ast.KindAsteriskToken), p.parseAssignmentExpressionOrHigher()) + result = p.factory.NewYieldExpression(p.parseOptionalToken(ast.KindAsteriskToken), p.parseAssignmentExpressionOrHigherWorker(flags)) } else { // if the next token is not on the same line as yield. or we don't have an '*' or // the start of an expression, then this is just a simple "yield" expression. @@ -4266,10 +4272,10 @@ func (p *Parser) parseYieldExpression() *ast.Node { return p.finishNode(result, pos) } -func (p *Parser) isParenthesizedArrowFunctionExpression() core.Tristate { +func (p *Parser) isParenthesizedArrowFunctionExpression(flags ParseFlags) core.Tristate { if p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken || p.token == ast.KindAsyncKeyword { state := p.mark() - result := p.nextIsParenthesizedArrowFunctionExpression() + result := p.nextIsParenthesizedArrowFunctionExpression(flags) p.rewind(state) return result } @@ -4283,8 +4289,9 @@ func (p *Parser) isParenthesizedArrowFunctionExpression() core.Tristate { return core.TSFalse } -func (p *Parser) nextIsParenthesizedArrowFunctionExpression() core.Tristate { - if p.token == ast.KindAsyncKeyword { +func (p *Parser) nextIsParenthesizedArrowFunctionExpression(flags ParseFlags) core.Tristate { + isAsync := p.token == ast.KindAsyncKeyword + if isAsync { p.nextToken() if p.hasPrecedingLineBreak() { return core.TSFalse @@ -4298,16 +4305,30 @@ func (p *Parser) nextIsParenthesizedArrowFunctionExpression() core.Tristate { if first == ast.KindOpenParenToken { if second == ast.KindCloseParenToken { // Simple cases: "() =>", "(): ", and "() {". - // This is an arrow function with no parameters. // The last one is not actually an arrow function, // but this is probably what the user intended. - third := p.nextToken() - switch third { - case ast.KindEqualsGreaterThanToken, ast.KindColonToken, ast.KindOpenBraceToken: + switch p.nextToken() { + case ast.KindColonToken: + if isAsync && flags&ParseFlagsAllowAmbiguousAsyncArrow == 0 { + return core.TSUnknown + } + return core.TSTrue + case ast.KindEqualsGreaterThanToken, ast.KindOpenBraceToken: return core.TSTrue } return core.TSFalse } + // Simple case: "(...". After "async", this could also be a spread argument. + if second == ast.KindDotDotDotToken { + if isAsync { + if flags&ParseFlagsAllowAmbiguousAsyncArrow != 0 { + return core.TSTrue + } + second = p.nextToken() + } else { + return core.TSTrue + } + } // If encounter "([" or "({", this could be the start of a binding pattern. // Examples: // ([ x ]) => { } @@ -4317,11 +4338,6 @@ func (p *Parser) nextIsParenthesizedArrowFunctionExpression() core.Tristate { if second == ast.KindOpenBracketToken || second == ast.KindOpenBraceToken { return core.TSUnknown } - // Simple case: "(..." - // This is an arrow function with a rest parameter. - if second == ast.KindDotDotDotToken { - return core.TSTrue - } // Check for "(xxx yyy", where xxx is a modifier and yyy is an identifier. This // isn't actually allowed, but we want to treat it as a lambda so we can provide // a good error message. @@ -4391,8 +4407,8 @@ func (p *Parser) nextIsParenthesizedArrowFunctionExpression() core.Tristate { } } -func (p *Parser) tryParseParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction bool) *ast.Node { - tristate := p.isParenthesizedArrowFunctionExpression() +func (p *Parser) tryParseParenthesizedArrowFunctionExpression(flags ParseFlags) *ast.Node { + tristate := p.isParenthesizedArrowFunctionExpression(flags) if tristate == core.TSFalse { // It's definitely not a parenthesized arrow function expression. return nil @@ -4402,17 +4418,17 @@ func (p *Parser) tryParseParenthesizedArrowFunctionExpression(allowReturnTypeInA // it out, but don't allow any ambiguity, and return 'undefined' if this could be an // expression instead. if tristate == core.TSTrue { - return p.parseParenthesizedArrowFunctionExpression(true /*allowAmbiguity*/, true /*allowReturnTypeInArrowFunction*/) + return p.parseParenthesizedArrowFunctionExpression(true /*allowAmbiguity*/, flags) } state := p.mark() - result := p.parsePossibleParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction) + result := p.parsePossibleParenthesizedArrowFunctionExpression(flags) if result == nil { p.rewind(state) } return result } -func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, allowReturnTypeInArrowFunction bool) *ast.Node { +func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, flags ParseFlags) *ast.Node { pos := p.nodePos() jsdoc := p.jsdocScannerInfo() modifiers := p.parseModifiersForArrowFunction() @@ -4426,6 +4442,7 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, // And think that "(b =>" was actually a parenthesized arrow function with a missing // close paren. typeParameters := p.parseTypeParameters() + bodyFlags := flags var parameters *ast.NodeList if !p.parseExpected(ast.KindOpenParenToken) { if !allowAmbiguity { @@ -4433,6 +4450,9 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, } parameters = p.createMissingList() } else { + if isAsync && typeParameters == nil && (p.token == ast.KindCloseParenToken || p.token == ast.KindDotDotDotToken) { + bodyFlags = flags & ParseFlagsAllowAmbiguousAsyncArrow + } if !allowAmbiguity { maybeParameters := p.parseParametersWorker(signatureFlags, allowAmbiguity) if maybeParameters == nil { @@ -4446,7 +4466,7 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, return nil } } - hasReturnColon := p.token == ast.KindColonToken + requiresColon := !allowAmbiguity && p.token == ast.KindColonToken && flags&ParseFlagsDisallowArrowReturnType != 0 returnType := p.parseReturnType(ast.KindColonToken /*isType*/, false) if returnType != nil && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(returnType) { return nil @@ -4475,7 +4495,12 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, equalsGreaterThanToken := p.parseExpectedToken(ast.KindEqualsGreaterThanToken) var body *ast.Node if lastToken == ast.KindEqualsGreaterThanToken || lastToken == ast.KindOpenBraceToken { - body = p.parseArrowFunctionExpressionBody(isAsync, allowReturnTypeInArrowFunction) + if requiresColon { + bodyFlags |= ParseFlagsAllowAmbiguousAsyncArrow + } else { + bodyFlags = flags + } + body = p.parseArrowFunctionExpressionBody(isAsync, bodyFlags) } else { body = p.parseIdentifier() } @@ -4493,7 +4518,7 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, // a() ? (b: number, c?: string): void => d() : e // is determined by isParenthesizedArrowFunctionExpression to unambiguously // be an arrow expression, so we allow a return type. - if !allowReturnTypeInArrowFunction && hasReturnColon { + if requiresColon { // However, if the arrow function we were able to parse is followed by another colon // as in: // a ? (x): string => x : null @@ -4533,7 +4558,7 @@ func typeHasArrowFunctionBlockingParseError(node *ast.TypeNode) bool { return false } -func (p *Parser) parseArrowFunctionExpressionBody(isAsync bool, allowReturnTypeInArrowFunction bool) *ast.Node { +func (p *Parser) parseArrowFunctionExpressionBody(isAsync bool, flags ParseFlags) *ast.Node { if p.token == ast.KindOpenBraceToken { return p.parseFunctionBlock(core.IfElse(isAsync, ParseFlagsAwait, ParseFlagsNone), nil /*diagnosticMessage*/) } @@ -4557,7 +4582,7 @@ func (p *Parser) parseArrowFunctionExpressionBody(isAsync bool, allowReturnTypeI saveContextFlags := p.contextFlags p.setContextFlags(ast.NodeFlagsAwaitContext, isAsync) p.setContextFlags(ast.NodeFlagsYieldContext, false) - node := p.parseAssignmentExpressionOrHigherWorker(allowReturnTypeInArrowFunction) + node := p.parseAssignmentExpressionOrHigherWorker(flags) p.contextFlags = saveContextFlags return node } @@ -4567,26 +4592,26 @@ func (p *Parser) isStartOfExpressionStatement() bool { return p.token != ast.KindOpenBraceToken && p.token != ast.KindFunctionKeyword && p.token != ast.KindClassKeyword && p.token != ast.KindAtToken && p.isStartOfExpression() } -func (p *Parser) parsePossibleParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction bool) *ast.Node { +func (p *Parser) parsePossibleParenthesizedArrowFunctionExpression(flags ParseFlags) *ast.Node { tokenPos := p.scanner.TokenStart() if p.notParenthesizedArrow.Has(tokenPos) { return nil } - result := p.parseParenthesizedArrowFunctionExpression(false /*allowAmbiguity*/, allowReturnTypeInArrowFunction) + result := p.parseParenthesizedArrowFunctionExpression(false /*allowAmbiguity*/, flags) if result == nil { p.notParenthesizedArrow.Add(tokenPos) } return result } -func (p *Parser) tryParseAsyncSimpleArrowFunctionExpression(allowReturnTypeInArrowFunction bool) *ast.Node { +func (p *Parser) tryParseAsyncSimpleArrowFunctionExpression(flags ParseFlags) *ast.Node { // We do a check here so that we won't be doing unnecessarily call to "lookAhead" if p.token == ast.KindAsyncKeyword && p.lookAhead((*Parser).nextIsUnParenthesizedAsyncArrowFunction) { pos := p.nodePos() jsdoc := p.jsdocScannerInfo() asyncModifier := p.parseModifiersForArrowFunction() expr := p.parseBinaryExpressionOrHigher(ast.OperatorPrecedenceLowest) - return p.parseSimpleArrowFunctionExpression(pos, expr, allowReturnTypeInArrowFunction, jsdoc, asyncModifier) + return p.parseSimpleArrowFunctionExpression(pos, expr, flags, jsdoc, asyncModifier) } return nil } @@ -4612,18 +4637,18 @@ func (p *Parser) nextIsUnParenthesizedAsyncArrowFunction() bool { return false } -func (p *Parser) parseSimpleArrowFunctionExpression(pos int, identifier *ast.Node, allowReturnTypeInArrowFunction bool, jsdoc jsdocScannerInfo, asyncModifier *ast.ModifierList) *ast.Node { +func (p *Parser) parseSimpleArrowFunctionExpression(pos int, identifier *ast.Node, flags ParseFlags, jsdoc jsdocScannerInfo, asyncModifier *ast.ModifierList) *ast.Node { debug.Assert(p.token == ast.KindEqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>") parameter := p.finishNode(p.factory.NewParameterDeclaration(nil /*modifiers*/, nil /*dotDotDotToken*/, identifier, nil /*questionToken*/, nil /*typeNode*/, nil /*initializer*/), identifier.Pos()) parameters := p.newNodeList(parameter.Loc, []*ast.Node{parameter}) equalsGreaterThanToken := p.parseExpectedToken(ast.KindEqualsGreaterThanToken) - body := p.parseArrowFunctionExpressionBody(asyncModifier != nil /*isAsync*/, allowReturnTypeInArrowFunction) + body := p.parseArrowFunctionExpressionBody(asyncModifier != nil /*isAsync*/, flags) result := p.finishNode(p.factory.NewArrowFunction(asyncModifier, nil /*typeParameters*/, parameters, nil /*returnType*/, nil /*fullSignature*/, equalsGreaterThanToken, body), pos) p.withJSDoc(result, jsdoc) return result } -func (p *Parser) parseConditionalExpressionRest(leftOperand *ast.Expression, pos int, allowReturnTypeInArrowFunction bool) *ast.Expression { +func (p *Parser) parseConditionalExpressionRest(leftOperand *ast.Expression, pos int, flags ParseFlags) *ast.Expression { // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher. questionToken := p.parseOptionalToken(ast.KindQuestionToken) if questionToken == nil { @@ -4633,12 +4658,12 @@ func (p *Parser) parseConditionalExpressionRest(leftOperand *ast.Expression, pos // we do not that for the 'whenFalse' part. saveContextFlags := p.contextFlags p.setContextFlags(ast.NodeFlagsDisallowInContext, false) - trueExpression := p.parseAssignmentExpressionOrHigherWorker(false /*allowReturnTypeInArrowFunction*/) + trueExpression := p.parseAssignmentExpressionOrHigherWorker(ParseFlagsDisallowArrowReturnType) p.contextFlags = saveContextFlags colonToken := p.parseExpectedToken(ast.KindColonToken) var falseExpression *ast.Expression if ast.NodeIsPresent(colonToken) { - falseExpression = p.parseAssignmentExpressionOrHigherWorker(allowReturnTypeInArrowFunction) + falseExpression = p.parseAssignmentExpressionOrHigherWorker(flags) } else { falseExpression = p.createMissingIdentifier() } diff --git a/tsc/internal/parser/parser_test.go b/tsc/internal/parser/parser_test.go index ffa96713eb444..a8b878f031127 100644 --- a/tsc/internal/parser/parser_test.go +++ b/tsc/internal/parser/parser_test.go @@ -188,6 +188,461 @@ class MissingImplements implements B. {} assert.Equal(t, missingImplementsDecl.HeritageClauses.Nodes[0].AsHeritageClause().Types.Nodes[0].Kind, ast.KindExpressionWithTypeArguments) } +func TestConditionalAsyncCall(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "function* g() { const a = b ? async(...c) : 0; }", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] + declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindNumericLiteral) +} + +func TestConditionalAsyncCallWithArrow(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "function* g() { const a = b ? async(...c) : d => d; }", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] + declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) +} + +func TestConditionalAsyncCallYield(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "function* g() { const a = b ? yield async(...c) : 0; }", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] + declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindYieldExpression) + assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindNumericLiteral) + assert.Equal(t, conditional.WhenTrue.Expression().Kind, ast.KindCallExpression) +} + +func TestConditionalAsyncCallYieldWithArrow(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "function* g() { const a = b ? yield async(...c) : d => d; }", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] + declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindYieldExpression) + assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenTrue.Expression().Kind, ast.KindCallExpression) +} + +func TestConditionalAsyncCallJS(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.js", + PathKey: "/a.js", + }, "function* g() { const a = b ? async(...c) : 0; }", core.ScriptKindJS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] + declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindNumericLiteral) +} + +func TestConditionalAsyncCallWithArrowJS(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.js", + PathKey: "/a.js", + }, "function* g() { const a = b ? async(...c) : d => d; }", core.ScriptKindJS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] + declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) +} + +func TestConditionalAsyncCallYieldJS(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.js", + PathKey: "/a.js", + }, "function* g() { const a = b ? yield async(...c) : 0; }", core.ScriptKindJS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] + declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindYieldExpression) + assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindNumericLiteral) + assert.Equal(t, conditional.WhenTrue.Expression().Kind, ast.KindCallExpression) +} + +func TestConditionalAsyncCallYieldWithArrowJS(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.js", + PathKey: "/a.js", + }, "function* g() { const a = b ? yield async(...c) : d => d; }", core.ScriptKindJS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] + declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindYieldExpression) + assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenTrue.Expression().Kind, ast.KindCallExpression) +} + +func TestConditionalAsyncCallReturnType(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? async() : d => async (...c): Promise => c.length;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + arrow := conditional.WhenFalse.Body() + assert.Equal(t, arrow.Kind, ast.KindArrowFunction) + assert.Equal(t, arrow.Type().Kind, ast.KindTypeReference) +} + +func TestConditionalAsyncCallReturnTypeAlias(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? async() : d => async (...c): T => c.length;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + arrow := conditional.WhenFalse.Body() + assert.Equal(t, arrow.Kind, ast.KindArrowFunction) + assert.Equal(t, arrow.Type().Kind, ast.KindTypeReference) +} + +func TestConditionalAsyncCallWithTypedArrow(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? async() : d => async (): T => 0;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + arrow := conditional.WhenFalse.Body() + assert.Equal(t, arrow.Kind, ast.KindArrowFunction) + assert.Equal(t, len(arrow.Parameters()), 0) + assert.Equal(t, arrow.Modifiers().Nodes[0].Kind, ast.KindAsyncKeyword) + assert.Equal(t, arrow.Type().Kind, ast.KindTypeReference) + assert.Equal(t, arrow.Type().AsTypeReferenceNode().TypeName.Text(), "T") + assert.Equal(t, arrow.Body().Kind, ast.KindNumericLiteral) +} + +func TestConditionalParenthesizedExpressionWithTypedArrow(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? (value) : d => async (): T => 0;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindParenthesizedExpression) + assert.Equal(t, conditional.WhenTrue.Expression().Text(), "value") + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + arrow := conditional.WhenFalse.Body() + assert.Equal(t, arrow.Kind, ast.KindArrowFunction) + assert.Equal(t, len(arrow.Parameters()), 0) + assert.Equal(t, arrow.Modifiers().Nodes[0].Kind, ast.KindAsyncKeyword) + assert.Equal(t, arrow.Type().Kind, ast.KindTypeReference) + assert.Equal(t, arrow.Type().AsTypeReferenceNode().TypeName.Text(), "T") + assert.Equal(t, arrow.Body().Kind, ast.KindNumericLiteral) +} + +func TestConditionalAsyncCallWithParenthesizedTypedArrow(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? async() : d => (e): T => 0;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + arrow := conditional.WhenFalse.Body() + assert.Equal(t, arrow.Kind, ast.KindArrowFunction) + assert.Equal(t, len(arrow.Parameters()), 1) + assert.Equal(t, arrow.Parameters()[0].Name().Text(), "e") + assert.Equal(t, arrow.Type().AsTypeReferenceNode().TypeName.Text(), "T") + assert.Equal(t, arrow.Body().Kind, ast.KindNumericLiteral) +} + +func TestConditionalAsyncCallWithGenericTypedArrow(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? async() : d => async (): T => 0;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + arrow := conditional.WhenFalse.Body() + assert.Equal(t, arrow.Kind, ast.KindArrowFunction) + assert.Equal(t, len(arrow.TypeParameterList().Nodes), 1) + assert.Equal(t, arrow.TypeParameterList().Nodes[0].Name().Text(), "U") + assert.Equal(t, len(arrow.Parameters()), 0) + assert.Equal(t, arrow.Modifiers().Nodes[0].Kind, ast.KindAsyncKeyword) + assert.Equal(t, arrow.Type().AsTypeReferenceNode().TypeName.Text(), "T") + assert.Equal(t, arrow.Body().Kind, ast.KindNumericLiteral) +} + +func TestConditionalParenthesizedTypedArrowPriority(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? (c) : d => (e): T => 0;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenTrue.Type().AsTypeReferenceNode().TypeName.Text(), "d") + assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindParenthesizedExpression) + assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "e") + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenFalse.Parameters()[0].Name().Text(), "T") + assert.Equal(t, conditional.WhenFalse.Body().Kind, ast.KindNumericLiteral) +} + +func TestConditionalGenericTypedArrowPriority(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? async() : d => (e): T => 0;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) + assert.Equal(t, len(conditional.WhenTrue.TypeParameterList().Nodes), 1) + assert.Equal(t, conditional.WhenTrue.Type().AsTypeReferenceNode().TypeName.Text(), "d") + assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindParenthesizedExpression) + assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "e") + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenFalse.Parameters()[0].Name().Text(), "T") + assert.Equal(t, conditional.WhenFalse.Body().Kind, ast.KindNumericLiteral) +} + +func TestConditionalAsyncArrowWithConditionalBody(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? async (): Promise => b ? async() : 0 : () => 0;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindConditionalExpression) + body := conditional.WhenTrue.Body().AsConditionalExpression() + assert.Equal(t, body.WhenTrue.Kind, ast.KindCallExpression) + assert.Equal(t, body.WhenFalse.Kind, ast.KindNumericLiteral) +} + +func TestConditionalAsyncArrowBody(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? async () => async() : c => c;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) +} + +func TestConditionalAsyncArrowBodyJS(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.js", + PathKey: "/a.js", + }, "const a = b ? async () => async() : c => c;", core.ScriptKindJS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) +} + +func TestConditionalAsyncRestArrowBody(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? async (...c) => async() : d => d;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) +} + +func TestConditionalAsyncRestArrowBodyJS(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.js", + PathKey: "/a.js", + }, "const a = b ? async (...c) => async() : d => d;", core.ScriptKindJS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) +} + +func TestConditionalArrowBody(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? () => async() : c => c;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) +} + +func TestConditionalArrowBodyJS(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.js", + PathKey: "/a.js", + }, "const a = b ? () => async() : c => c;", core.ScriptKindJS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) +} + +func TestConditionalTypedAsyncArrowBody(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? async (c: number): Promise => async() : d => d;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenTrue.Type().Kind, ast.KindTypeReference) + assert.Equal(t, conditional.WhenTrue.Parameters()[0].Type().Kind, ast.KindNumberKeyword) + assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) +} + +func TestConditionalAsyncCallJSDoc(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.js", + PathKey: "/a.js", + }, "const a = b ? async(...c) : d => /** @param {number */ e => e;", core.ScriptKindJS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + assert.Equal(t, len(file.JSDocDiagnostics()), 1) + assert.Equal(t, len(file.Statements.Nodes), 1) + statement := file.Statements.Nodes[0] + declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + arrow := declaration.Initializer().AsConditionalExpression().WhenFalse.Body() + assert.Equal(t, len(arrow.JSDoc(file)), 1) +} + +func TestConditionalAsyncCallJSDocTypedef(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.js", + PathKey: "/a.js", + }, "const a = b ? async(...c) : d => /** @typedef {number} T */ e => e;", core.ScriptKindJS) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + assert.Equal(t, len(file.JSDocDiagnostics()), 0) + assert.Equal(t, len(file.Statements.Nodes), 2) + statement := file.Statements.Nodes[1] + declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + arrow := declaration.Initializer().AsConditionalExpression().WhenFalse.Body() + assert.Equal(t, len(arrow.JSDoc(file)), 1) +} + +func TestConditionalAsyncCallRecovery(t *testing.T) { + t.Parallel() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, "const a = b ? async(...c: number[]): Promise => 0;", core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 1) + assert.Equal(t, file.Diagnostics()[0].Code(), diagnostics.X_0_expected.Code()) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + assert.Equal(t, declaration.Initializer().AsConditionalExpression().WhenTrue.Kind, ast.KindArrowFunction) +} + func TestParseStaticSourcePhaseImport(t *testing.T) { t.Parallel() tests := []struct { diff --git a/tsc/internal/parser/types.go b/tsc/internal/parser/types.go index 671189445f1eb..03db776cfd029 100644 --- a/tsc/internal/parser/types.go +++ b/tsc/internal/parser/types.go @@ -5,10 +5,12 @@ package parser type ParseFlags uint32 const ( - ParseFlagsNone ParseFlags = 0 - ParseFlagsYield ParseFlags = 1 << 0 - ParseFlagsAwait ParseFlags = 1 << 1 - ParseFlagsType ParseFlags = 1 << 2 - ParseFlagsIgnoreMissingOpenBrace ParseFlags = 1 << 4 - ParseFlagsJSDoc ParseFlags = 1 << 5 + ParseFlagsNone ParseFlags = 0 + ParseFlagsYield ParseFlags = 1 << 0 + ParseFlagsAwait ParseFlags = 1 << 1 + ParseFlagsType ParseFlags = 1 << 2 + ParseFlagsIgnoreMissingOpenBrace ParseFlags = 1 << 4 + ParseFlagsJSDoc ParseFlags = 1 << 5 + ParseFlagsDisallowArrowReturnType ParseFlags = 1 << 6 + ParseFlagsAllowAmbiguousAsyncArrow ParseFlags = 1 << 7 ) diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js index a7b6057753bcf..d6c82758ba444 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js @@ -4,6 +4,49 @@ // Repro from #20096 let foo = (async bar => bar); + +const a = true; +const b = 1; +const c = [b]; + +function async(...c: number[]): number { + return b; +} + +const f1 = a ? async() : 0; +const f2 = a ? async() : x => x; +const f3 = a ? a ? async() : 0 : b; +const f4 = a ? x => async() : x => x; +const f5 = a ? async (): Promise => b : () => b; +const f6 = a ? async (): Promise => { return b; } : () => b; +const f7 = a ? async (): Promise => a ? async() : 0 : () => b; +const f8 = a ? (): number => b : () => b; + +const f9 = a ? async(...c) : 0; +const f10 = a ? async(...c) : x => x; +const f11 = a ? async (...c: number[]): Promise => c.length : () => 0; +const f12 = a ? async() : x => async (...c): Promise => c.length; + +type T = Promise; +const f13 = a ? async() : x => async (): Promise => b; +const f14 = a ? async() : x => async (): T => 0; +const f15 = a ? (b) : x => async (): T => 0; +const f16 = a ? async(...c) : x => async (): T => 0; +const f17 = a ? async() : x => (y): number => y; +const f18 = a ? async() : x => async (): T => 0; +const f19 = a ? async(...c) : x => (y): number => y; +const f20 = a ? async(...c) : x => async (): T => 0; +const f21 = a ? (x): number => (b): T => 0; +const f22 = a ? async (): Promise => (b): T => 0; +const f23 = a ? async () => async() : x => x; +const f24 = a ? async (...c) => async() : x => x; +const f25 = a ? () => async() : x => x; +const f26 = a ? async (c: number): Promise => async() : x => x; + +function* g() { + const f1 = a ? yield async(...c) : 0; + const f2 = a ? yield async(...c) : x => x; +} //// [parenthesizedAsyncArrowFunction.js] @@ -19,3 +62,39 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; let foo = ((bar) => __awaiter(void 0, void 0, void 0, function* () { return bar; })); +const a = true; +const b = 1; +const c = [b]; +function async(...c) { + return b; +} +const f1 = a ? async() : 0; +const f2 = a ? async() : x => x; +const f3 = a ? a ? async() : 0 : b; +const f4 = a ? x => async() : x => x; +const f5 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return b; }) : () => b; +const f6 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return b; }) : () => b; +const f7 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return a ? async() : 0; }) : () => b; +const f8 = a ? () => b : () => b; +const f9 = a ? async(...c) : 0; +const f10 = a ? async(...c) : x => x; +const f11 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return c.length; }) : () => 0; +const f12 = a ? async() : x => (...c) => __awaiter(void 0, void 0, void 0, function* () { return c.length; }); +const f13 = a ? async() : x => () => __awaiter(void 0, void 0, void 0, function* () { return b; }); +const f14 = a ? async() : x => () => __awaiter(void 0, void 0, void 0, function* () { return 0; }); +const f15 = a ? (b) : x => () => __awaiter(void 0, void 0, void 0, function* () { return 0; }); +const f16 = a ? async(...c) : x => () => __awaiter(void 0, void 0, void 0, function* () { return 0; }); +const f17 = a ? async() : x => (y) => y; +const f18 = a ? async() : x => () => __awaiter(void 0, void 0, void 0, function* () { return 0; }); +const f19 = a ? async(...c) : x => (y) => y; +const f20 = a ? async(...c) : x => () => __awaiter(void 0, void 0, void 0, function* () { return 0; }); +const f21 = a ? (x) => (b) : T => 0; +const f22 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return (b); }) : T => 0; +const f23 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; +const f24 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; +const f25 = a ? () => async() : x => x; +const f26 = a ? (c) => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; +function* g() { + const f1 = a ? yield async(...c) : 0; + const f2 = a ? yield async(...c) : x => x; +} diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols index 53286f39e8465..b1978407861ee 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols @@ -8,3 +8,242 @@ let foo = (async bar => bar); >bar : Symbol(bar, Decl(parenthesizedAsyncArrowFunction.ts, 2, 16)) >bar : Symbol(bar, Decl(parenthesizedAsyncArrowFunction.ts, 2, 16)) +const a = true; +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) + +const b = 1; +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) + +const c = [b]; +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) + +function async(...c: number[]): number { +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 8, 15)) + + return b; +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +} + +const f1 = a ? async() : 0; +>f1 : Symbol(f1, Decl(parenthesizedAsyncArrowFunction.ts, 12, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) + +const f2 = a ? async() : x => x; +>f2 : Symbol(f2, Decl(parenthesizedAsyncArrowFunction.ts, 13, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 13, 24)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 13, 24)) + +const f3 = a ? a ? async() : 0 : b; +>f3 : Symbol(f3, Decl(parenthesizedAsyncArrowFunction.ts, 14, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) + +const f4 = a ? x => async() : x => x; +>f4 : Symbol(f4, Decl(parenthesizedAsyncArrowFunction.ts, 15, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 15, 14)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 15, 29)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 15, 29)) + +const f5 = a ? async (): Promise => b : () => b; +>f5 : Symbol(f5, Decl(parenthesizedAsyncArrowFunction.ts, 16, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) + +const f6 = a ? async (): Promise => { return b; } : () => b; +>f6 : Symbol(f6, Decl(parenthesizedAsyncArrowFunction.ts, 17, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) + +const f7 = a ? async (): Promise => a ? async() : 0 : () => b; +>f7 : Symbol(f7, Decl(parenthesizedAsyncArrowFunction.ts, 18, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) + +const f8 = a ? (): number => b : () => b; +>f8 : Symbol(f8, Decl(parenthesizedAsyncArrowFunction.ts, 19, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) + +const f9 = a ? async(...c) : 0; +>f9 : Symbol(f9, Decl(parenthesizedAsyncArrowFunction.ts, 21, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) + +const f10 = a ? async(...c) : x => x; +>f10 : Symbol(f10, Decl(parenthesizedAsyncArrowFunction.ts, 22, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 22, 29)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 22, 29)) + +const f11 = a ? async (...c: number[]): Promise => c.length : () => 0; +>f11 : Symbol(f11, Decl(parenthesizedAsyncArrowFunction.ts, 23, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 23, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>c.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 23, 23)) +>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) + +const f12 = a ? async() : x => async (...c): Promise => c.length; +>f12 : Symbol(f12, Decl(parenthesizedAsyncArrowFunction.ts, 24, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 24, 25)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 24, 38)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>c.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 24, 38)) +>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) + +type T = Promise; +>T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 24, 73)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +const f13 = a ? async() : x => async (): Promise => b; +>f13 : Symbol(f13, Decl(parenthesizedAsyncArrowFunction.ts, 27, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 27, 25)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) + +const f14 = a ? async() : x => async (): T => 0; +>f14 : Symbol(f14, Decl(parenthesizedAsyncArrowFunction.ts, 28, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 28, 25)) +>T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 24, 73)) + +const f15 = a ? (b) : x => async (): T => 0; +>f15 : Symbol(f15, Decl(parenthesizedAsyncArrowFunction.ts, 29, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 29, 21)) +>T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 24, 73)) + +const f16 = a ? async(...c) : x => async (): T => 0; +>f16 : Symbol(f16, Decl(parenthesizedAsyncArrowFunction.ts, 30, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 30, 29)) +>T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 24, 73)) + +const f17 = a ? async() : x => (y): number => y; +>f17 : Symbol(f17, Decl(parenthesizedAsyncArrowFunction.ts, 31, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 31, 25)) +>y : Symbol(y, Decl(parenthesizedAsyncArrowFunction.ts, 31, 32)) +>y : Symbol(y, Decl(parenthesizedAsyncArrowFunction.ts, 31, 32)) + +const f18 = a ? async() : x => async (): T => 0; +>f18 : Symbol(f18, Decl(parenthesizedAsyncArrowFunction.ts, 32, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 32, 25)) +>U : Symbol(U, Decl(parenthesizedAsyncArrowFunction.ts, 32, 38)) +>T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 24, 73)) + +const f19 = a ? async(...c) : x => (y): number => y; +>f19 : Symbol(f19, Decl(parenthesizedAsyncArrowFunction.ts, 33, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 33, 29)) +>y : Symbol(y, Decl(parenthesizedAsyncArrowFunction.ts, 33, 36)) +>y : Symbol(y, Decl(parenthesizedAsyncArrowFunction.ts, 33, 36)) + +const f20 = a ? async(...c) : x => async (): T => 0; +>f20 : Symbol(f20, Decl(parenthesizedAsyncArrowFunction.ts, 34, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 34, 29)) +>U : Symbol(U, Decl(parenthesizedAsyncArrowFunction.ts, 34, 42)) +>T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 24, 73)) + +const f21 = a ? (x): number => (b): T => 0; +>f21 : Symbol(f21, Decl(parenthesizedAsyncArrowFunction.ts, 35, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 35, 17)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 35, 35)) + +const f22 = a ? async (): Promise => (b): T => 0; +>f22 : Symbol(f22, Decl(parenthesizedAsyncArrowFunction.ts, 36, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>U : Symbol(U, Decl(parenthesizedAsyncArrowFunction.ts, 36, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 36, 52)) + +const f23 = a ? async () => async() : x => x; +>f23 : Symbol(f23, Decl(parenthesizedAsyncArrowFunction.ts, 37, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 37, 37)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 37, 37)) + +const f24 = a ? async (...c) => async() : x => x; +>f24 : Symbol(f24, Decl(parenthesizedAsyncArrowFunction.ts, 38, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 38, 23)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 38, 41)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 38, 41)) + +const f25 = a ? () => async() : x => x; +>f25 : Symbol(f25, Decl(parenthesizedAsyncArrowFunction.ts, 39, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 39, 31)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 39, 31)) + +const f26 = a ? async (c: number): Promise => async() : x => x; +>f26 : Symbol(f26, Decl(parenthesizedAsyncArrowFunction.ts, 40, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 40, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 40, 63)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 40, 63)) + +function* g() { +>g : Symbol(g, Decl(parenthesizedAsyncArrowFunction.ts, 40, 71)) + + const f1 = a ? yield async(...c) : 0; +>f1 : Symbol(f1, Decl(parenthesizedAsyncArrowFunction.ts, 43, 9)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) + + const f2 = a ? yield async(...c) : x => x; +>f2 : Symbol(f2, Decl(parenthesizedAsyncArrowFunction.ts, 44, 9)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 44, 38)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 44, 38)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types index 9f5aa33f8d645..231e4f8adb549 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types @@ -10,3 +10,349 @@ let foo = (async bar => bar); >bar : any >bar : any +const a = true; +>a : true +>true : true + +const b = 1; +>b : 1 +>1 : 1 + +const c = [b]; +>c : number[] +>[b] : number[] +>b : 1 + +function async(...c: number[]): number { +>async : (...c: number[]) => number +>c : number[] + + return b; +>b : 1 +} + +const f1 = a ? async() : 0; +>f1 : number +>a ? async() : 0 : number +>a : true +>async() : number +>async : (...c: number[]) => number +>0 : 0 + +const f2 = a ? async() : x => x; +>f2 : number | ((x: any) => any) +>a ? async() : x => x : number | ((x: any) => any) +>a : true +>async() : number +>async : (...c: number[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +const f3 = a ? a ? async() : 0 : b; +>f3 : number +>a ? a ? async() : 0 : b : number +>a : true +>a ? async() : 0 : number +>a : true +>async() : number +>async : (...c: number[]) => number +>0 : 0 +>b : 1 + +const f4 = a ? x => async() : x => x; +>f4 : (x: any) => any +>a ? x => async() : x => x : (x: any) => any +>a : true +>x => async() : (x: any) => number +>x : any +>async() : number +>async : (...c: number[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +const f5 = a ? async (): Promise => b : () => b; +>f5 : (() => Promise) | (() => number) +>a ? async (): Promise => b : () => b : (() => Promise) | (() => number) +>a : true +>async (): Promise => b : () => Promise +>b : 1 +>() => b : () => number +>b : 1 + +const f6 = a ? async (): Promise => { return b; } : () => b; +>f6 : (() => Promise) | (() => number) +>a ? async (): Promise => { return b; } : () => b : (() => Promise) | (() => number) +>a : true +>async (): Promise => { return b; } : () => Promise +>b : 1 +>() => b : () => number +>b : 1 + +const f7 = a ? async (): Promise => a ? async() : 0 : () => b; +>f7 : (() => Promise) | (() => number) +>a ? async (): Promise => a ? async() : 0 : () => b : (() => Promise) | (() => number) +>a : true +>async (): Promise => a ? async() : 0 : () => Promise +>a ? async() : 0 : number +>a : true +>async() : number +>async : (...c: number[]) => number +>0 : 0 +>() => b : () => number +>b : 1 + +const f8 = a ? (): number => b : () => b; +>f8 : () => number +>a ? (): number => b : () => b : () => number +>a : true +>(): number => b : () => number +>b : 1 +>() => b : () => number +>b : 1 + +const f9 = a ? async(...c) : 0; +>f9 : number +>a ? async(...c) : 0 : number +>a : true +>async(...c) : number +>async : (...c: number[]) => number +>...c : number +>c : number[] +>0 : 0 + +const f10 = a ? async(...c) : x => x; +>f10 : number | ((x: any) => any) +>a ? async(...c) : x => x : number | ((x: any) => any) +>a : true +>async(...c) : number +>async : (...c: number[]) => number +>...c : number +>c : number[] +>x => x : (x: any) => any +>x : any +>x : any + +const f11 = a ? async (...c: number[]): Promise => c.length : () => 0; +>f11 : ((...c: number[]) => Promise) | (() => number) +>a ? async (...c: number[]): Promise => c.length : () => 0 : ((...c: number[]) => Promise) | (() => number) +>a : true +>async (...c: number[]): Promise => c.length : (...c: number[]) => Promise +>c : number[] +>c.length : number +>c : number[] +>length : number +>() => 0 : () => number +>0 : 0 + +const f12 = a ? async() : x => async (...c): Promise => c.length; +>f12 : number | ((x: any) => (...c: any[]) => Promise) +>a ? async() : x => async (...c): Promise => c.length : number | ((x: any) => (...c: any[]) => Promise) +>a : true +>async() : number +>async : (...c: number[]) => number +>x => async (...c): Promise => c.length : (x: any) => (...c: any[]) => Promise +>x : any +>async (...c): Promise => c.length : (...c: any[]) => Promise +>c : any[] +>c.length : number +>c : any[] +>length : number + +type T = Promise; +>T : T + +const f13 = a ? async() : x => async (): Promise => b; +>f13 : number | ((x: any) => () => Promise) +>a ? async() : x => async (): Promise => b : number | ((x: any) => () => Promise) +>a : true +>async() : number +>async : (...c: number[]) => number +>x => async (): Promise => b : (x: any) => () => Promise +>x : any +>async (): Promise => b : () => Promise +>b : 1 + +const f14 = a ? async() : x => async (): T => 0; +>f14 : number | ((x: any) => () => T) +>a ? async() : x => async (): T => 0 : number | ((x: any) => () => T) +>a : true +>async() : number +>async : (...c: number[]) => number +>x => async (): T => 0 : (x: any) => () => T +>x : any +>async (): T => 0 : () => T +>0 : 0 + +const f15 = a ? (b) : x => async (): T => 0; +>f15 : 1 | ((x: any) => () => T) +>a ? (b) : x => async (): T => 0 : 1 | ((x: any) => () => T) +>a : true +>(b) : 1 +>b : 1 +>x => async (): T => 0 : (x: any) => () => T +>x : any +>async (): T => 0 : () => T +>0 : 0 + +const f16 = a ? async(...c) : x => async (): T => 0; +>f16 : number | ((x: any) => () => T) +>a ? async(...c) : x => async (): T => 0 : number | ((x: any) => () => T) +>a : true +>async(...c) : number +>async : (...c: number[]) => number +>...c : number +>c : number[] +>x => async (): T => 0 : (x: any) => () => T +>x : any +>async (): T => 0 : () => T +>0 : 0 + +const f17 = a ? async() : x => (y): number => y; +>f17 : number | ((x: any) => (y: any) => number) +>a ? async() : x => (y): number => y : number | ((x: any) => (y: any) => number) +>a : true +>async() : number +>async : (...c: number[]) => number +>x => (y): number => y : (x: any) => (y: any) => number +>x : any +>(y): number => y : (y: any) => number +>y : any +>y : any + +const f18 = a ? async() : x => async (): T => 0; +>f18 : number | ((x: any) => () => T) +>a ? async() : x => async (): T => 0 : number | ((x: any) => () => T) +>a : true +>async() : number +>async : (...c: number[]) => number +>x => async (): T => 0 : (x: any) => () => T +>x : any +>async (): T => 0 : () => T +>0 : 0 + +const f19 = a ? async(...c) : x => (y): number => y; +>f19 : number | ((x: any) => (y: any) => number) +>a ? async(...c) : x => (y): number => y : number | ((x: any) => (y: any) => number) +>a : true +>async(...c) : number +>async : (...c: number[]) => number +>...c : number +>c : number[] +>x => (y): number => y : (x: any) => (y: any) => number +>x : any +>(y): number => y : (y: any) => number +>y : any +>y : any + +const f20 = a ? async(...c) : x => async (): T => 0; +>f20 : number | ((x: any) => () => T) +>a ? async(...c) : x => async (): T => 0 : number | ((x: any) => () => T) +>a : true +>async(...c) : number +>async : (...c: number[]) => number +>...c : number +>c : number[] +>x => async (): T => 0 : (x: any) => () => T +>x : any +>async (): T => 0 : () => T +>0 : 0 + +const f21 = a ? (x): number => (b): T => 0; +>f21 : (x: any) => number +>a ? (x): number => (b): T => 0 : (x: any) => number +>a : true +>(x): number => (b) : (x: any) => number +>x : any +>(b) : 1 +>b : 1 +>T => 0 : (T: any) => number +>T : any +>0 : 0 + +const f22 = a ? async (): Promise => (b): T => 0; +>f22 : (() => Promise) | ((T: any) => number) +>a ? async (): Promise => (b): T => 0 : (() => Promise) | ((T: any) => number) +>a : true +>async (): Promise => (b) : () => Promise +>(b) : 1 +>b : 1 +>T => 0 : (T: any) => number +>T : any +>0 : 0 + +const f23 = a ? async () => async() : x => x; +>f23 : (x: any) => any +>a ? async () => async() : x => x : (x: any) => any +>a : true +>async () => async() : () => Promise +>async() : number +>async : (...c: number[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +const f24 = a ? async (...c) => async() : x => x; +>f24 : ((...c: any[]) => Promise) | ((x: any) => any) +>a ? async (...c) => async() : x => x : ((...c: any[]) => Promise) | ((x: any) => any) +>a : true +>async (...c) => async() : (...c: any[]) => Promise +>c : any[] +>async() : number +>async : (...c: number[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +const f25 = a ? () => async() : x => x; +>f25 : (x: any) => any +>a ? () => async() : x => x : (x: any) => any +>a : true +>() => async() : () => number +>async() : number +>async : (...c: number[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +const f26 = a ? async (c: number): Promise => async() : x => x; +>f26 : (x: any) => any +>a ? async (c: number): Promise => async() : x => x : (x: any) => any +>a : true +>async (c: number): Promise => async() : (c: number) => Promise +>c : number +>async() : number +>async : (...c: number[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +function* g() { +>g : () => Generator + + const f1 = a ? yield async(...c) : 0; +>f1 : any +>a ? yield async(...c) : 0 : any +>a : true +>yield async(...c) : any +>async(...c) : number +>async : (...c: number[]) => number +>...c : number +>c : number[] +>0 : 0 + + const f2 = a ? yield async(...c) : x => x; +>f2 : any +>a ? yield async(...c) : x => x : any +>a : true +>yield async(...c) : any +>async(...c) : number +>async : (...c: number[]) => number +>...c : number +>c : number[] +>x => x : (x: any) => any +>x : any +>x : any +} + diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js new file mode 100644 index 0000000000000..feeaf996546a8 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js @@ -0,0 +1,49 @@ +//// [tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts] //// + +//// [a.js] +const a = true; +const b = 1; +const c = [b]; + +function async(...c) { + return b; +} + +const f1 = a ? async(...c) : 0; +const f2 = a ? async(...c) : x => x; +const f3 = a ? async () => async() : x => x; +const f4 = a ? async (...c) => async() : x => x; +const f5 = a ? () => async() : x => x; + +function* g() { + const f1 = a ? yield async(...c) : 0; + const f2 = a ? yield async(...c) : x => x; +} + + +//// [a.js] +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +const a = true; +const b = 1; +const c = [b]; +function async(...c) { + return b; +} +const f1 = a ? async(...c) : 0; +const f2 = a ? async(...c) : x => x; +const f3 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; +const f4 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; +const f5 = a ? () => async() : x => x; +function* g() { + const f1 = a ? yield async(...c) : 0; + const f2 = a ? yield async(...c) : x => x; +} diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols new file mode 100644 index 0000000000000..2a779b0db2291 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols @@ -0,0 +1,75 @@ +//// [tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts] //// + +=== a.js === +const a = true; +>a : Symbol(a, Decl(a.js, 0, 5)) + +const b = 1; +>b : Symbol(b, Decl(a.js, 1, 5)) + +const c = [b]; +>c : Symbol(c, Decl(a.js, 2, 5)) +>b : Symbol(b, Decl(a.js, 1, 5)) + +function async(...c) { +>async : Symbol(async, Decl(a.js, 2, 14)) +>c : Symbol(c, Decl(a.js, 4, 15)) + + return b; +>b : Symbol(b, Decl(a.js, 1, 5)) +} + +const f1 = a ? async(...c) : 0; +>f1 : Symbol(f1, Decl(a.js, 8, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>c : Symbol(c, Decl(a.js, 2, 5)) + +const f2 = a ? async(...c) : x => x; +>f2 : Symbol(f2, Decl(a.js, 9, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>c : Symbol(c, Decl(a.js, 2, 5)) +>x : Symbol(x, Decl(a.js, 9, 28)) +>x : Symbol(x, Decl(a.js, 9, 28)) + +const f3 = a ? async () => async() : x => x; +>f3 : Symbol(f3, Decl(a.js, 10, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>x : Symbol(x, Decl(a.js, 10, 36)) +>x : Symbol(x, Decl(a.js, 10, 36)) + +const f4 = a ? async (...c) => async() : x => x; +>f4 : Symbol(f4, Decl(a.js, 11, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>c : Symbol(c, Decl(a.js, 11, 22)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>x : Symbol(x, Decl(a.js, 11, 40)) +>x : Symbol(x, Decl(a.js, 11, 40)) + +const f5 = a ? () => async() : x => x; +>f5 : Symbol(f5, Decl(a.js, 12, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>x : Symbol(x, Decl(a.js, 12, 30)) +>x : Symbol(x, Decl(a.js, 12, 30)) + +function* g() { +>g : Symbol(g, Decl(a.js, 12, 38)) + + const f1 = a ? yield async(...c) : 0; +>f1 : Symbol(f1, Decl(a.js, 15, 9)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>c : Symbol(c, Decl(a.js, 2, 5)) + + const f2 = a ? yield async(...c) : x => x; +>f2 : Symbol(f2, Decl(a.js, 16, 9)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>c : Symbol(c, Decl(a.js, 2, 5)) +>x : Symbol(x, Decl(a.js, 16, 38)) +>x : Symbol(x, Decl(a.js, 16, 38)) +} + diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types new file mode 100644 index 0000000000000..61e4470d50c75 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types @@ -0,0 +1,108 @@ +//// [tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts] //// + +=== a.js === +const a = true; +>a : true +>true : true + +const b = 1; +>b : 1 +>1 : 1 + +const c = [b]; +>c : number[] +>[b] : number[] +>b : 1 + +function async(...c) { +>async : (...c: any[]) => number +>c : any[] + + return b; +>b : 1 +} + +const f1 = a ? async(...c) : 0; +>f1 : number +>a ? async(...c) : 0 : number +>a : true +>async(...c) : number +>async : (...c: any[]) => number +>...c : number +>c : number[] +>0 : 0 + +const f2 = a ? async(...c) : x => x; +>f2 : number | ((x: any) => any) +>a ? async(...c) : x => x : number | ((x: any) => any) +>a : true +>async(...c) : number +>async : (...c: any[]) => number +>...c : number +>c : number[] +>x => x : (x: any) => any +>x : any +>x : any + +const f3 = a ? async () => async() : x => x; +>f3 : (x: any) => any +>a ? async () => async() : x => x : (x: any) => any +>a : true +>async () => async() : () => Promise +>async() : number +>async : (...c: any[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +const f4 = a ? async (...c) => async() : x => x; +>f4 : ((...c: any[]) => Promise) | ((x: any) => any) +>a ? async (...c) => async() : x => x : ((...c: any[]) => Promise) | ((x: any) => any) +>a : true +>async (...c) => async() : (...c: any[]) => Promise +>c : any[] +>async() : number +>async : (...c: any[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +const f5 = a ? () => async() : x => x; +>f5 : (x: any) => any +>a ? () => async() : x => x : (x: any) => any +>a : true +>() => async() : () => number +>async() : number +>async : (...c: any[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +function* g() { +>g : () => Generator + + const f1 = a ? yield async(...c) : 0; +>f1 : any +>a ? yield async(...c) : 0 : any +>a : true +>yield async(...c) : any +>async(...c) : number +>async : (...c: any[]) => number +>...c : number +>c : number[] +>0 : 0 + + const f2 = a ? yield async(...c) : x => x; +>f2 : any +>a ? yield async(...c) : x => x : any +>a : true +>yield async(...c) : any +>async(...c) : number +>async : (...c: any[]) => number +>...c : number +>c : number[] +>x => x : (x: any) => any +>x : any +>x : any +} + diff --git a/tsc/testdata/baselines/reference/conformance/asyncArrowFunction_allowJs.errors.txt b/tsc/testdata/baselines/reference/conformance/asyncArrowFunction_allowJs.errors.txt index 08dc36a626764..e322798fd3804 100644 --- a/tsc/testdata/baselines/reference/conformance/asyncArrowFunction_allowJs.errors.txt +++ b/tsc/testdata/baselines/reference/conformance/asyncArrowFunction_allowJs.errors.txt @@ -45,4 +45,18 @@ file.js(22,12): error TS7006: Parameter 'p' implicitly has an 'any' type. // Error (good) f(async () => { return 0 - }) \ No newline at end of file + }) + + const g = true; + + function async() { + return 1; + } + + const f1 = g ? async() : 0; + /** @type {number | ((x: number) => number)} */ + const f2 = g ? async() : x => x; + const f3 = g ? g ? async() : 0 : 1; + /** @type {(x: number) => number} */ + const f4 = g ? x => async() : x => x; + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/conformance/asyncArrowFunction_allowJs.symbols b/tsc/testdata/baselines/reference/conformance/asyncArrowFunction_allowJs.symbols index 40bae3eb3736c..4fc7c6c17c44c 100644 --- a/tsc/testdata/baselines/reference/conformance/asyncArrowFunction_allowJs.symbols +++ b/tsc/testdata/baselines/reference/conformance/asyncArrowFunction_allowJs.symbols @@ -38,3 +38,41 @@ f(async () => { return 0 }) + +const g = true; +>g : Symbol(g, Decl(file.js, 28, 5)) + +function async() { +>async : Symbol(async, Decl(file.js, 28, 15)) + + return 1; +} + +const f1 = g ? async() : 0; +>f1 : Symbol(f1, Decl(file.js, 34, 5)) +>g : Symbol(g, Decl(file.js, 28, 5)) +>async : Symbol(async, Decl(file.js, 28, 15)) + +/** @type {number | ((x: number) => number)} */ +const f2 = g ? async() : x => x; +>f2 : Symbol(f2, Decl(file.js, 36, 5)) +>g : Symbol(g, Decl(file.js, 28, 5)) +>async : Symbol(async, Decl(file.js, 28, 15)) +>x : Symbol(x, Decl(file.js, 36, 24)) +>x : Symbol(x, Decl(file.js, 36, 24)) + +const f3 = g ? g ? async() : 0 : 1; +>f3 : Symbol(f3, Decl(file.js, 37, 5)) +>g : Symbol(g, Decl(file.js, 28, 5)) +>g : Symbol(g, Decl(file.js, 28, 5)) +>async : Symbol(async, Decl(file.js, 28, 15)) + +/** @type {(x: number) => number} */ +const f4 = g ? x => async() : x => x; +>f4 : Symbol(f4, Decl(file.js, 39, 5)) +>g : Symbol(g, Decl(file.js, 28, 5)) +>x : Symbol(x, Decl(file.js, 39, 14)) +>async : Symbol(async, Decl(file.js, 28, 15)) +>x : Symbol(x, Decl(file.js, 39, 29)) +>x : Symbol(x, Decl(file.js, 39, 29)) + diff --git a/tsc/testdata/baselines/reference/conformance/asyncArrowFunction_allowJs.types b/tsc/testdata/baselines/reference/conformance/asyncArrowFunction_allowJs.types index d8d3316603e0e..376d8932fec68 100644 --- a/tsc/testdata/baselines/reference/conformance/asyncArrowFunction_allowJs.types +++ b/tsc/testdata/baselines/reference/conformance/asyncArrowFunction_allowJs.types @@ -51,3 +51,58 @@ f(async () => { >0 : 0 }) + +const g = true; +>g : true +>true : true + +function async() { +>async : () => number + + return 1; +>1 : 1 +} + +const f1 = g ? async() : 0; +>f1 : number +>g ? async() : 0 : number +>g : true +>async() : number +>async : () => number +>0 : 0 + +/** @type {number | ((x: number) => number)} */ +const f2 = g ? async() : x => x; +>f2 : number | ((x: number) => number) +>g ? async() : x => x : number | ((x: number) => number) +>g : true +>async() : number +>async : () => number +>x => x : (x: number) => number +>x : number +>x : number + +const f3 = g ? g ? async() : 0 : 1; +>f3 : number +>g ? g ? async() : 0 : 1 : number +>g : true +>g ? async() : 0 : number +>g : true +>async() : number +>async : () => number +>0 : 0 +>1 : 1 + +/** @type {(x: number) => number} */ +const f4 = g ? x => async() : x => x; +>f4 : (x: number) => number +>g ? x => async() : x => x : (x: number) => number +>g : true +>x => async() : (x: number) => number +>x : number +>async() : number +>async : () => number +>x => x : (x: number) => number +>x : number +>x : number + diff --git a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts index 057eb64c82138..e19686811884a 100644 --- a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts +++ b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts @@ -3,3 +3,46 @@ // Repro from #20096 let foo = (async bar => bar); + +const a = true; +const b = 1; +const c = [b]; + +function async(...c: number[]): number { + return b; +} + +const f1 = a ? async() : 0; +const f2 = a ? async() : x => x; +const f3 = a ? a ? async() : 0 : b; +const f4 = a ? x => async() : x => x; +const f5 = a ? async (): Promise => b : () => b; +const f6 = a ? async (): Promise => { return b; } : () => b; +const f7 = a ? async (): Promise => a ? async() : 0 : () => b; +const f8 = a ? (): number => b : () => b; + +const f9 = a ? async(...c) : 0; +const f10 = a ? async(...c) : x => x; +const f11 = a ? async (...c: number[]): Promise => c.length : () => 0; +const f12 = a ? async() : x => async (...c): Promise => c.length; + +type T = Promise; +const f13 = a ? async() : x => async (): Promise => b; +const f14 = a ? async() : x => async (): T => 0; +const f15 = a ? (b) : x => async (): T => 0; +const f16 = a ? async(...c) : x => async (): T => 0; +const f17 = a ? async() : x => (y): number => y; +const f18 = a ? async() : x => async (): T => 0; +const f19 = a ? async(...c) : x => (y): number => y; +const f20 = a ? async(...c) : x => async (): T => 0; +const f21 = a ? (x): number => (b): T => 0; +const f22 = a ? async (): Promise => (b): T => 0; +const f23 = a ? async () => async() : x => x; +const f24 = a ? async (...c) => async() : x => x; +const f25 = a ? () => async() : x => x; +const f26 = a ? async (c: number): Promise => async() : x => x; + +function* g() { + const f1 = a ? yield async(...c) : 0; + const f2 = a ? yield async(...c) : x => x; +} diff --git a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts new file mode 100644 index 0000000000000..1e01dd2edac1d --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts @@ -0,0 +1,24 @@ +// @target: es2015 +// @strict: false +// @checkJs: true +// @outDir: out +// @filename: a.js + +const a = true; +const b = 1; +const c = [b]; + +function async(...c) { + return b; +} + +const f1 = a ? async(...c) : 0; +const f2 = a ? async(...c) : x => x; +const f3 = a ? async () => async() : x => x; +const f4 = a ? async (...c) => async() : x => x; +const f5 = a ? () => async() : x => x; + +function* g() { + const f1 = a ? yield async(...c) : 0; + const f2 = a ? yield async(...c) : x => x; +} diff --git a/tsc/testdata/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction_allowJs.ts b/tsc/testdata/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction_allowJs.ts index 9f1f76100434d..39759f6cb41d8 100644 --- a/tsc/testdata/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction_allowJs.ts +++ b/tsc/testdata/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction_allowJs.ts @@ -30,4 +30,17 @@ const f = (p) => {} // Error (good) f(async () => { return 0 -}) \ No newline at end of file +}) + +const g = true; + +function async() { + return 1; +} + +const f1 = g ? async() : 0; +/** @type {number | ((x: number) => number)} */ +const f2 = g ? async() : x => x; +const f3 = g ? g ? async() : 0 : 1; +/** @type {(x: number) => number} */ +const f4 = g ? x => async() : x => x; From 8a8315d9468b67fa580931b003944374815bed0a Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk Date: Sun, 18 Oct 2026 14:16:47 +0300 Subject: [PATCH 2/7] separate expression parsing flags --- tsc/internal/parser/parser.go | 36 +++++++++++++++++------------------ tsc/internal/parser/types.go | 22 +++++++++++++-------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/tsc/internal/parser/parser.go b/tsc/internal/parser/parser.go index ce4899a68ab9a..3665680f0af26 100644 --- a/tsc/internal/parser/parser.go +++ b/tsc/internal/parser/parser.go @@ -4155,10 +4155,10 @@ func (p *Parser) parseExpressionAllowIn() *ast.Expression { } func (p *Parser) parseAssignmentExpressionOrHigher() *ast.Expression { - return p.parseAssignmentExpressionOrHigherWorker(ParseFlagsNone) + return p.parseAssignmentExpressionOrHigherWorker(ExpressionParseFlagsNone) } -func (p *Parser) parseAssignmentExpressionOrHigherWorker(flags ParseFlags) *ast.Expression { +func (p *Parser) parseAssignmentExpressionOrHigherWorker(flags ExpressionParseFlags) *ast.Expression { // AssignmentExpression[in,yield]: // 1) ConditionalExpression[?in,?yield] // 2) LeftHandSideExpression = AssignmentExpression[?in,?yield] @@ -4254,7 +4254,7 @@ func (p *Parser) isYieldExpression() bool { return false } -func (p *Parser) parseYieldExpression(flags ParseFlags) *ast.Node { +func (p *Parser) parseYieldExpression(flags ExpressionParseFlags) *ast.Node { pos := p.nodePos() // YieldExpression[In] : // yield @@ -4272,7 +4272,7 @@ func (p *Parser) parseYieldExpression(flags ParseFlags) *ast.Node { return p.finishNode(result, pos) } -func (p *Parser) isParenthesizedArrowFunctionExpression(flags ParseFlags) core.Tristate { +func (p *Parser) isParenthesizedArrowFunctionExpression(flags ExpressionParseFlags) core.Tristate { if p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken || p.token == ast.KindAsyncKeyword { state := p.mark() result := p.nextIsParenthesizedArrowFunctionExpression(flags) @@ -4289,7 +4289,7 @@ func (p *Parser) isParenthesizedArrowFunctionExpression(flags ParseFlags) core.T return core.TSFalse } -func (p *Parser) nextIsParenthesizedArrowFunctionExpression(flags ParseFlags) core.Tristate { +func (p *Parser) nextIsParenthesizedArrowFunctionExpression(flags ExpressionParseFlags) core.Tristate { isAsync := p.token == ast.KindAsyncKeyword if isAsync { p.nextToken() @@ -4309,7 +4309,7 @@ func (p *Parser) nextIsParenthesizedArrowFunctionExpression(flags ParseFlags) co // but this is probably what the user intended. switch p.nextToken() { case ast.KindColonToken: - if isAsync && flags&ParseFlagsAllowAmbiguousAsyncArrow == 0 { + if isAsync && flags&ExpressionParseFlagsAllowAmbiguousAsyncArrow == 0 { return core.TSUnknown } return core.TSTrue @@ -4321,7 +4321,7 @@ func (p *Parser) nextIsParenthesizedArrowFunctionExpression(flags ParseFlags) co // Simple case: "(...". After "async", this could also be a spread argument. if second == ast.KindDotDotDotToken { if isAsync { - if flags&ParseFlagsAllowAmbiguousAsyncArrow != 0 { + if flags&ExpressionParseFlagsAllowAmbiguousAsyncArrow != 0 { return core.TSTrue } second = p.nextToken() @@ -4407,7 +4407,7 @@ func (p *Parser) nextIsParenthesizedArrowFunctionExpression(flags ParseFlags) co } } -func (p *Parser) tryParseParenthesizedArrowFunctionExpression(flags ParseFlags) *ast.Node { +func (p *Parser) tryParseParenthesizedArrowFunctionExpression(flags ExpressionParseFlags) *ast.Node { tristate := p.isParenthesizedArrowFunctionExpression(flags) if tristate == core.TSFalse { // It's definitely not a parenthesized arrow function expression. @@ -4428,7 +4428,7 @@ func (p *Parser) tryParseParenthesizedArrowFunctionExpression(flags ParseFlags) return result } -func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, flags ParseFlags) *ast.Node { +func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, flags ExpressionParseFlags) *ast.Node { pos := p.nodePos() jsdoc := p.jsdocScannerInfo() modifiers := p.parseModifiersForArrowFunction() @@ -4451,7 +4451,7 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, parameters = p.createMissingList() } else { if isAsync && typeParameters == nil && (p.token == ast.KindCloseParenToken || p.token == ast.KindDotDotDotToken) { - bodyFlags = flags & ParseFlagsAllowAmbiguousAsyncArrow + bodyFlags = flags & ExpressionParseFlagsAllowAmbiguousAsyncArrow } if !allowAmbiguity { maybeParameters := p.parseParametersWorker(signatureFlags, allowAmbiguity) @@ -4466,7 +4466,7 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, return nil } } - requiresColon := !allowAmbiguity && p.token == ast.KindColonToken && flags&ParseFlagsDisallowArrowReturnType != 0 + requiresColon := !allowAmbiguity && p.token == ast.KindColonToken && flags&ExpressionParseFlagsDisallowArrowReturnType != 0 returnType := p.parseReturnType(ast.KindColonToken /*isType*/, false) if returnType != nil && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(returnType) { return nil @@ -4496,7 +4496,7 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, var body *ast.Node if lastToken == ast.KindEqualsGreaterThanToken || lastToken == ast.KindOpenBraceToken { if requiresColon { - bodyFlags |= ParseFlagsAllowAmbiguousAsyncArrow + bodyFlags |= ExpressionParseFlagsAllowAmbiguousAsyncArrow } else { bodyFlags = flags } @@ -4558,7 +4558,7 @@ func typeHasArrowFunctionBlockingParseError(node *ast.TypeNode) bool { return false } -func (p *Parser) parseArrowFunctionExpressionBody(isAsync bool, flags ParseFlags) *ast.Node { +func (p *Parser) parseArrowFunctionExpressionBody(isAsync bool, flags ExpressionParseFlags) *ast.Node { if p.token == ast.KindOpenBraceToken { return p.parseFunctionBlock(core.IfElse(isAsync, ParseFlagsAwait, ParseFlagsNone), nil /*diagnosticMessage*/) } @@ -4592,7 +4592,7 @@ func (p *Parser) isStartOfExpressionStatement() bool { return p.token != ast.KindOpenBraceToken && p.token != ast.KindFunctionKeyword && p.token != ast.KindClassKeyword && p.token != ast.KindAtToken && p.isStartOfExpression() } -func (p *Parser) parsePossibleParenthesizedArrowFunctionExpression(flags ParseFlags) *ast.Node { +func (p *Parser) parsePossibleParenthesizedArrowFunctionExpression(flags ExpressionParseFlags) *ast.Node { tokenPos := p.scanner.TokenStart() if p.notParenthesizedArrow.Has(tokenPos) { return nil @@ -4604,7 +4604,7 @@ func (p *Parser) parsePossibleParenthesizedArrowFunctionExpression(flags ParseFl return result } -func (p *Parser) tryParseAsyncSimpleArrowFunctionExpression(flags ParseFlags) *ast.Node { +func (p *Parser) tryParseAsyncSimpleArrowFunctionExpression(flags ExpressionParseFlags) *ast.Node { // We do a check here so that we won't be doing unnecessarily call to "lookAhead" if p.token == ast.KindAsyncKeyword && p.lookAhead((*Parser).nextIsUnParenthesizedAsyncArrowFunction) { pos := p.nodePos() @@ -4637,7 +4637,7 @@ func (p *Parser) nextIsUnParenthesizedAsyncArrowFunction() bool { return false } -func (p *Parser) parseSimpleArrowFunctionExpression(pos int, identifier *ast.Node, flags ParseFlags, jsdoc jsdocScannerInfo, asyncModifier *ast.ModifierList) *ast.Node { +func (p *Parser) parseSimpleArrowFunctionExpression(pos int, identifier *ast.Node, flags ExpressionParseFlags, jsdoc jsdocScannerInfo, asyncModifier *ast.ModifierList) *ast.Node { debug.Assert(p.token == ast.KindEqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>") parameter := p.finishNode(p.factory.NewParameterDeclaration(nil /*modifiers*/, nil /*dotDotDotToken*/, identifier, nil /*questionToken*/, nil /*typeNode*/, nil /*initializer*/), identifier.Pos()) parameters := p.newNodeList(parameter.Loc, []*ast.Node{parameter}) @@ -4648,7 +4648,7 @@ func (p *Parser) parseSimpleArrowFunctionExpression(pos int, identifier *ast.Nod return result } -func (p *Parser) parseConditionalExpressionRest(leftOperand *ast.Expression, pos int, flags ParseFlags) *ast.Expression { +func (p *Parser) parseConditionalExpressionRest(leftOperand *ast.Expression, pos int, flags ExpressionParseFlags) *ast.Expression { // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher. questionToken := p.parseOptionalToken(ast.KindQuestionToken) if questionToken == nil { @@ -4658,7 +4658,7 @@ func (p *Parser) parseConditionalExpressionRest(leftOperand *ast.Expression, pos // we do not that for the 'whenFalse' part. saveContextFlags := p.contextFlags p.setContextFlags(ast.NodeFlagsDisallowInContext, false) - trueExpression := p.parseAssignmentExpressionOrHigherWorker(ParseFlagsDisallowArrowReturnType) + trueExpression := p.parseAssignmentExpressionOrHigherWorker(ExpressionParseFlagsDisallowArrowReturnType) p.contextFlags = saveContextFlags colonToken := p.parseExpectedToken(ast.KindColonToken) var falseExpression *ast.Expression diff --git a/tsc/internal/parser/types.go b/tsc/internal/parser/types.go index 03db776cfd029..c2295bb1976c8 100644 --- a/tsc/internal/parser/types.go +++ b/tsc/internal/parser/types.go @@ -5,12 +5,18 @@ package parser type ParseFlags uint32 const ( - ParseFlagsNone ParseFlags = 0 - ParseFlagsYield ParseFlags = 1 << 0 - ParseFlagsAwait ParseFlags = 1 << 1 - ParseFlagsType ParseFlags = 1 << 2 - ParseFlagsIgnoreMissingOpenBrace ParseFlags = 1 << 4 - ParseFlagsJSDoc ParseFlags = 1 << 5 - ParseFlagsDisallowArrowReturnType ParseFlags = 1 << 6 - ParseFlagsAllowAmbiguousAsyncArrow ParseFlags = 1 << 7 + ParseFlagsNone ParseFlags = 0 + ParseFlagsYield ParseFlags = 1 << 0 + ParseFlagsAwait ParseFlags = 1 << 1 + ParseFlagsType ParseFlags = 1 << 2 + ParseFlagsIgnoreMissingOpenBrace ParseFlags = 1 << 4 + ParseFlagsJSDoc ParseFlags = 1 << 5 +) + +type ExpressionParseFlags uint32 + +const ( + ExpressionParseFlagsNone ExpressionParseFlags = 0 + ExpressionParseFlagsDisallowArrowReturnType ExpressionParseFlags = 1 << 0 + ExpressionParseFlagsAllowAmbiguousAsyncArrow ExpressionParseFlags = 1 << 1 ) From 56e2eefc48e9170f45409ef14185d13c264dc1a6 Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk Date: Tue, 20 Oct 2026 14:05:44 +0300 Subject: [PATCH 3/7] fix typed async arrow parsing in conditional expressions --- tsc/internal/parser/parser.go | 11 ++ tsc/internal/parser/parser_test.go | 163 ++++++++++++++++-- .../parenthesizedAsyncArrowFunction.js | 21 +++ .../parenthesizedAsyncArrowFunction.symbols | 75 +++++++- .../parenthesizedAsyncArrowFunction.types | 89 ++++++++++ .../parenthesizedAsyncArrowFunctionJs.js | 9 + .../parenthesizedAsyncArrowFunctionJs.symbols | 23 ++- .../parenthesizedAsyncArrowFunctionJs.types | 19 ++ .../parenthesizedAsyncArrowFunction.ts | 11 ++ .../parenthesizedAsyncArrowFunctionJs.ts | 5 + 10 files changed, 403 insertions(+), 23 deletions(-) diff --git a/tsc/internal/parser/parser.go b/tsc/internal/parser/parser.go index 3665680f0af26..6796e4b8723f0 100644 --- a/tsc/internal/parser/parser.go +++ b/tsc/internal/parser/parser.go @@ -4467,6 +4467,7 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, } } requiresColon := !allowAmbiguity && p.token == ast.KindColonToken && flags&ExpressionParseFlagsDisallowArrowReturnType != 0 + returnTypeCanStartArrowFunction := requiresColon && p.lookAhead((*Parser).nextTokenIsStartOfArrowFunction) returnType := p.parseReturnType(ast.KindColonToken /*isType*/, false) if returnType != nil && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(returnType) { return nil @@ -4489,6 +4490,9 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, // Returning undefined here will cause our caller to rewind to where we started from. return nil } + if p.token == ast.KindEqualsGreaterThanToken { + requiresColon = returnTypeCanStartArrowFunction + } // If we have an arrow, then try to parse the body. Even if not, try to parse if we // have an opening brace, just in case we're in an error state. lastToken := p.token @@ -4535,6 +4539,13 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, return result } +func (p *Parser) nextTokenIsStartOfArrowFunction() bool { + p.nextToken() + return p.isParenthesizedArrowFunctionExpression(ExpressionParseFlagsNone).IsTrueOrUnknown() || + p.token == ast.KindAsyncKeyword && p.lookAhead((*Parser).nextIsUnParenthesizedAsyncArrowFunction) || + p.isIdentifier() && p.nextToken() == ast.KindEqualsGreaterThanToken +} + func (p *Parser) parseModifiersForArrowFunction() *ast.ModifierList { if p.token == ast.KindAsyncKeyword { pos := p.nodePos() diff --git a/tsc/internal/parser/parser_test.go b/tsc/internal/parser/parser_test.go index a8b878f031127..2c40898e777b1 100644 --- a/tsc/internal/parser/parser_test.go +++ b/tsc/internal/parser/parser_test.go @@ -585,18 +585,91 @@ func TestConditionalArrowBodyJS(t *testing.T) { func TestConditionalTypedAsyncArrowBody(t *testing.T) { t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? async (c: number): Promise => async() : d => d;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenTrue.Type().Kind, ast.KindTypeReference) - assert.Equal(t, conditional.WhenTrue.Parameters()[0].Type().Kind, ast.KindNumberKeyword) - assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + arrow := checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (c: number): Promise => async() : d => d;") + assert.Equal(t, arrow.Parameters()[0].Type().Kind, ast.KindNumberKeyword) +} + +func TestConditionalTypedAsyncArrowBodyWithEmptyParameters(t *testing.T) { + t.Parallel() + checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (): Promise => async() : d => d;") +} + +func TestConditionalTypedAsyncArrowBodyWithSpreadCall(t *testing.T) { + t.Parallel() + checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (): Promise => async(...c) : d => d;") +} + +func TestConditionalTypedAsyncArrowBodyWithRestParameter(t *testing.T) { + t.Parallel() + checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (...c): Promise => async() : d => d;") +} + +func TestConditionalTypedAsyncArrowBodyWithTypedRestParameter(t *testing.T) { + t.Parallel() + arrow := checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (...c: number[]): Promise => async() : d => d;") + assert.Equal(t, arrow.Parameters()[0].Type().Kind, ast.KindArrayType) +} + +func TestConditionalTypedAsyncArrowBodyWithTypeParameter(t *testing.T) { + t.Parallel() + checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (): Promise => async() : d => d;") +} + +func TestConditionalTypedAsyncArrowBodyWithParenthesizedReturnType(t *testing.T) { + t.Parallel() + checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (): (Promise) => async() : d => d;") +} + +func TestConditionalAsyncCallWithFunction(t *testing.T) { + t.Parallel() + checkConditionalAsyncCallWithFunction(t, "/a.ts") +} + +func TestConditionalAsyncCallWithFunctionJS(t *testing.T) { + t.Parallel() + checkConditionalAsyncCallWithFunction(t, "/a.js") +} + +func TestConditionalExpressionFollowedByBlock(t *testing.T) { + t.Parallel() + const source = "const a = b ? async() : 0\n{}" + checkConditionalExpressionFollowedByBlock(t, "/a.ts", source, ast.KindCallExpression, ast.KindNumericLiteral) + checkConditionalExpressionFollowedByBlock(t, "/a.js", source, ast.KindCallExpression, ast.KindNumericLiteral) +} + +func TestConditionalExpressionWithObjectFollowedByBlock(t *testing.T) { + t.Parallel() + const source = "const a = b ? async() : {}\n{}" + checkConditionalExpressionFollowedByBlock(t, "/a.ts", source, ast.KindCallExpression, ast.KindObjectLiteralExpression) + checkConditionalExpressionFollowedByBlock(t, "/a.js", source, ast.KindCallExpression, ast.KindObjectLiteralExpression) +} + +func TestConditionalExpressionWithStringFollowedByBlock(t *testing.T) { + t.Parallel() + const source = "const a = b ? async() : \"c\"\n{}" + checkConditionalExpressionFollowedByBlock(t, "/a.ts", source, ast.KindCallExpression, ast.KindStringLiteral) + checkConditionalExpressionFollowedByBlock(t, "/a.js", source, ast.KindCallExpression, ast.KindStringLiteral) +} + +func TestConditionalSpreadCallFollowedByBlock(t *testing.T) { + t.Parallel() + const source = "const a = b ? async(...c) : 0\n{}" + checkConditionalExpressionFollowedByBlock(t, "/a.ts", source, ast.KindCallExpression, ast.KindNumericLiteral) + checkConditionalExpressionFollowedByBlock(t, "/a.js", source, ast.KindCallExpression, ast.KindNumericLiteral) +} + +func TestConditionalParenthesizedExpressionFollowedByBlock(t *testing.T) { + t.Parallel() + const source = "const a = b ? (c) : 0\n{}" + checkConditionalExpressionFollowedByBlock(t, "/a.ts", source, ast.KindParenthesizedExpression, ast.KindNumericLiteral) + checkConditionalExpressionFollowedByBlock(t, "/a.js", source, ast.KindParenthesizedExpression, ast.KindNumericLiteral) +} + +func TestConditionalExpressionWithSemicolonFollowedByBlock(t *testing.T) { + t.Parallel() + const source = "const a = b ? async() : 0;\n{}" + checkConditionalExpressionFollowedByBlock(t, "/a.ts", source, ast.KindCallExpression, ast.KindNumericLiteral) + checkConditionalExpressionFollowedByBlock(t, "/a.js", source, ast.KindCallExpression, ast.KindNumericLiteral) } func TestConditionalAsyncCallJSDoc(t *testing.T) { @@ -633,10 +706,74 @@ func TestConditionalAsyncCallJSDocTypedef(t *testing.T) { func TestConditionalAsyncCallRecovery(t *testing.T) { t.Parallel() + checkConditionalArrowRecovery(t, "const a = b ? async(...c: number[]): Promise => 0;") +} + +func TestConditionalTypedAsyncArrowRecovery(t *testing.T) { + t.Parallel() + checkConditionalArrowRecovery(t, "const a = b ? async (): Promise {} : d => d;") +} + +func TestConditionalTypedArrowRecovery(t *testing.T) { + t.Parallel() + checkConditionalArrowRecovery(t, "const a = b ? (c): number {} : d => d;") +} + +func checkConditionalTypedAsyncArrowBody(t *testing.T, source string) *ast.Node { + t.Helper() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: "/a.ts", + PathKey: "/a.ts", + }, source, core.ScriptKindTS) + assert.Equal(t, len(file.Diagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) + assert.Assert(t, conditional.WhenTrue.Type() != nil) + assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") + assert.Equal(t, conditional.WhenTrue.Body().Flags&ast.NodeFlagsAwaitContext, ast.NodeFlagsAwaitContext) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) + assert.Equal(t, conditional.WhenFalse.Parameters()[0].Name().Text(), "d") + return conditional.WhenTrue +} + +func checkConditionalAsyncCallWithFunction(t *testing.T, fileName tspath.RootedFilePath) { + t.Helper() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: fileName, + PathKey: tspath.PathKeyFromCanonical(fileName.AsString()), + }, "const a = b ? async() : function() {};", core.GetScriptKindFromFileName(fileName)) + assert.Equal(t, len(file.Diagnostics()), 0) + assert.Equal(t, len(file.JSDiagnostics()), 0) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) + assert.Equal(t, conditional.WhenFalse.Kind, ast.KindFunctionExpression) +} + +func checkConditionalExpressionFollowedByBlock(t *testing.T, fileName tspath.RootedFilePath, source string, whenTrueKind ast.Kind, whenFalseKind ast.Kind) { + t.Helper() + file := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: fileName, + PathKey: tspath.PathKeyFromCanonical(fileName.AsString()), + }, source, core.GetScriptKindFromFileName(fileName)) + assert.Equal(t, len(file.Diagnostics()), 0, fileName) + assert.Equal(t, len(file.JSDiagnostics()), 0, fileName) + assert.Equal(t, len(file.Statements.Nodes), 2) + assert.Equal(t, file.Statements.Nodes[1].Kind, ast.KindBlock) + declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Kind, whenTrueKind) + assert.Equal(t, conditional.WhenFalse.Kind, whenFalseKind) +} + +func checkConditionalArrowRecovery(t *testing.T, source string) { + t.Helper() file := parser.ParseSourceFile(ast.SourceFileParseOptions{ FileName: "/a.ts", PathKey: "/a.ts", - }, "const a = b ? async(...c: number[]): Promise => 0;", core.ScriptKindTS) + }, source, core.ScriptKindTS) assert.Equal(t, len(file.Diagnostics()), 1) assert.Equal(t, file.Diagnostics()[0].Code(), diagnostics.X_0_expected.Code()) declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js index d6c82758ba444..0b0c679234a42 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js @@ -42,6 +42,17 @@ const f23 = a ? async () => async() : x => x; const f24 = a ? async (...c) => async() : x => x; const f25 = a ? () => async() : x => x; const f26 = a ? async (c: number): Promise => async() : x => x; +const f27 = a ? async (): Promise => async() : x => x; +const f28 = a ? async (): Promise => async(...c) : x => x; +const f29 = a ? async (...c): Promise => async() : x => x; +const f30 = a ? async (): Promise => async() : x => x; +const f31 = a ? async (): (Promise) => async() : x => x; +const f32 = a ? async (...c: number[]): Promise => async() : x => x; + +const f33 = a ? async() : 0 +{} +const f34 = a ? async() : {} +{} function* g() { const f1 = a ? yield async(...c) : 0; @@ -94,6 +105,16 @@ const f23 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return as const f24 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; const f25 = a ? () => async() : x => x; const f26 = a ? (c) => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; +const f27 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; +const f28 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(...c); }) : x => x; +const f29 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; +const f30 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; +const f31 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; +const f32 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; +const f33 = a ? async() : 0; +{ } +const f34 = a ? async() : {}; +{ } function* g() { const f1 = a ? yield async(...c) : 0; const f2 = a ? yield async(...c) : x => x; diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols index b1978407861ee..af1a8029efbb7 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols @@ -229,21 +229,86 @@ const f26 = a ? async (c: number): Promise => async() : x => x; >x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 40, 63)) >x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 40, 63)) +const f27 = a ? async (): Promise => async() : x => x; +>f27 : Symbol(f27, Decl(parenthesizedAsyncArrowFunction.ts, 41, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 41, 54)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 41, 54)) + +const f28 = a ? async (): Promise => async(...c) : x => x; +>f28 : Symbol(f28, Decl(parenthesizedAsyncArrowFunction.ts, 42, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 42, 58)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 42, 58)) + +const f29 = a ? async (...c): Promise => async() : x => x; +>f29 : Symbol(f29, Decl(parenthesizedAsyncArrowFunction.ts, 43, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 43, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 43, 58)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 43, 58)) + +const f30 = a ? async (): Promise => async() : x => x; +>f30 : Symbol(f30, Decl(parenthesizedAsyncArrowFunction.ts, 44, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>U : Symbol(U, Decl(parenthesizedAsyncArrowFunction.ts, 44, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 44, 57)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 44, 57)) + +const f31 = a ? async (): (Promise) => async() : x => x; +>f31 : Symbol(f31, Decl(parenthesizedAsyncArrowFunction.ts, 45, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 45, 56)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 45, 56)) + +const f32 = a ? async (...c: number[]): Promise => async() : x => x; +>f32 : Symbol(f32, Decl(parenthesizedAsyncArrowFunction.ts, 46, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 46, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 46, 68)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 46, 68)) + +const f33 = a ? async() : 0 +>f33 : Symbol(f33, Decl(parenthesizedAsyncArrowFunction.ts, 48, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) + +{} +const f34 = a ? async() : {} +>f34 : Symbol(f34, Decl(parenthesizedAsyncArrowFunction.ts, 50, 5)) +>a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) + +{} + function* g() { ->g : Symbol(g, Decl(parenthesizedAsyncArrowFunction.ts, 40, 71)) +>g : Symbol(g, Decl(parenthesizedAsyncArrowFunction.ts, 51, 2)) const f1 = a ? yield async(...c) : 0; ->f1 : Symbol(f1, Decl(parenthesizedAsyncArrowFunction.ts, 43, 9)) +>f1 : Symbol(f1, Decl(parenthesizedAsyncArrowFunction.ts, 54, 9)) >a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) >async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) >c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) const f2 = a ? yield async(...c) : x => x; ->f2 : Symbol(f2, Decl(parenthesizedAsyncArrowFunction.ts, 44, 9)) +>f2 : Symbol(f2, Decl(parenthesizedAsyncArrowFunction.ts, 55, 9)) >a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) >async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) >c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 44, 38)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 44, 38)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 55, 38)) +>x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 55, 38)) } diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types index 231e4f8adb549..cc7bbfa28ca22 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types @@ -328,6 +328,95 @@ const f26 = a ? async (c: number): Promise => async() : x => x; >x : any >x : any +const f27 = a ? async (): Promise => async() : x => x; +>f27 : (x: any) => any +>a ? async (): Promise => async() : x => x : (x: any) => any +>a : true +>async (): Promise => async() : () => Promise +>async() : number +>async : (...c: number[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +const f28 = a ? async (): Promise => async(...c) : x => x; +>f28 : (x: any) => any +>a ? async (): Promise => async(...c) : x => x : (x: any) => any +>a : true +>async (): Promise => async(...c) : () => Promise +>async(...c) : number +>async : (...c: number[]) => number +>...c : number +>c : number[] +>x => x : (x: any) => any +>x : any +>x : any + +const f29 = a ? async (...c): Promise => async() : x => x; +>f29 : ((...c: any[]) => Promise) | ((x: any) => any) +>a ? async (...c): Promise => async() : x => x : ((...c: any[]) => Promise) | ((x: any) => any) +>a : true +>async (...c): Promise => async() : (...c: any[]) => Promise +>c : any[] +>async() : number +>async : (...c: number[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +const f30 = a ? async (): Promise => async() : x => x; +>f30 : (x: any) => any +>a ? async (): Promise => async() : x => x : (x: any) => any +>a : true +>async (): Promise => async() : () => Promise +>async() : number +>async : (...c: number[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +const f31 = a ? async (): (Promise) => async() : x => x; +>f31 : (x: any) => any +>a ? async (): (Promise) => async() : x => x : (x: any) => any +>a : true +>async (): (Promise) => async() : () => (Promise) +>async() : number +>async : (...c: number[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +const f32 = a ? async (...c: number[]): Promise => async() : x => x; +>f32 : ((...c: number[]) => Promise) | ((x: any) => any) +>a ? async (...c: number[]): Promise => async() : x => x : ((...c: number[]) => Promise) | ((x: any) => any) +>a : true +>async (...c: number[]): Promise => async() : (...c: number[]) => Promise +>c : number[] +>async() : number +>async : (...c: number[]) => number +>x => x : (x: any) => any +>x : any +>x : any + +const f33 = a ? async() : 0 +>f33 : number +>a ? async() : 0 : number +>a : true +>async() : number +>async : (...c: number[]) => number +>0 : 0 + +{} +const f34 = a ? async() : {} +>f34 : {} +>a ? async() : {} : number | {} +>a : true +>async() : number +>async : (...c: number[]) => number +>{} : {} + +{} + function* g() { >g : () => Generator diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js index feeaf996546a8..ce281ca4d36e0 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js @@ -15,6 +15,11 @@ const f3 = a ? async () => async() : x => x; const f4 = a ? async (...c) => async() : x => x; const f5 = a ? () => async() : x => x; +const f6 = a ? async() : 0 +{} +const f7 = a ? async() : {} +{} + function* g() { const f1 = a ? yield async(...c) : 0; const f2 = a ? yield async(...c) : x => x; @@ -43,6 +48,10 @@ const f2 = a ? async(...c) : x => x; const f3 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; const f4 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; const f5 = a ? () => async() : x => x; +const f6 = a ? async() : 0; +{ } +const f7 = a ? async() : {}; +{ } function* g() { const f1 = a ? yield async(...c) : 0; const f2 = a ? yield async(...c) : x => x; diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols index 2a779b0db2291..4262a0cc5e111 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols @@ -55,21 +55,34 @@ const f5 = a ? () => async() : x => x; >x : Symbol(x, Decl(a.js, 12, 30)) >x : Symbol(x, Decl(a.js, 12, 30)) +const f6 = a ? async() : 0 +>f6 : Symbol(f6, Decl(a.js, 14, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) + +{} +const f7 = a ? async() : {} +>f7 : Symbol(f7, Decl(a.js, 16, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) + +{} + function* g() { ->g : Symbol(g, Decl(a.js, 12, 38)) +>g : Symbol(g, Decl(a.js, 17, 2)) const f1 = a ? yield async(...c) : 0; ->f1 : Symbol(f1, Decl(a.js, 15, 9)) +>f1 : Symbol(f1, Decl(a.js, 20, 9)) >a : Symbol(a, Decl(a.js, 0, 5)) >async : Symbol(async, Decl(a.js, 2, 14)) >c : Symbol(c, Decl(a.js, 2, 5)) const f2 = a ? yield async(...c) : x => x; ->f2 : Symbol(f2, Decl(a.js, 16, 9)) +>f2 : Symbol(f2, Decl(a.js, 21, 9)) >a : Symbol(a, Decl(a.js, 0, 5)) >async : Symbol(async, Decl(a.js, 2, 14)) >c : Symbol(c, Decl(a.js, 2, 5)) ->x : Symbol(x, Decl(a.js, 16, 38)) ->x : Symbol(x, Decl(a.js, 16, 38)) +>x : Symbol(x, Decl(a.js, 21, 38)) +>x : Symbol(x, Decl(a.js, 21, 38)) } diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types index 61e4470d50c75..f875fe7aa90e7 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types @@ -78,6 +78,25 @@ const f5 = a ? () => async() : x => x; >x : any >x : any +const f6 = a ? async() : 0 +>f6 : number +>a ? async() : 0 : number +>a : true +>async() : number +>async : (...c: any[]) => number +>0 : 0 + +{} +const f7 = a ? async() : {} +>f7 : {} +>a ? async() : {} : number | {} +>a : true +>async() : number +>async : (...c: any[]) => number +>{} : {} + +{} + function* g() { >g : () => Generator diff --git a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts index e19686811884a..c20dde520edd0 100644 --- a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts +++ b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts @@ -41,6 +41,17 @@ const f23 = a ? async () => async() : x => x; const f24 = a ? async (...c) => async() : x => x; const f25 = a ? () => async() : x => x; const f26 = a ? async (c: number): Promise => async() : x => x; +const f27 = a ? async (): Promise => async() : x => x; +const f28 = a ? async (): Promise => async(...c) : x => x; +const f29 = a ? async (...c): Promise => async() : x => x; +const f30 = a ? async (): Promise => async() : x => x; +const f31 = a ? async (): (Promise) => async() : x => x; +const f32 = a ? async (...c: number[]): Promise => async() : x => x; + +const f33 = a ? async() : 0 +{} +const f34 = a ? async() : {} +{} function* g() { const f1 = a ? yield async(...c) : 0; diff --git a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts index 1e01dd2edac1d..2ceb1d47222cc 100644 --- a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts +++ b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts @@ -18,6 +18,11 @@ const f3 = a ? async () => async() : x => x; const f4 = a ? async (...c) => async() : x => x; const f5 = a ? () => async() : x => x; +const f6 = a ? async() : 0 +{} +const f7 = a ? async() : {} +{} + function* g() { const f1 = a ? yield async(...c) : 0; const f2 = a ? yield async(...c) : x => x; From 41342fcfae3cad045056b85cf006d3de9835c48b Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk Date: Fri, 23 Oct 2026 21:17:53 +0300 Subject: [PATCH 4/7] fix async call and arrow parsing in conditional expressions --- tsc/internal/parser/jsdoc.go | 2 +- tsc/internal/parser/parser.go | 416 ++++++--- tsc/internal/parser/parser_test.go | 588 +++--------- tsc/internal/parser/tentative.go | 121 +++ tsc/internal/parser/tentative_test.go | 299 +++++++ tsc/internal/parser/types.go | 14 +- ...parenthesizedAsyncArrowFunction.errors.txt | 148 ++++ .../parenthesizedAsyncArrowFunction.js | 166 +++- .../parenthesizedAsyncArrowFunction.symbols | 835 +++++++++++++----- .../parenthesizedAsyncArrowFunction.types | 756 ++++++++++++++-- .../parenthesizedAsyncArrowFunctionJs.js | 49 + .../parenthesizedAsyncArrowFunctionJs.symbols | 149 ++++ .../parenthesizedAsyncArrowFunctionJs.types | 232 +++++ .../parenthesizedAsyncArrowFunction.ts | 81 +- .../parenthesizedAsyncArrowFunctionJs.ts | 26 + 15 files changed, 2947 insertions(+), 935 deletions(-) create mode 100644 tsc/internal/parser/tentative.go create mode 100644 tsc/internal/parser/tentative_test.go create mode 100644 tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.errors.txt diff --git a/tsc/internal/parser/jsdoc.go b/tsc/internal/parser/jsdoc.go index 6d239d2f228fc..650cb66892d22 100644 --- a/tsc/internal/parser/jsdoc.go +++ b/tsc/internal/parser/jsdoc.go @@ -54,7 +54,7 @@ const ( ) func (p *Parser) withJSDoc(node *ast.Node, info jsdocScannerInfo) []*ast.Node { - if info&jsdocScannerInfoHasJSDoc == 0 { + if info&jsdocScannerInfoHasJSDoc == 0 || p.parsingFlags&ParsingFlagsTentative != 0 { return nil } diff --git a/tsc/internal/parser/parser.go b/tsc/internal/parser/parser.go index 6796e4b8723f0..d43536037cd07 100644 --- a/tsc/internal/parser/parser.go +++ b/tsc/internal/parser/parser.go @@ -62,6 +62,20 @@ const ( jsdocScannerInfoHasSeeOrLink ) +type functionSignature struct { + modifiers *ast.ModifierList + typeParameters *ast.NodeList + parameters *ast.NodeList + returnType *ast.Node +} + +type tentativeExpression struct { + expressions collections.Set[int] + heads []int + contextFlags ast.NodeFlags + result core.Tristate +} + type Parser struct { scanner *scanner.Scanner factory ast.NodeFactory @@ -85,6 +99,9 @@ type Parser struct { identifierCount int notParenthesizedArrow collections.Set[int] + tentativeExpression *tentativeExpression + tentativeNodes map[int][]tentativeNode + parsingFlags ParsingFlags nodeSliceArena core.Arena[*ast.Node] stringSliceArena core.Arena[string] jsdocInfos []JSDocInfo @@ -327,6 +344,9 @@ func (p *Parser) parseErrorAtCurrentToken(message *diagnostics.Message, args ... } func (p *Parser) parseErrorAtRange(loc core.TextRange, message *diagnostics.Message, args ...any) *ast.Diagnostic { + if p.parsingFlags&ParsingFlagsTentative != 0 { + panic(tentativeParseFailure{}) + } // Don't report another error if it would just be at the same location as the last error var result *ast.Diagnostic if len(p.diagnostics) == 0 || p.diagnostics[len(p.diagnostics)-1].Pos() != loc.Pos() { @@ -338,6 +358,9 @@ func (p *Parser) parseErrorAtRange(loc core.TextRange, message *diagnostics.Mess } type ParserState struct { + tentativeExpression *tentativeExpression + tentativeNodes map[int][]tentativeNode + identifierCount int scannerState scanner.ScannerState contextFlags ast.NodeFlags diagnosticsLen int @@ -352,6 +375,9 @@ type ParserState struct { func (p *Parser) mark() ParserState { return ParserState{ + tentativeExpression: p.tentativeExpression, + tentativeNodes: p.tentativeNodes, + identifierCount: p.identifierCount, scannerState: p.scanner.Mark(), contextFlags: p.contextFlags, diagnosticsLen: len(p.diagnostics), @@ -366,6 +392,9 @@ func (p *Parser) mark() ParserState { } func (p *Parser) rewind(state ParserState) { + p.tentativeExpression = state.tentativeExpression + p.tentativeNodes = state.tentativeNodes + p.identifierCount = state.identifierCount p.scanner.Rewind(state.scannerState) p.token = p.scanner.Token() p.contextFlags = state.contextFlags @@ -4155,7 +4184,11 @@ func (p *Parser) parseExpressionAllowIn() *ast.Expression { } func (p *Parser) parseAssignmentExpressionOrHigher() *ast.Expression { - return p.parseAssignmentExpressionOrHigherWorker(ExpressionParseFlagsNone) + scope := p.beginTentativeScope() + scope.suspendExpression() + expression := p.parseAssignmentExpressionOrHigherWorker(ExpressionParseFlagsNone) + scope.restore() + return expression } func (p *Parser) parseAssignmentExpressionOrHigherWorker(flags ExpressionParseFlags) *ast.Expression { @@ -4192,10 +4225,6 @@ func (p *Parser) parseAssignmentExpressionOrHigherWorker(flags ExpressionParseFl if arrowExpression != nil { return arrowExpression } - // arrowExpression2 := p.tryParseAsyncSimpleArrowFunctionExpression(flags) - // if arrowExpression2 != nil { - // return arrowExpression2 - // } // Now try to see if we're in production '1', '2' or '3'. A conditional expression can // start with a LogicalOrExpression, while the assignment productions can only start with // LeftHandSideExpressions. @@ -4221,7 +4250,9 @@ func (p *Parser) parseAssignmentExpressionOrHigherWorker(flags ExpressionParseFl // Note: we call reScanGreaterToken so that we get an appropriately merged token // for cases like `> > =` becoming `>>=` if ast.IsLeftHandSideExpression(expr) && ast.IsAssignmentOperator(p.reScanGreaterThanToken()) { - return p.makeBinaryExpression(expr, p.parseTokenNode(), p.parseAssignmentExpressionOrHigherWorker(flags), pos) + operatorToken := p.parseTokenNode() + right := p.parseAssignmentExpressionOrHigherWorker(flags) + return p.makeBinaryExpression(expr, operatorToken, right, pos) } // It wasn't an assignment or a lambda. This is a conditional expression: return p.parseConditionalExpressionRest(expr, pos, flags) @@ -4263,7 +4294,9 @@ func (p *Parser) parseYieldExpression(flags ExpressionParseFlags) *ast.Node { p.nextToken() var result *ast.Node if !p.hasPrecedingLineBreak() && (p.token == ast.KindAsteriskToken || p.isStartOfExpression()) { - result = p.factory.NewYieldExpression(p.parseOptionalToken(ast.KindAsteriskToken), p.parseAssignmentExpressionOrHigherWorker(flags)) + asteriskToken := p.parseOptionalToken(ast.KindAsteriskToken) + expression := p.parseAssignmentExpressionOrHigherWorker(flags) + result = p.factory.NewYieldExpression(asteriskToken, expression) } else { // if the next token is not on the same line as yield. or we don't have an '*' or // the start of an expression, then this is just a simple "yield" expression. @@ -4272,10 +4305,10 @@ func (p *Parser) parseYieldExpression(flags ExpressionParseFlags) *ast.Node { return p.finishNode(result, pos) } -func (p *Parser) isParenthesizedArrowFunctionExpression(flags ExpressionParseFlags) core.Tristate { +func (p *Parser) isParenthesizedArrowFunctionExpression() core.Tristate { if p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken || p.token == ast.KindAsyncKeyword { state := p.mark() - result := p.nextIsParenthesizedArrowFunctionExpression(flags) + result := p.nextIsParenthesizedArrowFunctionExpression() p.rewind(state) return result } @@ -4289,7 +4322,7 @@ func (p *Parser) isParenthesizedArrowFunctionExpression(flags ExpressionParseFla return core.TSFalse } -func (p *Parser) nextIsParenthesizedArrowFunctionExpression(flags ExpressionParseFlags) core.Tristate { +func (p *Parser) nextIsParenthesizedArrowFunctionExpression() core.Tristate { isAsync := p.token == ast.KindAsyncKeyword if isAsync { p.nextToken() @@ -4309,7 +4342,7 @@ func (p *Parser) nextIsParenthesizedArrowFunctionExpression(flags ExpressionPars // but this is probably what the user intended. switch p.nextToken() { case ast.KindColonToken: - if isAsync && flags&ExpressionParseFlagsAllowAmbiguousAsyncArrow == 0 { + if isAsync { return core.TSUnknown } return core.TSTrue @@ -4321,9 +4354,6 @@ func (p *Parser) nextIsParenthesizedArrowFunctionExpression(flags ExpressionPars // Simple case: "(...". After "async", this could also be a spread argument. if second == ast.KindDotDotDotToken { if isAsync { - if flags&ExpressionParseFlagsAllowAmbiguousAsyncArrow != 0 { - return core.TSTrue - } second = p.nextToken() } else { return core.TSTrue @@ -4408,29 +4438,141 @@ func (p *Parser) nextIsParenthesizedArrowFunctionExpression(flags ExpressionPars } func (p *Parser) tryParseParenthesizedArrowFunctionExpression(flags ExpressionParseFlags) *ast.Node { - tristate := p.isParenthesizedArrowFunctionExpression(flags) - if tristate == core.TSFalse { - // It's definitely not a parenthesized arrow function expression. + result := p.isParenthesizedArrowFunctionExpression() + if result == core.TSFalse { return nil } - // If we definitely have an arrow function, then we can just parse one, not requiring a - // following => or { token. Otherwise, we *might* have an arrow function. Try to parse - // it out, but don't allow any ambiguity, and return 'undefined' if this could be an - // expression instead. - if tristate == core.TSTrue { - return p.parseParenthesizedArrowFunctionExpression(true /*allowAmbiguity*/, flags) - } - state := p.mark() - result := p.parsePossibleParenthesizedArrowFunctionExpression(flags) - if result == nil { - p.rewind(state) + if result == core.TSTrue { + flags |= ExpressionParseFlagsAllowArrowFunctionRecovery } - return result + return p.parseParenthesizedArrowFunctionExpression(flags) } -func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, flags ExpressionParseFlags) *ast.Node { +func (p *Parser) parseParenthesizedArrowFunctionExpression(flags ExpressionParseFlags) *ast.Node { pos := p.nodePos() jsdoc := p.jsdocScannerInfo() + + var tentative tentativeParse + if flags&ExpressionParseFlagsAllowArrowFunctionRecovery == 0 { + tentative = p.beginTentativeParse() + defer tentative.close() + } + + result, signature := p.tryParseArrowFunctionHead(flags) + if result == core.TSFalse { + return nil + } + + isAsync := modifierListHasAsync(signature.modifiers) + requiresColon := result == core.TSUnknown + bodyFlags := flags & (ExpressionParseFlagsDisallowArrowReturnType | ExpressionParseFlagsAllowAmbiguousAsyncArrow) + if requiresColon && !isAsync { + bodyFlags |= ExpressionParseFlagsAllowAmbiguousAsyncArrow + } + + expression := p.tentativeExpression + switch result { + case core.TSTrue: + tentative.commit() + case core.TSUnknown: + if p.token == ast.KindEqualsGreaterThanToken && (expression == nil || expression.result != core.TSFalse) { + if expression == nil { + tentative.commit() + panic(tentativeParseFailure{}) + } + if expression.expressions.Has(pos) { + return nil + } + if expression.result == core.TSUnknown && p.isArrowFunctionHeadAmbiguous(tentative.state, signature.returnType) { + debug.Assert(len(expression.heads) == 0 || expression.heads[len(expression.heads)-1] < pos) + expression.heads = append(expression.heads, pos) + } + tentative.commit() + } + } + lastToken := p.token + equalsGreaterThanToken := p.parseExpectedToken(ast.KindEqualsGreaterThanToken) + + var body *ast.Node + if lastToken == ast.KindEqualsGreaterThanToken || lastToken == ast.KindOpenBraceToken { + body = p.parseArrowFunctionExpressionBody(isAsync, bodyFlags) + } else { + body = p.parseIdentifier() + } + if requiresColon && p.token != ast.KindColonToken { + if lastToken == ast.KindOpenBraceToken || expression == nil || expression.result == core.TSFalse { + return nil + } + if expression.result == core.TSUnknown { + panic(tentativeParseFailure{}) + } + } + node := p.finishNode(p.factory.NewArrowFunction(signature.modifiers, signature.typeParameters, signature.parameters, signature.returnType, nil /*fullSignature*/, equalsGreaterThanToken, body), pos) + p.withJSDoc(node, jsdoc) + p.checkJSSyntax(node) + tentative.commit() + return node +} + +func (p *Parser) isArrowFunctionHeadAmbiguous(state ParserState, returnType *ast.Node) bool { + tentative := p.beginTentativeParse() + defer tentative.close() + + contextFlags := p.tentativeExpression.contextFlags + arrowPos := p.scanner.TokenStart() + p.rewind(state) + tentative.silence() + tentative.suspendExpression() + + p.parseBinaryExpressionOrHigher(ast.OperatorPrecedenceLowest) + if p.token != ast.KindColonToken || p.scanner.TokenEnd() != returnType.Pos() { + return false + } + + p.contextFlags = contextFlags + p.nextToken() + for { + if p.isIdentifier() { + p.nextToken() + } else { + result, _ := p.parseArrowFunctionHead(ExpressionParseFlagsNone) + if result == core.TSFalse { + return false + } + } + if p.token != ast.KindEqualsGreaterThanToken || p.hasPrecedingLineBreak() { + return false + } + pos := p.scanner.TokenStart() + if pos >= arrowPos { + return pos == arrowPos + } + p.nextToken() + } +} + +func (p *Parser) tryParseArrowFunctionHead(flags ExpressionParseFlags) (core.Tristate, functionSignature) { + pos := p.nodePos() + result, signature := p.parseArrowFunctionHead(flags) + if result == core.TSFalse { + p.notParenthesizedArrow.Add(pos) + } + return result, signature +} + +func (p *Parser) parseArrowFunctionHead(flags ExpressionParseFlags) (result core.Tristate, signature functionSignature) { + result = core.TSFalse + pos := p.nodePos() + if flags&ExpressionParseFlagsAllowArrowFunctionRecovery == 0 && p.notParenthesizedArrow.Has(pos) { + return core.TSFalse, functionSignature{} + } + + var tentative tentativeParse + if flags&ExpressionParseFlagsAllowArrowFunctionRecovery == 0 && p.parsingFlags&ParsingFlagsTentative != 0 { + tentative = p.beginTentativeParse() + defer tentative.close() + } + modifiers := p.parseModifiersForArrowFunction() isAsync := modifierListHasAsync(modifiers) signatureFlags := core.IfElse(isAsync, ParseFlagsAwait, ParseFlagsNone) @@ -4442,35 +4584,30 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, // And think that "(b =>" was actually a parenthesized arrow function with a missing // close paren. typeParameters := p.parseTypeParameters() - bodyFlags := flags + parameterToken := ast.KindUnknown var parameters *ast.NodeList if !p.parseExpected(ast.KindOpenParenToken) { - if !allowAmbiguity { - return nil + if flags&ExpressionParseFlagsAllowArrowFunctionRecovery == 0 { + return core.TSFalse, functionSignature{} } parameters = p.createMissingList() } else { - if isAsync && typeParameters == nil && (p.token == ast.KindCloseParenToken || p.token == ast.KindDotDotDotToken) { - bodyFlags = flags & ExpressionParseFlagsAllowAmbiguousAsyncArrow + parameterToken = p.token + parameters = p.parseParametersWorker(signatureFlags, flags&ExpressionParseFlagsAllowArrowFunctionRecovery != 0) + if parameters == nil { + return core.TSFalse, functionSignature{} } - if !allowAmbiguity { - maybeParameters := p.parseParametersWorker(signatureFlags, allowAmbiguity) - if maybeParameters == nil { - return nil - } - parameters = maybeParameters - } else { - parameters = p.parseParametersWorker(signatureFlags, allowAmbiguity) - } - if !p.parseExpected(ast.KindCloseParenToken) && !allowAmbiguity { - return nil + if !p.parseExpected(ast.KindCloseParenToken) && flags&ExpressionParseFlagsAllowArrowFunctionRecovery == 0 { + return core.TSFalse, functionSignature{} } } - requiresColon := !allowAmbiguity && p.token == ast.KindColonToken && flags&ExpressionParseFlagsDisallowArrowReturnType != 0 - returnTypeCanStartArrowFunction := requiresColon && p.lookAhead((*Parser).nextTokenIsStartOfArrowFunction) + requiresColon := flags&ExpressionParseFlagsAllowArrowFunctionRecovery == 0 && p.token == ast.KindColonToken && flags&ExpressionParseFlagsDisallowArrowReturnType != 0 + if canParseAmbiguousAsyncArrow(isAsync, typeParameters, parameterToken, flags) { + requiresColon = false + } returnType := p.parseReturnType(ast.KindColonToken /*isType*/, false) - if returnType != nil && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(returnType) { - return nil + if returnType != nil && flags&ExpressionParseFlagsAllowArrowFunctionRecovery == 0 && typeHasArrowFunctionBlockingParseError(returnType) { + return core.TSFalse, functionSignature{} } // Parsing a signature isn't enough. // Parenthesized arrow signatures often look like other valid expressions. @@ -4482,68 +4619,20 @@ func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, // - "a ? (b): (function() {})" as well, but inside of a parenthesized type with an arbitrary amount of nesting. // // So we need just a bit of lookahead to ensure that it can only be a signature. - unwrappedType := returnType - for unwrappedType != nil && unwrappedType.Kind == ast.KindParenthesizedType { - unwrappedType = unwrappedType.Type() // Skip parens if need be - } - if !allowAmbiguity && p.token != ast.KindEqualsGreaterThanToken && p.token != ast.KindOpenBraceToken { - // Returning undefined here will cause our caller to rewind to where we started from. - return nil - } - if p.token == ast.KindEqualsGreaterThanToken { - requiresColon = returnTypeCanStartArrowFunction - } - // If we have an arrow, then try to parse the body. Even if not, try to parse if we - // have an opening brace, just in case we're in an error state. - lastToken := p.token - equalsGreaterThanToken := p.parseExpectedToken(ast.KindEqualsGreaterThanToken) - var body *ast.Node - if lastToken == ast.KindEqualsGreaterThanToken || lastToken == ast.KindOpenBraceToken { - if requiresColon { - bodyFlags |= ExpressionParseFlagsAllowAmbiguousAsyncArrow - } else { - bodyFlags = flags - } - body = p.parseArrowFunctionExpressionBody(isAsync, bodyFlags) - } else { - body = p.parseIdentifier() + if flags&ExpressionParseFlagsAllowArrowFunctionRecovery == 0 && p.token != ast.KindEqualsGreaterThanToken && p.token != ast.KindOpenBraceToken { + return core.TSFalse, functionSignature{} } - // Given: - // x ? y => ({ y }) : z => ({ z }) - // We try to parse the body of the first arrow function by looking at: - // ({ y }) : z => ({ z }) - // This is a valid arrow function with "z" as the return type. - // - // But, if we're in the true side of a conditional expression, this colon - // terminates the expression, so we cannot allow a return type if we aren't - // certain whether or not the preceding text was parsed as a parameter list. - // - // For example, - // a() ? (b: number, c?: string): void => d() : e - // is determined by isParenthesizedArrowFunctionExpression to unambiguously - // be an arrow expression, so we allow a return type. + result = core.TSTrue if requiresColon { - // However, if the arrow function we were able to parse is followed by another colon - // as in: - // a ? (x): string => x : null - // Then allow the arrow function, and treat the second colon as terminating - // the conditional expression. It's okay to do this because this code would - // be a syntax error in JavaScript (as the second colon shouldn't be there). - if p.token != ast.KindColonToken { - return nil - } + result = core.TSUnknown } - result := p.finishNode(p.factory.NewArrowFunction(modifiers, typeParameters, parameters, returnType, nil /*fullSignature*/, equalsGreaterThanToken, body), pos) - p.withJSDoc(result, jsdoc) - p.checkJSSyntax(result) - return result + tentative.commit() + return result, functionSignature{modifiers, typeParameters, parameters, returnType} } -func (p *Parser) nextTokenIsStartOfArrowFunction() bool { - p.nextToken() - return p.isParenthesizedArrowFunctionExpression(ExpressionParseFlagsNone).IsTrueOrUnknown() || - p.token == ast.KindAsyncKeyword && p.lookAhead((*Parser).nextIsUnParenthesizedAsyncArrowFunction) || - p.isIdentifier() && p.nextToken() == ast.KindEqualsGreaterThanToken +func canParseAmbiguousAsyncArrow(isAsync bool, typeParameters *ast.NodeList, parameterToken ast.Kind, flags ExpressionParseFlags) bool { + return isAsync && typeParameters == nil && flags&ExpressionParseFlagsAllowAmbiguousAsyncArrow != 0 && + (parameterToken == ast.KindCloseParenToken || parameterToken == ast.KindDotDotDotToken) } func (p *Parser) parseModifiersForArrowFunction() *ast.ModifierList { @@ -4603,18 +4692,6 @@ func (p *Parser) isStartOfExpressionStatement() bool { return p.token != ast.KindOpenBraceToken && p.token != ast.KindFunctionKeyword && p.token != ast.KindClassKeyword && p.token != ast.KindAtToken && p.isStartOfExpression() } -func (p *Parser) parsePossibleParenthesizedArrowFunctionExpression(flags ExpressionParseFlags) *ast.Node { - tokenPos := p.scanner.TokenStart() - if p.notParenthesizedArrow.Has(tokenPos) { - return nil - } - result := p.parseParenthesizedArrowFunctionExpression(false /*allowAmbiguity*/, flags) - if result == nil { - p.notParenthesizedArrow.Add(tokenPos) - } - return result -} - func (p *Parser) tryParseAsyncSimpleArrowFunctionExpression(flags ExpressionParseFlags) *ast.Node { // We do a check here so that we won't be doing unnecessarily call to "lookAhead" if p.token == ast.KindAsyncKeyword && p.lookAhead((*Parser).nextIsUnParenthesizedAsyncArrowFunction) { @@ -4660,17 +4737,92 @@ func (p *Parser) parseSimpleArrowFunctionExpression(pos int, identifier *ast.Nod } func (p *Parser) parseConditionalExpressionRest(leftOperand *ast.Expression, pos int, flags ExpressionParseFlags) *ast.Expression { - // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher. questionToken := p.parseOptionalToken(ast.KindQuestionToken) if questionToken == nil { return leftOperand } - // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and - // we do not that for the 'whenFalse' part. - saveContextFlags := p.contextFlags + if p.tentativeExpression != nil || flags&ExpressionParseFlagsDisallowArrowReturnType != 0 { + return p.parseConditionalBranches(leftOperand, questionToken, pos, flags) + } + node := p.tryParseConditionalBranches(leftOperand, questionToken, pos, flags) + if node != nil { + return node + } + + node = p.tryParseConditionalExpression(leftOperand, questionToken, pos, flags|ExpressionParseFlagsAllowAmbiguousAsyncArrow) + if node != nil { + return node + } + node = p.tryParseConditionalExpression(leftOperand, questionToken, pos, flags) + if node != nil { + return node + } + expression := tentativeExpression{result: core.TSFalse} + scope := p.beginTentativeScope() + defer scope.restore() + p.tentativeExpression = &expression + return p.parseConditionalBranches(leftOperand, questionToken, pos, flags) +} + +func (p *Parser) tryParseConditionalExpression(leftOperand, questionToken *ast.Node, pos int, flags ExpressionParseFlags) *ast.Node { + tentative := p.beginTentativeParse() + defer tentative.revert() + var expression tentativeExpression + for { + tentative.rewind() + p.tentativeExpression = &expression + expression.heads = expression.heads[:0] + tentative.silence() + node := p.tryParseConditionalBranches(leftOperand, questionToken, pos, flags) + if node != nil { + if tentative.parsingFlags&ParsingFlagsTentative != 0 { + tentative.commit() + return node + } + expression.result = core.TSTrue + tentative.rewind() + p.tentativeExpression = &expression + p.tentativeNodes = tentative.nodes + node = p.parseConditionalBranches(leftOperand, questionToken, pos, flags) + tentative.commit() + return node + } + if len(expression.heads) == 0 { + return nil + } + expression.expressions.Add(expression.heads[len(expression.heads)-1]) + } +} + +func (p *Parser) tryParseConditionalBranches(leftOperand, questionToken *ast.Node, pos int, flags ExpressionParseFlags) (node *ast.Node) { + tentative := p.beginTentativeParse() + defer tentative.close() + node = p.parseConditionalBranches(leftOperand, questionToken, pos, flags) + tentative.commit() + return node +} + +func (p *Parser) parseConditionalBranches(leftOperand, questionToken *ast.Node, pos int, flags ExpressionParseFlags) *ast.Node { + expression := p.tentativeExpression + outerContextFlags := p.contextFlags + var contextFlags ast.NodeFlags + if expression != nil { + contextFlags = expression.contextFlags + expression.contextFlags = outerContextFlags + } p.setContextFlags(ast.NodeFlagsDisallowInContext, false) - trueExpression := p.parseAssignmentExpressionOrHigherWorker(ExpressionParseFlagsDisallowArrowReturnType) - p.contextFlags = saveContextFlags + expressionFlags := ExpressionParseFlagsDisallowArrowReturnType | flags&ExpressionParseFlagsAllowAmbiguousAsyncArrow + if expression != nil && expression.result == core.TSFalse { + expressionFlags |= ExpressionParseFlagsAllowAmbiguousAsyncArrow + } + trueExpression := p.parseAssignmentExpressionOrHigherWorker(expressionFlags) + if p.token != ast.KindColonToken && p.parsingFlags&ParsingFlagsTentative != 0 { + panic(tentativeParseFailure{}) + } + if expression != nil { + expression.contextFlags = contextFlags + } + p.contextFlags = outerContextFlags colonToken := p.parseExpectedToken(ast.KindColonToken) var falseExpression *ast.Expression if ast.NodeIsPresent(colonToken) { @@ -5717,13 +5869,20 @@ func (p *Parser) parsePrimaryExpression() *ast.Expression { return p.parseIdentifierWithDiagnostic(diagnostics.Expression_expected, nil) } -func (p *Parser) parseParenthesizedExpression() *ast.Expression { +func (p *Parser) parseParenthesizedExpression() (result *ast.Expression) { pos := p.nodePos() + if p.parsingFlags&ParsingFlagsTentative != 0 { + node := p.getTentativeNode(pos, ast.KindParenthesizedExpression) + if node != nil { + return node + } + defer p.recordTentativeNode(pos, ast.KindParenthesizedExpression, p.contextFlags, &result) + } jsdoc := p.jsdocScannerInfo() p.parseExpected(ast.KindOpenParenToken) expression := p.parseExpressionAllowIn() p.parseExpected(ast.KindCloseParenToken) - result := p.finishNode(p.factory.NewParenthesizedExpression(expression), pos) + result = p.finishNode(p.factory.NewParenthesizedExpression(expression), pos) p.withJSDoc(result, jsdoc) return result } @@ -6836,9 +6995,10 @@ func (p *Parser) checkJSDecoratorSyntax(node *ast.Node) { } func (p *Parser) checkJSSyntax(node *ast.Node) *ast.Node { - if node.Flags&ast.NodeFlagsJavaScriptFile == 0 || node.Flags&(ast.NodeFlagsJSDoc|ast.NodeFlagsReparsed) != 0 { + if p.parsingFlags&ParsingFlagsTentative != 0 || node.Flags&ast.NodeFlagsJavaScriptFile == 0 || node.Flags&(ast.NodeFlagsJSDoc|ast.NodeFlagsReparsed) != 0 { return node } + switch node.Kind { case ast.KindParameter, ast.KindPropertyDeclaration, ast.KindMethodDeclaration: if token := node.QuestionToken(); token != nil && token.Flags&ast.NodeFlagsReparsed == 0 && ast.IsQuestionToken(token) { diff --git a/tsc/internal/parser/parser_test.go b/tsc/internal/parser/parser_test.go index 2c40898e777b1..c49c79d837682 100644 --- a/tsc/internal/parser/parser_test.go +++ b/tsc/internal/parser/parser_test.go @@ -5,6 +5,7 @@ import ( "iter" "os" "path/filepath" + "strconv" "strings" "testing" @@ -45,6 +46,44 @@ func BenchmarkParse(b *testing.B) { } } +func BenchmarkConditionalAsyncExpressions(b *testing.B) { + for _, test := range []struct{ name, prefix, suffix, closing string }{ + {"call", "a ? async() : x => ", "0;", ""}, + {"arrow", "a ? async(): T => async() : x => ", "0;", ""}, + {"priority", "a ? d = (d): T => a ? 0 : async(...c) : T => ", "0;", ""}, + {"invalidCall", "a ? async() : x => ", "0 +;", ""}, + {"invalidArrow", "a ? async(): T => async() : x => ", "0 +;", ""}, + {"parenthesizedCall", "a ? async() : x => (", "0", ")"}, + {"invalidParenthesizedCall", "a ? async() : x => (", "0 +", ")"}, + } { + b.Run(test.name, func(b *testing.B) { + for _, count := range []int{10, 20, 40, 80} { + b.Run(strconv.Itoa(count), func(b *testing.B) { + source := "const r = " + strings.Repeat(test.prefix, count) + test.suffix + strings.Repeat(test.closing, count) + opts := ast.SourceFileParseOptions{FileName: "/a.ts", PathKey: "/a.ts"} + b.ReportAllocs() + for b.Loop() { + parser.ParseSourceFile(opts, source, core.ScriptKindTS) + } + }) + } + }) + } +} + +func BenchmarkConditionalExpressions(b *testing.B) { + for _, count := range []int{1, 100} { + b.Run(strconv.Itoa(count), func(b *testing.B) { + source := strings.Repeat("{ const r = a ? b : c; }\n", count) + opts := ast.SourceFileParseOptions{FileName: "/a.ts", PathKey: "/a.ts"} + b.ReportAllocs() + for b.Loop() { + parser.ParseSourceFile(opts, source, core.ScriptKindTS) + } + }) + } +} + type parsableFile struct { path string name string @@ -188,17 +227,23 @@ class MissingImplements implements B. {} assert.Equal(t, missingImplementsDecl.HeritageClauses.Nodes[0].AsHeritageClause().Types.Nodes[0].Kind, ast.KindExpressionWithTypeArguments) } -func TestConditionalAsyncCall(t *testing.T) { - t.Parallel() +func parseConditionalInGenerator(t *testing.T, expression string, kind core.ScriptKind) *ast.ConditionalExpression { + t.Helper() + fileName := tspath.RootedFilePathFromNormalized(core.IfElse(kind == core.ScriptKindJS, "/a.js", "/a.ts")) file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "function* g() { const a = b ? async(...c) : 0; }", core.ScriptKindTS) + FileName: fileName, + PathKey: tspath.CaseSensitive.PathKey(tspath.RootedPath(fileName)), + }, "function* g() { const a = "+expression+"; }", kind) assert.Equal(t, len(file.Diagnostics()), 0) assert.Equal(t, len(file.JSDiagnostics()), 0) statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() + return declaration.Initializer().AsConditionalExpression() +} + +func TestConditionalAsyncCall(t *testing.T) { + t.Parallel() + conditional := parseConditionalInGenerator(t, "b ? async(...c) : 0", core.ScriptKindTS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindNumericLiteral) @@ -206,15 +251,7 @@ func TestConditionalAsyncCall(t *testing.T) { func TestConditionalAsyncCallWithArrow(t *testing.T) { t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "function* g() { const a = b ? async(...c) : d => d; }", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] - declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() + conditional := parseConditionalInGenerator(t, "b ? async(...c) : d => d", core.ScriptKindTS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) @@ -222,15 +259,7 @@ func TestConditionalAsyncCallWithArrow(t *testing.T) { func TestConditionalAsyncCallYield(t *testing.T) { t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "function* g() { const a = b ? yield async(...c) : 0; }", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] - declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() + conditional := parseConditionalInGenerator(t, "b ? yield async(...c) : 0", core.ScriptKindTS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindYieldExpression) assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindNumericLiteral) @@ -239,15 +268,7 @@ func TestConditionalAsyncCallYield(t *testing.T) { func TestConditionalAsyncCallYieldWithArrow(t *testing.T) { t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "function* g() { const a = b ? yield async(...c) : d => d; }", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] - declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() + conditional := parseConditionalInGenerator(t, "b ? yield async(...c) : d => d", core.ScriptKindTS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindYieldExpression) assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) @@ -256,15 +277,7 @@ func TestConditionalAsyncCallYieldWithArrow(t *testing.T) { func TestConditionalAsyncCallJS(t *testing.T) { t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.js", - PathKey: "/a.js", - }, "function* g() { const a = b ? async(...c) : 0; }", core.ScriptKindJS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] - declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() + conditional := parseConditionalInGenerator(t, "b ? async(...c) : 0", core.ScriptKindJS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindNumericLiteral) @@ -272,15 +285,7 @@ func TestConditionalAsyncCallJS(t *testing.T) { func TestConditionalAsyncCallWithArrowJS(t *testing.T) { t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.js", - PathKey: "/a.js", - }, "function* g() { const a = b ? async(...c) : d => d; }", core.ScriptKindJS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] - declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() + conditional := parseConditionalInGenerator(t, "b ? async(...c) : d => d", core.ScriptKindJS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) @@ -288,15 +293,7 @@ func TestConditionalAsyncCallWithArrowJS(t *testing.T) { func TestConditionalAsyncCallYieldJS(t *testing.T) { t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.js", - PathKey: "/a.js", - }, "function* g() { const a = b ? yield async(...c) : 0; }", core.ScriptKindJS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] - declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() + conditional := parseConditionalInGenerator(t, "b ? yield async(...c) : 0", core.ScriptKindJS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindYieldExpression) assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindNumericLiteral) @@ -305,373 +302,13 @@ func TestConditionalAsyncCallYieldJS(t *testing.T) { func TestConditionalAsyncCallYieldWithArrowJS(t *testing.T) { t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.js", - PathKey: "/a.js", - }, "function* g() { const a = b ? yield async(...c) : d => d; }", core.ScriptKindJS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] - declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() + conditional := parseConditionalInGenerator(t, "b ? yield async(...c) : d => d", core.ScriptKindJS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindYieldExpression) assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) assert.Equal(t, conditional.WhenTrue.Expression().Kind, ast.KindCallExpression) } -func TestConditionalAsyncCallReturnType(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? async() : d => async (...c): Promise => c.length;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) - arrow := conditional.WhenFalse.Body() - assert.Equal(t, arrow.Kind, ast.KindArrowFunction) - assert.Equal(t, arrow.Type().Kind, ast.KindTypeReference) -} - -func TestConditionalAsyncCallReturnTypeAlias(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? async() : d => async (...c): T => c.length;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) - arrow := conditional.WhenFalse.Body() - assert.Equal(t, arrow.Kind, ast.KindArrowFunction) - assert.Equal(t, arrow.Type().Kind, ast.KindTypeReference) -} - -func TestConditionalAsyncCallWithTypedArrow(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? async() : d => async (): T => 0;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) - arrow := conditional.WhenFalse.Body() - assert.Equal(t, arrow.Kind, ast.KindArrowFunction) - assert.Equal(t, len(arrow.Parameters()), 0) - assert.Equal(t, arrow.Modifiers().Nodes[0].Kind, ast.KindAsyncKeyword) - assert.Equal(t, arrow.Type().Kind, ast.KindTypeReference) - assert.Equal(t, arrow.Type().AsTypeReferenceNode().TypeName.Text(), "T") - assert.Equal(t, arrow.Body().Kind, ast.KindNumericLiteral) -} - -func TestConditionalParenthesizedExpressionWithTypedArrow(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? (value) : d => async (): T => 0;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindParenthesizedExpression) - assert.Equal(t, conditional.WhenTrue.Expression().Text(), "value") - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) - arrow := conditional.WhenFalse.Body() - assert.Equal(t, arrow.Kind, ast.KindArrowFunction) - assert.Equal(t, len(arrow.Parameters()), 0) - assert.Equal(t, arrow.Modifiers().Nodes[0].Kind, ast.KindAsyncKeyword) - assert.Equal(t, arrow.Type().Kind, ast.KindTypeReference) - assert.Equal(t, arrow.Type().AsTypeReferenceNode().TypeName.Text(), "T") - assert.Equal(t, arrow.Body().Kind, ast.KindNumericLiteral) -} - -func TestConditionalAsyncCallWithParenthesizedTypedArrow(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? async() : d => (e): T => 0;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) - arrow := conditional.WhenFalse.Body() - assert.Equal(t, arrow.Kind, ast.KindArrowFunction) - assert.Equal(t, len(arrow.Parameters()), 1) - assert.Equal(t, arrow.Parameters()[0].Name().Text(), "e") - assert.Equal(t, arrow.Type().AsTypeReferenceNode().TypeName.Text(), "T") - assert.Equal(t, arrow.Body().Kind, ast.KindNumericLiteral) -} - -func TestConditionalAsyncCallWithGenericTypedArrow(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? async() : d => async (): T => 0;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) - arrow := conditional.WhenFalse.Body() - assert.Equal(t, arrow.Kind, ast.KindArrowFunction) - assert.Equal(t, len(arrow.TypeParameterList().Nodes), 1) - assert.Equal(t, arrow.TypeParameterList().Nodes[0].Name().Text(), "U") - assert.Equal(t, len(arrow.Parameters()), 0) - assert.Equal(t, arrow.Modifiers().Nodes[0].Kind, ast.KindAsyncKeyword) - assert.Equal(t, arrow.Type().AsTypeReferenceNode().TypeName.Text(), "T") - assert.Equal(t, arrow.Body().Kind, ast.KindNumericLiteral) -} - -func TestConditionalParenthesizedTypedArrowPriority(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? (c) : d => (e): T => 0;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenTrue.Type().AsTypeReferenceNode().TypeName.Text(), "d") - assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindParenthesizedExpression) - assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "e") - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenFalse.Parameters()[0].Name().Text(), "T") - assert.Equal(t, conditional.WhenFalse.Body().Kind, ast.KindNumericLiteral) -} - -func TestConditionalGenericTypedArrowPriority(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? async() : d => (e): T => 0;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) - assert.Equal(t, len(conditional.WhenTrue.TypeParameterList().Nodes), 1) - assert.Equal(t, conditional.WhenTrue.Type().AsTypeReferenceNode().TypeName.Text(), "d") - assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindParenthesizedExpression) - assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "e") - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenFalse.Parameters()[0].Name().Text(), "T") - assert.Equal(t, conditional.WhenFalse.Body().Kind, ast.KindNumericLiteral) -} - -func TestConditionalAsyncArrowWithConditionalBody(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? async (): Promise => b ? async() : 0 : () => 0;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindConditionalExpression) - body := conditional.WhenTrue.Body().AsConditionalExpression() - assert.Equal(t, body.WhenTrue.Kind, ast.KindCallExpression) - assert.Equal(t, body.WhenFalse.Kind, ast.KindNumericLiteral) -} - -func TestConditionalAsyncArrowBody(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? async () => async() : c => c;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) -} - -func TestConditionalAsyncArrowBodyJS(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.js", - PathKey: "/a.js", - }, "const a = b ? async () => async() : c => c;", core.ScriptKindJS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) -} - -func TestConditionalAsyncRestArrowBody(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? async (...c) => async() : d => d;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) -} - -func TestConditionalAsyncRestArrowBodyJS(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.js", - PathKey: "/a.js", - }, "const a = b ? async (...c) => async() : d => d;", core.ScriptKindJS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) -} - -func TestConditionalArrowBody(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, "const a = b ? () => async() : c => c;", core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) -} - -func TestConditionalArrowBodyJS(t *testing.T) { - t.Parallel() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.js", - PathKey: "/a.js", - }, "const a = b ? () => async() : c => c;", core.ScriptKindJS) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) -} - -func TestConditionalTypedAsyncArrowBody(t *testing.T) { - t.Parallel() - arrow := checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (c: number): Promise => async() : d => d;") - assert.Equal(t, arrow.Parameters()[0].Type().Kind, ast.KindNumberKeyword) -} - -func TestConditionalTypedAsyncArrowBodyWithEmptyParameters(t *testing.T) { - t.Parallel() - checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (): Promise => async() : d => d;") -} - -func TestConditionalTypedAsyncArrowBodyWithSpreadCall(t *testing.T) { - t.Parallel() - checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (): Promise => async(...c) : d => d;") -} - -func TestConditionalTypedAsyncArrowBodyWithRestParameter(t *testing.T) { - t.Parallel() - checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (...c): Promise => async() : d => d;") -} - -func TestConditionalTypedAsyncArrowBodyWithTypedRestParameter(t *testing.T) { - t.Parallel() - arrow := checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (...c: number[]): Promise => async() : d => d;") - assert.Equal(t, arrow.Parameters()[0].Type().Kind, ast.KindArrayType) -} - -func TestConditionalTypedAsyncArrowBodyWithTypeParameter(t *testing.T) { - t.Parallel() - checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (): Promise => async() : d => d;") -} - -func TestConditionalTypedAsyncArrowBodyWithParenthesizedReturnType(t *testing.T) { - t.Parallel() - checkConditionalTypedAsyncArrowBody(t, "const a = b ? async (): (Promise) => async() : d => d;") -} - -func TestConditionalAsyncCallWithFunction(t *testing.T) { - t.Parallel() - checkConditionalAsyncCallWithFunction(t, "/a.ts") -} - -func TestConditionalAsyncCallWithFunctionJS(t *testing.T) { - t.Parallel() - checkConditionalAsyncCallWithFunction(t, "/a.js") -} - -func TestConditionalExpressionFollowedByBlock(t *testing.T) { - t.Parallel() - const source = "const a = b ? async() : 0\n{}" - checkConditionalExpressionFollowedByBlock(t, "/a.ts", source, ast.KindCallExpression, ast.KindNumericLiteral) - checkConditionalExpressionFollowedByBlock(t, "/a.js", source, ast.KindCallExpression, ast.KindNumericLiteral) -} - -func TestConditionalExpressionWithObjectFollowedByBlock(t *testing.T) { - t.Parallel() - const source = "const a = b ? async() : {}\n{}" - checkConditionalExpressionFollowedByBlock(t, "/a.ts", source, ast.KindCallExpression, ast.KindObjectLiteralExpression) - checkConditionalExpressionFollowedByBlock(t, "/a.js", source, ast.KindCallExpression, ast.KindObjectLiteralExpression) -} - -func TestConditionalExpressionWithStringFollowedByBlock(t *testing.T) { - t.Parallel() - const source = "const a = b ? async() : \"c\"\n{}" - checkConditionalExpressionFollowedByBlock(t, "/a.ts", source, ast.KindCallExpression, ast.KindStringLiteral) - checkConditionalExpressionFollowedByBlock(t, "/a.js", source, ast.KindCallExpression, ast.KindStringLiteral) -} - -func TestConditionalSpreadCallFollowedByBlock(t *testing.T) { - t.Parallel() - const source = "const a = b ? async(...c) : 0\n{}" - checkConditionalExpressionFollowedByBlock(t, "/a.ts", source, ast.KindCallExpression, ast.KindNumericLiteral) - checkConditionalExpressionFollowedByBlock(t, "/a.js", source, ast.KindCallExpression, ast.KindNumericLiteral) -} - -func TestConditionalParenthesizedExpressionFollowedByBlock(t *testing.T) { - t.Parallel() - const source = "const a = b ? (c) : 0\n{}" - checkConditionalExpressionFollowedByBlock(t, "/a.ts", source, ast.KindParenthesizedExpression, ast.KindNumericLiteral) - checkConditionalExpressionFollowedByBlock(t, "/a.js", source, ast.KindParenthesizedExpression, ast.KindNumericLiteral) -} - -func TestConditionalExpressionWithSemicolonFollowedByBlock(t *testing.T) { - t.Parallel() - const source = "const a = b ? async() : 0;\n{}" - checkConditionalExpressionFollowedByBlock(t, "/a.ts", source, ast.KindCallExpression, ast.KindNumericLiteral) - checkConditionalExpressionFollowedByBlock(t, "/a.js", source, ast.KindCallExpression, ast.KindNumericLiteral) -} - func TestConditionalAsyncCallJSDoc(t *testing.T) { t.Parallel() file := parser.ParseSourceFile(ast.SourceFileParseOptions{ @@ -704,80 +341,57 @@ func TestConditionalAsyncCallJSDocTypedef(t *testing.T) { assert.Equal(t, len(arrow.JSDoc(file)), 1) } -func TestConditionalAsyncCallRecovery(t *testing.T) { - t.Parallel() - checkConditionalArrowRecovery(t, "const a = b ? async(...c: number[]): Promise => 0;") -} - -func TestConditionalTypedAsyncArrowRecovery(t *testing.T) { - t.Parallel() - checkConditionalArrowRecovery(t, "const a = b ? async (): Promise {} : d => d;") +func TestConditionalAsyncCallCommentDirectives(t *testing.T) { + t.Parallel() + file := parsetestutil.ParseTypeScript(`const r = a ? async() : x => + // @ts-expect-error + a ? async() : x => + // @ts-ignore + 0; + const s = a ? async(x = ( + // @ts-expect-error + b + ), + // @ts-ignore + c + ): T => b : c;`, false) + parsetestutil.CheckDiagnostics(t, file) + assert.Equal(t, len(file.CommentDirectives), 4) + assert.Equal(t, file.CommentDirectives[0].Kind, ast.CommentDirectiveKindExpectError) + assert.Equal(t, file.CommentDirectives[1].Kind, ast.CommentDirectiveKindIgnore) + assert.Equal(t, file.CommentDirectives[2].Kind, ast.CommentDirectiveKindExpectError) + assert.Equal(t, file.CommentDirectives[3].Kind, ast.CommentDirectiveKindIgnore) + assert.Equal(t, len(file.Statements.Nodes), 2) } -func TestConditionalTypedArrowRecovery(t *testing.T) { +func TestConditionalAsyncArrowBodyContext(t *testing.T) { t.Parallel() - checkConditionalArrowRecovery(t, "const a = b ? (c): number {} : d => d;") -} - -func checkConditionalTypedAsyncArrowBody(t *testing.T, source string) *ast.Node { - t.Helper() file := parser.ParseSourceFile(ast.SourceFileParseOptions{ FileName: "/a.ts", PathKey: "/a.ts", - }, source, core.ScriptKindTS) + }, "const a = b ? async (): Promise => async() : d => d;", core.ScriptKindTS) assert.Equal(t, len(file.Diagnostics()), 0) declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindArrowFunction) - assert.Assert(t, conditional.WhenTrue.Type() != nil) - assert.Equal(t, conditional.WhenTrue.Body().Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenTrue.Body().Expression().Text(), "async") - assert.Equal(t, conditional.WhenTrue.Body().Flags&ast.NodeFlagsAwaitContext, ast.NodeFlagsAwaitContext) - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) - assert.Equal(t, conditional.WhenFalse.Parameters()[0].Name().Text(), "d") - return conditional.WhenTrue -} - -func checkConditionalAsyncCallWithFunction(t *testing.T, fileName tspath.RootedFilePath) { - t.Helper() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: fileName, - PathKey: tspath.PathKeyFromCanonical(fileName.AsString()), - }, "const a = b ? async() : function() {};", core.GetScriptKindFromFileName(fileName)) - assert.Equal(t, len(file.Diagnostics()), 0) - assert.Equal(t, len(file.JSDiagnostics()), 0) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenFalse.Kind, ast.KindFunctionExpression) -} - -func checkConditionalExpressionFollowedByBlock(t *testing.T, fileName tspath.RootedFilePath, source string, whenTrueKind ast.Kind, whenFalseKind ast.Kind) { - t.Helper() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: fileName, - PathKey: tspath.PathKeyFromCanonical(fileName.AsString()), - }, source, core.GetScriptKindFromFileName(fileName)) - assert.Equal(t, len(file.Diagnostics()), 0, fileName) - assert.Equal(t, len(file.JSDiagnostics()), 0, fileName) - assert.Equal(t, len(file.Statements.Nodes), 2) - assert.Equal(t, file.Statements.Nodes[1].Kind, ast.KindBlock) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - conditional := declaration.Initializer().AsConditionalExpression() - assert.Equal(t, conditional.WhenTrue.Kind, whenTrueKind) - assert.Equal(t, conditional.WhenFalse.Kind, whenFalseKind) -} - -func checkConditionalArrowRecovery(t *testing.T, source string) { - t.Helper() - file := parser.ParseSourceFile(ast.SourceFileParseOptions{ - FileName: "/a.ts", - PathKey: "/a.ts", - }, source, core.ScriptKindTS) - assert.Equal(t, len(file.Diagnostics()), 1) - assert.Equal(t, file.Diagnostics()[0].Code(), diagnostics.X_0_expected.Code()) - declaration := file.Statements.Nodes[0].AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - assert.Equal(t, declaration.Initializer().AsConditionalExpression().WhenTrue.Kind, ast.KindArrowFunction) + arrow := declaration.Initializer().AsConditionalExpression().WhenTrue + assert.Equal(t, arrow.Kind, ast.KindArrowFunction) + body := arrow.Body() + assert.Equal(t, body.Kind, ast.KindCallExpression) + assert.Equal(t, body.Flags&ast.NodeFlagsAwaitContext, ast.NodeFlagsAwaitContext) + assert.Equal(t, body.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsNone) +} + +func TestConditionalAsyncArrowYieldContext(t *testing.T) { + t.Parallel() + expression := parseConditionalInGenerator(t, "a ? async (): T => a ? async (): T => async() : async() : yield b", core.ScriptKindTS) + assert.Equal(t, expression.WhenTrue.Kind, ast.KindArrowFunction) + assert.Equal(t, expression.WhenFalse.Kind, ast.KindYieldExpression) + assert.Assert(t, expression.WhenFalse.Flags&ast.NodeFlagsYieldContext != 0) + assert.Equal(t, expression.WhenFalse.Flags&ast.NodeFlagsAwaitContext, ast.NodeFlagsNone) + body := expression.WhenTrue.Body().AsConditionalExpression() + assert.Equal(t, body.WhenTrue.Kind, ast.KindArrowFunction) + assert.Equal(t, body.WhenFalse.Kind, ast.KindCallExpression) + assert.Assert(t, body.WhenFalse.Flags&ast.NodeFlagsAwaitContext != 0) + assert.Equal(t, body.WhenFalse.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsNone) } func TestParseStaticSourcePhaseImport(t *testing.T) { diff --git a/tsc/internal/parser/tentative.go b/tsc/internal/parser/tentative.go new file mode 100644 index 0000000000000..8578978111430 --- /dev/null +++ b/tsc/internal/parser/tentative.go @@ -0,0 +1,121 @@ +package parser + +import "github.com/microsoft/TypeScript/tsc/internal/ast" + +type tentativeParseFailure struct{} + +type tentativeNode struct { + kind ast.Kind + contextFlags ast.NodeFlags + node *ast.Node +} + +type tentativeScope struct { + parser *Parser + expression *tentativeExpression +} + +type tentativeParse struct { + tentativeScope + state ParserState + nodes map[int][]tentativeNode + parsingFlags ParsingFlags + parsingContexts ParsingContexts +} + +func (p *Parser) beginTentativeScope() tentativeScope { + return tentativeScope{parser: p, expression: p.tentativeExpression} +} + +func (tc *tentativeScope) suspendExpression() { + tc.parser.tentativeExpression = nil +} + +func (tc *tentativeScope) restore() { + tc.parser.tentativeExpression = tc.expression +} + +func (p *Parser) beginTentativeParse() tentativeParse { + return tentativeParse{ + tentativeScope: p.beginTentativeScope(), + state: p.mark(), + parsingFlags: p.parsingFlags, + parsingContexts: p.parsingContexts, + } +} + +func (tp *tentativeParse) silence() { + if tp.nodes == nil { + tp.nodes = tp.parser.tentativeNodes + if tp.nodes == nil { + tp.nodes = make(map[int][]tentativeNode) + } + } + tp.parser.tentativeNodes = tp.nodes + tp.parser.parsingFlags |= ParsingFlagsTentative + tp.parser.hasParseError = false +} + +func (tp *tentativeParse) rewind() { + tp.parser.rewind(tp.state) + tp.parser.parsingFlags = tp.parsingFlags + tp.parser.parsingContexts = tp.parsingContexts +} + +func (tp *tentativeParse) commit() { + if tp.parser != nil { + tp.restore() + tp.parser.tentativeNodes = tp.state.tentativeNodes + } + tp.parser = nil +} + +func (tp *tentativeParse) revert() { + if tp.parser != nil { + tp.rewind() + tp.parser = nil + } +} + +func (tp *tentativeParse) close() { + failure := recover() + if failure == nil { + tp.revert() + return + } + if tp.parser == nil { + panic(failure) + } + tp.revert() + if _, ok := failure.(tentativeParseFailure); ok { + return + } + panic(failure) +} + +func (p *Parser) getTentativeNode(pos int, kind ast.Kind) *ast.Node { + for _, annotation := range p.tentativeNodes[pos] { + if annotation.kind == kind && annotation.contextFlags == p.contextFlags { + if annotation.node == nil { + panic(tentativeParseFailure{}) + } + p.scanner.ResetTokenState(annotation.node.End()) + p.nextToken() + return annotation.node + } + } + return nil +} + +func (p *Parser) recordTentativeNode(pos int, kind ast.Kind, contextFlags ast.NodeFlags, node **ast.Node) { + failure := recover() + if failure != nil { + if _, ok := failure.(tentativeParseFailure); !ok { + panic(failure) + } + } + p.tentativeNodes[pos] = append(p.tentativeNodes[pos], tentativeNode{kind: kind, contextFlags: contextFlags, node: *node}) + if failure != nil { + panic(failure) + } +} diff --git a/tsc/internal/parser/tentative_test.go b/tsc/internal/parser/tentative_test.go new file mode 100644 index 0000000000000..01bddf880ecb9 --- /dev/null +++ b/tsc/internal/parser/tentative_test.go @@ -0,0 +1,299 @@ +package parser + +import ( + "reflect" + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/ast" + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/diagnostics" + "gotest.tools/v3/assert" +) + +func newTestParser(source string) *Parser { + p := newParser() + p.initializeState(ast.SourceFileParseOptions{FileName: "/a.ts", PathKey: "/a.ts"}, source, core.ScriptKindTS) + p.nextToken() + return p +} + +func TestTentativeScopeRestore(t *testing.T) { + t.Parallel() + p := newTestParser("a + b") + var expression tentativeExpression + p.tentativeExpression = &expression + failure := new(int) + var recovered any + func() { + defer func() { recovered = recover() }() + scope := p.beginTentativeScope() + defer scope.restore() + scope.suspendExpression() + assert.Assert(t, p.tentativeExpression == nil) + p.nextToken() + panic(failure) + }() + assert.Equal(t, recovered, any(failure)) + assert.Equal(t, p.tentativeExpression, &expression) + assert.Equal(t, p.token, ast.KindPlusToken) +} + +func TestTentativeParseCommitAndRevert(t *testing.T) { + t.Parallel() + p := newTestParser("a + b") + outer := p.beginTentativeParse() + p.nextToken() + inner := p.beginTentativeParse() + p.nextToken() + inner.commit() + inner.close() + assert.Equal(t, p.scanner.TokenText(), "b") + outer.revert() + assert.Equal(t, p.scanner.TokenText(), "a") + + outer = p.beginTentativeParse() + p.nextToken() + inner = p.beginTentativeParse() + p.nextToken() + inner.revert() + outer.commit() + outer.close() + assert.Equal(t, p.token, ast.KindPlusToken) +} + +func TestTentativeParseExpression(t *testing.T) { + t.Parallel() + p := newTestParser("a + b") + var expression tentativeExpression + p.tentativeExpression = &expression + tentative := p.beginTentativeParse() + tentative.suspendExpression() + assert.Assert(t, p.tentativeExpression == nil) + p.nextToken() + tentative.commit() + assert.Equal(t, p.tentativeExpression, &expression) + assert.Equal(t, p.token, ast.KindPlusToken) + + state := p.mark() + tentative = p.beginTentativeParse() + tentative.suspendExpression() + inner := p.beginTentativeParse() + p.tentativeExpression = &tentativeExpression{} + p.nextToken() + inner.commit() + assert.Assert(t, p.tentativeExpression == nil) + tentative.revert() + assert.Assert(t, reflect.DeepEqual(p.mark(), state)) +} + +func TestTentativeParseFailure(t *testing.T) { + t.Parallel() + p := newTestParser("a + // @ts-expect-error\nb") + p.tentativeExpression = &tentativeExpression{} + state := p.mark() + result := func() (result *ast.Node) { + tentative := p.beginTentativeParse() + defer tentative.close() + tentative.silence() + tentative.suspendExpression() + p.parsingContexts |= 1 << PCParameters + p.contextFlags |= ast.NodeFlagsAwaitContext + p.nextToken() + p.nextToken() + p.parseErrorAtCurrentToken(diagnostics.Expression_expected) + return p.factory.NewEmptyStatement() + }() + assert.Assert(t, result == nil) + assert.Assert(t, reflect.DeepEqual(p.mark(), state)) + assert.Equal(t, p.parsingContexts, ParsingContexts(0)) + assert.Equal(t, p.parsingFlags, ParsingFlagsNone) + p.nextToken() + p.nextToken() + assert.Equal(t, len(p.scanner.CommentDirectives()), 1) +} + +func TestTentativeParseUnexpectedFailure(t *testing.T) { + t.Parallel() + p := newTestParser("a + b") + failure := new(int) + var recovered any + func() { + defer func() { recovered = recover() }() + tentative := p.beginTentativeParse() + defer tentative.close() + p.nextToken() + panic(failure) + }() + assert.Equal(t, recovered, any(failure)) + assert.Equal(t, p.scanner.TokenText(), "a") +} + +func TestTentativeConditionalFailure(t *testing.T) { + t.Parallel() + p := newTestParser("a ? b") + leftOperand := p.parseIdentifier() + questionToken := p.parseExpectedToken(ast.KindQuestionToken) + p.tentativeExpression = &tentativeExpression{} + p.parsingFlags = ParsingFlagsTentative + state := p.mark() + node := p.tryParseConditionalBranches(leftOperand, questionToken, leftOperand.Pos(), ExpressionParseFlagsNone) + assert.Assert(t, node == nil) + assert.Assert(t, reflect.DeepEqual(p.mark(), state)) + assert.Equal(t, p.parsingFlags, ParsingFlagsTentative) +} + +func TestTentativeParseCommittedFailure(t *testing.T) { + t.Parallel() + p := newTestParser("a + b") + state := p.mark() + outer := p.beginTentativeParse() + func() { + defer outer.close() + outer.silence() + func() { + inner := p.beginTentativeParse() + defer inner.close() + p.nextToken() + inner.commit() + p.parseErrorAtCurrentToken(diagnostics.Expression_expected) + }() + t.Fatal("a committed inner transaction swallowed the failure") + }() + assert.Assert(t, reflect.DeepEqual(p.mark(), state)) + assert.Equal(t, p.parsingFlags, ParsingFlagsNone) +} + +func TestArrowFunctionHeadSyntaxFailure(t *testing.T) { + t.Parallel() + p := newTestParser("(a = b; c)") + pos := p.nodePos() + p.parsingFlags = ParsingFlagsTentative + status, _ := p.tryParseArrowFunctionHead(ExpressionParseFlagsNone) + assert.Equal(t, status, core.TSFalse) + assert.Assert(t, p.notParenthesizedArrow.Has(pos)) + assert.Equal(t, p.nodePos(), pos) + expression := p.tryParseParenthesizedArrowFunctionExpression(ExpressionParseFlagsNone) + assert.Assert(t, expression == nil) + assert.Assert(t, p.notParenthesizedArrow.Has(pos)) + assert.Equal(t, p.nodePos(), pos) +} + +func TestTentativeParseNode(t *testing.T) { + t.Parallel() + p := newTestParser("(a) + b") + tentative := p.beginTentativeParse() + tentative.silence() + state := p.mark() + first := p.parseParenthesizedExpression() + assert.Equal(t, p.token, ast.KindPlusToken) + p.rewind(state) + second := p.parseParenthesizedExpression() + assert.Equal(t, first, second) + assert.Equal(t, p.token, ast.KindPlusToken) + p.rewind(state) + p.contextFlags |= ast.NodeFlagsAwaitContext + third := p.parseParenthesizedExpression() + assert.Assert(t, third != first) + assert.Equal(t, third.Flags&ast.NodeFlagsAwaitContext, ast.NodeFlagsAwaitContext) + tentative.revert() + assert.Assert(t, p.tentativeNodes == nil) + assert.Equal(t, p.scanner.TokenText(), "(") +} + +func TestTentativeParseNodeFailure(t *testing.T) { + t.Parallel() + p := newTestParser("(a +)") + tentative := p.beginTentativeParse() + tentative.silence() + pos := p.nodePos() + func() { + attempt := p.beginTentativeParse() + defer attempt.close() + p.parseParenthesizedExpression() + t.Fatal("invalid expression accepted") + }() + assert.Equal(t, len(p.tentativeNodes[pos]), 1) + assert.Assert(t, p.tentativeNodes[pos][0].node == nil) + func() { + attempt := p.beginTentativeParse() + defer attempt.close() + p.parseParenthesizedExpression() + t.Fatal("failed recognition reused as a valid expression") + }() + assert.Equal(t, len(p.tentativeNodes[pos]), 1) + assert.Equal(t, p.nodePos(), pos) + tentative.revert() + assert.Assert(t, p.tentativeNodes == nil) +} + +func TestArrowFunctionHeadAmbiguity(t *testing.T) { + t.Parallel() + p := newTestParser("async(): T => a ?") + p.tentativeExpression = &tentativeExpression{} + state := p.mark() + status, signature := p.parseArrowFunctionHead(ExpressionParseFlagsDisallowArrowReturnType) + assert.Equal(t, status, core.TSUnknown) + assert.Equal(t, len(signature.parameters.Nodes), 0) + assert.Equal(t, signature.returnType.Kind, ast.KindTypeReference) + assert.Equal(t, p.token, ast.KindEqualsGreaterThanToken) + assert.Equal(t, len(p.diagnostics), 0) + headState := p.mark() + assert.Assert(t, p.isArrowFunctionHeadAmbiguous(state, signature.returnType)) + assert.Assert(t, reflect.DeepEqual(p.mark(), headState)) +} + +func TestArrowFunctionHeadParameterType(t *testing.T) { + t.Parallel() + p := newTestParser("async (...a: number[]): T => a ?") + status, signature := p.parseArrowFunctionHead(ExpressionParseFlagsAllowArrowFunctionRecovery | ExpressionParseFlagsDisallowArrowReturnType) + assert.Equal(t, status, core.TSTrue) + assert.Equal(t, len(signature.parameters.Nodes), 1) + assert.Equal(t, signature.parameters.Nodes[0].Type().Kind, ast.KindArrayType) + assert.Equal(t, p.token, ast.KindEqualsGreaterThanToken) + assert.Equal(t, len(p.diagnostics), 0) +} + +func TestArrowFunctionHeadRollback(t *testing.T) { + t.Parallel() + p := newTestParser("async(a = b.c)") + pos := p.nodePos() + tentative := p.beginTentativeParse() + status, _ := p.parseArrowFunctionHead(ExpressionParseFlagsNone) + assert.Equal(t, status, core.TSFalse) + assert.Equal(t, p.notParenthesizedArrow.Len(), 0) + tentative.revert() + expression := p.tryParseParenthesizedArrowFunctionExpression(ExpressionParseFlagsNone) + assert.Assert(t, expression == nil) + assert.Assert(t, p.notParenthesizedArrow.Has(pos)) + assert.Equal(t, p.nodePos(), pos) + expression = p.parseAssignmentExpressionOrHigher() + assert.Equal(t, expression.Kind, ast.KindCallExpression) + assert.Equal(t, p.token, ast.KindEndOfFile) + assert.Equal(t, len(p.diagnostics), 0) +} + +func TestArrowFunctionBodyFailureDoesNotCacheHead(t *testing.T) { + t.Parallel() + p := newTestParser("async(): T => a") + p.tentativeExpression = &tentativeExpression{result: core.TSFalse} + p.parsingFlags |= ParsingFlagsTentative + expression := p.tryParseParenthesizedArrowFunctionExpression(ExpressionParseFlagsDisallowArrowReturnType) + assert.Assert(t, expression == nil) + assert.Equal(t, p.notParenthesizedArrow.Len(), 0) + p.parsingFlags = ParsingFlagsNone + expression = p.tryParseParenthesizedArrowFunctionExpression(ExpressionParseFlagsNone) + assert.Equal(t, expression.Kind, ast.KindArrowFunction) + assert.Equal(t, p.token, ast.KindEndOfFile) +} + +func TestArrowFunctionBodySyntaxFailureDoesNotCacheHead(t *testing.T) { + t.Parallel() + p := newTestParser("async(): T => a +;") + p.tentativeExpression = &tentativeExpression{result: core.TSFalse} + p.parsingFlags |= ParsingFlagsTentative + pos := p.nodePos() + expression := p.tryParseParenthesizedArrowFunctionExpression(ExpressionParseFlagsDisallowArrowReturnType) + assert.Assert(t, expression == nil) + assert.Equal(t, p.notParenthesizedArrow.Len(), 0) + assert.Equal(t, p.nodePos(), pos) +} diff --git a/tsc/internal/parser/types.go b/tsc/internal/parser/types.go index c2295bb1976c8..17f5a5895d361 100644 --- a/tsc/internal/parser/types.go +++ b/tsc/internal/parser/types.go @@ -16,7 +16,15 @@ const ( type ExpressionParseFlags uint32 const ( - ExpressionParseFlagsNone ExpressionParseFlags = 0 - ExpressionParseFlagsDisallowArrowReturnType ExpressionParseFlags = 1 << 0 - ExpressionParseFlagsAllowAmbiguousAsyncArrow ExpressionParseFlags = 1 << 1 + ExpressionParseFlagsNone ExpressionParseFlags = 0 + ExpressionParseFlagsDisallowArrowReturnType ExpressionParseFlags = 1 << 0 + ExpressionParseFlagsAllowAmbiguousAsyncArrow ExpressionParseFlags = 1 << 1 + ExpressionParseFlagsAllowArrowFunctionRecovery ExpressionParseFlags = 1 << 2 +) + +type ParsingFlags uint8 + +const ( + ParsingFlagsNone ParsingFlags = 0 + ParsingFlagsTentative ParsingFlags = 1 << 0 ) diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.errors.txt b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.errors.txt new file mode 100644 index 0000000000000..164ebaa7b0280 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.errors.txt @@ -0,0 +1,148 @@ +b.ts(1,60): error TS1005: ':' expected. +b.ts(2,27): error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. +b.ts(2,43): error TS1005: '=>' expected. +b.ts(3,22): error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. +b.ts(3,29): error TS1005: '=>' expected. +b.ts(5,43): error TS1005: ':' expected. +b.ts(5,44): error TS1005: ':' expected. + + +==== a.ts (0 errors) ==== + // Repro from #20096 + + let foo = (async bar => bar); + + const a = true; + const b = 1; + const c = [b]; + + function async(...c: number[]): number { + return b; + } + + const f1 = a ? async() : 0; + const f2 = a ? async() : x => x; + const f3 = a ? a ? async() : 0 : b; + const f4 = a ? x => async() : x => x; + const f5 = a ? async (): Promise => b : () => b; + const f6 = a ? async (): Promise => { return b; } : () => b; + const f7 = a ? async (): Promise => a ? async() : 0 : () => b; + const f8 = a ? (): number => b : () => b; + + const f9 = a ? async(...c) : 0; + const f10 = a ? async(...c) : x => x; + const f11 = a ? async (...c: number[]): Promise => c.length : () => 0; + const f12 = a ? async() : x => async (...c): Promise => c.length; + + type T = Promise; + const f13 = a ? async() : x => async (): Promise => b; + const f14 = a ? async() : T => async (): T => 0; + const f15 = a ? (b) : x => async (): T => 0; + const f16 = a ? async(...c) : T => async (): T => 0; + const f17 = a ? async() : T => (b): number => b; + const f18 = a ? async() : T => async (): T => 0; + const f19 = a ? async(...c) : T => (b): number => b; + const f20 = a ? async(...c) : T => async (): T => 0; + const f21 = a ? (x): number => (b): T => 0; + const f22 = a ? async (): Promise => (b): T => 0; + const f23 = a ? async () => async() : x => x; + const f24 = a ? async (...c) => async() : x => x; + const f25 = a ? () => async() : x => x; + const f26 = a ? async (c: number): Promise => async() : x => x; + const f27 = a ? async (): Promise => async() : x => x; + const f28 = a ? async (): Promise => async(...c) : x => x; + const f29 = a ? async (...c): Promise => async() : x => x; + const f30 = a ? async (): Promise => async() : x => x; + const f31 = a ? async (): (Promise) => async() : x => x; + const f32 = a ? async (...c: number[]): Promise => async() : x => x; + + const f33 = a ? async() : 0 + {} + const f34 = a ? async() : {} + {} + + function* g() { + const f1 = a ? yield async(...c) : 0; + const f2 = a ? yield async(...c) : x => x; + } + + const d = { a: c }; + const e = () => c; + const f35 = async(...d.a); + const f36 = async(...e()); + const f37 = async(...[b]); + + type U = number; + const f38 = a ? (c): U => (b) : x => x; + const f39 = a ? async() : function() {}; + const f40 = a ? async() : "b" + {} + const f41 = a ? async(...c) : 0 + {} + const f42 = a ? (c) : 0 + {} + const f43 = a ? async() : 0; + {} + + const f44 = a ? async() : T => async (...c): T => c.length; + + const f45 = a ? async (): T => (b) : d => d; + const f46 = a ? async (): T => async() : d => d; + const f47 = a ? async (): T => async() : b; + const f48 = a ? a ? async() : d => d : b; + const f49 = a ? a ? async(b) : d => d : b; + const f50 = a ? a ? async(...c) : d => d : b; + const f51 = a ? a ? async() : T => b : async (): T => b; + const f52 = a ? async (): T => async() : (d): number => d; + const f53 = a ? a ? async (): T => async() : d => d : b; + const f54 = a ? async (): T => a ? async() : b : d => d; + const f55 = a ? a ? async() : d => d : a ? async() : d => d; + const f56 = a ? a ? a ? async() : d => d : b : b; + + const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); + const f58 = a ? d => d = async () => async() : (d => d = 0); + +==== b.ts (7 errors) ==== + const f59 = a ? async(...c: number[]): Promise => 0; + ~ +!!! error TS1005: ':' expected. + const f60 = a ? async (): Promise {} : d => d; + ~~~~~~~~~~~~~~~ +!!! error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. + ~ +!!! error TS1005: '=>' expected. + const f61 = a ? (c): number {} : d => d; + ~~~~~~ +!!! error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. + ~ +!!! error TS1005: '=>' expected. + + const f62 = a ? async() : T => async(a ? b); + ~ +!!! error TS1005: ':' expected. + ~ +!!! error TS1005: ':' expected. + +==== c.ts (0 errors) ==== + export {}; + declare const a: any, b: any, c: any[]; + declare function async(...a: any[]): any; + type T = Promise; + let d: any; + const f63 = a ? d = (d): T => a ? 0 : async(...c) : T => b; + const f64 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; + const f65 = a ? async (): T => (d): T => async() : b; + const f66 = (a ? async (): T => (d): T => async() : b); + const f67 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; + const f68 = a ? async (c = a ? async() : d => d): T => async() : b; + const f69 = a ? a ? (d): T => a ? async() : b : d => d : b; + const f70 = a ? async() : (d => d); + const f71 = a ? async() : d => (a ? async() : d => d); + + type x = T; + declare const x: any; + const f72 = a ? a ? async (): T => (x): T => async() : x => x; + const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; + const f74 = a ? async (x): T => async (): T => b; + const f75 = a ? async (x): T => async() : x => x; + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js index 0b0c679234a42..7b148620f530a 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js @@ -1,6 +1,6 @@ //// [tests/cases/compiler/parenthesizedAsyncArrowFunction.ts] //// -//// [parenthesizedAsyncArrowFunction.ts] +//// [a.ts] // Repro from #20096 let foo = (async bar => bar); @@ -9,7 +9,7 @@ const a = true; const b = 1; const c = [b]; -function async(...c: number[]): number { +function async(...c: number[]): number { return b; } @@ -29,13 +29,13 @@ const f12 = a ? async() : x => async (...c): Promise => c.length; type T = Promise; const f13 = a ? async() : x => async (): Promise => b; -const f14 = a ? async() : x => async (): T => 0; +const f14 = a ? async() : T => async (): T => 0; const f15 = a ? (b) : x => async (): T => 0; -const f16 = a ? async(...c) : x => async (): T => 0; -const f17 = a ? async() : x => (y): number => y; -const f18 = a ? async() : x => async (): T => 0; -const f19 = a ? async(...c) : x => (y): number => y; -const f20 = a ? async(...c) : x => async (): T => 0; +const f16 = a ? async(...c) : T => async (): T => 0; +const f17 = a ? async() : T => (b): number => b; +const f18 = a ? async() : T => async (): T => 0; +const f19 = a ? async(...c) : T => (b): number => b; +const f20 = a ? async(...c) : T => async (): T => 0; const f21 = a ? (x): number => (b): T => 0; const f22 = a ? async (): Promise => (b): T => 0; const f23 = a ? async () => async() : x => x; @@ -58,9 +58,75 @@ function* g() { const f1 = a ? yield async(...c) : 0; const f2 = a ? yield async(...c) : x => x; } + +const d = { a: c }; +const e = () => c; +const f35 = async(...d.a); +const f36 = async(...e()); +const f37 = async(...[b]); + +type U = number; +const f38 = a ? (c): U => (b) : x => x; +const f39 = a ? async() : function() {}; +const f40 = a ? async() : "b" +{} +const f41 = a ? async(...c) : 0 +{} +const f42 = a ? (c) : 0 +{} +const f43 = a ? async() : 0; +{} + +const f44 = a ? async() : T => async (...c): T => c.length; + +const f45 = a ? async (): T => (b) : d => d; +const f46 = a ? async (): T => async() : d => d; +const f47 = a ? async (): T => async() : b; +const f48 = a ? a ? async() : d => d : b; +const f49 = a ? a ? async(b) : d => d : b; +const f50 = a ? a ? async(...c) : d => d : b; +const f51 = a ? a ? async() : T => b : async (): T => b; +const f52 = a ? async (): T => async() : (d): number => d; +const f53 = a ? a ? async (): T => async() : d => d : b; +const f54 = a ? async (): T => a ? async() : b : d => d; +const f55 = a ? a ? async() : d => d : a ? async() : d => d; +const f56 = a ? a ? a ? async() : d => d : b : b; + +const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +const f58 = a ? d => d = async () => async() : (d => d = 0); +//// [b.ts] +const f59 = a ? async(...c: number[]): Promise => 0; +const f60 = a ? async (): Promise {} : d => d; +const f61 = a ? (c): number {} : d => d; + +const f62 = a ? async() : T => async(a ? b); + +//// [c.ts] +export {}; +declare const a: any, b: any, c: any[]; +declare function async(...a: any[]): any; +type T = Promise; +let d: any; +const f63 = a ? d = (d): T => a ? 0 : async(...c) : T => b; +const f64 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; +const f65 = a ? async (): T => (d): T => async() : b; +const f66 = (a ? async (): T => (d): T => async() : b); +const f67 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; +const f68 = a ? async (c = a ? async() : d => d): T => async() : b; +const f69 = a ? a ? (d): T => a ? async() : b : d => d : b; +const f70 = a ? async() : (d => d); +const f71 = a ? async() : d => (a ? async() : d => d); + +type x = T; +declare const x: any; +const f72 = a ? a ? async (): T => (x): T => async() : x => x; +const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; +const f74 = a ? async (x): T => async (): T => b; +const f75 = a ? async (x): T => async() : x => x; -//// [parenthesizedAsyncArrowFunction.js] + +//// [a.js] "use strict"; // Repro from #20096 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { @@ -92,13 +158,13 @@ const f10 = a ? async(...c) : x => x; const f11 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return c.length; }) : () => 0; const f12 = a ? async() : x => (...c) => __awaiter(void 0, void 0, void 0, function* () { return c.length; }); const f13 = a ? async() : x => () => __awaiter(void 0, void 0, void 0, function* () { return b; }); -const f14 = a ? async() : x => () => __awaiter(void 0, void 0, void 0, function* () { return 0; }); +const f14 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : T => 0; const f15 = a ? (b) : x => () => __awaiter(void 0, void 0, void 0, function* () { return 0; }); -const f16 = a ? async(...c) : x => () => __awaiter(void 0, void 0, void 0, function* () { return 0; }); -const f17 = a ? async() : x => (y) => y; -const f18 = a ? async() : x => () => __awaiter(void 0, void 0, void 0, function* () { return 0; }); -const f19 = a ? async(...c) : x => (y) => y; -const f20 = a ? async(...c) : x => () => __awaiter(void 0, void 0, void 0, function* () { return 0; }); +const f16 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : T => 0; +const f17 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return (b); }) : number => b; +const f18 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : T => 0; +const f19 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return (b); }) : number => b; +const f20 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : T => 0; const f21 = a ? (x) => (b) : T => 0; const f22 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return (b); }) : T => 0; const f23 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : x => x; @@ -119,3 +185,73 @@ function* g() { const f1 = a ? yield async(...c) : 0; const f2 = a ? yield async(...c) : x => x; } +const d = { a: c }; +const e = () => c; +const f35 = async(...d.a); +const f36 = async(...e()); +const f37 = async(...[b]); +const f38 = a ? (c) => (b) : x => x; +const f39 = a ? async() : function () { }; +const f40 = a ? async() : "b"; +{ } +const f41 = a ? async(...c) : 0; +{ } +const f42 = a ? (c) : 0; +{ } +const f43 = a ? async() : 0; +{ } +const f44 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(...c); }) : T => c.length; +const f45 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return (b); }) : d => d; +const f46 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : d => d; +const f47 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : b; +const f48 = a ? a ? async() : d => d : b; +const f49 = a ? a ? async(b) : d => d : b; +const f50 = a ? a ? async(...c) : d => d : b; +const f51 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { return b; }) : async() : T => b; +const f52 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : (d) => d; +const f53 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : d => d : b; +const f54 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return a ? async() : b; }) : d => d; +const f55 = a ? a ? async() : d => d : a ? async() : d => d; +const f56 = a ? a ? a ? async() : d => d : b : b; +const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +const f58 = a ? d => d = () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : (d => d = 0); +//// [b.js] +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +const f59 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return 0; }) : ; +const f60 = a ? () => __awaiter(void 0, void 0, void 0, function* () { }) : d => d; +const f61 = a ? (c) => { } : d => d; +const f62 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(a ? b : ); }) : ; +//// [c.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +let d; +const f63 = a ? d = (d) : T => a ? 0 : (...c) => __awaiter(void 0, void 0, void 0, function* () { return b; }); +const f64 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return () => __awaiter(void 0, void 0, void 0, function* () { return (d) => b; }); }) : a ? d => (d) : T => (...c) => __awaiter(void 0, void 0, void 0, function* () { return b; }); +const f65 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return (d) => async(); }) : b; +const f66 = (a ? () => __awaiter(void 0, void 0, void 0, function* () { return (d) => async(); }) : b); +const f67 = a ? d = (d) : T => a ? 0 : (...c) => __awaiter(void 0, void 0, void 0, function* () { return a ? d = (d) : T => a ? 0 : (...c) => __awaiter(void 0, void 0, void 0, function* () { return b; }); }); +const f68 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (c = a ? async() : d => d) { return async(); }) : b; +const f69 = a ? a ? (d) => a ? async() : b : d => d : b; +const f70 = a ? async() : (d => d); +const f71 = a ? async() : d => (a ? async() : d => d); +const f72 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { return (x); }) : T => async() : x => x; +const f73 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { return (x); }) : T => async() : x => x; +const f74 = a ? async(x) : T => () => __awaiter(void 0, void 0, void 0, function* () { return b; }); +const f75 = a ? async(x) : T => () => __awaiter(void 0, void 0, void 0, function* () { return x; }); +export {}; diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols index af1a8029efbb7..d0e113043f0c1 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols @@ -1,314 +1,729 @@ //// [tests/cases/compiler/parenthesizedAsyncArrowFunction.ts] //// -=== parenthesizedAsyncArrowFunction.ts === +=== a.ts === // Repro from #20096 let foo = (async bar => bar); ->foo : Symbol(foo, Decl(parenthesizedAsyncArrowFunction.ts, 2, 3)) ->bar : Symbol(bar, Decl(parenthesizedAsyncArrowFunction.ts, 2, 16)) ->bar : Symbol(bar, Decl(parenthesizedAsyncArrowFunction.ts, 2, 16)) +>foo : Symbol(foo, Decl(a.ts, 2, 3)) +>bar : Symbol(bar, Decl(a.ts, 2, 16)) +>bar : Symbol(bar, Decl(a.ts, 2, 16)) const a = true; ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) const b = 1; ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) const c = [b]; ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>c : Symbol(c, Decl(a.ts, 6, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) -function async(...c: number[]): number { ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 8, 15)) +function async(...c: number[]): number { +>async : Symbol(async, Decl(a.ts, 6, 14)) +>V : Symbol(V, Decl(a.ts, 8, 15)) +>c : Symbol(c, Decl(a.ts, 8, 18)) return b; ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) } const f1 = a ? async() : 0; ->f1 : Symbol(f1, Decl(parenthesizedAsyncArrowFunction.ts, 12, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>f1 : Symbol(f1, Decl(a.ts, 12, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) const f2 = a ? async() : x => x; ->f2 : Symbol(f2, Decl(parenthesizedAsyncArrowFunction.ts, 13, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 13, 24)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 13, 24)) +>f2 : Symbol(f2, Decl(a.ts, 13, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 13, 24)) +>x : Symbol(x, Decl(a.ts, 13, 24)) const f3 = a ? a ? async() : 0 : b; ->f3 : Symbol(f3, Decl(parenthesizedAsyncArrowFunction.ts, 14, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>f3 : Symbol(f3, Decl(a.ts, 14, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>b : Symbol(b, Decl(a.ts, 5, 5)) const f4 = a ? x => async() : x => x; ->f4 : Symbol(f4, Decl(parenthesizedAsyncArrowFunction.ts, 15, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 15, 14)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 15, 29)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 15, 29)) +>f4 : Symbol(f4, Decl(a.ts, 15, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>x : Symbol(x, Decl(a.ts, 15, 14)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 15, 29)) +>x : Symbol(x, Decl(a.ts, 15, 29)) const f5 = a ? async (): Promise => b : () => b; ->f5 : Symbol(f5, Decl(parenthesizedAsyncArrowFunction.ts, 16, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>f5 : Symbol(f5, Decl(a.ts, 16, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) const f6 = a ? async (): Promise => { return b; } : () => b; ->f6 : Symbol(f6, Decl(parenthesizedAsyncArrowFunction.ts, 17, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>f6 : Symbol(f6, Decl(a.ts, 17, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) const f7 = a ? async (): Promise => a ? async() : 0 : () => b; ->f7 : Symbol(f7, Decl(parenthesizedAsyncArrowFunction.ts, 18, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>f7 : Symbol(f7, Decl(a.ts, 18, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>b : Symbol(b, Decl(a.ts, 5, 5)) const f8 = a ? (): number => b : () => b; ->f8 : Symbol(f8, Decl(parenthesizedAsyncArrowFunction.ts, 19, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>f8 : Symbol(f8, Decl(a.ts, 19, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) const f9 = a ? async(...c) : 0; ->f9 : Symbol(f9, Decl(parenthesizedAsyncArrowFunction.ts, 21, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) +>f9 : Symbol(f9, Decl(a.ts, 21, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>c : Symbol(c, Decl(a.ts, 6, 5)) const f10 = a ? async(...c) : x => x; ->f10 : Symbol(f10, Decl(parenthesizedAsyncArrowFunction.ts, 22, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 22, 29)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 22, 29)) +>f10 : Symbol(f10, Decl(a.ts, 22, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>c : Symbol(c, Decl(a.ts, 6, 5)) +>x : Symbol(x, Decl(a.ts, 22, 29)) +>x : Symbol(x, Decl(a.ts, 22, 29)) const f11 = a ? async (...c: number[]): Promise => c.length : () => 0; ->f11 : Symbol(f11, Decl(parenthesizedAsyncArrowFunction.ts, 23, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 23, 23)) +>f11 : Symbol(f11, Decl(a.ts, 23, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>c : Symbol(c, Decl(a.ts, 23, 23)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >c.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 23, 23)) +>c : Symbol(c, Decl(a.ts, 23, 23)) >length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) const f12 = a ? async() : x => async (...c): Promise => c.length; ->f12 : Symbol(f12, Decl(parenthesizedAsyncArrowFunction.ts, 24, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 24, 25)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 24, 38)) +>f12 : Symbol(f12, Decl(a.ts, 24, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 24, 25)) +>c : Symbol(c, Decl(a.ts, 24, 38)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >c.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 24, 38)) +>c : Symbol(c, Decl(a.ts, 24, 38)) >length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) type T = Promise; ->T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 24, 73)) +>T : Symbol(T, Decl(a.ts, 24, 73)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) const f13 = a ? async() : x => async (): Promise => b; ->f13 : Symbol(f13, Decl(parenthesizedAsyncArrowFunction.ts, 27, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 27, 25)) +>f13 : Symbol(f13, Decl(a.ts, 27, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 27, 25)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) -const f14 = a ? async() : x => async (): T => 0; ->f14 : Symbol(f14, Decl(parenthesizedAsyncArrowFunction.ts, 28, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 28, 25)) ->T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 24, 73)) +const f14 = a ? async() : T => async (): T => 0; +>f14 : Symbol(f14, Decl(a.ts, 28, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>T : Symbol(T, Decl(a.ts, 28, 40)) const f15 = a ? (b) : x => async (): T => 0; ->f15 : Symbol(f15, Decl(parenthesizedAsyncArrowFunction.ts, 29, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 29, 21)) ->T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 24, 73)) - -const f16 = a ? async(...c) : x => async (): T => 0; ->f16 : Symbol(f16, Decl(parenthesizedAsyncArrowFunction.ts, 30, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 30, 29)) ->T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 24, 73)) - -const f17 = a ? async() : x => (y): number => y; ->f17 : Symbol(f17, Decl(parenthesizedAsyncArrowFunction.ts, 31, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 31, 25)) ->y : Symbol(y, Decl(parenthesizedAsyncArrowFunction.ts, 31, 32)) ->y : Symbol(y, Decl(parenthesizedAsyncArrowFunction.ts, 31, 32)) - -const f18 = a ? async() : x => async (): T => 0; ->f18 : Symbol(f18, Decl(parenthesizedAsyncArrowFunction.ts, 32, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 32, 25)) ->U : Symbol(U, Decl(parenthesizedAsyncArrowFunction.ts, 32, 38)) ->T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 24, 73)) - -const f19 = a ? async(...c) : x => (y): number => y; ->f19 : Symbol(f19, Decl(parenthesizedAsyncArrowFunction.ts, 33, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 33, 29)) ->y : Symbol(y, Decl(parenthesizedAsyncArrowFunction.ts, 33, 36)) ->y : Symbol(y, Decl(parenthesizedAsyncArrowFunction.ts, 33, 36)) - -const f20 = a ? async(...c) : x => async (): T => 0; ->f20 : Symbol(f20, Decl(parenthesizedAsyncArrowFunction.ts, 34, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 34, 29)) ->U : Symbol(U, Decl(parenthesizedAsyncArrowFunction.ts, 34, 42)) ->T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 24, 73)) +>f15 : Symbol(f15, Decl(a.ts, 29, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>x : Symbol(x, Decl(a.ts, 29, 21)) +>T : Symbol(T, Decl(a.ts, 24, 73)) + +const f16 = a ? async(...c) : T => async (): T => 0; +>f16 : Symbol(f16, Decl(a.ts, 30, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>c : Symbol(c, Decl(a.ts, 30, 22)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>T : Symbol(T, Decl(a.ts, 30, 44)) + +const f17 = a ? async() : T => (b): number => b; +>f17 : Symbol(f17, Decl(a.ts, 31, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>number : Symbol(number, Decl(a.ts, 31, 35)) +>b : Symbol(b, Decl(a.ts, 5, 5)) + +const f18 = a ? async() : T => async (): T => 0; +>f18 : Symbol(f18, Decl(a.ts, 32, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>U : Symbol(U, Decl(a.ts, 62, 26)) +>T : Symbol(T, Decl(a.ts, 32, 43)) + +const f19 = a ? async(...c) : T => (b): number => b; +>f19 : Symbol(f19, Decl(a.ts, 33, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>c : Symbol(c, Decl(a.ts, 33, 22)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>number : Symbol(number, Decl(a.ts, 33, 39)) +>b : Symbol(b, Decl(a.ts, 5, 5)) + +const f20 = a ? async(...c) : T => async (): T => 0; +>f20 : Symbol(f20, Decl(a.ts, 34, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>c : Symbol(c, Decl(a.ts, 34, 22)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>U : Symbol(U, Decl(a.ts, 62, 26)) +>T : Symbol(T, Decl(a.ts, 34, 47)) const f21 = a ? (x): number => (b): T => 0; ->f21 : Symbol(f21, Decl(parenthesizedAsyncArrowFunction.ts, 35, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 35, 17)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) ->T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 35, 35)) +>f21 : Symbol(f21, Decl(a.ts, 35, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>x : Symbol(x, Decl(a.ts, 35, 17)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>T : Symbol(T, Decl(a.ts, 35, 35)) const f22 = a ? async (): Promise => (b): T => 0; ->f22 : Symbol(f22, Decl(parenthesizedAsyncArrowFunction.ts, 36, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->U : Symbol(U, Decl(parenthesizedAsyncArrowFunction.ts, 36, 23)) +>f22 : Symbol(f22, Decl(a.ts, 36, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>U : Symbol(U, Decl(a.ts, 36, 23)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->b : Symbol(b, Decl(parenthesizedAsyncArrowFunction.ts, 5, 5)) ->T : Symbol(T, Decl(parenthesizedAsyncArrowFunction.ts, 36, 52)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>T : Symbol(T, Decl(a.ts, 36, 52)) const f23 = a ? async () => async() : x => x; ->f23 : Symbol(f23, Decl(parenthesizedAsyncArrowFunction.ts, 37, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 37, 37)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 37, 37)) +>f23 : Symbol(f23, Decl(a.ts, 37, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 37, 37)) +>x : Symbol(x, Decl(a.ts, 37, 37)) const f24 = a ? async (...c) => async() : x => x; ->f24 : Symbol(f24, Decl(parenthesizedAsyncArrowFunction.ts, 38, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 38, 23)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 38, 41)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 38, 41)) +>f24 : Symbol(f24, Decl(a.ts, 38, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>c : Symbol(c, Decl(a.ts, 38, 23)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 38, 41)) +>x : Symbol(x, Decl(a.ts, 38, 41)) const f25 = a ? () => async() : x => x; ->f25 : Symbol(f25, Decl(parenthesizedAsyncArrowFunction.ts, 39, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 39, 31)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 39, 31)) +>f25 : Symbol(f25, Decl(a.ts, 39, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 39, 31)) +>x : Symbol(x, Decl(a.ts, 39, 31)) const f26 = a ? async (c: number): Promise => async() : x => x; ->f26 : Symbol(f26, Decl(parenthesizedAsyncArrowFunction.ts, 40, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 40, 23)) +>f26 : Symbol(f26, Decl(a.ts, 40, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>c : Symbol(c, Decl(a.ts, 40, 23)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 40, 63)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 40, 63)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 40, 63)) +>x : Symbol(x, Decl(a.ts, 40, 63)) const f27 = a ? async (): Promise => async() : x => x; ->f27 : Symbol(f27, Decl(parenthesizedAsyncArrowFunction.ts, 41, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>f27 : Symbol(f27, Decl(a.ts, 41, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 41, 54)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 41, 54)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 41, 54)) +>x : Symbol(x, Decl(a.ts, 41, 54)) const f28 = a ? async (): Promise => async(...c) : x => x; ->f28 : Symbol(f28, Decl(parenthesizedAsyncArrowFunction.ts, 42, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>f28 : Symbol(f28, Decl(a.ts, 42, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 42, 58)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 42, 58)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>c : Symbol(c, Decl(a.ts, 6, 5)) +>x : Symbol(x, Decl(a.ts, 42, 58)) +>x : Symbol(x, Decl(a.ts, 42, 58)) const f29 = a ? async (...c): Promise => async() : x => x; ->f29 : Symbol(f29, Decl(parenthesizedAsyncArrowFunction.ts, 43, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 43, 23)) +>f29 : Symbol(f29, Decl(a.ts, 43, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>c : Symbol(c, Decl(a.ts, 43, 23)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 43, 58)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 43, 58)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 43, 58)) +>x : Symbol(x, Decl(a.ts, 43, 58)) const f30 = a ? async (): Promise => async() : x => x; ->f30 : Symbol(f30, Decl(parenthesizedAsyncArrowFunction.ts, 44, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->U : Symbol(U, Decl(parenthesizedAsyncArrowFunction.ts, 44, 23)) +>f30 : Symbol(f30, Decl(a.ts, 44, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>U : Symbol(U, Decl(a.ts, 44, 23)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 44, 57)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 44, 57)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 44, 57)) +>x : Symbol(x, Decl(a.ts, 44, 57)) const f31 = a ? async (): (Promise) => async() : x => x; ->f31 : Symbol(f31, Decl(parenthesizedAsyncArrowFunction.ts, 45, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) +>f31 : Symbol(f31, Decl(a.ts, 45, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 45, 56)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 45, 56)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 45, 56)) +>x : Symbol(x, Decl(a.ts, 45, 56)) const f32 = a ? async (...c: number[]): Promise => async() : x => x; ->f32 : Symbol(f32, Decl(parenthesizedAsyncArrowFunction.ts, 46, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 46, 23)) +>f32 : Symbol(f32, Decl(a.ts, 46, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>c : Symbol(c, Decl(a.ts, 46, 23)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 46, 68)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 46, 68)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>x : Symbol(x, Decl(a.ts, 46, 68)) +>x : Symbol(x, Decl(a.ts, 46, 68)) const f33 = a ? async() : 0 ->f33 : Symbol(f33, Decl(parenthesizedAsyncArrowFunction.ts, 48, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>f33 : Symbol(f33, Decl(a.ts, 48, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) {} const f34 = a ? async() : {} ->f34 : Symbol(f34, Decl(parenthesizedAsyncArrowFunction.ts, 50, 5)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) +>f34 : Symbol(f34, Decl(a.ts, 50, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) {} function* g() { ->g : Symbol(g, Decl(parenthesizedAsyncArrowFunction.ts, 51, 2)) +>g : Symbol(g, Decl(a.ts, 51, 2)) const f1 = a ? yield async(...c) : 0; ->f1 : Symbol(f1, Decl(parenthesizedAsyncArrowFunction.ts, 54, 9)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) +>f1 : Symbol(f1, Decl(a.ts, 54, 9)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>c : Symbol(c, Decl(a.ts, 6, 5)) const f2 = a ? yield async(...c) : x => x; ->f2 : Symbol(f2, Decl(parenthesizedAsyncArrowFunction.ts, 55, 9)) ->a : Symbol(a, Decl(parenthesizedAsyncArrowFunction.ts, 4, 5)) ->async : Symbol(async, Decl(parenthesizedAsyncArrowFunction.ts, 6, 14)) ->c : Symbol(c, Decl(parenthesizedAsyncArrowFunction.ts, 6, 5)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 55, 38)) ->x : Symbol(x, Decl(parenthesizedAsyncArrowFunction.ts, 55, 38)) +>f2 : Symbol(f2, Decl(a.ts, 55, 9)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>c : Symbol(c, Decl(a.ts, 6, 5)) +>x : Symbol(x, Decl(a.ts, 55, 38)) +>x : Symbol(x, Decl(a.ts, 55, 38)) } +const d = { a: c }; +>d : Symbol(d, Decl(a.ts, 58, 5)) +>a : Symbol(a, Decl(a.ts, 58, 11)) +>c : Symbol(c, Decl(a.ts, 6, 5)) + +const e = () => c; +>e : Symbol(e, Decl(a.ts, 59, 5)) +>c : Symbol(c, Decl(a.ts, 6, 5)) + +const f35 = async(...d.a); +>f35 : Symbol(f35, Decl(a.ts, 60, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>d.a : Symbol(a, Decl(a.ts, 58, 11)) +>d : Symbol(d, Decl(a.ts, 58, 5)) +>a : Symbol(a, Decl(a.ts, 58, 11)) + +const f36 = async(...e()); +>f36 : Symbol(f36, Decl(a.ts, 61, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>e : Symbol(e, Decl(a.ts, 59, 5)) + +const f37 = async(...[b]); +>f37 : Symbol(f37, Decl(a.ts, 62, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>b : Symbol(b, Decl(a.ts, 5, 5)) + +type U = number; +>U : Symbol(U, Decl(a.ts, 62, 26)) + +const f38 = a ? (c): U => (b) : x => x; +>f38 : Symbol(f38, Decl(a.ts, 65, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>c : Symbol(c, Decl(a.ts, 65, 17)) +>U : Symbol(U, Decl(a.ts, 62, 26)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>x : Symbol(x, Decl(a.ts, 65, 31)) +>x : Symbol(x, Decl(a.ts, 65, 31)) + +const f39 = a ? async() : function() {}; +>f39 : Symbol(f39, Decl(a.ts, 66, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) + +const f40 = a ? async() : "b" +>f40 : Symbol(f40, Decl(a.ts, 67, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) + +{} +const f41 = a ? async(...c) : 0 +>f41 : Symbol(f41, Decl(a.ts, 69, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>c : Symbol(c, Decl(a.ts, 6, 5)) + +{} +const f42 = a ? (c) : 0 +>f42 : Symbol(f42, Decl(a.ts, 71, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>c : Symbol(c, Decl(a.ts, 6, 5)) + +{} +const f43 = a ? async() : 0; +>f43 : Symbol(f43, Decl(a.ts, 73, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) + +{} + +const f44 = a ? async() : T => async (...c): T => c.length; +>f44 : Symbol(f44, Decl(a.ts, 76, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>c : Symbol(c, Decl(a.ts, 6, 5)) +>T : Symbol(T, Decl(a.ts, 76, 44)) +>c.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) +>c : Symbol(c, Decl(a.ts, 6, 5)) +>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) + +const f45 = a ? async (): T => (b) : d => d; +>f45 : Symbol(f45, Decl(a.ts, 78, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>d : Symbol(d, Decl(a.ts, 78, 36)) +>d : Symbol(d, Decl(a.ts, 78, 36)) + +const f46 = a ? async (): T => async() : d => d; +>f46 : Symbol(f46, Decl(a.ts, 79, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>d : Symbol(d, Decl(a.ts, 79, 40)) +>d : Symbol(d, Decl(a.ts, 79, 40)) + +const f47 = a ? async (): T => async() : b; +>f47 : Symbol(f47, Decl(a.ts, 80, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>b : Symbol(b, Decl(a.ts, 5, 5)) + +const f48 = a ? a ? async() : d => d : b; +>f48 : Symbol(f48, Decl(a.ts, 81, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>d : Symbol(d, Decl(a.ts, 81, 29)) +>d : Symbol(d, Decl(a.ts, 81, 29)) +>b : Symbol(b, Decl(a.ts, 5, 5)) + +const f49 = a ? a ? async(b) : d => d : b; +>f49 : Symbol(f49, Decl(a.ts, 82, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>d : Symbol(d, Decl(a.ts, 82, 30)) +>d : Symbol(d, Decl(a.ts, 82, 30)) +>b : Symbol(b, Decl(a.ts, 5, 5)) + +const f50 = a ? a ? async(...c) : d => d : b; +>f50 : Symbol(f50, Decl(a.ts, 83, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>c : Symbol(c, Decl(a.ts, 6, 5)) +>d : Symbol(d, Decl(a.ts, 83, 33)) +>d : Symbol(d, Decl(a.ts, 83, 33)) +>b : Symbol(b, Decl(a.ts, 5, 5)) + +const f51 = a ? a ? async() : T => b : async (): T => b; +>f51 : Symbol(f51, Decl(a.ts, 84, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>T : Symbol(T, Decl(a.ts, 84, 48)) +>b : Symbol(b, Decl(a.ts, 5, 5)) + +const f52 = a ? async (): T => async() : (d): number => d; +>f52 : Symbol(f52, Decl(a.ts, 85, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>d : Symbol(d, Decl(a.ts, 85, 42)) +>d : Symbol(d, Decl(a.ts, 85, 42)) + +const f53 = a ? a ? async (): T => async() : d => d : b; +>f53 : Symbol(f53, Decl(a.ts, 86, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>d : Symbol(d, Decl(a.ts, 86, 44)) +>d : Symbol(d, Decl(a.ts, 86, 44)) +>b : Symbol(b, Decl(a.ts, 5, 5)) + +const f54 = a ? async (): T => a ? async() : b : d => d; +>f54 : Symbol(f54, Decl(a.ts, 87, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>d : Symbol(d, Decl(a.ts, 87, 48)) +>d : Symbol(d, Decl(a.ts, 87, 48)) + +const f55 = a ? a ? async() : d => d : a ? async() : d => d; +>f55 : Symbol(f55, Decl(a.ts, 88, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>d : Symbol(d, Decl(a.ts, 88, 29)) +>d : Symbol(d, Decl(a.ts, 88, 29)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>d : Symbol(d, Decl(a.ts, 88, 52)) +>d : Symbol(d, Decl(a.ts, 88, 52)) + +const f56 = a ? a ? a ? async() : d => d : b : b; +>f56 : Symbol(f56, Decl(a.ts, 89, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>d : Symbol(d, Decl(a.ts, 89, 33)) +>d : Symbol(d, Decl(a.ts, 89, 33)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) + +const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +>f57 : Symbol(f57, Decl(a.ts, 91, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>d : Symbol(d, Decl(a.ts, 91, 15)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>b : Symbol(b, Decl(a.ts, 5, 5)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>d : Symbol(d, Decl(a.ts, 91, 57)) +>d : Symbol(d, Decl(a.ts, 91, 57)) +>a : Symbol(a, Decl(a.ts, 4, 5)) + +const f58 = a ? d => d = async () => async() : (d => d = 0); +>f58 : Symbol(f58, Decl(a.ts, 92, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>d : Symbol(d, Decl(a.ts, 92, 15)) +>d : Symbol(d, Decl(a.ts, 92, 15)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>d : Symbol(d, Decl(a.ts, 92, 48)) +>d : Symbol(d, Decl(a.ts, 92, 48)) + +=== b.ts === +const f59 = a ? async(...c: number[]): Promise => 0; +>f59 : Symbol(f59, Decl(b.ts, 0, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>c : Symbol(c, Decl(b.ts, 0, 22)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +const f60 = a ? async (): Promise {} : d => d; +>f60 : Symbol(f60, Decl(b.ts, 1, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>d : Symbol(d, Decl(b.ts, 1, 46)) +>d : Symbol(d, Decl(b.ts, 1, 46)) + +const f61 = a ? (c): number {} : d => d; +>f61 : Symbol(f61, Decl(b.ts, 2, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>c : Symbol(c, Decl(b.ts, 2, 17)) +>d : Symbol(d, Decl(b.ts, 2, 32)) +>d : Symbol(d, Decl(b.ts, 2, 32)) + +const f62 = a ? async() : T => async(a ? b); +>f62 : Symbol(f62, Decl(b.ts, 4, 5)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>T : Symbol(T, Decl(a.ts, 24, 73)) +>async : Symbol(async, Decl(a.ts, 6, 14)) +>a : Symbol(a, Decl(a.ts, 4, 5)) +>b : Symbol(b, Decl(a.ts, 5, 5)) + +=== c.ts === +export {}; +declare const a: any, b: any, c: any[]; +>a : Symbol(a, Decl(c.ts, 1, 13)) +>b : Symbol(b, Decl(c.ts, 1, 21)) +>c : Symbol(c, Decl(c.ts, 1, 29)) + +declare function async(...a: any[]): any; +>async : Symbol(async, Decl(c.ts, 1, 39)) +>a : Symbol(a, Decl(c.ts, 2, 23)) + +type T = Promise; +>T : Symbol(T, Decl(c.ts, 2, 41)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +let d: any; +>d : Symbol(d, Decl(c.ts, 4, 3)) + +const f63 = a ? d = (d): T => a ? 0 : async(...c) : T => b; +>f63 : Symbol(f63, Decl(c.ts, 5, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>d : Symbol(d, Decl(c.ts, 4, 3)) +>d : Symbol(d, Decl(c.ts, 4, 3)) +>T : Symbol(T, Decl(c.ts, 5, 24)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>c : Symbol(c, Decl(c.ts, 5, 44)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>b : Symbol(b, Decl(c.ts, 1, 21)) + +const f64 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; +>f64 : Symbol(f64, Decl(c.ts, 6, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>d : Symbol(d, Decl(c.ts, 6, 47)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>b : Symbol(b, Decl(c.ts, 1, 21)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>d : Symbol(d, Decl(c.ts, 6, 63)) +>d : Symbol(d, Decl(c.ts, 6, 63)) +>T : Symbol(T, Decl(c.ts, 6, 73)) +>c : Symbol(c, Decl(c.ts, 6, 85)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>b : Symbol(b, Decl(c.ts, 1, 21)) + +const f65 = a ? async (): T => (d): T => async() : b; +>f65 : Symbol(f65, Decl(c.ts, 7, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>d : Symbol(d, Decl(c.ts, 7, 32)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>async : Symbol(async, Decl(c.ts, 1, 39)) +>b : Symbol(b, Decl(c.ts, 1, 21)) + +const f66 = (a ? async (): T => (d): T => async() : b); +>f66 : Symbol(f66, Decl(c.ts, 8, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>d : Symbol(d, Decl(c.ts, 8, 33)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>async : Symbol(async, Decl(c.ts, 1, 39)) +>b : Symbol(b, Decl(c.ts, 1, 21)) + +const f67 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; +>f67 : Symbol(f67, Decl(c.ts, 9, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>d : Symbol(d, Decl(c.ts, 4, 3)) +>d : Symbol(d, Decl(c.ts, 4, 3)) +>T : Symbol(T, Decl(c.ts, 9, 24)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>c : Symbol(c, Decl(c.ts, 9, 44)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>d : Symbol(d, Decl(c.ts, 4, 3)) +>d : Symbol(d, Decl(c.ts, 4, 3)) +>T : Symbol(T, Decl(c.ts, 9, 69)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>c : Symbol(c, Decl(c.ts, 9, 89)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>b : Symbol(b, Decl(c.ts, 1, 21)) + +const f68 = a ? async (c = a ? async() : d => d): T => async() : b; +>f68 : Symbol(f68, Decl(c.ts, 10, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>c : Symbol(c, Decl(c.ts, 10, 23)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>async : Symbol(async, Decl(c.ts, 1, 39)) +>d : Symbol(d, Decl(c.ts, 10, 40)) +>d : Symbol(d, Decl(c.ts, 10, 40)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>async : Symbol(async, Decl(c.ts, 1, 39)) +>b : Symbol(b, Decl(c.ts, 1, 21)) + +const f69 = a ? a ? (d): T => a ? async() : b : d => d : b; +>f69 : Symbol(f69, Decl(c.ts, 11, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>d : Symbol(d, Decl(c.ts, 11, 21)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>async : Symbol(async, Decl(c.ts, 1, 39)) +>b : Symbol(b, Decl(c.ts, 1, 21)) +>d : Symbol(d, Decl(c.ts, 11, 47)) +>d : Symbol(d, Decl(c.ts, 11, 47)) +>b : Symbol(b, Decl(c.ts, 1, 21)) + +const f70 = a ? async() : (d => d); +>f70 : Symbol(f70, Decl(c.ts, 12, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>async : Symbol(async, Decl(c.ts, 1, 39)) +>d : Symbol(d, Decl(c.ts, 12, 27)) +>d : Symbol(d, Decl(c.ts, 12, 27)) + +const f71 = a ? async() : d => (a ? async() : d => d); +>f71 : Symbol(f71, Decl(c.ts, 13, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>async : Symbol(async, Decl(c.ts, 1, 39)) +>d : Symbol(d, Decl(c.ts, 13, 25)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>async : Symbol(async, Decl(c.ts, 1, 39)) +>d : Symbol(d, Decl(c.ts, 13, 45)) +>d : Symbol(d, Decl(c.ts, 13, 45)) + +type x = T; +>x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) +>T : Symbol(T, Decl(c.ts, 2, 41)) + +declare const x: any; +>x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) + +const f72 = a ? a ? async (): T => (x): T => async() : x => x; +>f72 : Symbol(f72, Decl(c.ts, 17, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) +>T : Symbol(T, Decl(c.ts, 17, 39)) +>async : Symbol(async, Decl(c.ts, 1, 39)) +>x : Symbol(x, Decl(c.ts, 17, 54)) +>x : Symbol(x, Decl(c.ts, 17, 54)) + +const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; +>f73 : Symbol(f73, Decl(c.ts, 18, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) +>T : Symbol(T, Decl(c.ts, 18, 50)) +>async : Symbol(async, Decl(c.ts, 1, 39)) +>x : Symbol(x, Decl(c.ts, 18, 65)) +>x : Symbol(x, Decl(c.ts, 18, 65)) + +const f74 = a ? async (x): T => async (): T => b; +>f74 : Symbol(f74, Decl(c.ts, 19, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>async : Symbol(async, Decl(c.ts, 1, 39)) +>x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) +>T : Symbol(T, Decl(c.ts, 19, 26)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>b : Symbol(b, Decl(c.ts, 1, 21)) + +const f75 = a ? async (x): T => async() : x => x; +>f75 : Symbol(f75, Decl(c.ts, 20, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>async : Symbol(async, Decl(c.ts, 1, 39)) +>x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) +>T : Symbol(T, Decl(c.ts, 20, 26)) +>x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) +>x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) + diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types index cc7bbfa28ca22..71cd9e4e313af 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types @@ -1,6 +1,6 @@ //// [tests/cases/compiler/parenthesizedAsyncArrowFunction.ts] //// -=== parenthesizedAsyncArrowFunction.ts === +=== a.ts === // Repro from #20096 let foo = (async bar => bar); @@ -23,8 +23,8 @@ const c = [b]; >[b] : number[] >b : 1 -function async(...c: number[]): number { ->async : (...c: number[]) => number +function async(...c: number[]): number { +>async : (...c: number[]) => number >c : number[] return b; @@ -36,7 +36,7 @@ const f1 = a ? async() : 0; >a ? async() : 0 : number >a : true >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >0 : 0 const f2 = a ? async() : x => x; @@ -44,7 +44,7 @@ const f2 = a ? async() : x => x; >a ? async() : x => x : number | ((x: any) => any) >a : true >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => x : (x: any) => any >x : any >x : any @@ -56,7 +56,7 @@ const f3 = a ? a ? async() : 0 : b; >a ? async() : 0 : number >a : true >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >0 : 0 >b : 1 @@ -67,7 +67,7 @@ const f4 = a ? x => async() : x => x; >x => async() : (x: any) => number >x : any >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => x : (x: any) => any >x : any >x : any @@ -98,7 +98,7 @@ const f7 = a ? async (): Promise => a ? async() : 0 : () => b; >a ? async() : 0 : number >a : true >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >0 : 0 >() => b : () => number >b : 1 @@ -117,7 +117,7 @@ const f9 = a ? async(...c) : 0; >a ? async(...c) : 0 : number >a : true >async(...c) : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >...c : number >c : number[] >0 : 0 @@ -127,7 +127,7 @@ const f10 = a ? async(...c) : x => x; >a ? async(...c) : x => x : number | ((x: any) => any) >a : true >async(...c) : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >...c : number >c : number[] >x => x : (x: any) => any @@ -151,7 +151,7 @@ const f12 = a ? async() : x => async (...c): Promise => c.length; >a ? async() : x => async (...c): Promise => c.length : number | ((x: any) => (...c: any[]) => Promise) >a : true >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => async (...c): Promise => c.length : (x: any) => (...c: any[]) => Promise >x : any >async (...c): Promise => c.length : (...c: any[]) => Promise @@ -168,21 +168,21 @@ const f13 = a ? async() : x => async (): Promise => b; >a ? async() : x => async (): Promise => b : number | ((x: any) => () => Promise) >a : true >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => async (): Promise => b : (x: any) => () => Promise >x : any >async (): Promise => b : () => Promise >b : 1 -const f14 = a ? async() : x => async (): T => 0; ->f14 : number | ((x: any) => () => T) ->a ? async() : x => async (): T => 0 : number | ((x: any) => () => T) +const f14 = a ? async() : T => async (): T => 0; +>f14 : (() => T) | ((T: any) => number) +>a ? async() : T => async (): T => 0 : (() => T) | ((T: any) => number) >a : true ->async() : number ->async : (...c: number[]) => number ->x => async (): T => 0 : (x: any) => () => T ->x : any ->async (): T => 0 : () => T +>async() : T => async () : () => T +>async () : number +>async : (...c: number[]) => number +>T => 0 : (T: any) => number +>T : any >0 : 0 const f15 = a ? (b) : x => async (): T => 0; @@ -196,67 +196,62 @@ const f15 = a ? (b) : x => async (): T => 0; >async (): T => 0 : () => T >0 : 0 -const f16 = a ? async(...c) : x => async (): T => 0; ->f16 : number | ((x: any) => () => T) ->a ? async(...c) : x => async (): T => 0 : number | ((x: any) => () => T) +const f16 = a ? async(...c) : T => async (): T => 0; +>f16 : ((...c: any[]) => T) | ((T: any) => number) +>a ? async(...c) : T => async (): T => 0 : ((...c: any[]) => T) | ((T: any) => number) >a : true ->async(...c) : number ->async : (...c: number[]) => number ->...c : number ->c : number[] ->x => async (): T => 0 : (x: any) => () => T ->x : any ->async (): T => 0 : () => T +>async(...c) : T => async () : (...c: any[]) => T +>c : any[] +>async () : number +>async : (...c: number[]) => number +>T => 0 : (T: any) => number +>T : any >0 : 0 -const f17 = a ? async() : x => (y): number => y; ->f17 : number | ((x: any) => (y: any) => number) ->a ? async() : x => (y): number => y : number | ((x: any) => (y: any) => number) +const f17 = a ? async() : T => (b): number => b; +>f17 : (() => T) | ((number: any) => number) +>a ? async() : T => (b): number => b : (() => T) | ((number: any) => number) >a : true ->async() : number ->async : (...c: number[]) => number ->x => (y): number => y : (x: any) => (y: any) => number ->x : any ->(y): number => y : (y: any) => number ->y : any ->y : any +>async() : T => (b) : () => T +>(b) : 1 +>b : 1 +>number => b : (number: any) => number +>number : any +>b : 1 -const f18 = a ? async() : x => async (): T => 0; ->f18 : number | ((x: any) => () => T) ->a ? async() : x => async (): T => 0 : number | ((x: any) => () => T) +const f18 = a ? async() : T => async (): T => 0; +>f18 : (() => T) | ((T: any) => number) +>a ? async() : T => async (): T => 0 : (() => T) | ((T: any) => number) >a : true ->async() : number ->async : (...c: number[]) => number ->x => async (): T => 0 : (x: any) => () => T ->x : any ->async (): T => 0 : () => T +>async() : T => async () : () => T +>async () : number +>async : (...c: number[]) => number +>T => 0 : (T: any) => number +>T : any >0 : 0 -const f19 = a ? async(...c) : x => (y): number => y; ->f19 : number | ((x: any) => (y: any) => number) ->a ? async(...c) : x => (y): number => y : number | ((x: any) => (y: any) => number) +const f19 = a ? async(...c) : T => (b): number => b; +>f19 : ((...c: any[]) => T) | ((number: any) => number) +>a ? async(...c) : T => (b): number => b : ((...c: any[]) => T) | ((number: any) => number) >a : true ->async(...c) : number ->async : (...c: number[]) => number ->...c : number ->c : number[] ->x => (y): number => y : (x: any) => (y: any) => number ->x : any ->(y): number => y : (y: any) => number ->y : any ->y : any +>async(...c) : T => (b) : (...c: any[]) => T +>c : any[] +>(b) : 1 +>b : 1 +>number => b : (number: any) => number +>number : any +>b : 1 -const f20 = a ? async(...c) : x => async (): T => 0; ->f20 : number | ((x: any) => () => T) ->a ? async(...c) : x => async (): T => 0 : number | ((x: any) => () => T) +const f20 = a ? async(...c) : T => async (): T => 0; +>f20 : ((...c: any[]) => T) | ((T: any) => number) +>a ? async(...c) : T => async (): T => 0 : ((...c: any[]) => T) | ((T: any) => number) >a : true ->async(...c) : number ->async : (...c: number[]) => number ->...c : number ->c : number[] ->x => async (): T => 0 : (x: any) => () => T ->x : any ->async (): T => 0 : () => T +>async(...c) : T => async () : (...c: any[]) => T +>c : any[] +>async () : number +>async : (...c: number[]) => number +>T => 0 : (T: any) => number +>T : any >0 : 0 const f21 = a ? (x): number => (b): T => 0; @@ -288,7 +283,7 @@ const f23 = a ? async () => async() : x => x; >a : true >async () => async() : () => Promise >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => x : (x: any) => any >x : any >x : any @@ -300,7 +295,7 @@ const f24 = a ? async (...c) => async() : x => x; >async (...c) => async() : (...c: any[]) => Promise >c : any[] >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => x : (x: any) => any >x : any >x : any @@ -311,7 +306,7 @@ const f25 = a ? () => async() : x => x; >a : true >() => async() : () => number >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => x : (x: any) => any >x : any >x : any @@ -323,7 +318,7 @@ const f26 = a ? async (c: number): Promise => async() : x => x; >async (c: number): Promise => async() : (c: number) => Promise >c : number >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => x : (x: any) => any >x : any >x : any @@ -334,7 +329,7 @@ const f27 = a ? async (): Promise => async() : x => x; >a : true >async (): Promise => async() : () => Promise >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => x : (x: any) => any >x : any >x : any @@ -345,7 +340,7 @@ const f28 = a ? async (): Promise => async(...c) : x => x; >a : true >async (): Promise => async(...c) : () => Promise >async(...c) : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >...c : number >c : number[] >x => x : (x: any) => any @@ -359,7 +354,7 @@ const f29 = a ? async (...c): Promise => async() : x => x; >async (...c): Promise => async() : (...c: any[]) => Promise >c : any[] >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => x : (x: any) => any >x : any >x : any @@ -370,7 +365,7 @@ const f30 = a ? async (): Promise => async() : x => x; >a : true >async (): Promise => async() : () => Promise >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => x : (x: any) => any >x : any >x : any @@ -381,7 +376,7 @@ const f31 = a ? async (): (Promise) => async() : x => x; >a : true >async (): (Promise) => async() : () => (Promise) >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => x : (x: any) => any >x : any >x : any @@ -393,7 +388,7 @@ const f32 = a ? async (...c: number[]): Promise => async() : x => x; >async (...c: number[]): Promise => async() : (...c: number[]) => Promise >c : number[] >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >x => x : (x: any) => any >x : any >x : any @@ -403,7 +398,7 @@ const f33 = a ? async() : 0 >a ? async() : 0 : number >a : true >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >0 : 0 {} @@ -412,7 +407,7 @@ const f34 = a ? async() : {} >a ? async() : {} : number | {} >a : true >async() : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >{} : {} {} @@ -426,7 +421,7 @@ function* g() { >a : true >yield async(...c) : any >async(...c) : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >...c : number >c : number[] >0 : 0 @@ -437,7 +432,7 @@ function* g() { >a : true >yield async(...c) : any >async(...c) : number ->async : (...c: number[]) => number +>async : (...c: number[]) => number >...c : number >c : number[] >x => x : (x: any) => any @@ -445,3 +440,596 @@ function* g() { >x : any } +const d = { a: c }; +>d : { a: number[]; } +>{ a: c } : { a: number[]; } +>a : number[] +>c : number[] + +const e = () => c; +>e : () => number[] +>() => c : () => number[] +>c : number[] + +const f35 = async(...d.a); +>f35 : number +>async(...d.a) : number +>async : (...c: number[]) => number +>...d.a : number +>d.a : number[] +>d : { a: number[]; } +>a : number[] + +const f36 = async(...e()); +>f36 : number +>async(...e()) : number +>async : (...c: number[]) => number +>...e() : number +>e() : number[] +>e : () => number[] + +const f37 = async(...[b]); +>f37 : number +>async(...[b]) : number +>async : (...c: number[]) => number +>...[b] : number +>[b] : [number] +>b : 1 + +type U = number; +>U : number + +const f38 = a ? (c): U => (b) : x => x; +>f38 : (x: any) => any +>a ? (c): U => (b) : x => x : (x: any) => any +>a : true +>(c): U => (b) : (c: any) => U +>c : any +>(b) : 1 +>b : 1 +>x => x : (x: any) => any +>x : any +>x : any + +const f39 = a ? async() : function() {}; +>f39 : number | (() => void) +>a ? async() : function() {} : number | (() => void) +>a : true +>async() : number +>async : (...c: number[]) => number +>function() {} : () => void + +const f40 = a ? async() : "b" +>f40 : number | "b" +>a ? async() : "b" : number | "b" +>a : true +>async() : number +>async : (...c: number[]) => number +>"b" : "b" + +{} +const f41 = a ? async(...c) : 0 +>f41 : number +>a ? async(...c) : 0 : number +>a : true +>async(...c) : number +>async : (...c: number[]) => number +>...c : number +>c : number[] +>0 : 0 + +{} +const f42 = a ? (c) : 0 +>f42 : 0 | number[] +>a ? (c) : 0 : 0 | number[] +>a : true +>(c) : number[] +>c : number[] +>0 : 0 + +{} +const f43 = a ? async() : 0; +>f43 : number +>a ? async() : 0 : number +>a : true +>async() : number +>async : (...c: number[]) => number +>0 : 0 + +{} + +const f44 = a ? async() : T => async (...c): T => c.length; +>f44 : (() => T) | ((T: any) => number) +>a ? async() : T => async (...c): T => c.length : (() => T) | ((T: any) => number) +>a : true +>async() : T => async (...c) : () => T +>async (...c) : number +>async : (...c: number[]) => number +>...c : number +>c : number[] +>T => c.length : (T: any) => number +>T : any +>c.length : number +>c : number[] +>length : number + +const f45 = a ? async (): T => (b) : d => d; +>f45 : (d: any) => any +>a ? async (): T => (b) : d => d : (d: any) => any +>a : true +>async (): T => (b) : () => T +>(b) : 1 +>b : 1 +>d => d : (d: any) => any +>d : any +>d : any + +const f46 = a ? async (): T => async() : d => d; +>f46 : (d: any) => any +>a ? async (): T => async() : d => d : (d: any) => any +>a : true +>async (): T => async() : () => T +>async() : number +>async : (...c: number[]) => number +>d => d : (d: any) => any +>d : any +>d : any + +const f47 = a ? async (): T => async() : b; +>f47 : 1 | (() => T) +>a ? async (): T => async() : b : 1 | (() => T) +>a : true +>async (): T => async() : () => T +>async() : number +>async : (...c: number[]) => number +>b : 1 + +const f48 = a ? a ? async() : d => d : b; +>f48 : number | ((d: any) => any) +>a ? a ? async() : d => d : b : number | ((d: any) => any) +>a : true +>a ? async() : d => d : number | ((d: any) => any) +>a : true +>async() : number +>async : (...c: number[]) => number +>d => d : (d: any) => any +>d : any +>d : any +>b : 1 + +const f49 = a ? a ? async(b) : d => d : b; +>f49 : number | ((d: any) => any) +>a ? a ? async(b) : d => d : b : number | ((d: any) => any) +>a : true +>a ? async(b) : d => d : number | ((d: any) => any) +>a : true +>async(b) : number +>async : (...c: number[]) => number +>b : 1 +>d => d : (d: any) => any +>d : any +>d : any +>b : 1 + +const f50 = a ? a ? async(...c) : d => d : b; +>f50 : number | ((d: any) => any) +>a ? a ? async(...c) : d => d : b : number | ((d: any) => any) +>a : true +>a ? async(...c) : d => d : number | ((d: any) => any) +>a : true +>async(...c) : number +>async : (...c: number[]) => number +>...c : number +>c : number[] +>d => d : (d: any) => any +>d : any +>d : any +>b : 1 + +const f51 = a ? a ? async() : T => b : async (): T => b; +>f51 : number | (() => T) | ((T: any) => number) +>a ? a ? async() : T => b : async (): T => b : number | (() => T) | ((T: any) => number) +>a : true +>a ? async() : T => b : async () : number | (() => T) +>a : true +>async() : T => b : () => T +>b : 1 +>async () : number +>async : (...c: number[]) => number +>T => b : (T: any) => number +>T : any +>b : 1 + +const f52 = a ? async (): T => async() : (d): number => d; +>f52 : (() => T) | ((d: any) => number) +>a ? async (): T => async() : (d): number => d : (() => T) | ((d: any) => number) +>a : true +>async (): T => async() : () => T +>async() : number +>async : (...c: number[]) => number +>(d): number => d : (d: any) => number +>d : any +>d : any + +const f53 = a ? a ? async (): T => async() : d => d : b; +>f53 : 1 | ((d: any) => any) +>a ? a ? async (): T => async() : d => d : b : 1 | ((d: any) => any) +>a : true +>a ? async (): T => async() : d => d : (d: any) => any +>a : true +>async (): T => async() : () => T +>async() : number +>async : (...c: number[]) => number +>d => d : (d: any) => any +>d : any +>d : any +>b : 1 + +const f54 = a ? async (): T => a ? async() : b : d => d; +>f54 : (d: any) => any +>a ? async (): T => a ? async() : b : d => d : (d: any) => any +>a : true +>async (): T => a ? async() : b : () => T +>a ? async() : b : number +>a : true +>async() : number +>async : (...c: number[]) => number +>b : 1 +>d => d : (d: any) => any +>d : any +>d : any + +const f55 = a ? a ? async() : d => d : a ? async() : d => d; +>f55 : number | ((d: any) => any) +>a ? a ? async() : d => d : a ? async() : d => d : number | ((d: any) => any) +>a : true +>a ? async() : d => d : number | ((d: any) => any) +>a : true +>async() : number +>async : (...c: number[]) => number +>d => d : (d: any) => any +>d : any +>d : any +>a ? async() : d => d : number | ((d: any) => any) +>a : true +>async() : number +>async : (...c: number[]) => number +>d => d : (d: any) => any +>d : any +>d : any + +const f56 = a ? a ? a ? async() : d => d : b : b; +>f56 : number | ((d: any) => any) +>a ? a ? a ? async() : d => d : b : b : number | ((d: any) => any) +>a : true +>a ? a ? async() : d => d : b : number | ((d: any) => any) +>a : true +>a ? async() : d => d : number | ((d: any) => any) +>a : true +>async() : number +>async : (...c: number[]) => number +>d => d : (d: any) => any +>d : any +>d : any +>b : 1 +>b : 1 + +const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +>f57 : ((d: any) => number) | ((d: any) => boolean) +>a ? d => a ? (0) : a ? async(b) : async() : (d => d = a) : ((d: any) => number) | ((d: any) => boolean) +>a : true +>d => a ? (0) : a ? async(b) : async() : (d: any) => number +>d : any +>a ? (0) : a ? async(b) : async() : number +>a : true +>(0) : 0 +>0 : 0 +>a ? async(b) : async() : number +>a : true +>async(b) : number +>async : (...c: number[]) => number +>b : 1 +>async() : number +>async : (...c: number[]) => number +>(d => d = a) : (d: any) => boolean +>d => d = a : (d: any) => boolean +>d : any +>d = a : true +>d : any +>a : true + +const f58 = a ? d => d = async () => async() : (d => d = 0); +>f58 : ((d: any) => () => Promise) | ((d: any) => number) +>a ? d => d = async () => async() : (d => d = 0) : ((d: any) => () => Promise) | ((d: any) => number) +>a : true +>d => d = async () => async() : (d: any) => () => Promise +>d : any +>d = async () => async() : () => Promise +>d : any +>async () => async() : () => Promise +>async() : number +>async : (...c: number[]) => number +>(d => d = 0) : (d: any) => number +>d => d = 0 : (d: any) => number +>d : any +>d = 0 : 0 +>d : any +>0 : 0 + +=== b.ts === +const f59 = a ? async(...c: number[]): Promise => 0; +>f59 : any +>a ? async(...c: number[]): Promise => 0 : any +>a : true +>async(...c: number[]): Promise => 0 : (...c: number[]) => Promise +>c : number[] +>0 : 0 +> : any + +const f60 = a ? async (): Promise {} : d => d; +>f60 : (d: any) => any +>a ? async (): Promise {} : d => d : (d: any) => any +>a : true +>async (): Promise {} : () => Promise +>d => d : (d: any) => any +>d : any +>d : any + +const f61 = a ? (c): number {} : d => d; +>f61 : (d: any) => any +>a ? (c): number {} : d => d : (d: any) => any +>a : true +>(c): number {} : (c: any) => number +>c : any +>d => d : (d: any) => any +>d : any +>d : any + +const f62 = a ? async() : T => async(a ? b); +>f62 : any +>a ? async() : T => async(a ? b) : any +>a : true +>async() : T => async(a ? b) : () => T +>async(a ? b) : number +>async : (...c: number[]) => number +>a ? b : any +>a : true +>b : 1 +> : any +> : any + +=== c.ts === +export {}; +declare const a: any, b: any, c: any[]; +>a : any +>b : any +>c : any[] + +declare function async(...a: any[]): any; +>async : (...a: any[]) => any +>a : any[] + +type T = Promise; +>T : T + +let d: any; +>d : any + +const f63 = a ? d = (d): T => a ? 0 : async(...c) : T => b; +>f63 : any +>a ? d = (d): T => a ? 0 : async(...c) : T => b : any +>a : any +>d = (d) : any +>d : any +>(d) : any +>d : any +>T => a ? 0 : async(...c) : T => b : (T: any) => 0 | ((...c: any[]) => T) +>T : any +>a ? 0 : async(...c) : T => b : 0 | ((...c: any[]) => T) +>a : any +>0 : 0 +>async(...c) : T => b : (...c: any[]) => T +>c : any[] +>b : any + +const f64 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; +>f64 : (d: any) => any +>a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b : (d: any) => any +>a : any +>async (): T => async (): T => (d): T => b : () => T +>async (): T => (d): T => b : () => T +>(d): T => b : (d: any) => T +>d : any +>b : any +>a ? d => (d): T => async(...c) : T => b : (d: any) => any +>a : any +>d => (d) : (d: any) => any +>d : any +>(d) : any +>d : any +>T => async(...c) : T => b : (T: any) => (...c: any[]) => T +>T : any +>async(...c) : T => b : (...c: any[]) => T +>c : any[] +>b : any + +const f65 = a ? async (): T => (d): T => async() : b; +>f65 : any +>a ? async (): T => (d): T => async() : b : any +>a : any +>async (): T => (d): T => async() : () => T +>(d): T => async() : (d: any) => T +>d : any +>async() : any +>async : (...a: any[]) => any +>b : any + +const f66 = (a ? async (): T => (d): T => async() : b); +>f66 : any +>(a ? async (): T => (d): T => async() : b) : any +>a ? async (): T => (d): T => async() : b : any +>a : any +>async (): T => (d): T => async() : () => T +>(d): T => async() : (d: any) => T +>d : any +>async() : any +>async : (...a: any[]) => any +>b : any + +const f67 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; +>f67 : any +>a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b : any +>a : any +>d = (d) : any +>d : any +>(d) : any +>d : any +>T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b : (T: any) => 0 | ((...c: any[]) => T) +>T : any +>a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b : 0 | ((...c: any[]) => T) +>a : any +>0 : 0 +>async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b : (...c: any[]) => T +>c : any[] +>a ? d = (d): T => a ? 0 : async(...c) : T => b : any +>a : any +>d = (d) : any +>d : any +>(d) : any +>d : any +>T => a ? 0 : async(...c) : T => b : (T: any) => 0 | ((...c: any[]) => T) +>T : any +>a ? 0 : async(...c) : T => b : 0 | ((...c: any[]) => T) +>a : any +>0 : 0 +>async(...c) : T => b : (...c: any[]) => T +>c : any[] +>b : any + +const f68 = a ? async (c = a ? async() : d => d): T => async() : b; +>f68 : any +>a ? async (c = a ? async() : d => d): T => async() : b : any +>a : any +>async (c = a ? async() : d => d): T => async() : (c?: any) => T +>c : any +>a ? async() : d => d : any +>a : any +>async() : any +>async : (...a: any[]) => any +>d => d : (d: any) => any +>d : any +>d : any +>async() : any +>async : (...a: any[]) => any +>b : any + +const f69 = a ? a ? (d): T => a ? async() : b : d => d : b; +>f69 : any +>a ? a ? (d): T => a ? async() : b : d => d : b : any +>a : any +>a ? (d): T => a ? async() : b : d => d : (d: any) => any +>a : any +>(d): T => a ? async() : b : (d: any) => T +>d : any +>a ? async() : b : any +>a : any +>async() : any +>async : (...a: any[]) => any +>b : any +>d => d : (d: any) => any +>d : any +>d : any +>b : any + +const f70 = a ? async() : (d => d); +>f70 : any +>a ? async() : (d => d) : any +>a : any +>async() : any +>async : (...a: any[]) => any +>(d => d) : (d: any) => any +>d => d : (d: any) => any +>d : any +>d : any + +const f71 = a ? async() : d => (a ? async() : d => d); +>f71 : any +>a ? async() : d => (a ? async() : d => d) : any +>a : any +>async() : any +>async : (...a: any[]) => any +>d => (a ? async() : d => d) : (d: any) => any +>d : any +>(a ? async() : d => d) : any +>a ? async() : d => d : any +>a : any +>async() : any +>async : (...a: any[]) => any +>d => d : (d: any) => any +>d : any +>d : any + +type x = T; +>x : T + +declare const x: any; +>x : any + +const f72 = a ? a ? async (): T => (x): T => async() : x => x; +>f72 : (T: any) => any +>a ? a ? async (): T => (x): T => async() : x => x : (T: any) => any +>a : any +>a ? async (): T => (x): T => async() : (T: any) => any +>a : any +>async (): T => (x) : () => T +>(x) : any +>x : any +>T => async() : (T: any) => any +>T : any +>async() : any +>async : (...a: any[]) => any +>x => x : (x: any) => any +>x : any +>x : any + +const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; +>f73 : (T: any) => any +>a ? a ? async (): Promise => (x): T => async() : x => x : (T: any) => any +>a : any +>a ? async (): Promise => (x): T => async() : (T: any) => any +>a : any +>async (): Promise => (x) : () => Promise +>(x) : any +>x : any +>T => async() : (T: any) => any +>T : any +>async() : any +>async : (...a: any[]) => any +>x => x : (x: any) => any +>x : any +>x : any + +const f74 = a ? async (x): T => async (): T => b; +>f74 : any +>a ? async (x): T => async (): T => b : any +>a : any +>async (x) : any +>async : (...a: any[]) => any +>x : any +>T => async (): T => b : (T: any) => () => T +>T : any +>async (): T => b : () => T +>b : any + +const f75 = a ? async (x): T => async() : x => x; +>f75 : any +>a ? async (x): T => async() : x => x : any +>a : any +>async (x) : any +>async : (...a: any[]) => any +>x : any +>T => async() : x => x : (T: any) => () => x +>T : any +>async() : x => x : () => x +>x : any + diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js index ce281ca4d36e0..7f11a6c69a7b4 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js @@ -24,6 +24,32 @@ function* g() { const f1 = a ? yield async(...c) : 0; const f2 = a ? yield async(...c) : x => x; } + +const d = { a: c }; +const e = () => c; +const f8 = async(...d.a); +const f9 = async(...e()); +const f10 = async(...[b]); +const f11 = a ? async() : function() {}; +const f12 = a ? async() : "b" +{} +const f13 = a ? async(...c) : 0 +{} +const f14 = a ? (c) : 0 +{} +const f15 = a ? async() : 0; +{} + +const f16 = a ? a ? async() : d => d : b; +const f17 = a ? a ? async(b) : d => d : b; +const f18 = a ? a ? async(...c) : d => d : b; +const f19 = a ? a ? a ? async() : d => d : b : b; + +const f20 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +const f21 = a ? d => d = async () => async() : (d => d = 0); +const f22 = h => a ? async(h = a ? async() : d => d) : d => d; +const f23 = a ? async() : (d => d); +const f24 = a ? async() : d => (a ? async() : d => d); //// [a.js] @@ -56,3 +82,26 @@ function* g() { const f1 = a ? yield async(...c) : 0; const f2 = a ? yield async(...c) : x => x; } +const d = { a: c }; +const e = () => c; +const f8 = async(...d.a); +const f9 = async(...e()); +const f10 = async(...[b]); +const f11 = a ? async() : function () { }; +const f12 = a ? async() : "b"; +{ } +const f13 = a ? async(...c) : 0; +{ } +const f14 = a ? (c) : 0; +{ } +const f15 = a ? async() : 0; +{ } +const f16 = a ? a ? async() : d => d : b; +const f17 = a ? a ? async(b) : d => d : b; +const f18 = a ? a ? async(...c) : d => d : b; +const f19 = a ? a ? a ? async() : d => d : b : b; +const f20 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +const f21 = a ? d => d = () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : (d => d = 0); +const f22 = h => a ? async(h = a ? async() : d => d) : d => d; +const f23 = a ? async() : (d => d); +const f24 = a ? async() : d => (a ? async() : d => d); diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols index 4262a0cc5e111..6ce0cdc5aa283 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols @@ -86,3 +86,152 @@ function* g() { >x : Symbol(x, Decl(a.js, 21, 38)) } +const d = { a: c }; +>d : Symbol(d, Decl(a.js, 24, 5)) +>a : Symbol(a, Decl(a.js, 24, 11)) +>c : Symbol(c, Decl(a.js, 2, 5)) + +const e = () => c; +>e : Symbol(e, Decl(a.js, 25, 5)) +>c : Symbol(c, Decl(a.js, 2, 5)) + +const f8 = async(...d.a); +>f8 : Symbol(f8, Decl(a.js, 26, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>d.a : Symbol(a, Decl(a.js, 24, 11)) +>d : Symbol(d, Decl(a.js, 24, 5)) +>a : Symbol(a, Decl(a.js, 24, 11)) + +const f9 = async(...e()); +>f9 : Symbol(f9, Decl(a.js, 27, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>e : Symbol(e, Decl(a.js, 25, 5)) + +const f10 = async(...[b]); +>f10 : Symbol(f10, Decl(a.js, 28, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>b : Symbol(b, Decl(a.js, 1, 5)) + +const f11 = a ? async() : function() {}; +>f11 : Symbol(f11, Decl(a.js, 29, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) + +const f12 = a ? async() : "b" +>f12 : Symbol(f12, Decl(a.js, 30, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) + +{} +const f13 = a ? async(...c) : 0 +>f13 : Symbol(f13, Decl(a.js, 32, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>c : Symbol(c, Decl(a.js, 2, 5)) + +{} +const f14 = a ? (c) : 0 +>f14 : Symbol(f14, Decl(a.js, 34, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>c : Symbol(c, Decl(a.js, 2, 5)) + +{} +const f15 = a ? async() : 0; +>f15 : Symbol(f15, Decl(a.js, 36, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) + +{} + +const f16 = a ? a ? async() : d => d : b; +>f16 : Symbol(f16, Decl(a.js, 39, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>d : Symbol(d, Decl(a.js, 39, 29)) +>d : Symbol(d, Decl(a.js, 39, 29)) +>b : Symbol(b, Decl(a.js, 1, 5)) + +const f17 = a ? a ? async(b) : d => d : b; +>f17 : Symbol(f17, Decl(a.js, 40, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>b : Symbol(b, Decl(a.js, 1, 5)) +>d : Symbol(d, Decl(a.js, 40, 30)) +>d : Symbol(d, Decl(a.js, 40, 30)) +>b : Symbol(b, Decl(a.js, 1, 5)) + +const f18 = a ? a ? async(...c) : d => d : b; +>f18 : Symbol(f18, Decl(a.js, 41, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>c : Symbol(c, Decl(a.js, 2, 5)) +>d : Symbol(d, Decl(a.js, 41, 33)) +>d : Symbol(d, Decl(a.js, 41, 33)) +>b : Symbol(b, Decl(a.js, 1, 5)) + +const f19 = a ? a ? a ? async() : d => d : b : b; +>f19 : Symbol(f19, Decl(a.js, 42, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>d : Symbol(d, Decl(a.js, 42, 33)) +>d : Symbol(d, Decl(a.js, 42, 33)) +>b : Symbol(b, Decl(a.js, 1, 5)) +>b : Symbol(b, Decl(a.js, 1, 5)) + +const f20 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +>f20 : Symbol(f20, Decl(a.js, 44, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>d : Symbol(d, Decl(a.js, 44, 15)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>b : Symbol(b, Decl(a.js, 1, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>d : Symbol(d, Decl(a.js, 44, 57)) +>d : Symbol(d, Decl(a.js, 44, 57)) +>a : Symbol(a, Decl(a.js, 0, 5)) + +const f21 = a ? d => d = async () => async() : (d => d = 0); +>f21 : Symbol(f21, Decl(a.js, 45, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>d : Symbol(d, Decl(a.js, 45, 15)) +>d : Symbol(d, Decl(a.js, 45, 15)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>d : Symbol(d, Decl(a.js, 45, 48)) +>d : Symbol(d, Decl(a.js, 45, 48)) + +const f22 = h => a ? async(h = a ? async() : d => d) : d => d; +>f22 : Symbol(f22, Decl(a.js, 46, 5)) +>h : Symbol(h, Decl(a.js, 46, 11)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>h : Symbol(h, Decl(a.js, 46, 11)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>d : Symbol(d, Decl(a.js, 46, 44)) +>d : Symbol(d, Decl(a.js, 46, 44)) +>d : Symbol(d, Decl(a.js, 46, 54)) +>d : Symbol(d, Decl(a.js, 46, 54)) + +const f23 = a ? async() : (d => d); +>f23 : Symbol(f23, Decl(a.js, 47, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>d : Symbol(d, Decl(a.js, 47, 27)) +>d : Symbol(d, Decl(a.js, 47, 27)) + +const f24 = a ? async() : d => (a ? async() : d => d); +>f24 : Symbol(f24, Decl(a.js, 48, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>d : Symbol(d, Decl(a.js, 48, 25)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>async : Symbol(async, Decl(a.js, 2, 14)) +>d : Symbol(d, Decl(a.js, 48, 45)) +>d : Symbol(d, Decl(a.js, 48, 45)) + diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types index f875fe7aa90e7..ac9e771b20735 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types @@ -125,3 +125,235 @@ function* g() { >x : any } +const d = { a: c }; +>d : { a: number[]; } +>{ a: c } : { a: number[]; } +>a : number[] +>c : number[] + +const e = () => c; +>e : () => number[] +>() => c : () => number[] +>c : number[] + +const f8 = async(...d.a); +>f8 : number +>async(...d.a) : number +>async : (...c: any[]) => number +>...d.a : number +>d.a : number[] +>d : { a: number[]; } +>a : number[] + +const f9 = async(...e()); +>f9 : number +>async(...e()) : number +>async : (...c: any[]) => number +>...e() : number +>e() : number[] +>e : () => number[] + +const f10 = async(...[b]); +>f10 : number +>async(...[b]) : number +>async : (...c: any[]) => number +>...[b] : number +>[b] : [number] +>b : 1 + +const f11 = a ? async() : function() {}; +>f11 : number | (() => void) +>a ? async() : function() {} : number | (() => void) +>a : true +>async() : number +>async : (...c: any[]) => number +>function() {} : () => void + +const f12 = a ? async() : "b" +>f12 : number | "b" +>a ? async() : "b" : number | "b" +>a : true +>async() : number +>async : (...c: any[]) => number +>"b" : "b" + +{} +const f13 = a ? async(...c) : 0 +>f13 : number +>a ? async(...c) : 0 : number +>a : true +>async(...c) : number +>async : (...c: any[]) => number +>...c : number +>c : number[] +>0 : 0 + +{} +const f14 = a ? (c) : 0 +>f14 : 0 | number[] +>a ? (c) : 0 : 0 | number[] +>a : true +>(c) : number[] +>c : number[] +>0 : 0 + +{} +const f15 = a ? async() : 0; +>f15 : number +>a ? async() : 0 : number +>a : true +>async() : number +>async : (...c: any[]) => number +>0 : 0 + +{} + +const f16 = a ? a ? async() : d => d : b; +>f16 : number | ((d: any) => any) +>a ? a ? async() : d => d : b : number | ((d: any) => any) +>a : true +>a ? async() : d => d : number | ((d: any) => any) +>a : true +>async() : number +>async : (...c: any[]) => number +>d => d : (d: any) => any +>d : any +>d : any +>b : 1 + +const f17 = a ? a ? async(b) : d => d : b; +>f17 : number | ((d: any) => any) +>a ? a ? async(b) : d => d : b : number | ((d: any) => any) +>a : true +>a ? async(b) : d => d : number | ((d: any) => any) +>a : true +>async(b) : number +>async : (...c: any[]) => number +>b : 1 +>d => d : (d: any) => any +>d : any +>d : any +>b : 1 + +const f18 = a ? a ? async(...c) : d => d : b; +>f18 : number | ((d: any) => any) +>a ? a ? async(...c) : d => d : b : number | ((d: any) => any) +>a : true +>a ? async(...c) : d => d : number | ((d: any) => any) +>a : true +>async(...c) : number +>async : (...c: any[]) => number +>...c : number +>c : number[] +>d => d : (d: any) => any +>d : any +>d : any +>b : 1 + +const f19 = a ? a ? a ? async() : d => d : b : b; +>f19 : number | ((d: any) => any) +>a ? a ? a ? async() : d => d : b : b : number | ((d: any) => any) +>a : true +>a ? a ? async() : d => d : b : number | ((d: any) => any) +>a : true +>a ? async() : d => d : number | ((d: any) => any) +>a : true +>async() : number +>async : (...c: any[]) => number +>d => d : (d: any) => any +>d : any +>d : any +>b : 1 +>b : 1 + +const f20 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +>f20 : ((d: any) => number) | ((d: any) => boolean) +>a ? d => a ? (0) : a ? async(b) : async() : (d => d = a) : ((d: any) => number) | ((d: any) => boolean) +>a : true +>d => a ? (0) : a ? async(b) : async() : (d: any) => number +>d : any +>a ? (0) : a ? async(b) : async() : number +>a : true +>(0) : 0 +>0 : 0 +>a ? async(b) : async() : number +>a : true +>async(b) : number +>async : (...c: any[]) => number +>b : 1 +>async() : number +>async : (...c: any[]) => number +>(d => d = a) : (d: any) => boolean +>d => d = a : (d: any) => boolean +>d : any +>d = a : true +>d : any +>a : true + +const f21 = a ? d => d = async () => async() : (d => d = 0); +>f21 : ((d: any) => () => Promise) | ((d: any) => number) +>a ? d => d = async () => async() : (d => d = 0) : ((d: any) => () => Promise) | ((d: any) => number) +>a : true +>d => d = async () => async() : (d: any) => () => Promise +>d : any +>d = async () => async() : () => Promise +>d : any +>async () => async() : () => Promise +>async() : number +>async : (...c: any[]) => number +>(d => d = 0) : (d: any) => number +>d => d = 0 : (d: any) => number +>d : any +>d = 0 : 0 +>d : any +>0 : 0 + +const f22 = h => a ? async(h = a ? async() : d => d) : d => d; +>f22 : (h: any) => number | ((d: any) => any) +>h => a ? async(h = a ? async() : d => d) : d => d : (h: any) => number | ((d: any) => any) +>h : any +>a ? async(h = a ? async() : d => d) : d => d : number | ((d: any) => any) +>a : true +>async(h = a ? async() : d => d) : number +>async : (...c: any[]) => number +>h = a ? async() : d => d : number | ((d: any) => any) +>h : any +>a ? async() : d => d : number | ((d: any) => any) +>a : true +>async() : number +>async : (...c: any[]) => number +>d => d : (d: any) => any +>d : any +>d : any +>d => d : (d: any) => any +>d : any +>d : any + +const f23 = a ? async() : (d => d); +>f23 : number | ((d: any) => any) +>a ? async() : (d => d) : number | ((d: any) => any) +>a : true +>async() : number +>async : (...c: any[]) => number +>(d => d) : (d: any) => any +>d => d : (d: any) => any +>d : any +>d : any + +const f24 = a ? async() : d => (a ? async() : d => d); +>f24 : number | ((d: any) => number | ((d: any) => any)) +>a ? async() : d => (a ? async() : d => d) : number | ((d: any) => number | ((d: any) => any)) +>a : true +>async() : number +>async : (...c: any[]) => number +>d => (a ? async() : d => d) : (d: any) => number | ((d: any) => any) +>d : any +>(a ? async() : d => d) : number | ((d: any) => any) +>a ? async() : d => d : number | ((d: any) => any) +>a : true +>async() : number +>async : (...c: any[]) => number +>d => d : (d: any) => any +>d : any +>d : any + diff --git a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts index c20dde520edd0..23004f2263b09 100644 --- a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts +++ b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts @@ -1,5 +1,6 @@ // @target: es2015 // @strict: false +// @filename: a.ts // Repro from #20096 let foo = (async bar => bar); @@ -8,7 +9,7 @@ const a = true; const b = 1; const c = [b]; -function async(...c: number[]): number { +function async(...c: number[]): number { return b; } @@ -28,13 +29,13 @@ const f12 = a ? async() : x => async (...c): Promise => c.length; type T = Promise; const f13 = a ? async() : x => async (): Promise => b; -const f14 = a ? async() : x => async (): T => 0; +const f14 = a ? async() : T => async (): T => 0; const f15 = a ? (b) : x => async (): T => 0; -const f16 = a ? async(...c) : x => async (): T => 0; -const f17 = a ? async() : x => (y): number => y; -const f18 = a ? async() : x => async (): T => 0; -const f19 = a ? async(...c) : x => (y): number => y; -const f20 = a ? async(...c) : x => async (): T => 0; +const f16 = a ? async(...c) : T => async (): T => 0; +const f17 = a ? async() : T => (b): number => b; +const f18 = a ? async() : T => async (): T => 0; +const f19 = a ? async(...c) : T => (b): number => b; +const f20 = a ? async(...c) : T => async (): T => 0; const f21 = a ? (x): number => (b): T => 0; const f22 = a ? async (): Promise => (b): T => 0; const f23 = a ? async () => async() : x => x; @@ -57,3 +58,69 @@ function* g() { const f1 = a ? yield async(...c) : 0; const f2 = a ? yield async(...c) : x => x; } + +const d = { a: c }; +const e = () => c; +const f35 = async(...d.a); +const f36 = async(...e()); +const f37 = async(...[b]); + +type U = number; +const f38 = a ? (c): U => (b) : x => x; +const f39 = a ? async() : function() {}; +const f40 = a ? async() : "b" +{} +const f41 = a ? async(...c) : 0 +{} +const f42 = a ? (c) : 0 +{} +const f43 = a ? async() : 0; +{} + +const f44 = a ? async() : T => async (...c): T => c.length; + +const f45 = a ? async (): T => (b) : d => d; +const f46 = a ? async (): T => async() : d => d; +const f47 = a ? async (): T => async() : b; +const f48 = a ? a ? async() : d => d : b; +const f49 = a ? a ? async(b) : d => d : b; +const f50 = a ? a ? async(...c) : d => d : b; +const f51 = a ? a ? async() : T => b : async (): T => b; +const f52 = a ? async (): T => async() : (d): number => d; +const f53 = a ? a ? async (): T => async() : d => d : b; +const f54 = a ? async (): T => a ? async() : b : d => d; +const f55 = a ? a ? async() : d => d : a ? async() : d => d; +const f56 = a ? a ? a ? async() : d => d : b : b; + +const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +const f58 = a ? d => d = async () => async() : (d => d = 0); + +// @filename: b.ts +const f59 = a ? async(...c: number[]): Promise => 0; +const f60 = a ? async (): Promise {} : d => d; +const f61 = a ? (c): number {} : d => d; + +const f62 = a ? async() : T => async(a ? b); + +// @filename: c.ts +export {}; +declare const a: any, b: any, c: any[]; +declare function async(...a: any[]): any; +type T = Promise; +let d: any; +const f63 = a ? d = (d): T => a ? 0 : async(...c) : T => b; +const f64 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; +const f65 = a ? async (): T => (d): T => async() : b; +const f66 = (a ? async (): T => (d): T => async() : b); +const f67 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; +const f68 = a ? async (c = a ? async() : d => d): T => async() : b; +const f69 = a ? a ? (d): T => a ? async() : b : d => d : b; +const f70 = a ? async() : (d => d); +const f71 = a ? async() : d => (a ? async() : d => d); + +type x = T; +declare const x: any; +const f72 = a ? a ? async (): T => (x): T => async() : x => x; +const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; +const f74 = a ? async (x): T => async (): T => b; +const f75 = a ? async (x): T => async() : x => x; diff --git a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts index 2ceb1d47222cc..cad044a41a02f 100644 --- a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts +++ b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts @@ -27,3 +27,29 @@ function* g() { const f1 = a ? yield async(...c) : 0; const f2 = a ? yield async(...c) : x => x; } + +const d = { a: c }; +const e = () => c; +const f8 = async(...d.a); +const f9 = async(...e()); +const f10 = async(...[b]); +const f11 = a ? async() : function() {}; +const f12 = a ? async() : "b" +{} +const f13 = a ? async(...c) : 0 +{} +const f14 = a ? (c) : 0 +{} +const f15 = a ? async() : 0; +{} + +const f16 = a ? a ? async() : d => d : b; +const f17 = a ? a ? async(b) : d => d : b; +const f18 = a ? a ? async(...c) : d => d : b; +const f19 = a ? a ? a ? async() : d => d : b : b; + +const f20 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +const f21 = a ? d => d = async () => async() : (d => d = 0); +const f22 = h => a ? async(h = a ? async() : d => d) : d => d; +const f23 = a ? async() : (d => d); +const f24 = a ? async() : d => (a ? async() : d => d); From b2e2068bc7855fc9de1d4f03c945a379e8147a91 Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk Date: Fri, 23 Oct 2026 22:20:14 +0300 Subject: [PATCH 5/7] prevent exponential reparsing of nested async expressions --- tsc/internal/parser/parser.go | 24 +++++++++++++----------- tsc/internal/parser/parser_test.go | 24 ++++++++++++++++++++++++ tsc/internal/parser/tentative.go | 17 ++++++++--------- tsc/internal/parser/tentative_test.go | 24 ++++++++++++++---------- 4 files changed, 59 insertions(+), 30 deletions(-) diff --git a/tsc/internal/parser/parser.go b/tsc/internal/parser/parser.go index d43536037cd07..945a71e77329e 100644 --- a/tsc/internal/parser/parser.go +++ b/tsc/internal/parser/parser.go @@ -4183,10 +4183,19 @@ func (p *Parser) parseExpressionAllowIn() *ast.Expression { return p.doInContext(ast.NodeFlagsDisallowInContext, false, (*Parser).parseExpression) } -func (p *Parser) parseAssignmentExpressionOrHigher() *ast.Expression { +func (p *Parser) parseAssignmentExpressionOrHigher() (expression *ast.Expression) { + if p.parsingFlags&ParsingFlagsTentative != 0 { + pos := p.nodePos() + node := p.getTentativeNode(pos) + if node == nil { + defer p.recordTentativeNode(pos, p.contextFlags, &expression) + } else { + return node + } + } scope := p.beginTentativeScope() scope.suspendExpression() - expression := p.parseAssignmentExpressionOrHigherWorker(ExpressionParseFlagsNone) + expression = p.parseAssignmentExpressionOrHigherWorker(ExpressionParseFlagsNone) scope.restore() return expression } @@ -5869,20 +5878,13 @@ func (p *Parser) parsePrimaryExpression() *ast.Expression { return p.parseIdentifierWithDiagnostic(diagnostics.Expression_expected, nil) } -func (p *Parser) parseParenthesizedExpression() (result *ast.Expression) { +func (p *Parser) parseParenthesizedExpression() *ast.Expression { pos := p.nodePos() - if p.parsingFlags&ParsingFlagsTentative != 0 { - node := p.getTentativeNode(pos, ast.KindParenthesizedExpression) - if node != nil { - return node - } - defer p.recordTentativeNode(pos, ast.KindParenthesizedExpression, p.contextFlags, &result) - } jsdoc := p.jsdocScannerInfo() p.parseExpected(ast.KindOpenParenToken) expression := p.parseExpressionAllowIn() p.parseExpected(ast.KindCloseParenToken) - result = p.finishNode(p.factory.NewParenthesizedExpression(expression), pos) + result := p.finishNode(p.factory.NewParenthesizedExpression(expression), pos) p.withJSDoc(result, jsdoc) return result } diff --git a/tsc/internal/parser/parser_test.go b/tsc/internal/parser/parser_test.go index c49c79d837682..0deb634482298 100644 --- a/tsc/internal/parser/parser_test.go +++ b/tsc/internal/parser/parser_test.go @@ -55,6 +55,10 @@ func BenchmarkConditionalAsyncExpressions(b *testing.B) { {"invalidArrow", "a ? async(): T => async() : x => ", "0 +;", ""}, {"parenthesizedCall", "a ? async() : x => (", "0", ")"}, {"invalidParenthesizedCall", "a ? async() : x => (", "0 +", ")"}, + {"array", "a ? async() : x => [", "0", "]"}, + {"invalidArray", "a ? async() : x => [", "0 +", "]"}, + {"callArgument", "a ? async() : x => b(", "0", ")"}, + {"invalidCallArgument", "a ? async() : x => b(", "0 +", ")"}, } { b.Run(test.name, func(b *testing.B) { for _, count := range []int{10, 20, 40, 80} { @@ -241,6 +245,26 @@ func parseConditionalInGenerator(t *testing.T, expression string, kind core.Scri return declaration.Initializer().AsConditionalExpression() } +func checkConditionalAsyncNesting(t *testing.T, prefix string, closing string) { + t.Helper() + const depth = 8 + source := "const r = " + strings.Repeat(prefix, depth) + "0" + strings.Repeat(closing, depth) + ";" + file := parsetestutil.ParseTypeScript(source, false) + parsetestutil.CheckDiagnostics(t, file) + maxNodeCount := len(source) * len(source) + assert.Assert(t, file.NodeCount <= maxNodeCount, "created %d nodes for %d bytes", file.NodeCount, len(source)) +} + +func TestConditionalAsyncNestedArray(t *testing.T) { + t.Parallel() + checkConditionalAsyncNesting(t, "a ? async() : x => [", "]") +} + +func TestConditionalAsyncNestedCallArgument(t *testing.T) { + t.Parallel() + checkConditionalAsyncNesting(t, "a ? async() : x => b(", ")") +} + func TestConditionalAsyncCall(t *testing.T) { t.Parallel() conditional := parseConditionalInGenerator(t, "b ? async(...c) : 0", core.ScriptKindTS) diff --git a/tsc/internal/parser/tentative.go b/tsc/internal/parser/tentative.go index 8578978111430..01ba6c95d57ea 100644 --- a/tsc/internal/parser/tentative.go +++ b/tsc/internal/parser/tentative.go @@ -5,7 +5,6 @@ import "github.com/microsoft/TypeScript/tsc/internal/ast" type tentativeParseFailure struct{} type tentativeNode struct { - kind ast.Kind contextFlags ast.NodeFlags node *ast.Node } @@ -93,28 +92,28 @@ func (tp *tentativeParse) close() { panic(failure) } -func (p *Parser) getTentativeNode(pos int, kind ast.Kind) *ast.Node { - for _, annotation := range p.tentativeNodes[pos] { - if annotation.kind == kind && annotation.contextFlags == p.contextFlags { - if annotation.node == nil { +func (p *Parser) getTentativeNode(pos int) *ast.Node { + for _, entry := range p.tentativeNodes[pos] { + if entry.contextFlags == p.contextFlags { + if entry.node == nil { panic(tentativeParseFailure{}) } - p.scanner.ResetTokenState(annotation.node.End()) + p.scanner.ResetTokenState(entry.node.End()) p.nextToken() - return annotation.node + return entry.node } } return nil } -func (p *Parser) recordTentativeNode(pos int, kind ast.Kind, contextFlags ast.NodeFlags, node **ast.Node) { +func (p *Parser) recordTentativeNode(pos int, contextFlags ast.NodeFlags, node **ast.Node) { failure := recover() if failure != nil { if _, ok := failure.(tentativeParseFailure); !ok { panic(failure) } } - p.tentativeNodes[pos] = append(p.tentativeNodes[pos], tentativeNode{kind: kind, contextFlags: contextFlags, node: *node}) + p.tentativeNodes[pos] = append(p.tentativeNodes[pos], tentativeNode{contextFlags: contextFlags, node: *node}) if failure != nil { panic(failure) } diff --git a/tsc/internal/parser/tentative_test.go b/tsc/internal/parser/tentative_test.go index 01bddf880ecb9..564df790438b1 100644 --- a/tsc/internal/parser/tentative_test.go +++ b/tsc/internal/parser/tentative_test.go @@ -167,7 +167,9 @@ func TestArrowFunctionHeadSyntaxFailure(t *testing.T) { t.Parallel() p := newTestParser("(a = b; c)") pos := p.nodePos() - p.parsingFlags = ParsingFlagsTentative + tentative := p.beginTentativeParse() + defer tentative.revert() + tentative.silence() status, _ := p.tryParseArrowFunctionHead(ExpressionParseFlagsNone) assert.Equal(t, status, core.TSFalse) assert.Assert(t, p.notParenthesizedArrow.Has(pos)) @@ -180,24 +182,26 @@ func TestArrowFunctionHeadSyntaxFailure(t *testing.T) { func TestTentativeParseNode(t *testing.T) { t.Parallel() - p := newTestParser("(a) + b") + p := newTestParser("b(await(a)), c") tentative := p.beginTentativeParse() tentative.silence() state := p.mark() - first := p.parseParenthesizedExpression() - assert.Equal(t, p.token, ast.KindPlusToken) + first := p.parseAssignmentExpressionOrHigher() + assert.Equal(t, first.AsCallExpression().Arguments.Nodes[0].Kind, ast.KindCallExpression) + assert.Equal(t, p.token, ast.KindCommaToken) p.rewind(state) - second := p.parseParenthesizedExpression() + second := p.parseAssignmentExpressionOrHigher() assert.Equal(t, first, second) - assert.Equal(t, p.token, ast.KindPlusToken) + assert.Equal(t, p.token, ast.KindCommaToken) p.rewind(state) p.contextFlags |= ast.NodeFlagsAwaitContext - third := p.parseParenthesizedExpression() + third := p.parseAssignmentExpressionOrHigher() assert.Assert(t, third != first) assert.Equal(t, third.Flags&ast.NodeFlagsAwaitContext, ast.NodeFlagsAwaitContext) + assert.Equal(t, third.AsCallExpression().Arguments.Nodes[0].Kind, ast.KindAwaitExpression) tentative.revert() assert.Assert(t, p.tentativeNodes == nil) - assert.Equal(t, p.scanner.TokenText(), "(") + assert.Equal(t, p.scanner.TokenText(), "b") } func TestTentativeParseNodeFailure(t *testing.T) { @@ -209,7 +213,7 @@ func TestTentativeParseNodeFailure(t *testing.T) { func() { attempt := p.beginTentativeParse() defer attempt.close() - p.parseParenthesizedExpression() + p.parseAssignmentExpressionOrHigher() t.Fatal("invalid expression accepted") }() assert.Equal(t, len(p.tentativeNodes[pos]), 1) @@ -217,7 +221,7 @@ func TestTentativeParseNodeFailure(t *testing.T) { func() { attempt := p.beginTentativeParse() defer attempt.close() - p.parseParenthesizedExpression() + p.parseAssignmentExpressionOrHigher() t.Fatal("failed recognition reused as a valid expression") }() assert.Equal(t, len(p.tentativeNodes[pos]), 1) From aa0aea259663a6c9dbe82ff9f4197485f9fefe7c Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk Date: Sat, 24 Oct 2026 08:54:06 +0300 Subject: [PATCH 6/7] isolate tentative parser probe failures --- tsc/internal/parser/parser.go | 64 +++++--- tsc/internal/parser/tentative_test.go | 42 ++++++ ...parenthesizedAsyncArrowFunction.errors.txt | 19 ++- .../parenthesizedAsyncArrowFunction.js | 25 ++++ .../parenthesizedAsyncArrowFunction.symbols | 97 ++++++++++++ .../parenthesizedAsyncArrowFunction.types | 140 ++++++++++++++++++ .../parenthesizedAsyncArrowFunctionJs.js | 2 + .../parenthesizedAsyncArrowFunctionJs.symbols | 9 ++ .../parenthesizedAsyncArrowFunctionJs.types | 13 ++ .../parenthesizedAsyncArrowFunction.ts | 14 ++ .../parenthesizedAsyncArrowFunctionJs.ts | 1 + 11 files changed, 404 insertions(+), 22 deletions(-) diff --git a/tsc/internal/parser/parser.go b/tsc/internal/parser/parser.go index 945a71e77329e..ea6c0de4cba27 100644 --- a/tsc/internal/parser/parser.go +++ b/tsc/internal/parser/parser.go @@ -409,10 +409,16 @@ func (p *Parser) rewind(state ParserState) { } func (p *Parser) lookAhead(callback func(p *Parser) bool) bool { - state := p.mark() - result := callback(p) - p.rewind(state) - return result + if p.parsingFlags == ParsingFlagsNone { + state := p.mark() + result := callback(p) + p.rewind(state) + return result + } + tentative := p.beginTentativeParse() + defer tentative.close() + p.parsingFlags = ParsingFlagsNone + return callback(p) } func (p *Parser) nextToken() ast.Kind { @@ -2861,13 +2867,10 @@ func (p *Parser) parseNonArrayType() *ast.Node { switch p.token { case ast.KindAnyKeyword, ast.KindUnknownKeyword, ast.KindStringKeyword, ast.KindNumberKeyword, ast.KindBigIntKeyword, ast.KindSymbolKeyword, ast.KindBooleanKeyword, ast.KindUndefinedKeyword, ast.KindNeverKeyword, ast.KindObjectKeyword: - state := p.mark() - keywordTypeNode := p.parseKeywordTypeNode() - // If these are followed by a dot then parse these out as a dotted type reference instead - if p.token != ast.KindDotToken { + keywordTypeNode := p.tryParseKeywordTypeNode() + if keywordTypeNode != nil { return keywordTypeNode } - p.rewind(state) return p.parseTypeReference() case ast.KindAsteriskEqualsToken: // If there is '*=', treat it as * followed by postfix = @@ -2927,6 +2930,17 @@ func (p *Parser) parseNonArrayType() *ast.Node { } } +func (p *Parser) tryParseKeywordTypeNode() *ast.Node { + tentative := p.beginTentativeParse() + defer tentative.close() + node := p.parseKeywordTypeNode() + if p.token == ast.KindDotToken { + return nil + } + tentative.commit() + return node +} + func (p *Parser) parseKeywordTypeNode() *ast.Node { pos := p.nodePos() result := p.factory.NewKeywordTypeNode(p.token) @@ -4049,20 +4063,28 @@ func (p *Parser) tryParseModifier(hasSeenStaticModifier bool, permitConstAsModif } func (p *Parser) parseContextualModifier(t ast.Kind) bool { - state := p.mark() - if p.token == t && p.nextTokenCanFollowModifier() { + if p.token != t { + return false + } + tentative := p.beginTentativeParse() + defer tentative.close() + if p.nextTokenCanFollowModifier() { + tentative.commit() return true } - p.rewind(state) return false } func (p *Parser) parseAnyContextualModifier() bool { - state := p.mark() - if ast.IsModifierKind(p.token) && p.nextTokenCanFollowModifier() { + if !ast.IsModifierKind(p.token) { + return false + } + tentative := p.beginTentativeParse() + defer tentative.close() + if p.nextTokenCanFollowModifier() { + tentative.commit() return true } - p.rewind(state) return false } @@ -4316,10 +4338,9 @@ func (p *Parser) parseYieldExpression(flags ExpressionParseFlags) *ast.Node { func (p *Parser) isParenthesizedArrowFunctionExpression() core.Tristate { if p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken || p.token == ast.KindAsyncKeyword { - state := p.mark() - result := p.nextIsParenthesizedArrowFunctionExpression() - p.rewind(state) - return result + tentative := p.beginTentativeParse() + defer tentative.close() + return p.nextIsParenthesizedArrowFunctionExpression() } if p.token == ast.KindEqualsGreaterThanToken { // ERROR RECOVERY TWEAK: @@ -5534,7 +5555,8 @@ func (p *Parser) tryParseTypeArgumentsInExpression() *ast.NodeList { if p.contextFlags&ast.NodeFlagsJavaScriptFile != 0 || (p.token != ast.KindLessThanToken && p.token != ast.KindLessThanLessThanToken) { return nil } - state := p.mark() + tentative := p.beginTentativeParse() + defer tentative.close() if p.reScanLessThanToken() == ast.KindLessThanToken { p.nextToken() typeArguments := p.parseDelimitedList(PCTypeArguments, (*Parser).parseType) @@ -5546,11 +5568,11 @@ func (p *Parser) tryParseTypeArgumentsInExpression() *ast.NodeList { // `f(42)`, we favor the type argument interpretation even though JavaScript would view // it as a relational expression. if p.canFollowTypeArgumentsInExpression() { + tentative.commit() return typeArguments } } } - p.rewind(state) return nil } diff --git a/tsc/internal/parser/tentative_test.go b/tsc/internal/parser/tentative_test.go index 564df790438b1..45241300be6df 100644 --- a/tsc/internal/parser/tentative_test.go +++ b/tsc/internal/parser/tentative_test.go @@ -142,6 +142,48 @@ func TestTentativeConditionalFailure(t *testing.T) { assert.Equal(t, p.parsingFlags, ParsingFlagsTentative) } +func TestTentativeTypeArgumentsRollback(t *testing.T) { + t.Parallel() + p := newTestParser("<(a + 1)") + tentative := p.beginTentativeParse() + defer tentative.revert() + tentative.silence() + state := p.mark() + parsingContexts := p.parsingContexts + typeArguments := p.tryParseTypeArgumentsInExpression() + assert.Assert(t, typeArguments == nil) + assert.Assert(t, reflect.DeepEqual(p.mark(), state)) + assert.Equal(t, p.parsingContexts, parsingContexts) + assert.Equal(t, p.parsingFlags, ParsingFlagsTentative) +} + +func TestTentativeTypeArgumentsCommit(t *testing.T) { + t.Parallel() + p := newTestParser("(a)") + tentative := p.beginTentativeParse() + defer tentative.revert() + tentative.silence() + typeArguments := p.tryParseTypeArgumentsInExpression() + assert.Assert(t, typeArguments != nil) + assert.Equal(t, len(typeArguments.Nodes), 1) + assert.Equal(t, typeArguments.Nodes[0].Kind, ast.KindTypeReference) + assert.Equal(t, p.token, ast.KindOpenParenToken) + assert.Equal(t, p.parsingContexts, ParsingContexts(0)) + assert.Equal(t, p.parsingFlags, ParsingFlagsTentative) +} + +func TestTentativeLookAheadRecovery(t *testing.T) { + t.Parallel() + p := newTestParser(`r\u0065adonly: number`) + tentative := p.beginTentativeParse() + defer tentative.revert() + tentative.silence() + state := p.mark() + assert.Assert(t, p.lookAhead((*Parser).scanTypeMemberStart)) + assert.Assert(t, reflect.DeepEqual(p.mark(), state)) + assert.Equal(t, p.parsingFlags, ParsingFlagsTentative) +} + func TestTentativeParseCommittedFailure(t *testing.T) { t.Parallel() p := newTestParser("a + b") diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.errors.txt b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.errors.txt index 164ebaa7b0280..9f81590472faf 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.errors.txt +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.errors.txt @@ -5,6 +5,7 @@ b.ts(3,22): error TS2355: A function whose declared type is neither 'undefined', b.ts(3,29): error TS1005: '=>' expected. b.ts(5,43): error TS1005: ':' expected. b.ts(5,44): error TS1005: ':' expected. +c.ts(35,34): error TS1260: Keywords cannot contain escape characters. ==== a.ts (0 errors) ==== @@ -123,7 +124,7 @@ b.ts(5,44): error TS1005: ':' expected. ~ !!! error TS1005: ':' expected. -==== c.ts (0 errors) ==== +==== c.ts (1 errors) ==== export {}; declare const a: any, b: any, c: any[]; declare function async(...a: any[]): any; @@ -145,4 +146,20 @@ b.ts(5,44): error TS1005: ':' expected. const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; const f74 = a ? async (x): T => async (): T => b; const f75 = a ? async (x): T => async() : x => x; + + declare function h(a: A): A; + declare namespace number { type T = number; } + const f76 = a ? async(x = b < (d + 1)): T => x : 0; + const f77 = a ? async(x = b << (d + 1)): T => x : 0; + const f78 = a ? async(x = new b < (d + 1)): T => x : 0; + const f79 = a ? async(x = h(b)): T => x : 0; + const f80 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; + const f81 = a ? async(): Promise<([a: number])> => [b] : 0; + const f82 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; + const f83 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; + const f84 = a ? async(): Promise => b : 0; + const f85 = a ? a ? as\u0079nc() : d => d : b; + const f86 = a ? async(): Promise => 0 : 0; + ~~~~~~~~~~~ +!!! error TS1260: Keywords cannot contain escape characters. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js index 7b148620f530a..5d9c0ee230763 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js @@ -124,6 +124,20 @@ const f72 = a ? a ? async (): T => (x): T => async() : x => x; const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; const f74 = a ? async (x): T => async (): T => b; const f75 = a ? async (x): T => async() : x => x; + +declare function h(a: A): A; +declare namespace number { type T = number; } +const f76 = a ? async(x = b < (d + 1)): T => x : 0; +const f77 = a ? async(x = b << (d + 1)): T => x : 0; +const f78 = a ? async(x = new b < (d + 1)): T => x : 0; +const f79 = a ? async(x = h(b)): T => x : 0; +const f80 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; +const f81 = a ? async(): Promise<([a: number])> => [b] : 0; +const f82 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; +const f83 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; +const f84 = a ? async(): Promise => b : 0; +const f85 = a ? a ? as\u0079nc() : d => d : b; +const f86 = a ? async(): Promise => 0 : 0; //// [a.js] @@ -254,4 +268,15 @@ const f72 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { retur const f73 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { return (x); }) : T => async() : x => x; const f74 = a ? async(x) : T => () => __awaiter(void 0, void 0, void 0, function* () { return b; }); const f75 = a ? async(x) : T => () => __awaiter(void 0, void 0, void 0, function* () { return x; }); +const f76 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (x = b < (d + 1)) { return x; }) : 0; +const f77 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (x = b << (d + 1)) { return x; }) : 0; +const f78 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (x = new b < (d + 1)) { return x; }) : 0; +const f79 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (x = h(b)) { return x; }) : 0; +const f80 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return ({ a: [] }); }) : 0; +const f81 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return [b]; }) : 0; +const f82 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return ({ readonly: 0 }); }) : 0; +const f83 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return ({ get: 0 }); }) : 0; +const f84 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return b; }) : 0; +const f85 = a ? a ? as\u0079nc() : d => d : b; +const f86 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return 0; }) : 0; export {}; diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols index d0e113043f0c1..e0f9714b6a9bf 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols @@ -727,3 +727,100 @@ const f75 = a ? async (x): T => async() : x => x; >x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) >x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) +declare function h(a: A): A; +>h : Symbol(h, Decl(c.ts, 20, 49)) +>A : Symbol(A, Decl(c.ts, 22, 19)) +>a : Symbol(a, Decl(c.ts, 22, 22)) +>A : Symbol(A, Decl(c.ts, 22, 19)) +>A : Symbol(A, Decl(c.ts, 22, 19)) + +declare namespace number { type T = number; } +>number : Symbol(number, Decl(c.ts, 22, 31)) +>T : Symbol(T, Decl(c.ts, 23, 26)) + +const f76 = a ? async(x = b < (d + 1)): T => x : 0; +>f76 : Symbol(f76, Decl(c.ts, 24, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>x : Symbol(x, Decl(c.ts, 24, 22)) +>b : Symbol(b, Decl(c.ts, 1, 21)) +>d : Symbol(d, Decl(c.ts, 4, 3)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>x : Symbol(x, Decl(c.ts, 24, 22)) + +const f77 = a ? async(x = b << (d + 1)): T => x : 0; +>f77 : Symbol(f77, Decl(c.ts, 25, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>x : Symbol(x, Decl(c.ts, 25, 22)) +>b : Symbol(b, Decl(c.ts, 1, 21)) +>d : Symbol(d, Decl(c.ts, 4, 3)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>x : Symbol(x, Decl(c.ts, 25, 22)) + +const f78 = a ? async(x = new b < (d + 1)): T => x : 0; +>f78 : Symbol(f78, Decl(c.ts, 26, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>x : Symbol(x, Decl(c.ts, 26, 22)) +>b : Symbol(b, Decl(c.ts, 1, 21)) +>d : Symbol(d, Decl(c.ts, 4, 3)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>x : Symbol(x, Decl(c.ts, 26, 22)) + +const f79 = a ? async(x = h(b)): T => x : 0; +>f79 : Symbol(f79, Decl(c.ts, 27, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>x : Symbol(x, Decl(c.ts, 27, 22)) +>h : Symbol(h, Decl(c.ts, 20, 49)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>b : Symbol(b, Decl(c.ts, 1, 21)) +>T : Symbol(T, Decl(c.ts, 2, 41)) +>x : Symbol(x, Decl(c.ts, 27, 22)) + +const f80 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; +>f80 : Symbol(f80, Decl(c.ts, 28, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>a : Symbol(a, Decl(c.ts, 28, 35)) +>a : Symbol(a, Decl(c.ts, 28, 57)) + +const f81 = a ? async(): Promise<([a: number])> => [b] : 0; +>f81 : Symbol(f81, Decl(c.ts, 29, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>b : Symbol(b, Decl(c.ts, 1, 21)) + +const f82 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; +>f82 : Symbol(f82, Decl(c.ts, 30, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>r\u0065adonly : Symbol(r\u0065adonly, Decl(c.ts, 30, 34)) +>readonly : Symbol(readonly, Decl(c.ts, 30, 65)) + +const f83 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; +>f83 : Symbol(f83, Decl(c.ts, 31, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>g\u0065t : Symbol(g\u0065t, Decl(c.ts, 31, 34)) +>get : Symbol(get, Decl(c.ts, 31, 60)) + +const f84 = a ? async(): Promise => b : 0; +>f84 : Symbol(f84, Decl(c.ts, 32, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>n\u0075mber : Symbol(number, Decl(c.ts, 22, 31)) +>T : Symbol(number.T, Decl(c.ts, 23, 26)) +>b : Symbol(b, Decl(c.ts, 1, 21)) + +const f85 = a ? a ? as\u0079nc() : d => d : b; +>f85 : Symbol(f85, Decl(c.ts, 33, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>as\u0079nc : Symbol(async, Decl(c.ts, 1, 39)) +>d : Symbol(d, Decl(c.ts, 33, 34)) +>d : Symbol(d, Decl(c.ts, 33, 34)) +>b : Symbol(b, Decl(c.ts, 1, 21)) + +const f86 = a ? async(): Promise => 0 : 0; +>f86 : Symbol(f86, Decl(c.ts, 34, 5)) +>a : Symbol(a, Decl(c.ts, 1, 13)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types index 71cd9e4e313af..3d301c346425a 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types @@ -1033,3 +1033,143 @@ const f75 = a ? async (x): T => async() : x => x; >async() : x => x : () => x >x : any +declare function h(a: A): A; +>h : (a: A) => A +>a : A + +declare namespace number { type T = number; } +>T : number + +const f76 = a ? async(x = b < (d + 1)): T => x : 0; +>f76 : 0 | ((x?: boolean) => T) +>a ? async(x = b < (d + 1)): T => x : 0 : 0 | ((x?: boolean) => T) +>a : any +>async(x = b < (d + 1)): T => x : (x?: boolean) => T +>x : boolean +>b < (d + 1) : boolean +>b : any +>(d + 1) : any +>d + 1 : any +>d : any +>1 : 1 +>x : boolean +>0 : 0 + +const f77 = a ? async(x = b << (d + 1)): T => x : 0; +>f77 : 0 | ((x?: number) => T) +>a ? async(x = b << (d + 1)): T => x : 0 : 0 | ((x?: number) => T) +>a : any +>async(x = b << (d + 1)): T => x : (x?: number) => T +>x : number +>b << (d + 1) : number +>b : any +>(d + 1) : any +>d + 1 : any +>d : any +>1 : 1 +>x : number +>0 : 0 + +const f78 = a ? async(x = new b < (d + 1)): T => x : 0; +>f78 : 0 | ((x?: boolean) => T) +>a ? async(x = new b < (d + 1)): T => x : 0 : 0 | ((x?: boolean) => T) +>a : any +>async(x = new b < (d + 1)): T => x : (x?: boolean) => T +>x : boolean +>new b < (d + 1) : boolean +>new b : any +>b : any +>(d + 1) : any +>d + 1 : any +>d : any +>1 : 1 +>x : boolean +>0 : 0 + +const f79 = a ? async(x = h(b)): T => x : 0; +>f79 : 0 | ((x?: T) => T) +>a ? async(x = h(b)): T => x : 0 : 0 | ((x?: T) => T) +>a : any +>async(x = h(b)): T => x : (x?: T) => T +>x : T +>h(b) : T +>h : (a: A) => A +>b : any +>x : T +>0 : 0 + +const f80 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; +>f80 : 0 | (() => Promise<({ a: number[]; })>) +>a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0 : 0 | (() => Promise<({ a: number[]; })>) +>a : any +>async(): Promise<({ a: number[] })> => ({ a: [] }) : () => Promise<({ a: number[]; })> +>a : number[] +>({ a: [] }) : { a: undefined[]; } +>{ a: [] } : { a: undefined[]; } +>a : undefined[] +>[] : undefined[] +>0 : 0 + +const f81 = a ? async(): Promise<([a: number])> => [b] : 0; +>f81 : 0 | (() => Promise<([a: number])>) +>a ? async(): Promise<([a: number])> => [b] : 0 : 0 | (() => Promise<([a: number])>) +>a : any +>async(): Promise<([a: number])> => [b] : () => Promise<([a: number])> +>[b] : [any] +>b : any +>0 : 0 + +const f82 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; +>f82 : 0 | (() => Promise<{ readonly: number; }>) +>a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0 : 0 | (() => Promise<{ readonly: number; }>) +>a : any +>async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : () => Promise<{ readonly: number; }> +>r\u0065adonly : number +>({ readonly: 0 }) : { readonly: number; } +>{ readonly: 0 } : { readonly: number; } +>readonly : number +>0 : 0 +>0 : 0 + +const f83 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; +>f83 : 0 | (() => Promise<{ get: number; }>) +>a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0 : 0 | (() => Promise<{ get: number; }>) +>a : any +>async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : () => Promise<{ get: number; }> +>g\u0065t : number +>({ get: 0 }) : { get: number; } +>{ get: 0 } : { get: number; } +>get : number +>0 : 0 +>0 : 0 + +const f84 = a ? async(): Promise => b : 0; +>f84 : 0 | (() => Promise) +>a ? async(): Promise => b : 0 : 0 | (() => Promise) +>a : any +>async(): Promise => b : () => Promise +>n\u0075mber : any +>b : any +>0 : 0 + +const f85 = a ? a ? as\u0079nc() : d => d : b; +>f85 : any +>a ? a ? as\u0079nc() : d => d : b : any +>a : any +>a ? as\u0079nc() : d => d : any +>a : any +>as\u0079nc() : any +>as\u0079nc : (...a: any[]) => any +>d => d : (d: any) => any +>d : any +>d : any +>b : any + +const f86 = a ? async(): Promise => 0 : 0; +>f86 : 0 | (() => Promise) +>a ? async(): Promise => 0 : 0 : 0 | (() => Promise) +>a : any +>async(): Promise => 0 : () => Promise +>0 : 0 +>0 : 0 + diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js index 7f11a6c69a7b4..d2018d918bcc5 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.js @@ -50,6 +50,7 @@ const f21 = a ? d => d = async () => async() : (d => d = 0); const f22 = h => a ? async(h = a ? async() : d => d) : d => d; const f23 = a ? async() : (d => d); const f24 = a ? async() : d => (a ? async() : d => d); +const f25 = a ? a ? as\u0079nc() : d => d : b; //// [a.js] @@ -105,3 +106,4 @@ const f21 = a ? d => d = () => __awaiter(void 0, void 0, void 0, function* () { const f22 = h => a ? async(h = a ? async() : d => d) : d => d; const f23 = a ? async() : (d => d); const f24 = a ? async() : d => (a ? async() : d => d); +const f25 = a ? a ? as\u0079nc() : d => d : b; diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols index 6ce0cdc5aa283..8457a46127de5 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.symbols @@ -235,3 +235,12 @@ const f24 = a ? async() : d => (a ? async() : d => d); >d : Symbol(d, Decl(a.js, 48, 45)) >d : Symbol(d, Decl(a.js, 48, 45)) +const f25 = a ? a ? as\u0079nc() : d => d : b; +>f25 : Symbol(f25, Decl(a.js, 49, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>a : Symbol(a, Decl(a.js, 0, 5)) +>as\u0079nc : Symbol(async, Decl(a.js, 2, 14)) +>d : Symbol(d, Decl(a.js, 49, 34)) +>d : Symbol(d, Decl(a.js, 49, 34)) +>b : Symbol(b, Decl(a.js, 1, 5)) + diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types index ac9e771b20735..a4e726e10469b 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunctionJs.types @@ -357,3 +357,16 @@ const f24 = a ? async() : d => (a ? async() : d => d); >d : any >d : any +const f25 = a ? a ? as\u0079nc() : d => d : b; +>f25 : number | ((d: any) => any) +>a ? a ? as\u0079nc() : d => d : b : number | ((d: any) => any) +>a : true +>a ? as\u0079nc() : d => d : number | ((d: any) => any) +>a : true +>as\u0079nc() : number +>as\u0079nc : (...c: any[]) => number +>d => d : (d: any) => any +>d : any +>d : any +>b : 1 + diff --git a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts index 23004f2263b09..2c106bdbdbdf3 100644 --- a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts +++ b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts @@ -124,3 +124,17 @@ const f72 = a ? a ? async (): T => (x): T => async() : x => x; const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; const f74 = a ? async (x): T => async (): T => b; const f75 = a ? async (x): T => async() : x => x; + +declare function h(a: A): A; +declare namespace number { type T = number; } +const f76 = a ? async(x = b < (d + 1)): T => x : 0; +const f77 = a ? async(x = b << (d + 1)): T => x : 0; +const f78 = a ? async(x = new b < (d + 1)): T => x : 0; +const f79 = a ? async(x = h(b)): T => x : 0; +const f80 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; +const f81 = a ? async(): Promise<([a: number])> => [b] : 0; +const f82 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; +const f83 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; +const f84 = a ? async(): Promise => b : 0; +const f85 = a ? a ? as\u0079nc() : d => d : b; +const f86 = a ? async(): Promise => 0 : 0; diff --git a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts index cad044a41a02f..c4078243cd7ae 100644 --- a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts +++ b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunctionJs.ts @@ -53,3 +53,4 @@ const f21 = a ? d => d = async () => async() : (d => d = 0); const f22 = h => a ? async(h = a ? async() : d => d) : d => d; const f23 = a ? async() : (d => d); const f24 = a ? async() : d => (a ? async() : d => d); +const f25 = a ? a ? as\u0079nc() : d => d : b; From 9fb9005da083a26bdb1bb144f3808f256a1c3765 Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk Date: Sat, 24 Oct 2026 10:22:56 +0300 Subject: [PATCH 7/7] cleanup --- tsc/internal/parser/parser_test.go | 12 +- tsc/internal/parser/tentative.go | 31 ++- tsc/internal/parser/tentative_test.go | 11 - ...parenthesizedAsyncArrowFunction.errors.txt | 90 ++++--- .../parenthesizedAsyncArrowFunction.js | 176 ++++++------- .../parenthesizedAsyncArrowFunction.symbols | 248 +++++++++--------- .../parenthesizedAsyncArrowFunction.types | 189 +++++++------ .../parenthesizedAsyncArrowFunction.ts | 90 ++++--- 8 files changed, 406 insertions(+), 441 deletions(-) diff --git a/tsc/internal/parser/parser_test.go b/tsc/internal/parser/parser_test.go index 0deb634482298..b6c21367d509d 100644 --- a/tsc/internal/parser/parser_test.go +++ b/tsc/internal/parser/parser_test.go @@ -242,7 +242,9 @@ func parseConditionalInGenerator(t *testing.T, expression string, kind core.Scri assert.Equal(t, len(file.JSDiagnostics()), 0) statement := file.Statements.Nodes[0].Body().AsBlock().Statements.Nodes[0] declaration := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes[0] - return declaration.Initializer().AsConditionalExpression() + conditional := declaration.Initializer().AsConditionalExpression() + assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) + return conditional } func checkConditionalAsyncNesting(t *testing.T, prefix string, closing string) { @@ -269,7 +271,6 @@ func TestConditionalAsyncCall(t *testing.T) { t.Parallel() conditional := parseConditionalInGenerator(t, "b ? async(...c) : 0", core.ScriptKindTS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindNumericLiteral) } @@ -277,7 +278,6 @@ func TestConditionalAsyncCallWithArrow(t *testing.T) { t.Parallel() conditional := parseConditionalInGenerator(t, "b ? async(...c) : d => d", core.ScriptKindTS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) } @@ -285,7 +285,6 @@ func TestConditionalAsyncCallYield(t *testing.T) { t.Parallel() conditional := parseConditionalInGenerator(t, "b ? yield async(...c) : 0", core.ScriptKindTS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindYieldExpression) - assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindNumericLiteral) assert.Equal(t, conditional.WhenTrue.Expression().Kind, ast.KindCallExpression) } @@ -294,7 +293,6 @@ func TestConditionalAsyncCallYieldWithArrow(t *testing.T) { t.Parallel() conditional := parseConditionalInGenerator(t, "b ? yield async(...c) : d => d", core.ScriptKindTS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindYieldExpression) - assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) assert.Equal(t, conditional.WhenTrue.Expression().Kind, ast.KindCallExpression) } @@ -303,7 +301,6 @@ func TestConditionalAsyncCallJS(t *testing.T) { t.Parallel() conditional := parseConditionalInGenerator(t, "b ? async(...c) : 0", core.ScriptKindJS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindNumericLiteral) } @@ -311,7 +308,6 @@ func TestConditionalAsyncCallWithArrowJS(t *testing.T) { t.Parallel() conditional := parseConditionalInGenerator(t, "b ? async(...c) : d => d", core.ScriptKindJS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindCallExpression) - assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) } @@ -319,7 +315,6 @@ func TestConditionalAsyncCallYieldJS(t *testing.T) { t.Parallel() conditional := parseConditionalInGenerator(t, "b ? yield async(...c) : 0", core.ScriptKindJS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindYieldExpression) - assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindNumericLiteral) assert.Equal(t, conditional.WhenTrue.Expression().Kind, ast.KindCallExpression) } @@ -328,7 +323,6 @@ func TestConditionalAsyncCallYieldWithArrowJS(t *testing.T) { t.Parallel() conditional := parseConditionalInGenerator(t, "b ? yield async(...c) : d => d", core.ScriptKindJS) assert.Equal(t, conditional.WhenTrue.Kind, ast.KindYieldExpression) - assert.Equal(t, conditional.WhenTrue.Flags&ast.NodeFlagsYieldContext, ast.NodeFlagsYieldContext) assert.Equal(t, conditional.WhenFalse.Kind, ast.KindArrowFunction) assert.Equal(t, conditional.WhenTrue.Expression().Kind, ast.KindCallExpression) } diff --git a/tsc/internal/parser/tentative.go b/tsc/internal/parser/tentative.go index 01ba6c95d57ea..6adfb7a916389 100644 --- a/tsc/internal/parser/tentative.go +++ b/tsc/internal/parser/tentative.go @@ -44,36 +44,41 @@ func (p *Parser) beginTentativeParse() tentativeParse { } func (tp *tentativeParse) silence() { + parser := tp.parser if tp.nodes == nil { - tp.nodes = tp.parser.tentativeNodes + tp.nodes = parser.tentativeNodes if tp.nodes == nil { tp.nodes = make(map[int][]tentativeNode) } } - tp.parser.tentativeNodes = tp.nodes - tp.parser.parsingFlags |= ParsingFlagsTentative - tp.parser.hasParseError = false + parser.tentativeNodes = tp.nodes + parser.parsingFlags |= ParsingFlagsTentative + parser.hasParseError = false } func (tp *tentativeParse) rewind() { - tp.parser.rewind(tp.state) - tp.parser.parsingFlags = tp.parsingFlags - tp.parser.parsingContexts = tp.parsingContexts + parser := tp.parser + parser.rewind(tp.state) + parser.parsingFlags = tp.parsingFlags + parser.parsingContexts = tp.parsingContexts } func (tp *tentativeParse) commit() { - if tp.parser != nil { - tp.restore() - tp.parser.tentativeNodes = tp.state.tentativeNodes + parser := tp.parser + if parser == nil { + return } + tp.restore() + parser.tentativeNodes = tp.state.tentativeNodes tp.parser = nil } func (tp *tentativeParse) revert() { - if tp.parser != nil { - tp.rewind() - tp.parser = nil + if tp.parser == nil { + return } + tp.rewind() + tp.parser = nil } func (tp *tentativeParse) close() { diff --git a/tsc/internal/parser/tentative_test.go b/tsc/internal/parser/tentative_test.go index 45241300be6df..a653c3a4bc68d 100644 --- a/tsc/internal/parser/tentative_test.go +++ b/tsc/internal/parser/tentative_test.go @@ -288,17 +288,6 @@ func TestArrowFunctionHeadAmbiguity(t *testing.T) { assert.Assert(t, reflect.DeepEqual(p.mark(), headState)) } -func TestArrowFunctionHeadParameterType(t *testing.T) { - t.Parallel() - p := newTestParser("async (...a: number[]): T => a ?") - status, signature := p.parseArrowFunctionHead(ExpressionParseFlagsAllowArrowFunctionRecovery | ExpressionParseFlagsDisallowArrowReturnType) - assert.Equal(t, status, core.TSTrue) - assert.Equal(t, len(signature.parameters.Nodes), 1) - assert.Equal(t, signature.parameters.Nodes[0].Type().Kind, ast.KindArrayType) - assert.Equal(t, p.token, ast.KindEqualsGreaterThanToken) - assert.Equal(t, len(p.diagnostics), 0) -} - func TestArrowFunctionHeadRollback(t *testing.T) { t.Parallel() p := newTestParser("async(a = b.c)") diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.errors.txt b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.errors.txt index 9f81590472faf..b8dd4659c2b18 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.errors.txt +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.errors.txt @@ -55,7 +55,7 @@ c.ts(35,34): error TS1260: Keywords cannot contain escape characters. const f29 = a ? async (...c): Promise => async() : x => x; const f30 = a ? async (): Promise => async() : x => x; const f31 = a ? async (): (Promise) => async() : x => x; - const f32 = a ? async (...c: number[]): Promise => async() : x => x; + const f32 = a ? async (...c: number[]): T => async() : x => x; const f33 = a ? async() : 0 {} @@ -82,43 +82,41 @@ c.ts(35,34): error TS1260: Keywords cannot contain escape characters. {} const f42 = a ? (c) : 0 {} - const f43 = a ? async() : 0; - {} - const f44 = a ? async() : T => async (...c): T => c.length; + const f43 = a ? async() : T => async (...c): T => c.length; - const f45 = a ? async (): T => (b) : d => d; - const f46 = a ? async (): T => async() : d => d; - const f47 = a ? async (): T => async() : b; - const f48 = a ? a ? async() : d => d : b; - const f49 = a ? a ? async(b) : d => d : b; - const f50 = a ? a ? async(...c) : d => d : b; - const f51 = a ? a ? async() : T => b : async (): T => b; - const f52 = a ? async (): T => async() : (d): number => d; - const f53 = a ? a ? async (): T => async() : d => d : b; - const f54 = a ? async (): T => a ? async() : b : d => d; - const f55 = a ? a ? async() : d => d : a ? async() : d => d; - const f56 = a ? a ? a ? async() : d => d : b : b; + const f44 = a ? async (): T => (b) : d => d; + const f45 = a ? async (): T => async() : d => d; + const f46 = a ? async (): T => async() : b; + const f47 = a ? a ? async() : d => d : b; + const f48 = a ? a ? async(b) : d => d : b; + const f49 = a ? a ? async(...c) : d => d : b; + const f50 = a ? a ? async() : T => b : async (): T => b; + const f51 = a ? async (): T => async() : (d): number => d; + const f52 = a ? a ? async (): T => async() : d => d : b; + const f53 = a ? async (): T => a ? async() : b : d => d; + const f54 = a ? a ? async() : d => d : a ? async() : d => d; + const f55 = a ? a ? a ? async() : d => d : b : b; - const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); - const f58 = a ? d => d = async () => async() : (d => d = 0); + const f56 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); + const f57 = a ? d => d = async () => async() : (d => d = 0); ==== b.ts (7 errors) ==== - const f59 = a ? async(...c: number[]): Promise => 0; + const f58 = a ? async(...c: number[]): Promise => 0; ~ !!! error TS1005: ':' expected. - const f60 = a ? async (): Promise {} : d => d; + const f59 = a ? async (): Promise {} : d => d; ~~~~~~~~~~~~~~~ !!! error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. ~ !!! error TS1005: '=>' expected. - const f61 = a ? (c): number {} : d => d; + const f60 = a ? (c): number {} : d => d; ~~~~~~ !!! error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. ~ !!! error TS1005: '=>' expected. - const f62 = a ? async() : T => async(a ? b); + const f61 = a ? async() : T => async(a ? b); ~ !!! error TS1005: ':' expected. ~ @@ -130,36 +128,36 @@ c.ts(35,34): error TS1260: Keywords cannot contain escape characters. declare function async(...a: any[]): any; type T = Promise; let d: any; - const f63 = a ? d = (d): T => a ? 0 : async(...c) : T => b; - const f64 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; - const f65 = a ? async (): T => (d): T => async() : b; - const f66 = (a ? async (): T => (d): T => async() : b); - const f67 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; - const f68 = a ? async (c = a ? async() : d => d): T => async() : b; - const f69 = a ? a ? (d): T => a ? async() : b : d => d : b; - const f70 = a ? async() : (d => d); - const f71 = a ? async() : d => (a ? async() : d => d); + const f62 = a ? d = (d): T => a ? 0 : async(...c) : T => b; + const f63 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; + const f64 = a ? async (): T => (d): T => async() : b; + const f65 = (a ? async (): T => (d): T => async() : b); + const f66 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; + const f67 = a ? async (c = a ? async() : d => d): T => async() : b; + const f68 = a ? a ? (d): T => a ? async() : b : d => d : b; + const f69 = a ? async() : (d => d); + const f70 = a ? async() : d => (a ? async() : d => d); type x = T; declare const x: any; - const f72 = a ? a ? async (): T => (x): T => async() : x => x; - const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; - const f74 = a ? async (x): T => async (): T => b; - const f75 = a ? async (x): T => async() : x => x; + const f71 = a ? a ? async (): T => (x): T => async() : x => x; + const f72 = a ? a ? async (): Promise => (x): T => async() : x => x; + const f73 = a ? async (x): T => async (): T => b; + const f74 = a ? async (x): T => async() : x => x; declare function h(a: A): A; declare namespace number { type T = number; } - const f76 = a ? async(x = b < (d + 1)): T => x : 0; - const f77 = a ? async(x = b << (d + 1)): T => x : 0; - const f78 = a ? async(x = new b < (d + 1)): T => x : 0; - const f79 = a ? async(x = h(b)): T => x : 0; - const f80 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; - const f81 = a ? async(): Promise<([a: number])> => [b] : 0; - const f82 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; - const f83 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; - const f84 = a ? async(): Promise => b : 0; - const f85 = a ? a ? as\u0079nc() : d => d : b; - const f86 = a ? async(): Promise => 0 : 0; + const f75 = a ? async(x = b < (d + 1)): T => x : 0; + const f76 = a ? async(x = b << (d + 1)): T => x : 0; + const f77 = a ? async(x = new b < (d + 1)): T => x : 0; + const f78 = a ? async(x = h(b)): T => x : 0; + const f79 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; + const f80 = a ? async(): Promise<([a: number])> => [b] : 0; + const f81 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; + const f82 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; + const f83 = a ? async(): Promise => b : 0; + const f84 = a ? a ? as\u0079nc() : d => d : b; + const f85 = a ? async(): Promise => 0 : 0; ~~~~~~~~~~~ !!! error TS1260: Keywords cannot contain escape characters. \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js index 5d9c0ee230763..b0cca4276d68e 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.js @@ -47,7 +47,7 @@ const f28 = a ? async (): Promise => async(...c) : x => x; const f29 = a ? async (...c): Promise => async() : x => x; const f30 = a ? async (): Promise => async() : x => x; const f31 = a ? async (): (Promise) => async() : x => x; -const f32 = a ? async (...c: number[]): Promise => async() : x => x; +const f32 = a ? async (...c: number[]): T => async() : x => x; const f33 = a ? async() : 0 {} @@ -74,33 +74,31 @@ const f41 = a ? async(...c) : 0 {} const f42 = a ? (c) : 0 {} -const f43 = a ? async() : 0; -{} -const f44 = a ? async() : T => async (...c): T => c.length; +const f43 = a ? async() : T => async (...c): T => c.length; -const f45 = a ? async (): T => (b) : d => d; -const f46 = a ? async (): T => async() : d => d; -const f47 = a ? async (): T => async() : b; -const f48 = a ? a ? async() : d => d : b; -const f49 = a ? a ? async(b) : d => d : b; -const f50 = a ? a ? async(...c) : d => d : b; -const f51 = a ? a ? async() : T => b : async (): T => b; -const f52 = a ? async (): T => async() : (d): number => d; -const f53 = a ? a ? async (): T => async() : d => d : b; -const f54 = a ? async (): T => a ? async() : b : d => d; -const f55 = a ? a ? async() : d => d : a ? async() : d => d; -const f56 = a ? a ? a ? async() : d => d : b : b; +const f44 = a ? async (): T => (b) : d => d; +const f45 = a ? async (): T => async() : d => d; +const f46 = a ? async (): T => async() : b; +const f47 = a ? a ? async() : d => d : b; +const f48 = a ? a ? async(b) : d => d : b; +const f49 = a ? a ? async(...c) : d => d : b; +const f50 = a ? a ? async() : T => b : async (): T => b; +const f51 = a ? async (): T => async() : (d): number => d; +const f52 = a ? a ? async (): T => async() : d => d : b; +const f53 = a ? async (): T => a ? async() : b : d => d; +const f54 = a ? a ? async() : d => d : a ? async() : d => d; +const f55 = a ? a ? a ? async() : d => d : b : b; -const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); -const f58 = a ? d => d = async () => async() : (d => d = 0); +const f56 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +const f57 = a ? d => d = async () => async() : (d => d = 0); //// [b.ts] -const f59 = a ? async(...c: number[]): Promise => 0; -const f60 = a ? async (): Promise {} : d => d; -const f61 = a ? (c): number {} : d => d; +const f58 = a ? async(...c: number[]): Promise => 0; +const f59 = a ? async (): Promise {} : d => d; +const f60 = a ? (c): number {} : d => d; -const f62 = a ? async() : T => async(a ? b); +const f61 = a ? async() : T => async(a ? b); //// [c.ts] export {}; @@ -108,36 +106,36 @@ declare const a: any, b: any, c: any[]; declare function async(...a: any[]): any; type T = Promise; let d: any; -const f63 = a ? d = (d): T => a ? 0 : async(...c) : T => b; -const f64 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; -const f65 = a ? async (): T => (d): T => async() : b; -const f66 = (a ? async (): T => (d): T => async() : b); -const f67 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; -const f68 = a ? async (c = a ? async() : d => d): T => async() : b; -const f69 = a ? a ? (d): T => a ? async() : b : d => d : b; -const f70 = a ? async() : (d => d); -const f71 = a ? async() : d => (a ? async() : d => d); +const f62 = a ? d = (d): T => a ? 0 : async(...c) : T => b; +const f63 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; +const f64 = a ? async (): T => (d): T => async() : b; +const f65 = (a ? async (): T => (d): T => async() : b); +const f66 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; +const f67 = a ? async (c = a ? async() : d => d): T => async() : b; +const f68 = a ? a ? (d): T => a ? async() : b : d => d : b; +const f69 = a ? async() : (d => d); +const f70 = a ? async() : d => (a ? async() : d => d); type x = T; declare const x: any; -const f72 = a ? a ? async (): T => (x): T => async() : x => x; -const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; -const f74 = a ? async (x): T => async (): T => b; -const f75 = a ? async (x): T => async() : x => x; +const f71 = a ? a ? async (): T => (x): T => async() : x => x; +const f72 = a ? a ? async (): Promise => (x): T => async() : x => x; +const f73 = a ? async (x): T => async (): T => b; +const f74 = a ? async (x): T => async() : x => x; declare function h(a: A): A; declare namespace number { type T = number; } -const f76 = a ? async(x = b < (d + 1)): T => x : 0; -const f77 = a ? async(x = b << (d + 1)): T => x : 0; -const f78 = a ? async(x = new b < (d + 1)): T => x : 0; -const f79 = a ? async(x = h(b)): T => x : 0; -const f80 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; -const f81 = a ? async(): Promise<([a: number])> => [b] : 0; -const f82 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; -const f83 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; -const f84 = a ? async(): Promise => b : 0; -const f85 = a ? a ? as\u0079nc() : d => d : b; -const f86 = a ? async(): Promise => 0 : 0; +const f75 = a ? async(x = b < (d + 1)): T => x : 0; +const f76 = a ? async(x = b << (d + 1)): T => x : 0; +const f77 = a ? async(x = new b < (d + 1)): T => x : 0; +const f78 = a ? async(x = h(b)): T => x : 0; +const f79 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; +const f80 = a ? async(): Promise<([a: number])> => [b] : 0; +const f81 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; +const f82 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; +const f83 = a ? async(): Promise => b : 0; +const f84 = a ? a ? as\u0079nc() : d => d : b; +const f85 = a ? async(): Promise => 0 : 0; //// [a.js] @@ -212,23 +210,21 @@ const f41 = a ? async(...c) : 0; { } const f42 = a ? (c) : 0; { } -const f43 = a ? async() : 0; -{ } -const f44 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(...c); }) : T => c.length; -const f45 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return (b); }) : d => d; -const f46 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : d => d; -const f47 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : b; -const f48 = a ? a ? async() : d => d : b; -const f49 = a ? a ? async(b) : d => d : b; -const f50 = a ? a ? async(...c) : d => d : b; -const f51 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { return b; }) : async() : T => b; -const f52 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : (d) => d; -const f53 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : d => d : b; -const f54 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return a ? async() : b; }) : d => d; -const f55 = a ? a ? async() : d => d : a ? async() : d => d; -const f56 = a ? a ? a ? async() : d => d : b : b; -const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); -const f58 = a ? d => d = () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : (d => d = 0); +const f43 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(...c); }) : T => c.length; +const f44 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return (b); }) : d => d; +const f45 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : d => d; +const f46 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : b; +const f47 = a ? a ? async() : d => d : b; +const f48 = a ? a ? async(b) : d => d : b; +const f49 = a ? a ? async(...c) : d => d : b; +const f50 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { return b; }) : async() : T => b; +const f51 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : (d) => d; +const f52 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : d => d : b; +const f53 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return a ? async() : b; }) : d => d; +const f54 = a ? a ? async() : d => d : a ? async() : d => d; +const f55 = a ? a ? a ? async() : d => d : b : b; +const f56 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +const f57 = a ? d => d = () => __awaiter(void 0, void 0, void 0, function* () { return async(); }) : (d => d = 0); //// [b.js] "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { @@ -240,10 +236,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -const f59 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return 0; }) : ; -const f60 = a ? () => __awaiter(void 0, void 0, void 0, function* () { }) : d => d; -const f61 = a ? (c) => { } : d => d; -const f62 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(a ? b : ); }) : ; +const f58 = a ? (...c) => __awaiter(void 0, void 0, void 0, function* () { return 0; }) : ; +const f59 = a ? () => __awaiter(void 0, void 0, void 0, function* () { }) : d => d; +const f60 = a ? (c) => { } : d => d; +const f61 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return async(a ? b : ); }) : ; //// [c.js] var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } @@ -255,28 +251,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; let d; -const f63 = a ? d = (d) : T => a ? 0 : (...c) => __awaiter(void 0, void 0, void 0, function* () { return b; }); -const f64 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return () => __awaiter(void 0, void 0, void 0, function* () { return (d) => b; }); }) : a ? d => (d) : T => (...c) => __awaiter(void 0, void 0, void 0, function* () { return b; }); -const f65 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return (d) => async(); }) : b; -const f66 = (a ? () => __awaiter(void 0, void 0, void 0, function* () { return (d) => async(); }) : b); -const f67 = a ? d = (d) : T => a ? 0 : (...c) => __awaiter(void 0, void 0, void 0, function* () { return a ? d = (d) : T => a ? 0 : (...c) => __awaiter(void 0, void 0, void 0, function* () { return b; }); }); -const f68 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (c = a ? async() : d => d) { return async(); }) : b; -const f69 = a ? a ? (d) => a ? async() : b : d => d : b; -const f70 = a ? async() : (d => d); -const f71 = a ? async() : d => (a ? async() : d => d); +const f62 = a ? d = (d) : T => a ? 0 : (...c) => __awaiter(void 0, void 0, void 0, function* () { return b; }); +const f63 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return () => __awaiter(void 0, void 0, void 0, function* () { return (d) => b; }); }) : a ? d => (d) : T => (...c) => __awaiter(void 0, void 0, void 0, function* () { return b; }); +const f64 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return (d) => async(); }) : b; +const f65 = (a ? () => __awaiter(void 0, void 0, void 0, function* () { return (d) => async(); }) : b); +const f66 = a ? d = (d) : T => a ? 0 : (...c) => __awaiter(void 0, void 0, void 0, function* () { return a ? d = (d) : T => a ? 0 : (...c) => __awaiter(void 0, void 0, void 0, function* () { return b; }); }); +const f67 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (c = a ? async() : d => d) { return async(); }) : b; +const f68 = a ? a ? (d) => a ? async() : b : d => d : b; +const f69 = a ? async() : (d => d); +const f70 = a ? async() : d => (a ? async() : d => d); +const f71 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { return (x); }) : T => async() : x => x; const f72 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { return (x); }) : T => async() : x => x; -const f73 = a ? a ? () => __awaiter(void 0, void 0, void 0, function* () { return (x); }) : T => async() : x => x; -const f74 = a ? async(x) : T => () => __awaiter(void 0, void 0, void 0, function* () { return b; }); -const f75 = a ? async(x) : T => () => __awaiter(void 0, void 0, void 0, function* () { return x; }); -const f76 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (x = b < (d + 1)) { return x; }) : 0; -const f77 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (x = b << (d + 1)) { return x; }) : 0; -const f78 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (x = new b < (d + 1)) { return x; }) : 0; -const f79 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (x = h(b)) { return x; }) : 0; -const f80 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return ({ a: [] }); }) : 0; -const f81 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return [b]; }) : 0; -const f82 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return ({ readonly: 0 }); }) : 0; -const f83 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return ({ get: 0 }); }) : 0; -const f84 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return b; }) : 0; -const f85 = a ? a ? as\u0079nc() : d => d : b; -const f86 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return 0; }) : 0; +const f73 = a ? async(x) : T => () => __awaiter(void 0, void 0, void 0, function* () { return b; }); +const f74 = a ? async(x) : T => () => __awaiter(void 0, void 0, void 0, function* () { return x; }); +const f75 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (x = b < (d + 1)) { return x; }) : 0; +const f76 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (x = b << (d + 1)) { return x; }) : 0; +const f77 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (x = new b < (d + 1)) { return x; }) : 0; +const f78 = a ? (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (x = h(b)) { return x; }) : 0; +const f79 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return ({ a: [] }); }) : 0; +const f80 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return [b]; }) : 0; +const f81 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return ({ readonly: 0 }); }) : 0; +const f82 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return ({ get: 0 }); }) : 0; +const f83 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return b; }) : 0; +const f84 = a ? a ? as\u0079nc() : d => d : b; +const f85 = a ? () => __awaiter(void 0, void 0, void 0, function* () { return 0; }) : 0; export {}; diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols index e0f9714b6a9bf..3eeb79b9aef66 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.symbols @@ -273,14 +273,14 @@ const f31 = a ? async (): (Promise) => async() : x => x; >x : Symbol(x, Decl(a.ts, 45, 56)) >x : Symbol(x, Decl(a.ts, 45, 56)) -const f32 = a ? async (...c: number[]): Promise => async() : x => x; +const f32 = a ? async (...c: number[]): T => async() : x => x; >f32 : Symbol(f32, Decl(a.ts, 46, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >c : Symbol(c, Decl(a.ts, 46, 23)) ->Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>T : Symbol(T, Decl(a.ts, 24, 73)) >async : Symbol(async, Decl(a.ts, 6, 14)) ->x : Symbol(x, Decl(a.ts, 46, 68)) ->x : Symbol(x, Decl(a.ts, 46, 68)) +>x : Symbol(x, Decl(a.ts, 46, 54)) +>x : Symbol(x, Decl(a.ts, 46, 54)) const f33 = a ? async() : 0 >f33 : Symbol(f33, Decl(a.ts, 48, 5)) @@ -374,183 +374,177 @@ const f42 = a ? (c) : 0 >a : Symbol(a, Decl(a.ts, 4, 5)) >c : Symbol(c, Decl(a.ts, 6, 5)) -{} -const f43 = a ? async() : 0; ->f43 : Symbol(f43, Decl(a.ts, 73, 5)) ->a : Symbol(a, Decl(a.ts, 4, 5)) ->async : Symbol(async, Decl(a.ts, 6, 14)) - {} -const f44 = a ? async() : T => async (...c): T => c.length; ->f44 : Symbol(f44, Decl(a.ts, 76, 5)) +const f43 = a ? async() : T => async (...c): T => c.length; +>f43 : Symbol(f43, Decl(a.ts, 74, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >T : Symbol(T, Decl(a.ts, 24, 73)) >async : Symbol(async, Decl(a.ts, 6, 14)) >c : Symbol(c, Decl(a.ts, 6, 5)) ->T : Symbol(T, Decl(a.ts, 76, 44)) +>T : Symbol(T, Decl(a.ts, 74, 44)) >c.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) >c : Symbol(c, Decl(a.ts, 6, 5)) >length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --)) -const f45 = a ? async (): T => (b) : d => d; ->f45 : Symbol(f45, Decl(a.ts, 78, 5)) +const f44 = a ? async (): T => (b) : d => d; +>f44 : Symbol(f44, Decl(a.ts, 76, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >T : Symbol(T, Decl(a.ts, 24, 73)) >b : Symbol(b, Decl(a.ts, 5, 5)) ->d : Symbol(d, Decl(a.ts, 78, 36)) ->d : Symbol(d, Decl(a.ts, 78, 36)) +>d : Symbol(d, Decl(a.ts, 76, 36)) +>d : Symbol(d, Decl(a.ts, 76, 36)) -const f46 = a ? async (): T => async() : d => d; ->f46 : Symbol(f46, Decl(a.ts, 79, 5)) +const f45 = a ? async (): T => async() : d => d; +>f45 : Symbol(f45, Decl(a.ts, 77, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >T : Symbol(T, Decl(a.ts, 24, 73)) >async : Symbol(async, Decl(a.ts, 6, 14)) ->d : Symbol(d, Decl(a.ts, 79, 40)) ->d : Symbol(d, Decl(a.ts, 79, 40)) +>d : Symbol(d, Decl(a.ts, 77, 40)) +>d : Symbol(d, Decl(a.ts, 77, 40)) -const f47 = a ? async (): T => async() : b; ->f47 : Symbol(f47, Decl(a.ts, 80, 5)) +const f46 = a ? async (): T => async() : b; +>f46 : Symbol(f46, Decl(a.ts, 78, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >T : Symbol(T, Decl(a.ts, 24, 73)) >async : Symbol(async, Decl(a.ts, 6, 14)) >b : Symbol(b, Decl(a.ts, 5, 5)) -const f48 = a ? a ? async() : d => d : b; ->f48 : Symbol(f48, Decl(a.ts, 81, 5)) +const f47 = a ? a ? async() : d => d : b; +>f47 : Symbol(f47, Decl(a.ts, 79, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >async : Symbol(async, Decl(a.ts, 6, 14)) ->d : Symbol(d, Decl(a.ts, 81, 29)) ->d : Symbol(d, Decl(a.ts, 81, 29)) +>d : Symbol(d, Decl(a.ts, 79, 29)) +>d : Symbol(d, Decl(a.ts, 79, 29)) >b : Symbol(b, Decl(a.ts, 5, 5)) -const f49 = a ? a ? async(b) : d => d : b; ->f49 : Symbol(f49, Decl(a.ts, 82, 5)) +const f48 = a ? a ? async(b) : d => d : b; +>f48 : Symbol(f48, Decl(a.ts, 80, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >async : Symbol(async, Decl(a.ts, 6, 14)) >b : Symbol(b, Decl(a.ts, 5, 5)) ->d : Symbol(d, Decl(a.ts, 82, 30)) ->d : Symbol(d, Decl(a.ts, 82, 30)) +>d : Symbol(d, Decl(a.ts, 80, 30)) +>d : Symbol(d, Decl(a.ts, 80, 30)) >b : Symbol(b, Decl(a.ts, 5, 5)) -const f50 = a ? a ? async(...c) : d => d : b; ->f50 : Symbol(f50, Decl(a.ts, 83, 5)) +const f49 = a ? a ? async(...c) : d => d : b; +>f49 : Symbol(f49, Decl(a.ts, 81, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >async : Symbol(async, Decl(a.ts, 6, 14)) >c : Symbol(c, Decl(a.ts, 6, 5)) ->d : Symbol(d, Decl(a.ts, 83, 33)) ->d : Symbol(d, Decl(a.ts, 83, 33)) +>d : Symbol(d, Decl(a.ts, 81, 33)) +>d : Symbol(d, Decl(a.ts, 81, 33)) >b : Symbol(b, Decl(a.ts, 5, 5)) -const f51 = a ? a ? async() : T => b : async (): T => b; ->f51 : Symbol(f51, Decl(a.ts, 84, 5)) +const f50 = a ? a ? async() : T => b : async (): T => b; +>f50 : Symbol(f50, Decl(a.ts, 82, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >T : Symbol(T, Decl(a.ts, 24, 73)) >b : Symbol(b, Decl(a.ts, 5, 5)) >async : Symbol(async, Decl(a.ts, 6, 14)) ->T : Symbol(T, Decl(a.ts, 84, 48)) +>T : Symbol(T, Decl(a.ts, 82, 48)) >b : Symbol(b, Decl(a.ts, 5, 5)) -const f52 = a ? async (): T => async() : (d): number => d; ->f52 : Symbol(f52, Decl(a.ts, 85, 5)) +const f51 = a ? async (): T => async() : (d): number => d; +>f51 : Symbol(f51, Decl(a.ts, 83, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >T : Symbol(T, Decl(a.ts, 24, 73)) >async : Symbol(async, Decl(a.ts, 6, 14)) ->d : Symbol(d, Decl(a.ts, 85, 42)) ->d : Symbol(d, Decl(a.ts, 85, 42)) +>d : Symbol(d, Decl(a.ts, 83, 42)) +>d : Symbol(d, Decl(a.ts, 83, 42)) -const f53 = a ? a ? async (): T => async() : d => d : b; ->f53 : Symbol(f53, Decl(a.ts, 86, 5)) +const f52 = a ? a ? async (): T => async() : d => d : b; +>f52 : Symbol(f52, Decl(a.ts, 84, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >T : Symbol(T, Decl(a.ts, 24, 73)) >async : Symbol(async, Decl(a.ts, 6, 14)) ->d : Symbol(d, Decl(a.ts, 86, 44)) ->d : Symbol(d, Decl(a.ts, 86, 44)) +>d : Symbol(d, Decl(a.ts, 84, 44)) +>d : Symbol(d, Decl(a.ts, 84, 44)) >b : Symbol(b, Decl(a.ts, 5, 5)) -const f54 = a ? async (): T => a ? async() : b : d => d; ->f54 : Symbol(f54, Decl(a.ts, 87, 5)) +const f53 = a ? async (): T => a ? async() : b : d => d; +>f53 : Symbol(f53, Decl(a.ts, 85, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >T : Symbol(T, Decl(a.ts, 24, 73)) >a : Symbol(a, Decl(a.ts, 4, 5)) >async : Symbol(async, Decl(a.ts, 6, 14)) >b : Symbol(b, Decl(a.ts, 5, 5)) ->d : Symbol(d, Decl(a.ts, 87, 48)) ->d : Symbol(d, Decl(a.ts, 87, 48)) +>d : Symbol(d, Decl(a.ts, 85, 48)) +>d : Symbol(d, Decl(a.ts, 85, 48)) -const f55 = a ? a ? async() : d => d : a ? async() : d => d; ->f55 : Symbol(f55, Decl(a.ts, 88, 5)) +const f54 = a ? a ? async() : d => d : a ? async() : d => d; +>f54 : Symbol(f54, Decl(a.ts, 86, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >async : Symbol(async, Decl(a.ts, 6, 14)) ->d : Symbol(d, Decl(a.ts, 88, 29)) ->d : Symbol(d, Decl(a.ts, 88, 29)) +>d : Symbol(d, Decl(a.ts, 86, 29)) +>d : Symbol(d, Decl(a.ts, 86, 29)) >a : Symbol(a, Decl(a.ts, 4, 5)) >async : Symbol(async, Decl(a.ts, 6, 14)) ->d : Symbol(d, Decl(a.ts, 88, 52)) ->d : Symbol(d, Decl(a.ts, 88, 52)) +>d : Symbol(d, Decl(a.ts, 86, 52)) +>d : Symbol(d, Decl(a.ts, 86, 52)) -const f56 = a ? a ? a ? async() : d => d : b : b; ->f56 : Symbol(f56, Decl(a.ts, 89, 5)) +const f55 = a ? a ? a ? async() : d => d : b : b; +>f55 : Symbol(f55, Decl(a.ts, 87, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >async : Symbol(async, Decl(a.ts, 6, 14)) ->d : Symbol(d, Decl(a.ts, 89, 33)) ->d : Symbol(d, Decl(a.ts, 89, 33)) +>d : Symbol(d, Decl(a.ts, 87, 33)) +>d : Symbol(d, Decl(a.ts, 87, 33)) >b : Symbol(b, Decl(a.ts, 5, 5)) >b : Symbol(b, Decl(a.ts, 5, 5)) -const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); ->f57 : Symbol(f57, Decl(a.ts, 91, 5)) +const f56 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +>f56 : Symbol(f56, Decl(a.ts, 89, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) ->d : Symbol(d, Decl(a.ts, 91, 15)) +>d : Symbol(d, Decl(a.ts, 89, 15)) >a : Symbol(a, Decl(a.ts, 4, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >async : Symbol(async, Decl(a.ts, 6, 14)) >b : Symbol(b, Decl(a.ts, 5, 5)) >async : Symbol(async, Decl(a.ts, 6, 14)) ->d : Symbol(d, Decl(a.ts, 91, 57)) ->d : Symbol(d, Decl(a.ts, 91, 57)) +>d : Symbol(d, Decl(a.ts, 89, 57)) +>d : Symbol(d, Decl(a.ts, 89, 57)) >a : Symbol(a, Decl(a.ts, 4, 5)) -const f58 = a ? d => d = async () => async() : (d => d = 0); ->f58 : Symbol(f58, Decl(a.ts, 92, 5)) +const f57 = a ? d => d = async () => async() : (d => d = 0); +>f57 : Symbol(f57, Decl(a.ts, 90, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) ->d : Symbol(d, Decl(a.ts, 92, 15)) ->d : Symbol(d, Decl(a.ts, 92, 15)) +>d : Symbol(d, Decl(a.ts, 90, 15)) +>d : Symbol(d, Decl(a.ts, 90, 15)) >async : Symbol(async, Decl(a.ts, 6, 14)) ->d : Symbol(d, Decl(a.ts, 92, 48)) ->d : Symbol(d, Decl(a.ts, 92, 48)) +>d : Symbol(d, Decl(a.ts, 90, 48)) +>d : Symbol(d, Decl(a.ts, 90, 48)) === b.ts === -const f59 = a ? async(...c: number[]): Promise => 0; ->f59 : Symbol(f59, Decl(b.ts, 0, 5)) +const f58 = a ? async(...c: number[]): Promise => 0; +>f58 : Symbol(f58, Decl(b.ts, 0, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >c : Symbol(c, Decl(b.ts, 0, 22)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) -const f60 = a ? async (): Promise {} : d => d; ->f60 : Symbol(f60, Decl(b.ts, 1, 5)) +const f59 = a ? async (): Promise {} : d => d; +>f59 : Symbol(f59, Decl(b.ts, 1, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >d : Symbol(d, Decl(b.ts, 1, 46)) >d : Symbol(d, Decl(b.ts, 1, 46)) -const f61 = a ? (c): number {} : d => d; ->f61 : Symbol(f61, Decl(b.ts, 2, 5)) +const f60 = a ? (c): number {} : d => d; +>f60 : Symbol(f60, Decl(b.ts, 2, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >c : Symbol(c, Decl(b.ts, 2, 17)) >d : Symbol(d, Decl(b.ts, 2, 32)) >d : Symbol(d, Decl(b.ts, 2, 32)) -const f62 = a ? async() : T => async(a ? b); ->f62 : Symbol(f62, Decl(b.ts, 4, 5)) +const f61 = a ? async() : T => async(a ? b); +>f61 : Symbol(f61, Decl(b.ts, 4, 5)) >a : Symbol(a, Decl(a.ts, 4, 5)) >T : Symbol(T, Decl(a.ts, 24, 73)) >async : Symbol(async, Decl(a.ts, 6, 14)) @@ -575,8 +569,8 @@ type T = Promise; let d: any; >d : Symbol(d, Decl(c.ts, 4, 3)) -const f63 = a ? d = (d): T => a ? 0 : async(...c) : T => b; ->f63 : Symbol(f63, Decl(c.ts, 5, 5)) +const f62 = a ? d = (d): T => a ? 0 : async(...c) : T => b; +>f62 : Symbol(f62, Decl(c.ts, 5, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >d : Symbol(d, Decl(c.ts, 4, 3)) >d : Symbol(d, Decl(c.ts, 4, 3)) @@ -586,8 +580,8 @@ const f63 = a ? d = (d): T => a ? 0 : async(...c) : T => b; >T : Symbol(T, Decl(c.ts, 2, 41)) >b : Symbol(b, Decl(c.ts, 1, 21)) -const f64 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; ->f64 : Symbol(f64, Decl(c.ts, 6, 5)) +const f63 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; +>f63 : Symbol(f63, Decl(c.ts, 6, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >T : Symbol(T, Decl(c.ts, 2, 41)) >T : Symbol(T, Decl(c.ts, 2, 41)) @@ -602,8 +596,8 @@ const f64 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => a >T : Symbol(T, Decl(c.ts, 2, 41)) >b : Symbol(b, Decl(c.ts, 1, 21)) -const f65 = a ? async (): T => (d): T => async() : b; ->f65 : Symbol(f65, Decl(c.ts, 7, 5)) +const f64 = a ? async (): T => (d): T => async() : b; +>f64 : Symbol(f64, Decl(c.ts, 7, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >T : Symbol(T, Decl(c.ts, 2, 41)) >d : Symbol(d, Decl(c.ts, 7, 32)) @@ -611,8 +605,8 @@ const f65 = a ? async (): T => (d): T => async() : b; >async : Symbol(async, Decl(c.ts, 1, 39)) >b : Symbol(b, Decl(c.ts, 1, 21)) -const f66 = (a ? async (): T => (d): T => async() : b); ->f66 : Symbol(f66, Decl(c.ts, 8, 5)) +const f65 = (a ? async (): T => (d): T => async() : b); +>f65 : Symbol(f65, Decl(c.ts, 8, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >T : Symbol(T, Decl(c.ts, 2, 41)) >d : Symbol(d, Decl(c.ts, 8, 33)) @@ -620,8 +614,8 @@ const f66 = (a ? async (): T => (d): T => async() : b); >async : Symbol(async, Decl(c.ts, 1, 39)) >b : Symbol(b, Decl(c.ts, 1, 21)) -const f67 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; ->f67 : Symbol(f67, Decl(c.ts, 9, 5)) +const f66 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; +>f66 : Symbol(f66, Decl(c.ts, 9, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >d : Symbol(d, Decl(c.ts, 4, 3)) >d : Symbol(d, Decl(c.ts, 4, 3)) @@ -638,8 +632,8 @@ const f67 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 >T : Symbol(T, Decl(c.ts, 2, 41)) >b : Symbol(b, Decl(c.ts, 1, 21)) -const f68 = a ? async (c = a ? async() : d => d): T => async() : b; ->f68 : Symbol(f68, Decl(c.ts, 10, 5)) +const f67 = a ? async (c = a ? async() : d => d): T => async() : b; +>f67 : Symbol(f67, Decl(c.ts, 10, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >c : Symbol(c, Decl(c.ts, 10, 23)) >a : Symbol(a, Decl(c.ts, 1, 13)) @@ -650,8 +644,8 @@ const f68 = a ? async (c = a ? async() : d => d): T => async() : b; >async : Symbol(async, Decl(c.ts, 1, 39)) >b : Symbol(b, Decl(c.ts, 1, 21)) -const f69 = a ? a ? (d): T => a ? async() : b : d => d : b; ->f69 : Symbol(f69, Decl(c.ts, 11, 5)) +const f68 = a ? a ? (d): T => a ? async() : b : d => d : b; +>f68 : Symbol(f68, Decl(c.ts, 11, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >a : Symbol(a, Decl(c.ts, 1, 13)) >d : Symbol(d, Decl(c.ts, 11, 21)) @@ -663,15 +657,15 @@ const f69 = a ? a ? (d): T => a ? async() : b : d => d : b; >d : Symbol(d, Decl(c.ts, 11, 47)) >b : Symbol(b, Decl(c.ts, 1, 21)) -const f70 = a ? async() : (d => d); ->f70 : Symbol(f70, Decl(c.ts, 12, 5)) +const f69 = a ? async() : (d => d); +>f69 : Symbol(f69, Decl(c.ts, 12, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >async : Symbol(async, Decl(c.ts, 1, 39)) >d : Symbol(d, Decl(c.ts, 12, 27)) >d : Symbol(d, Decl(c.ts, 12, 27)) -const f71 = a ? async() : d => (a ? async() : d => d); ->f71 : Symbol(f71, Decl(c.ts, 13, 5)) +const f70 = a ? async() : d => (a ? async() : d => d); +>f70 : Symbol(f70, Decl(c.ts, 13, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >async : Symbol(async, Decl(c.ts, 1, 39)) >d : Symbol(d, Decl(c.ts, 13, 25)) @@ -687,8 +681,8 @@ type x = T; declare const x: any; >x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) -const f72 = a ? a ? async (): T => (x): T => async() : x => x; ->f72 : Symbol(f72, Decl(c.ts, 17, 5)) +const f71 = a ? a ? async (): T => (x): T => async() : x => x; +>f71 : Symbol(f71, Decl(c.ts, 17, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >a : Symbol(a, Decl(c.ts, 1, 13)) >T : Symbol(T, Decl(c.ts, 2, 41)) @@ -698,8 +692,8 @@ const f72 = a ? a ? async (): T => (x): T => async() : x => x; >x : Symbol(x, Decl(c.ts, 17, 54)) >x : Symbol(x, Decl(c.ts, 17, 54)) -const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; ->f73 : Symbol(f73, Decl(c.ts, 18, 5)) +const f72 = a ? a ? async (): Promise => (x): T => async() : x => x; +>f72 : Symbol(f72, Decl(c.ts, 18, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >a : Symbol(a, Decl(c.ts, 1, 13)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) @@ -709,8 +703,8 @@ const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; >x : Symbol(x, Decl(c.ts, 18, 65)) >x : Symbol(x, Decl(c.ts, 18, 65)) -const f74 = a ? async (x): T => async (): T => b; ->f74 : Symbol(f74, Decl(c.ts, 19, 5)) +const f73 = a ? async (x): T => async (): T => b; +>f73 : Symbol(f73, Decl(c.ts, 19, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >async : Symbol(async, Decl(c.ts, 1, 39)) >x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) @@ -718,8 +712,8 @@ const f74 = a ? async (x): T => async (): T => b; >T : Symbol(T, Decl(c.ts, 2, 41)) >b : Symbol(b, Decl(c.ts, 1, 21)) -const f75 = a ? async (x): T => async() : x => x; ->f75 : Symbol(f75, Decl(c.ts, 20, 5)) +const f74 = a ? async (x): T => async() : x => x; +>f74 : Symbol(f74, Decl(c.ts, 20, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >async : Symbol(async, Decl(c.ts, 1, 39)) >x : Symbol(x, Decl(c.ts, 13, 54), Decl(c.ts, 16, 13)) @@ -738,8 +732,8 @@ declare namespace number { type T = number; } >number : Symbol(number, Decl(c.ts, 22, 31)) >T : Symbol(T, Decl(c.ts, 23, 26)) -const f76 = a ? async(x = b < (d + 1)): T => x : 0; ->f76 : Symbol(f76, Decl(c.ts, 24, 5)) +const f75 = a ? async(x = b < (d + 1)): T => x : 0; +>f75 : Symbol(f75, Decl(c.ts, 24, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >x : Symbol(x, Decl(c.ts, 24, 22)) >b : Symbol(b, Decl(c.ts, 1, 21)) @@ -747,8 +741,8 @@ const f76 = a ? async(x = b < (d + 1)): T => x : 0; >T : Symbol(T, Decl(c.ts, 2, 41)) >x : Symbol(x, Decl(c.ts, 24, 22)) -const f77 = a ? async(x = b << (d + 1)): T => x : 0; ->f77 : Symbol(f77, Decl(c.ts, 25, 5)) +const f76 = a ? async(x = b << (d + 1)): T => x : 0; +>f76 : Symbol(f76, Decl(c.ts, 25, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >x : Symbol(x, Decl(c.ts, 25, 22)) >b : Symbol(b, Decl(c.ts, 1, 21)) @@ -756,8 +750,8 @@ const f77 = a ? async(x = b << (d + 1)): T => x : 0; >T : Symbol(T, Decl(c.ts, 2, 41)) >x : Symbol(x, Decl(c.ts, 25, 22)) -const f78 = a ? async(x = new b < (d + 1)): T => x : 0; ->f78 : Symbol(f78, Decl(c.ts, 26, 5)) +const f77 = a ? async(x = new b < (d + 1)): T => x : 0; +>f77 : Symbol(f77, Decl(c.ts, 26, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >x : Symbol(x, Decl(c.ts, 26, 22)) >b : Symbol(b, Decl(c.ts, 1, 21)) @@ -765,8 +759,8 @@ const f78 = a ? async(x = new b < (d + 1)): T => x : 0; >T : Symbol(T, Decl(c.ts, 2, 41)) >x : Symbol(x, Decl(c.ts, 26, 22)) -const f79 = a ? async(x = h(b)): T => x : 0; ->f79 : Symbol(f79, Decl(c.ts, 27, 5)) +const f78 = a ? async(x = h(b)): T => x : 0; +>f78 : Symbol(f78, Decl(c.ts, 27, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >x : Symbol(x, Decl(c.ts, 27, 22)) >h : Symbol(h, Decl(c.ts, 20, 49)) @@ -775,43 +769,43 @@ const f79 = a ? async(x = h(b)): T => x : 0; >T : Symbol(T, Decl(c.ts, 2, 41)) >x : Symbol(x, Decl(c.ts, 27, 22)) -const f80 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; ->f80 : Symbol(f80, Decl(c.ts, 28, 5)) +const f79 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; +>f79 : Symbol(f79, Decl(c.ts, 28, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >a : Symbol(a, Decl(c.ts, 28, 35)) >a : Symbol(a, Decl(c.ts, 28, 57)) -const f81 = a ? async(): Promise<([a: number])> => [b] : 0; ->f81 : Symbol(f81, Decl(c.ts, 29, 5)) +const f80 = a ? async(): Promise<([a: number])> => [b] : 0; +>f80 : Symbol(f80, Decl(c.ts, 29, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >b : Symbol(b, Decl(c.ts, 1, 21)) -const f82 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; ->f82 : Symbol(f82, Decl(c.ts, 30, 5)) +const f81 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; +>f81 : Symbol(f81, Decl(c.ts, 30, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >r\u0065adonly : Symbol(r\u0065adonly, Decl(c.ts, 30, 34)) >readonly : Symbol(readonly, Decl(c.ts, 30, 65)) -const f83 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; ->f83 : Symbol(f83, Decl(c.ts, 31, 5)) +const f82 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; +>f82 : Symbol(f82, Decl(c.ts, 31, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >g\u0065t : Symbol(g\u0065t, Decl(c.ts, 31, 34)) >get : Symbol(get, Decl(c.ts, 31, 60)) -const f84 = a ? async(): Promise => b : 0; ->f84 : Symbol(f84, Decl(c.ts, 32, 5)) +const f83 = a ? async(): Promise => b : 0; +>f83 : Symbol(f83, Decl(c.ts, 32, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >n\u0075mber : Symbol(number, Decl(c.ts, 22, 31)) >T : Symbol(number.T, Decl(c.ts, 23, 26)) >b : Symbol(b, Decl(c.ts, 1, 21)) -const f85 = a ? a ? as\u0079nc() : d => d : b; ->f85 : Symbol(f85, Decl(c.ts, 33, 5)) +const f84 = a ? a ? as\u0079nc() : d => d : b; +>f84 : Symbol(f84, Decl(c.ts, 33, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >a : Symbol(a, Decl(c.ts, 1, 13)) >as\u0079nc : Symbol(async, Decl(c.ts, 1, 39)) @@ -819,8 +813,8 @@ const f85 = a ? a ? as\u0079nc() : d => d : b; >d : Symbol(d, Decl(c.ts, 33, 34)) >b : Symbol(b, Decl(c.ts, 1, 21)) -const f86 = a ? async(): Promise => 0 : 0; ->f86 : Symbol(f86, Decl(c.ts, 34, 5)) +const f85 = a ? async(): Promise => 0 : 0; +>f85 : Symbol(f85, Decl(c.ts, 34, 5)) >a : Symbol(a, Decl(c.ts, 1, 13)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) diff --git a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types index 3d301c346425a..13daeee6b21a3 100644 --- a/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types +++ b/tsc/testdata/baselines/reference/compiler/parenthesizedAsyncArrowFunction.types @@ -381,11 +381,11 @@ const f31 = a ? async (): (Promise) => async() : x => x; >x : any >x : any -const f32 = a ? async (...c: number[]): Promise => async() : x => x; ->f32 : ((...c: number[]) => Promise) | ((x: any) => any) ->a ? async (...c: number[]): Promise => async() : x => x : ((...c: number[]) => Promise) | ((x: any) => any) +const f32 = a ? async (...c: number[]): T => async() : x => x; +>f32 : ((...c: number[]) => T) | ((x: any) => any) +>a ? async (...c: number[]): T => async() : x => x : ((...c: number[]) => T) | ((x: any) => any) >a : true ->async (...c: number[]): Promise => async() : (...c: number[]) => Promise +>async (...c: number[]): T => async() : (...c: number[]) => T >c : number[] >async() : number >async : (...c: number[]) => number @@ -528,18 +528,9 @@ const f42 = a ? (c) : 0 >0 : 0 {} -const f43 = a ? async() : 0; ->f43 : number ->a ? async() : 0 : number ->a : true ->async() : number ->async : (...c: number[]) => number ->0 : 0 -{} - -const f44 = a ? async() : T => async (...c): T => c.length; ->f44 : (() => T) | ((T: any) => number) +const f43 = a ? async() : T => async (...c): T => c.length; +>f43 : (() => T) | ((T: any) => number) >a ? async() : T => async (...c): T => c.length : (() => T) | ((T: any) => number) >a : true >async() : T => async (...c) : () => T @@ -553,8 +544,8 @@ const f44 = a ? async() : T => async (...c): T => c.length; >c : number[] >length : number -const f45 = a ? async (): T => (b) : d => d; ->f45 : (d: any) => any +const f44 = a ? async (): T => (b) : d => d; +>f44 : (d: any) => any >a ? async (): T => (b) : d => d : (d: any) => any >a : true >async (): T => (b) : () => T @@ -564,8 +555,8 @@ const f45 = a ? async (): T => (b) : d => d; >d : any >d : any -const f46 = a ? async (): T => async() : d => d; ->f46 : (d: any) => any +const f45 = a ? async (): T => async() : d => d; +>f45 : (d: any) => any >a ? async (): T => async() : d => d : (d: any) => any >a : true >async (): T => async() : () => T @@ -575,8 +566,8 @@ const f46 = a ? async (): T => async() : d => d; >d : any >d : any -const f47 = a ? async (): T => async() : b; ->f47 : 1 | (() => T) +const f46 = a ? async (): T => async() : b; +>f46 : 1 | (() => T) >a ? async (): T => async() : b : 1 | (() => T) >a : true >async (): T => async() : () => T @@ -584,8 +575,8 @@ const f47 = a ? async (): T => async() : b; >async : (...c: number[]) => number >b : 1 -const f48 = a ? a ? async() : d => d : b; ->f48 : number | ((d: any) => any) +const f47 = a ? a ? async() : d => d : b; +>f47 : number | ((d: any) => any) >a ? a ? async() : d => d : b : number | ((d: any) => any) >a : true >a ? async() : d => d : number | ((d: any) => any) @@ -597,8 +588,8 @@ const f48 = a ? a ? async() : d => d : b; >d : any >b : 1 -const f49 = a ? a ? async(b) : d => d : b; ->f49 : number | ((d: any) => any) +const f48 = a ? a ? async(b) : d => d : b; +>f48 : number | ((d: any) => any) >a ? a ? async(b) : d => d : b : number | ((d: any) => any) >a : true >a ? async(b) : d => d : number | ((d: any) => any) @@ -611,8 +602,8 @@ const f49 = a ? a ? async(b) : d => d : b; >d : any >b : 1 -const f50 = a ? a ? async(...c) : d => d : b; ->f50 : number | ((d: any) => any) +const f49 = a ? a ? async(...c) : d => d : b; +>f49 : number | ((d: any) => any) >a ? a ? async(...c) : d => d : b : number | ((d: any) => any) >a : true >a ? async(...c) : d => d : number | ((d: any) => any) @@ -626,8 +617,8 @@ const f50 = a ? a ? async(...c) : d => d : b; >d : any >b : 1 -const f51 = a ? a ? async() : T => b : async (): T => b; ->f51 : number | (() => T) | ((T: any) => number) +const f50 = a ? a ? async() : T => b : async (): T => b; +>f50 : number | (() => T) | ((T: any) => number) >a ? a ? async() : T => b : async (): T => b : number | (() => T) | ((T: any) => number) >a : true >a ? async() : T => b : async () : number | (() => T) @@ -640,8 +631,8 @@ const f51 = a ? a ? async() : T => b : async (): T => b; >T : any >b : 1 -const f52 = a ? async (): T => async() : (d): number => d; ->f52 : (() => T) | ((d: any) => number) +const f51 = a ? async (): T => async() : (d): number => d; +>f51 : (() => T) | ((d: any) => number) >a ? async (): T => async() : (d): number => d : (() => T) | ((d: any) => number) >a : true >async (): T => async() : () => T @@ -651,8 +642,8 @@ const f52 = a ? async (): T => async() : (d): number => d; >d : any >d : any -const f53 = a ? a ? async (): T => async() : d => d : b; ->f53 : 1 | ((d: any) => any) +const f52 = a ? a ? async (): T => async() : d => d : b; +>f52 : 1 | ((d: any) => any) >a ? a ? async (): T => async() : d => d : b : 1 | ((d: any) => any) >a : true >a ? async (): T => async() : d => d : (d: any) => any @@ -665,8 +656,8 @@ const f53 = a ? a ? async (): T => async() : d => d : b; >d : any >b : 1 -const f54 = a ? async (): T => a ? async() : b : d => d; ->f54 : (d: any) => any +const f53 = a ? async (): T => a ? async() : b : d => d; +>f53 : (d: any) => any >a ? async (): T => a ? async() : b : d => d : (d: any) => any >a : true >async (): T => a ? async() : b : () => T @@ -679,8 +670,8 @@ const f54 = a ? async (): T => a ? async() : b : d => d; >d : any >d : any -const f55 = a ? a ? async() : d => d : a ? async() : d => d; ->f55 : number | ((d: any) => any) +const f54 = a ? a ? async() : d => d : a ? async() : d => d; +>f54 : number | ((d: any) => any) >a ? a ? async() : d => d : a ? async() : d => d : number | ((d: any) => any) >a : true >a ? async() : d => d : number | ((d: any) => any) @@ -698,8 +689,8 @@ const f55 = a ? a ? async() : d => d : a ? async() : d => d; >d : any >d : any -const f56 = a ? a ? a ? async() : d => d : b : b; ->f56 : number | ((d: any) => any) +const f55 = a ? a ? a ? async() : d => d : b : b; +>f55 : number | ((d: any) => any) >a ? a ? a ? async() : d => d : b : b : number | ((d: any) => any) >a : true >a ? a ? async() : d => d : b : number | ((d: any) => any) @@ -714,8 +705,8 @@ const f56 = a ? a ? a ? async() : d => d : b : b; >b : 1 >b : 1 -const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); ->f57 : ((d: any) => number) | ((d: any) => boolean) +const f56 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +>f56 : ((d: any) => number) | ((d: any) => boolean) >a ? d => a ? (0) : a ? async(b) : async() : (d => d = a) : ((d: any) => number) | ((d: any) => boolean) >a : true >d => a ? (0) : a ? async(b) : async() : (d: any) => number @@ -738,8 +729,8 @@ const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); >d : any >a : true -const f58 = a ? d => d = async () => async() : (d => d = 0); ->f58 : ((d: any) => () => Promise) | ((d: any) => number) +const f57 = a ? d => d = async () => async() : (d => d = 0); +>f57 : ((d: any) => () => Promise) | ((d: any) => number) >a ? d => d = async () => async() : (d => d = 0) : ((d: any) => () => Promise) | ((d: any) => number) >a : true >d => d = async () => async() : (d: any) => () => Promise @@ -757,8 +748,8 @@ const f58 = a ? d => d = async () => async() : (d => d = 0); >0 : 0 === b.ts === -const f59 = a ? async(...c: number[]): Promise => 0; ->f59 : any +const f58 = a ? async(...c: number[]): Promise => 0; +>f58 : any >a ? async(...c: number[]): Promise => 0 : any >a : true >async(...c: number[]): Promise => 0 : (...c: number[]) => Promise @@ -766,8 +757,8 @@ const f59 = a ? async(...c: number[]): Promise => 0; >0 : 0 > : any -const f60 = a ? async (): Promise {} : d => d; ->f60 : (d: any) => any +const f59 = a ? async (): Promise {} : d => d; +>f59 : (d: any) => any >a ? async (): Promise {} : d => d : (d: any) => any >a : true >async (): Promise {} : () => Promise @@ -775,8 +766,8 @@ const f60 = a ? async (): Promise {} : d => d; >d : any >d : any -const f61 = a ? (c): number {} : d => d; ->f61 : (d: any) => any +const f60 = a ? (c): number {} : d => d; +>f60 : (d: any) => any >a ? (c): number {} : d => d : (d: any) => any >a : true >(c): number {} : (c: any) => number @@ -785,8 +776,8 @@ const f61 = a ? (c): number {} : d => d; >d : any >d : any -const f62 = a ? async() : T => async(a ? b); ->f62 : any +const f61 = a ? async() : T => async(a ? b); +>f61 : any >a ? async() : T => async(a ? b) : any >a : true >async() : T => async(a ? b) : () => T @@ -815,8 +806,8 @@ type T = Promise; let d: any; >d : any -const f63 = a ? d = (d): T => a ? 0 : async(...c) : T => b; ->f63 : any +const f62 = a ? d = (d): T => a ? 0 : async(...c) : T => b; +>f62 : any >a ? d = (d): T => a ? 0 : async(...c) : T => b : any >a : any >d = (d) : any @@ -832,8 +823,8 @@ const f63 = a ? d = (d): T => a ? 0 : async(...c) : T => b; >c : any[] >b : any -const f64 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; ->f64 : (d: any) => any +const f63 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; +>f63 : (d: any) => any >a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b : (d: any) => any >a : any >async (): T => async (): T => (d): T => b : () => T @@ -853,8 +844,8 @@ const f64 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => a >c : any[] >b : any -const f65 = a ? async (): T => (d): T => async() : b; ->f65 : any +const f64 = a ? async (): T => (d): T => async() : b; +>f64 : any >a ? async (): T => (d): T => async() : b : any >a : any >async (): T => (d): T => async() : () => T @@ -864,8 +855,8 @@ const f65 = a ? async (): T => (d): T => async() : b; >async : (...a: any[]) => any >b : any -const f66 = (a ? async (): T => (d): T => async() : b); ->f66 : any +const f65 = (a ? async (): T => (d): T => async() : b); +>f65 : any >(a ? async (): T => (d): T => async() : b) : any >a ? async (): T => (d): T => async() : b : any >a : any @@ -876,8 +867,8 @@ const f66 = (a ? async (): T => (d): T => async() : b); >async : (...a: any[]) => any >b : any -const f67 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; ->f67 : any +const f66 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; +>f66 : any >a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b : any >a : any >d = (d) : any @@ -906,8 +897,8 @@ const f67 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 >c : any[] >b : any -const f68 = a ? async (c = a ? async() : d => d): T => async() : b; ->f68 : any +const f67 = a ? async (c = a ? async() : d => d): T => async() : b; +>f67 : any >a ? async (c = a ? async() : d => d): T => async() : b : any >a : any >async (c = a ? async() : d => d): T => async() : (c?: any) => T @@ -923,8 +914,8 @@ const f68 = a ? async (c = a ? async() : d => d): T => async() : b; >async : (...a: any[]) => any >b : any -const f69 = a ? a ? (d): T => a ? async() : b : d => d : b; ->f69 : any +const f68 = a ? a ? (d): T => a ? async() : b : d => d : b; +>f68 : any >a ? a ? (d): T => a ? async() : b : d => d : b : any >a : any >a ? (d): T => a ? async() : b : d => d : (d: any) => any @@ -941,8 +932,8 @@ const f69 = a ? a ? (d): T => a ? async() : b : d => d : b; >d : any >b : any -const f70 = a ? async() : (d => d); ->f70 : any +const f69 = a ? async() : (d => d); +>f69 : any >a ? async() : (d => d) : any >a : any >async() : any @@ -952,8 +943,8 @@ const f70 = a ? async() : (d => d); >d : any >d : any -const f71 = a ? async() : d => (a ? async() : d => d); ->f71 : any +const f70 = a ? async() : d => (a ? async() : d => d); +>f70 : any >a ? async() : d => (a ? async() : d => d) : any >a : any >async() : any @@ -975,8 +966,8 @@ type x = T; declare const x: any; >x : any -const f72 = a ? a ? async (): T => (x): T => async() : x => x; ->f72 : (T: any) => any +const f71 = a ? a ? async (): T => (x): T => async() : x => x; +>f71 : (T: any) => any >a ? a ? async (): T => (x): T => async() : x => x : (T: any) => any >a : any >a ? async (): T => (x): T => async() : (T: any) => any @@ -992,8 +983,8 @@ const f72 = a ? a ? async (): T => (x): T => async() : x => x; >x : any >x : any -const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; ->f73 : (T: any) => any +const f72 = a ? a ? async (): Promise => (x): T => async() : x => x; +>f72 : (T: any) => any >a ? a ? async (): Promise => (x): T => async() : x => x : (T: any) => any >a : any >a ? async (): Promise => (x): T => async() : (T: any) => any @@ -1009,8 +1000,8 @@ const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; >x : any >x : any -const f74 = a ? async (x): T => async (): T => b; ->f74 : any +const f73 = a ? async (x): T => async (): T => b; +>f73 : any >a ? async (x): T => async (): T => b : any >a : any >async (x) : any @@ -1021,8 +1012,8 @@ const f74 = a ? async (x): T => async (): T => b; >async (): T => b : () => T >b : any -const f75 = a ? async (x): T => async() : x => x; ->f75 : any +const f74 = a ? async (x): T => async() : x => x; +>f74 : any >a ? async (x): T => async() : x => x : any >a : any >async (x) : any @@ -1040,8 +1031,8 @@ declare function h(a: A): A; declare namespace number { type T = number; } >T : number -const f76 = a ? async(x = b < (d + 1)): T => x : 0; ->f76 : 0 | ((x?: boolean) => T) +const f75 = a ? async(x = b < (d + 1)): T => x : 0; +>f75 : 0 | ((x?: boolean) => T) >a ? async(x = b < (d + 1)): T => x : 0 : 0 | ((x?: boolean) => T) >a : any >async(x = b < (d + 1)): T => x : (x?: boolean) => T @@ -1055,8 +1046,8 @@ const f76 = a ? async(x = b < (d + 1)): T => x : 0; >x : boolean >0 : 0 -const f77 = a ? async(x = b << (d + 1)): T => x : 0; ->f77 : 0 | ((x?: number) => T) +const f76 = a ? async(x = b << (d + 1)): T => x : 0; +>f76 : 0 | ((x?: number) => T) >a ? async(x = b << (d + 1)): T => x : 0 : 0 | ((x?: number) => T) >a : any >async(x = b << (d + 1)): T => x : (x?: number) => T @@ -1070,8 +1061,8 @@ const f77 = a ? async(x = b << (d + 1)): T => x : 0; >x : number >0 : 0 -const f78 = a ? async(x = new b < (d + 1)): T => x : 0; ->f78 : 0 | ((x?: boolean) => T) +const f77 = a ? async(x = new b < (d + 1)): T => x : 0; +>f77 : 0 | ((x?: boolean) => T) >a ? async(x = new b < (d + 1)): T => x : 0 : 0 | ((x?: boolean) => T) >a : any >async(x = new b < (d + 1)): T => x : (x?: boolean) => T @@ -1086,8 +1077,8 @@ const f78 = a ? async(x = new b < (d + 1)): T => x : 0; >x : boolean >0 : 0 -const f79 = a ? async(x = h(b)): T => x : 0; ->f79 : 0 | ((x?: T) => T) +const f78 = a ? async(x = h(b)): T => x : 0; +>f78 : 0 | ((x?: T) => T) >a ? async(x = h(b)): T => x : 0 : 0 | ((x?: T) => T) >a : any >async(x = h(b)): T => x : (x?: T) => T @@ -1098,8 +1089,8 @@ const f79 = a ? async(x = h(b)): T => x : 0; >x : T >0 : 0 -const f80 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; ->f80 : 0 | (() => Promise<({ a: number[]; })>) +const f79 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; +>f79 : 0 | (() => Promise<({ a: number[]; })>) >a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0 : 0 | (() => Promise<({ a: number[]; })>) >a : any >async(): Promise<({ a: number[] })> => ({ a: [] }) : () => Promise<({ a: number[]; })> @@ -1110,8 +1101,8 @@ const f80 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; >[] : undefined[] >0 : 0 -const f81 = a ? async(): Promise<([a: number])> => [b] : 0; ->f81 : 0 | (() => Promise<([a: number])>) +const f80 = a ? async(): Promise<([a: number])> => [b] : 0; +>f80 : 0 | (() => Promise<([a: number])>) >a ? async(): Promise<([a: number])> => [b] : 0 : 0 | (() => Promise<([a: number])>) >a : any >async(): Promise<([a: number])> => [b] : () => Promise<([a: number])> @@ -1119,8 +1110,8 @@ const f81 = a ? async(): Promise<([a: number])> => [b] : 0; >b : any >0 : 0 -const f82 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; ->f82 : 0 | (() => Promise<{ readonly: number; }>) +const f81 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; +>f81 : 0 | (() => Promise<{ readonly: number; }>) >a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0 : 0 | (() => Promise<{ readonly: number; }>) >a : any >async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : () => Promise<{ readonly: number; }> @@ -1131,8 +1122,8 @@ const f82 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) >0 : 0 >0 : 0 -const f83 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; ->f83 : 0 | (() => Promise<{ get: number; }>) +const f82 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; +>f82 : 0 | (() => Promise<{ get: number; }>) >a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0 : 0 | (() => Promise<{ get: number; }>) >a : any >async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : () => Promise<{ get: number; }> @@ -1143,8 +1134,8 @@ const f83 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; >0 : 0 >0 : 0 -const f84 = a ? async(): Promise => b : 0; ->f84 : 0 | (() => Promise) +const f83 = a ? async(): Promise => b : 0; +>f83 : 0 | (() => Promise) >a ? async(): Promise => b : 0 : 0 | (() => Promise) >a : any >async(): Promise => b : () => Promise @@ -1152,8 +1143,8 @@ const f84 = a ? async(): Promise => b : 0; >b : any >0 : 0 -const f85 = a ? a ? as\u0079nc() : d => d : b; ->f85 : any +const f84 = a ? a ? as\u0079nc() : d => d : b; +>f84 : any >a ? a ? as\u0079nc() : d => d : b : any >a : any >a ? as\u0079nc() : d => d : any @@ -1165,8 +1156,8 @@ const f85 = a ? a ? as\u0079nc() : d => d : b; >d : any >b : any -const f86 = a ? async(): Promise => 0 : 0; ->f86 : 0 | (() => Promise) +const f85 = a ? async(): Promise => 0 : 0; +>f85 : 0 | (() => Promise) >a ? async(): Promise => 0 : 0 : 0 | (() => Promise) >a : any >async(): Promise => 0 : () => Promise diff --git a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts index 2c106bdbdbdf3..be2031fe98db4 100644 --- a/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts +++ b/tsc/testdata/tests/cases/compiler/parenthesizedAsyncArrowFunction.ts @@ -47,7 +47,7 @@ const f28 = a ? async (): Promise => async(...c) : x => x; const f29 = a ? async (...c): Promise => async() : x => x; const f30 = a ? async (): Promise => async() : x => x; const f31 = a ? async (): (Promise) => async() : x => x; -const f32 = a ? async (...c: number[]): Promise => async() : x => x; +const f32 = a ? async (...c: number[]): T => async() : x => x; const f33 = a ? async() : 0 {} @@ -74,33 +74,31 @@ const f41 = a ? async(...c) : 0 {} const f42 = a ? (c) : 0 {} -const f43 = a ? async() : 0; -{} -const f44 = a ? async() : T => async (...c): T => c.length; +const f43 = a ? async() : T => async (...c): T => c.length; -const f45 = a ? async (): T => (b) : d => d; -const f46 = a ? async (): T => async() : d => d; -const f47 = a ? async (): T => async() : b; -const f48 = a ? a ? async() : d => d : b; -const f49 = a ? a ? async(b) : d => d : b; -const f50 = a ? a ? async(...c) : d => d : b; -const f51 = a ? a ? async() : T => b : async (): T => b; -const f52 = a ? async (): T => async() : (d): number => d; -const f53 = a ? a ? async (): T => async() : d => d : b; -const f54 = a ? async (): T => a ? async() : b : d => d; -const f55 = a ? a ? async() : d => d : a ? async() : d => d; -const f56 = a ? a ? a ? async() : d => d : b : b; +const f44 = a ? async (): T => (b) : d => d; +const f45 = a ? async (): T => async() : d => d; +const f46 = a ? async (): T => async() : b; +const f47 = a ? a ? async() : d => d : b; +const f48 = a ? a ? async(b) : d => d : b; +const f49 = a ? a ? async(...c) : d => d : b; +const f50 = a ? a ? async() : T => b : async (): T => b; +const f51 = a ? async (): T => async() : (d): number => d; +const f52 = a ? a ? async (): T => async() : d => d : b; +const f53 = a ? async (): T => a ? async() : b : d => d; +const f54 = a ? a ? async() : d => d : a ? async() : d => d; +const f55 = a ? a ? a ? async() : d => d : b : b; -const f57 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); -const f58 = a ? d => d = async () => async() : (d => d = 0); +const f56 = a ? d => a ? (0) : a ? async(b) : async() : (d => d = a); +const f57 = a ? d => d = async () => async() : (d => d = 0); // @filename: b.ts -const f59 = a ? async(...c: number[]): Promise => 0; -const f60 = a ? async (): Promise {} : d => d; -const f61 = a ? (c): number {} : d => d; +const f58 = a ? async(...c: number[]): Promise => 0; +const f59 = a ? async (): Promise {} : d => d; +const f60 = a ? (c): number {} : d => d; -const f62 = a ? async() : T => async(a ? b); +const f61 = a ? async() : T => async(a ? b); // @filename: c.ts export {}; @@ -108,33 +106,33 @@ declare const a: any, b: any, c: any[]; declare function async(...a: any[]): any; type T = Promise; let d: any; -const f63 = a ? d = (d): T => a ? 0 : async(...c) : T => b; -const f64 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; -const f65 = a ? async (): T => (d): T => async() : b; -const f66 = (a ? async (): T => (d): T => async() : b); -const f67 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; -const f68 = a ? async (c = a ? async() : d => d): T => async() : b; -const f69 = a ? a ? (d): T => a ? async() : b : d => d : b; -const f70 = a ? async() : (d => d); -const f71 = a ? async() : d => (a ? async() : d => d); +const f62 = a ? d = (d): T => a ? 0 : async(...c) : T => b; +const f63 = a ? async (): T => async (): T => (d): T => b : a ? d => (d): T => async(...c) : T => b; +const f64 = a ? async (): T => (d): T => async() : b; +const f65 = (a ? async (): T => (d): T => async() : b); +const f66 = a ? d = (d): T => a ? 0 : async(...c) : T => a ? d = (d): T => a ? 0 : async(...c) : T => b; +const f67 = a ? async (c = a ? async() : d => d): T => async() : b; +const f68 = a ? a ? (d): T => a ? async() : b : d => d : b; +const f69 = a ? async() : (d => d); +const f70 = a ? async() : d => (a ? async() : d => d); type x = T; declare const x: any; -const f72 = a ? a ? async (): T => (x): T => async() : x => x; -const f73 = a ? a ? async (): Promise => (x): T => async() : x => x; -const f74 = a ? async (x): T => async (): T => b; -const f75 = a ? async (x): T => async() : x => x; +const f71 = a ? a ? async (): T => (x): T => async() : x => x; +const f72 = a ? a ? async (): Promise => (x): T => async() : x => x; +const f73 = a ? async (x): T => async (): T => b; +const f74 = a ? async (x): T => async() : x => x; declare function h(a: A): A; declare namespace number { type T = number; } -const f76 = a ? async(x = b < (d + 1)): T => x : 0; -const f77 = a ? async(x = b << (d + 1)): T => x : 0; -const f78 = a ? async(x = new b < (d + 1)): T => x : 0; -const f79 = a ? async(x = h(b)): T => x : 0; -const f80 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; -const f81 = a ? async(): Promise<([a: number])> => [b] : 0; -const f82 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; -const f83 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; -const f84 = a ? async(): Promise => b : 0; -const f85 = a ? a ? as\u0079nc() : d => d : b; -const f86 = a ? async(): Promise => 0 : 0; +const f75 = a ? async(x = b < (d + 1)): T => x : 0; +const f76 = a ? async(x = b << (d + 1)): T => x : 0; +const f77 = a ? async(x = new b < (d + 1)): T => x : 0; +const f78 = a ? async(x = h(b)): T => x : 0; +const f79 = a ? async(): Promise<({ a: number[] })> => ({ a: [] }) : 0; +const f80 = a ? async(): Promise<([a: number])> => [b] : 0; +const f81 = a ? async(): Promise<{ r\u0065adonly: number }> => ({ readonly: 0 }) : 0; +const f82 = a ? async(): Promise<{ g\u0065t: number }> => ({ get: 0 }) : 0; +const f83 = a ? async(): Promise => b : 0; +const f84 = a ? a ? as\u0079nc() : d => d : b; +const f85 = a ? async(): Promise => 0 : 0;