From 562eb0ae15b24f5f88d785d865df30f1da39afb1 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 20 Apr 2022 11:03:42 -0700 Subject: [PATCH 1/7] Add test case --- .../parserArrowFunctionExpression15.errors.txt | 14 ++++++++++++++ .../reference/parserArrowFunctionExpression15.js | 7 +++++++ .../parserArrowFunctionExpression15.symbols | 4 ++++ .../parserArrowFunctionExpression15.types | 11 +++++++++++ .../parserArrowFunctionExpression16.errors.txt | 14 ++++++++++++++ .../reference/parserArrowFunctionExpression16.js | 7 +++++++ .../parserArrowFunctionExpression16.symbols | 4 ++++ .../parserArrowFunctionExpression16.types | 14 ++++++++++++++ .../parserArrowFunctionExpression15.ts | 1 + .../parserArrowFunctionExpression16.ts | 1 + 10 files changed, 77 insertions(+) create mode 100644 tests/baselines/reference/parserArrowFunctionExpression15.errors.txt create mode 100644 tests/baselines/reference/parserArrowFunctionExpression15.js create mode 100644 tests/baselines/reference/parserArrowFunctionExpression15.symbols create mode 100644 tests/baselines/reference/parserArrowFunctionExpression15.types create mode 100644 tests/baselines/reference/parserArrowFunctionExpression16.errors.txt create mode 100644 tests/baselines/reference/parserArrowFunctionExpression16.js create mode 100644 tests/baselines/reference/parserArrowFunctionExpression16.symbols create mode 100644 tests/baselines/reference/parserArrowFunctionExpression16.types create mode 100644 tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts create mode 100644 tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts diff --git a/tests/baselines/reference/parserArrowFunctionExpression15.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression15.errors.txt new file mode 100644 index 0000000000000..60def8ca15fa6 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression15.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts(1,10): error TS2304: Cannot find name 'param'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts(1,28): error TS2304: Cannot find name 'param'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts(1,34): error TS1005: ';' expected. + + +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts (3 errors) ==== + false ? (param): string => param : null + ~~~~~ +!!! error TS2304: Cannot find name 'param'. + ~~~~~ +!!! error TS2304: Cannot find name 'param'. + ~ +!!! error TS1005: ';' expected. + \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression15.js b/tests/baselines/reference/parserArrowFunctionExpression15.js new file mode 100644 index 0000000000000..047b09c6ddec0 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression15.js @@ -0,0 +1,7 @@ +//// [parserArrowFunctionExpression15.ts] +false ? (param): string => param : null + + +//// [parserArrowFunctionExpression15.js] +false ? (param) : function (string) { return param; }; +null; diff --git a/tests/baselines/reference/parserArrowFunctionExpression15.symbols b/tests/baselines/reference/parserArrowFunctionExpression15.symbols new file mode 100644 index 0000000000000..7750b8d43be97 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression15.symbols @@ -0,0 +1,4 @@ +=== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts === +false ? (param): string => param : null +>string : Symbol(string, Decl(parserArrowFunctionExpression15.ts, 0, 16)) + diff --git a/tests/baselines/reference/parserArrowFunctionExpression15.types b/tests/baselines/reference/parserArrowFunctionExpression15.types new file mode 100644 index 0000000000000..ec808c729eece --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression15.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts === +false ? (param): string => param : null +>false ? (param): string => param : any +>false : false +>(param) : any +>param : any +>string => param : (string: any) => any +>string : any +>param : any +>null : null + diff --git a/tests/baselines/reference/parserArrowFunctionExpression16.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression16.errors.txt new file mode 100644 index 0000000000000..740144391e298 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression16.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts(1,17): error TS2304: Cannot find name 'param'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts(1,35): error TS2304: Cannot find name 'param'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts(1,48): error TS1005: ';' expected. + + +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts (3 errors) ==== + true ? false ? (param): string => param : null : null + ~~~~~ +!!! error TS2304: Cannot find name 'param'. + ~~~~~ +!!! error TS2304: Cannot find name 'param'. + ~ +!!! error TS1005: ';' expected. + \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression16.js b/tests/baselines/reference/parserArrowFunctionExpression16.js new file mode 100644 index 0000000000000..a2b2fff3aad85 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression16.js @@ -0,0 +1,7 @@ +//// [parserArrowFunctionExpression16.ts] +true ? false ? (param): string => param : null : null + + +//// [parserArrowFunctionExpression16.js] +true ? false ? (param) : function (string) { return param; } : null; +null; diff --git a/tests/baselines/reference/parserArrowFunctionExpression16.symbols b/tests/baselines/reference/parserArrowFunctionExpression16.symbols new file mode 100644 index 0000000000000..684b74408ccd5 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression16.symbols @@ -0,0 +1,4 @@ +=== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts === +true ? false ? (param): string => param : null : null +>string : Symbol(string, Decl(parserArrowFunctionExpression16.ts, 0, 23)) + diff --git a/tests/baselines/reference/parserArrowFunctionExpression16.types b/tests/baselines/reference/parserArrowFunctionExpression16.types new file mode 100644 index 0000000000000..dbe5cc2e81733 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression16.types @@ -0,0 +1,14 @@ +=== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts === +true ? false ? (param): string => param : null : null +>true ? false ? (param): string => param : null : any +>true : true +>false ? (param): string => param : any +>false : false +>(param) : any +>param : any +>string => param : (string: any) => any +>string : any +>param : any +>null : null +>null : null + diff --git a/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts b/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts new file mode 100644 index 0000000000000..3348d24bfebe4 --- /dev/null +++ b/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts @@ -0,0 +1 @@ +false ? (param): string => param : null diff --git a/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts b/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts new file mode 100644 index 0000000000000..9a19bfdb6cfc1 --- /dev/null +++ b/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts @@ -0,0 +1 @@ +true ? false ? (param): string => param : null : null From d4d606d8e554a4546e0a6836e84408c3705937ac Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 20 Apr 2022 13:57:09 -0700 Subject: [PATCH 2/7] Allow return type in conditional if body is followed by a colon --- src/compiler/parser.ts | 16 +++++++++++++--- .../parserArrowFunctionExpression10.errors.txt | 11 ++++------- .../reference/parserArrowFunctionExpression10.js | 3 +-- .../parserArrowFunctionExpression10.symbols | 3 ++- .../parserArrowFunctionExpression10.types | 6 ++---- .../parserArrowFunctionExpression12.errors.txt | 11 ++++++++++- .../reference/parserArrowFunctionExpression12.js | 4 +++- .../parserArrowFunctionExpression12.symbols | 1 - .../parserArrowFunctionExpression12.types | 5 +++-- .../parserArrowFunctionExpression15.errors.txt | 14 -------------- .../reference/parserArrowFunctionExpression15.js | 3 +-- .../parserArrowFunctionExpression15.symbols | 3 ++- .../parserArrowFunctionExpression15.types | 6 ++---- .../parserArrowFunctionExpression16.errors.txt | 14 -------------- .../reference/parserArrowFunctionExpression16.js | 3 +-- .../parserArrowFunctionExpression16.symbols | 3 ++- .../parserArrowFunctionExpression16.types | 8 +++----- 17 files changed, 49 insertions(+), 65 deletions(-) delete mode 100644 tests/baselines/reference/parserArrowFunctionExpression15.errors.txt delete mode 100644 tests/baselines/reference/parserArrowFunctionExpression16.errors.txt diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e57a3fa98f390..baaef1c654f9d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4709,9 +4709,9 @@ namespace ts { // 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 (disallowReturnTypeInArrowFunction && token() === SyntaxKind.ColonToken) { - return undefined; - } + // if (disallowReturnTypeInArrowFunction && token() === SyntaxKind.ColonToken) { + // return undefined; + // } const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); if (type && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(type)) { @@ -4748,6 +4748,16 @@ namespace ts { ? parseArrowFunctionExpressionBody(some(modifiers, isAsyncModifier), disallowReturnTypeInArrowFunction) : parseIdentifier(); + if (disallowReturnTypeInArrowFunction) { + // If we are currently parsing a conditional expression, and were able to parse + // a return type before the body, and there's another colon after the body, allow + // parsing of this arrow function so that the following colon terminates the + // true side of the conditional. + if (!(type && token() === SyntaxKind.ColonToken)) { + return undefined; + } + } + const node = factory.createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body); return withJSDoc(finishNode(node, pos), hasJSDoc); } diff --git a/tests/baselines/reference/parserArrowFunctionExpression10.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression10.errors.txt index 43cf9de267b85..0ee29b021a1ef 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression10.errors.txt +++ b/tests/baselines/reference/parserArrowFunctionExpression10.errors.txt @@ -1,20 +1,17 @@ tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts(1,1): error TS2304: Cannot find name 'a'. -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts(1,6): error TS2304: Cannot find name 'b'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts(1,11): error TS2304: Cannot find name 'c'. tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts(1,17): error TS2304: Cannot find name 'd'. -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts(1,20): error TS1005: ';' expected. tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts(1,27): error TS2304: Cannot find name 'f'. -==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts (5 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts (4 errors) ==== a ? (b) : c => (d) : e => f ~ !!! error TS2304: Cannot find name 'a'. - ~ -!!! error TS2304: Cannot find name 'b'. + ~ +!!! error TS2304: Cannot find name 'c'. ~ !!! error TS2304: Cannot find name 'd'. - ~ -!!! error TS1005: ';' expected. ~ !!! error TS2304: Cannot find name 'f'. \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression10.js b/tests/baselines/reference/parserArrowFunctionExpression10.js index 86e1e61bb0716..7681332637b4e 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression10.js +++ b/tests/baselines/reference/parserArrowFunctionExpression10.js @@ -3,5 +3,4 @@ a ? (b) : c => (d) : e => f //// [parserArrowFunctionExpression10.js] -a ? (b) : function (c) { return (d); }; -(function (e) { return f; }); +a ? function (b) { return (d); } : function (e) { return f; }; diff --git a/tests/baselines/reference/parserArrowFunctionExpression10.symbols b/tests/baselines/reference/parserArrowFunctionExpression10.symbols index f30f0b3e3ca49..df391a0be345d 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression10.symbols +++ b/tests/baselines/reference/parserArrowFunctionExpression10.symbols @@ -1,5 +1,6 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts === a ? (b) : c => (d) : e => f ->c : Symbol(c, Decl(parserArrowFunctionExpression10.ts, 0, 9)) +>b : Symbol(b, Decl(parserArrowFunctionExpression10.ts, 0, 5)) +>c : Symbol(c) >e : Symbol(e, Decl(parserArrowFunctionExpression10.ts, 0, 20)) diff --git a/tests/baselines/reference/parserArrowFunctionExpression10.types b/tests/baselines/reference/parserArrowFunctionExpression10.types index 8ec7d69c29559..e4149fe4cbb5c 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression10.types +++ b/tests/baselines/reference/parserArrowFunctionExpression10.types @@ -1,11 +1,9 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts === a ? (b) : c => (d) : e => f ->a ? (b) : c => (d) : any +>a ? (b) : c => (d) : e => f : (b: any) => c >a : any ->(b) : any +>(b) : c => (d) : (b: any) => c >b : any ->c => (d) : (c: any) => any ->c : any >(d) : any >d : any >e => f : (e: any) => any diff --git a/tests/baselines/reference/parserArrowFunctionExpression12.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression12.errors.txt index c6cfd8f9ce855..bc6625a0e5a99 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression12.errors.txt +++ b/tests/baselines/reference/parserArrowFunctionExpression12.errors.txt @@ -1,14 +1,23 @@ tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts(1,1): error TS2304: Cannot find name 'a'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts(1,6): error TS2304: Cannot find name 'b'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts(1,9): error TS1005: ':' expected. tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts(1,13): error TS2304: Cannot find name 'c'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts(1,15): error TS1005: ';' expected. tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts(1,22): error TS2304: Cannot find name 'e'. -==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts (3 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts (6 errors) ==== a ? (b) => (c): d => e ~ !!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS2304: Cannot find name 'b'. + ~~ +!!! error TS1005: ':' expected. ~ !!! error TS2304: Cannot find name 'c'. + ~ +!!! error TS1005: ';' expected. ~ !!! error TS2304: Cannot find name 'e'. \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression12.js b/tests/baselines/reference/parserArrowFunctionExpression12.js index dbee37a2660cb..416b1aa1a6270 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression12.js +++ b/tests/baselines/reference/parserArrowFunctionExpression12.js @@ -3,4 +3,6 @@ a ? (b) => (c): d => e //// [parserArrowFunctionExpression12.js] -a ? function (b) { return (c); } : function (d) { return e; }; +a ? (b) : ; +(c); +(function (d) { return e; }); diff --git a/tests/baselines/reference/parserArrowFunctionExpression12.symbols b/tests/baselines/reference/parserArrowFunctionExpression12.symbols index 3a67717232041..c72b2d870c8e5 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression12.symbols +++ b/tests/baselines/reference/parserArrowFunctionExpression12.symbols @@ -1,5 +1,4 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts === a ? (b) => (c): d => e ->b : Symbol(b, Decl(parserArrowFunctionExpression12.ts, 0, 5)) >d : Symbol(d, Decl(parserArrowFunctionExpression12.ts, 0, 15)) diff --git a/tests/baselines/reference/parserArrowFunctionExpression12.types b/tests/baselines/reference/parserArrowFunctionExpression12.types index b833ae305a8b1..8ebbf59b7a0a5 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression12.types +++ b/tests/baselines/reference/parserArrowFunctionExpression12.types @@ -1,9 +1,10 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts === a ? (b) => (c): d => e ->a ? (b) => (c): d => e : (b: any) => any +>a ? (b) : any >a : any ->(b) => (c) : (b: any) => any +>(b) : any >b : any +> : any >(c) : any >c : any >d => e : (d: any) => any diff --git a/tests/baselines/reference/parserArrowFunctionExpression15.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression15.errors.txt deleted file mode 100644 index 60def8ca15fa6..0000000000000 --- a/tests/baselines/reference/parserArrowFunctionExpression15.errors.txt +++ /dev/null @@ -1,14 +0,0 @@ -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts(1,10): error TS2304: Cannot find name 'param'. -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts(1,28): error TS2304: Cannot find name 'param'. -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts(1,34): error TS1005: ';' expected. - - -==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts (3 errors) ==== - false ? (param): string => param : null - ~~~~~ -!!! error TS2304: Cannot find name 'param'. - ~~~~~ -!!! error TS2304: Cannot find name 'param'. - ~ -!!! error TS1005: ';' expected. - \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression15.js b/tests/baselines/reference/parserArrowFunctionExpression15.js index 047b09c6ddec0..a18efc84f0975 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression15.js +++ b/tests/baselines/reference/parserArrowFunctionExpression15.js @@ -3,5 +3,4 @@ false ? (param): string => param : null //// [parserArrowFunctionExpression15.js] -false ? (param) : function (string) { return param; }; -null; +false ? function (param) { return param; } : null; diff --git a/tests/baselines/reference/parserArrowFunctionExpression15.symbols b/tests/baselines/reference/parserArrowFunctionExpression15.symbols index 7750b8d43be97..7cb354c7dc912 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression15.symbols +++ b/tests/baselines/reference/parserArrowFunctionExpression15.symbols @@ -1,4 +1,5 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts === false ? (param): string => param : null ->string : Symbol(string, Decl(parserArrowFunctionExpression15.ts, 0, 16)) +>param : Symbol(param, Decl(parserArrowFunctionExpression15.ts, 0, 9)) +>param : Symbol(param, Decl(parserArrowFunctionExpression15.ts, 0, 9)) diff --git a/tests/baselines/reference/parserArrowFunctionExpression15.types b/tests/baselines/reference/parserArrowFunctionExpression15.types index ec808c729eece..4640763862112 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression15.types +++ b/tests/baselines/reference/parserArrowFunctionExpression15.types @@ -1,11 +1,9 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts === false ? (param): string => param : null ->false ? (param): string => param : any +>false ? (param): string => param : null : (param: any) => string >false : false ->(param) : any +>(param): string => param : (param: any) => string >param : any ->string => param : (string: any) => any ->string : any >param : any >null : null diff --git a/tests/baselines/reference/parserArrowFunctionExpression16.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression16.errors.txt deleted file mode 100644 index 740144391e298..0000000000000 --- a/tests/baselines/reference/parserArrowFunctionExpression16.errors.txt +++ /dev/null @@ -1,14 +0,0 @@ -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts(1,17): error TS2304: Cannot find name 'param'. -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts(1,35): error TS2304: Cannot find name 'param'. -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts(1,48): error TS1005: ';' expected. - - -==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts (3 errors) ==== - true ? false ? (param): string => param : null : null - ~~~~~ -!!! error TS2304: Cannot find name 'param'. - ~~~~~ -!!! error TS2304: Cannot find name 'param'. - ~ -!!! error TS1005: ';' expected. - \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression16.js b/tests/baselines/reference/parserArrowFunctionExpression16.js index a2b2fff3aad85..8d0404c91c853 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression16.js +++ b/tests/baselines/reference/parserArrowFunctionExpression16.js @@ -3,5 +3,4 @@ true ? false ? (param): string => param : null : null //// [parserArrowFunctionExpression16.js] -true ? false ? (param) : function (string) { return param; } : null; -null; +true ? false ? function (param) { return param; } : null : null; diff --git a/tests/baselines/reference/parserArrowFunctionExpression16.symbols b/tests/baselines/reference/parserArrowFunctionExpression16.symbols index 684b74408ccd5..f2a4ff04df134 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression16.symbols +++ b/tests/baselines/reference/parserArrowFunctionExpression16.symbols @@ -1,4 +1,5 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts === true ? false ? (param): string => param : null : null ->string : Symbol(string, Decl(parserArrowFunctionExpression16.ts, 0, 23)) +>param : Symbol(param, Decl(parserArrowFunctionExpression16.ts, 0, 16)) +>param : Symbol(param, Decl(parserArrowFunctionExpression16.ts, 0, 16)) diff --git a/tests/baselines/reference/parserArrowFunctionExpression16.types b/tests/baselines/reference/parserArrowFunctionExpression16.types index dbe5cc2e81733..fffd623adac0d 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression16.types +++ b/tests/baselines/reference/parserArrowFunctionExpression16.types @@ -1,13 +1,11 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts === true ? false ? (param): string => param : null : null ->true ? false ? (param): string => param : null : any +>true ? false ? (param): string => param : null : null : (param: any) => string >true : true ->false ? (param): string => param : any +>false ? (param): string => param : null : (param: any) => string >false : false ->(param) : any +>(param): string => param : (param: any) => string >param : any ->string => param : (string: any) => any ->string : any >param : any >null : null >null : null From 61e987b41404a7f7179f70c79ef688d98069e997 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 20 Apr 2022 14:00:42 -0700 Subject: [PATCH 3/7] Move comment --- src/compiler/parser.ts | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index baaef1c654f9d..7e69904f0a49a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4695,24 +4695,6 @@ namespace ts { } } - // 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. - // if (disallowReturnTypeInArrowFunction && token() === SyntaxKind.ColonToken) { - // return undefined; - // } - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); if (type && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(type)) { return undefined; @@ -4748,11 +4730,26 @@ namespace ts { ? parseArrowFunctionExpressionBody(some(modifiers, isAsyncModifier), disallowReturnTypeInArrowFunction) : parseIdentifier(); + // 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. if (disallowReturnTypeInArrowFunction) { - // If we are currently parsing a conditional expression, and were able to parse - // a return type before the body, and there's another colon after the body, allow - // parsing of this arrow function so that the following colon terminates the - // true side of the conditional. + // 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. if (!(type && token() === SyntaxKind.ColonToken)) { return undefined; } From 3b2ec35bb637c4bac630e46534498275423989b0 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 20 Apr 2022 14:31:47 -0700 Subject: [PATCH 4/7] Remember colon from earlier --- src/compiler/parser.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 7e69904f0a49a..f055c326b0a33 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4695,6 +4695,7 @@ namespace ts { } } + const hasReturnColon = token() === SyntaxKind.ColonToken; const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); if (type && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(type)) { return undefined; @@ -4744,13 +4745,13 @@ namespace ts { // 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 (disallowReturnTypeInArrowFunction) { + if (disallowReturnTypeInArrowFunction && hasReturnColon) { // 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. - if (!(type && token() === SyntaxKind.ColonToken)) { + if (token() !== SyntaxKind.ColonToken) { return undefined; } } From 23987628a368823bfe958f8ab09451320b088872 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 20 Apr 2022 14:32:23 -0700 Subject: [PATCH 5/7] Revert 12 --- .../parserArrowFunctionExpression12.errors.txt | 11 +---------- .../reference/parserArrowFunctionExpression12.js | 4 +--- .../reference/parserArrowFunctionExpression12.symbols | 1 + .../reference/parserArrowFunctionExpression12.types | 5 ++--- 4 files changed, 5 insertions(+), 16 deletions(-) diff --git a/tests/baselines/reference/parserArrowFunctionExpression12.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression12.errors.txt index bc6625a0e5a99..c6cfd8f9ce855 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression12.errors.txt +++ b/tests/baselines/reference/parserArrowFunctionExpression12.errors.txt @@ -1,23 +1,14 @@ tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts(1,1): error TS2304: Cannot find name 'a'. -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts(1,6): error TS2304: Cannot find name 'b'. -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts(1,9): error TS1005: ':' expected. tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts(1,13): error TS2304: Cannot find name 'c'. -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts(1,15): error TS1005: ';' expected. tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts(1,22): error TS2304: Cannot find name 'e'. -==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts (6 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts (3 errors) ==== a ? (b) => (c): d => e ~ !!! error TS2304: Cannot find name 'a'. - ~ -!!! error TS2304: Cannot find name 'b'. - ~~ -!!! error TS1005: ':' expected. ~ !!! error TS2304: Cannot find name 'c'. - ~ -!!! error TS1005: ';' expected. ~ !!! error TS2304: Cannot find name 'e'. \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression12.js b/tests/baselines/reference/parserArrowFunctionExpression12.js index 416b1aa1a6270..dbee37a2660cb 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression12.js +++ b/tests/baselines/reference/parserArrowFunctionExpression12.js @@ -3,6 +3,4 @@ a ? (b) => (c): d => e //// [parserArrowFunctionExpression12.js] -a ? (b) : ; -(c); -(function (d) { return e; }); +a ? function (b) { return (c); } : function (d) { return e; }; diff --git a/tests/baselines/reference/parserArrowFunctionExpression12.symbols b/tests/baselines/reference/parserArrowFunctionExpression12.symbols index c72b2d870c8e5..3a67717232041 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression12.symbols +++ b/tests/baselines/reference/parserArrowFunctionExpression12.symbols @@ -1,4 +1,5 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts === a ? (b) => (c): d => e +>b : Symbol(b, Decl(parserArrowFunctionExpression12.ts, 0, 5)) >d : Symbol(d, Decl(parserArrowFunctionExpression12.ts, 0, 15)) diff --git a/tests/baselines/reference/parserArrowFunctionExpression12.types b/tests/baselines/reference/parserArrowFunctionExpression12.types index 8ebbf59b7a0a5..b833ae305a8b1 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression12.types +++ b/tests/baselines/reference/parserArrowFunctionExpression12.types @@ -1,10 +1,9 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression12.ts === a ? (b) => (c): d => e ->a ? (b) : any +>a ? (b) => (c): d => e : (b: any) => any >a : any ->(b) : any +>(b) => (c) : (b: any) => any >b : any -> : any >(c) : any >c : any >d => e : (d: any) => any From f5ecb512d53cf938854a6ec8c61534f69b37d15b Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 20 Apr 2022 16:01:25 -0700 Subject: [PATCH 6/7] Make strict --- src/compiler/parser.ts | 56 ++++++++----------- ...parserArrowFunctionExpression10.errors.txt | 11 ++-- .../parserArrowFunctionExpression10.js | 3 +- .../parserArrowFunctionExpression10.symbols | 3 +- .../parserArrowFunctionExpression10.types | 6 +- ...parserArrowFunctionExpression13.errors.txt | 8 ++- .../parserArrowFunctionExpression13.js | 3 +- .../parserArrowFunctionExpression13.symbols | 4 +- .../parserArrowFunctionExpression13.types | 7 ++- ...parserArrowFunctionExpression14.errors.txt | 11 +++- .../parserArrowFunctionExpression14.js | 4 +- .../parserArrowFunctionExpression14.symbols | 5 +- .../parserArrowFunctionExpression14.types | 8 +-- ...parserArrowFunctionExpression15.errors.txt | 14 +++++ .../parserArrowFunctionExpression15.js | 3 +- .../parserArrowFunctionExpression15.symbols | 3 +- .../parserArrowFunctionExpression15.types | 6 +- ...parserArrowFunctionExpression16.errors.txt | 14 +++++ .../parserArrowFunctionExpression16.js | 3 +- .../parserArrowFunctionExpression16.symbols | 3 +- .../parserArrowFunctionExpression16.types | 8 ++- 21 files changed, 116 insertions(+), 67 deletions(-) create mode 100644 tests/baselines/reference/parserArrowFunctionExpression15.errors.txt create mode 100644 tests/baselines/reference/parserArrowFunctionExpression16.errors.txt diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index f055c326b0a33..20cacf711592e 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4452,7 +4452,7 @@ namespace ts { } function tryParseParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction: boolean): Expression | undefined { - const triState = isParenthesizedArrowFunctionExpression(); + const triState = isParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction); if (triState === Tristate.False) { // It's definitely not a parenthesized arrow function expression. return undefined; @@ -4463,7 +4463,7 @@ namespace ts { // it out, but don't allow any ambiguity, and return 'undefined' if this could be an // expression instead. return triState === Tristate.True ? - parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ true, /*disallowReturnTypeInArrowFunction*/ false) : + parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ true, disallowReturnTypeInArrowFunction) : tryParse(() => parsePossibleParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction)); } @@ -4471,9 +4471,9 @@ namespace ts { // False -> There *cannot* be a parenthesized arrow function here. // Unknown -> There *might* be a parenthesized arrow function here. // Speculatively look ahead to be sure, and rollback if not. - function isParenthesizedArrowFunctionExpression(): Tristate { + function isParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction: boolean): Tristate { if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken || token() === SyntaxKind.AsyncKeyword) { - return lookAhead(isParenthesizedArrowFunctionExpressionWorker); + return lookAhead(() => isParenthesizedArrowFunctionExpressionWorker(disallowReturnTypeInArrowFunction)); } if (token() === SyntaxKind.EqualsGreaterThanToken) { @@ -4486,7 +4486,7 @@ namespace ts { return Tristate.False; } - function isParenthesizedArrowFunctionExpressionWorker() { + function isParenthesizedArrowFunctionExpressionWorker(disallowReturnTypeInArrowFunction: boolean) { if (token() === SyntaxKind.AsyncKeyword) { nextToken(); if (scanner.hasPrecedingLineBreak()) { @@ -4508,8 +4508,13 @@ namespace ts { // but this is probably what the user intended. const third = nextToken(); switch (third) { - case SyntaxKind.EqualsGreaterThanToken: case SyntaxKind.ColonToken: + if (disallowReturnTypeInArrowFunction) { + // "a ? () : ..." + return Tristate.False; + } + return Tristate.True; + case SyntaxKind.EqualsGreaterThanToken: case SyntaxKind.OpenBraceToken: return Tristate.True; default: @@ -4695,7 +4700,19 @@ namespace ts { } } - const hasReturnColon = token() === SyntaxKind.ColonToken; + // 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, even if we aren't + // certain whether or not the preceding text was parsed as a parameter list. + if (disallowReturnTypeInArrowFunction && token() === SyntaxKind.ColonToken) { + return undefined; + } + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); if (type && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(type)) { return undefined; @@ -4731,31 +4748,6 @@ namespace ts { ? parseArrowFunctionExpressionBody(some(modifiers, isAsyncModifier), disallowReturnTypeInArrowFunction) : parseIdentifier(); - // 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. - if (disallowReturnTypeInArrowFunction && hasReturnColon) { - // 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. - if (token() !== SyntaxKind.ColonToken) { - return undefined; - } - } - const node = factory.createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body); return withJSDoc(finishNode(node, pos), hasJSDoc); } diff --git a/tests/baselines/reference/parserArrowFunctionExpression10.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression10.errors.txt index 0ee29b021a1ef..43cf9de267b85 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression10.errors.txt +++ b/tests/baselines/reference/parserArrowFunctionExpression10.errors.txt @@ -1,17 +1,20 @@ tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts(1,1): error TS2304: Cannot find name 'a'. -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts(1,11): error TS2304: Cannot find name 'c'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts(1,6): error TS2304: Cannot find name 'b'. tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts(1,17): error TS2304: Cannot find name 'd'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts(1,20): error TS1005: ';' expected. tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts(1,27): error TS2304: Cannot find name 'f'. -==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts (4 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts (5 errors) ==== a ? (b) : c => (d) : e => f ~ !!! error TS2304: Cannot find name 'a'. - ~ -!!! error TS2304: Cannot find name 'c'. + ~ +!!! error TS2304: Cannot find name 'b'. ~ !!! error TS2304: Cannot find name 'd'. + ~ +!!! error TS1005: ';' expected. ~ !!! error TS2304: Cannot find name 'f'. \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression10.js b/tests/baselines/reference/parserArrowFunctionExpression10.js index 7681332637b4e..86e1e61bb0716 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression10.js +++ b/tests/baselines/reference/parserArrowFunctionExpression10.js @@ -3,4 +3,5 @@ a ? (b) : c => (d) : e => f //// [parserArrowFunctionExpression10.js] -a ? function (b) { return (d); } : function (e) { return f; }; +a ? (b) : function (c) { return (d); }; +(function (e) { return f; }); diff --git a/tests/baselines/reference/parserArrowFunctionExpression10.symbols b/tests/baselines/reference/parserArrowFunctionExpression10.symbols index df391a0be345d..f30f0b3e3ca49 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression10.symbols +++ b/tests/baselines/reference/parserArrowFunctionExpression10.symbols @@ -1,6 +1,5 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts === a ? (b) : c => (d) : e => f ->b : Symbol(b, Decl(parserArrowFunctionExpression10.ts, 0, 5)) ->c : Symbol(c) +>c : Symbol(c, Decl(parserArrowFunctionExpression10.ts, 0, 9)) >e : Symbol(e, Decl(parserArrowFunctionExpression10.ts, 0, 20)) diff --git a/tests/baselines/reference/parserArrowFunctionExpression10.types b/tests/baselines/reference/parserArrowFunctionExpression10.types index e4149fe4cbb5c..8ec7d69c29559 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression10.types +++ b/tests/baselines/reference/parserArrowFunctionExpression10.types @@ -1,9 +1,11 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression10.ts === a ? (b) : c => (d) : e => f ->a ? (b) : c => (d) : e => f : (b: any) => c +>a ? (b) : c => (d) : any >a : any ->(b) : c => (d) : (b: any) => c +>(b) : any >b : any +>c => (d) : (c: any) => any +>c : any >(d) : any >d : any >e => f : (e: any) => any diff --git a/tests/baselines/reference/parserArrowFunctionExpression13.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression13.errors.txt index d0ea1c7d179ab..d4ced1fae38a4 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression13.errors.txt +++ b/tests/baselines/reference/parserArrowFunctionExpression13.errors.txt @@ -1,11 +1,17 @@ tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts(1,1): error TS2304: Cannot find name 'a'. tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts(1,11): error TS2304: Cannot find name 'a'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts(1,18): error TS1109: Expression expected. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts(1,19): error TS1005: ';' expected. -==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts (4 errors) ==== a ? () => a() : (): any => null; ~ !!! error TS2304: Cannot find name 'a'. ~ !!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1005: ';' expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression13.js b/tests/baselines/reference/parserArrowFunctionExpression13.js index d208d9ba90a1f..f9b67bf58e336 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression13.js +++ b/tests/baselines/reference/parserArrowFunctionExpression13.js @@ -3,4 +3,5 @@ a ? () => a() : (): any => null; //// [parserArrowFunctionExpression13.js] -a ? function () { return a(); } : function () { return null; }; +a ? function () { return a(); } : (); +(function (any) { return null; }); diff --git a/tests/baselines/reference/parserArrowFunctionExpression13.symbols b/tests/baselines/reference/parserArrowFunctionExpression13.symbols index 643cfcf1a2b78..81ab28ab8cc51 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression13.symbols +++ b/tests/baselines/reference/parserArrowFunctionExpression13.symbols @@ -1,4 +1,4 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts === a ? () => a() : (): any => null; -No type information for this code. -No type information for this code. \ No newline at end of file +>any : Symbol(any, Decl(parserArrowFunctionExpression13.ts, 0, 19)) + diff --git a/tests/baselines/reference/parserArrowFunctionExpression13.types b/tests/baselines/reference/parserArrowFunctionExpression13.types index 9341e27b0c30d..7594e1e0469a7 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression13.types +++ b/tests/baselines/reference/parserArrowFunctionExpression13.types @@ -1,10 +1,13 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts === a ? () => a() : (): any => null; ->a ? () => a() : (): any => null : () => any +>a ? () => a() : () : any >a : any >() => a() : () => any >a() : any >a : any ->(): any => null : () => any +>() : any +> : any +>any => null : (any: any) => any +>any : any >null : null diff --git a/tests/baselines/reference/parserArrowFunctionExpression14.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression14.errors.txt index b37e09d92ff3a..c19776f77a046 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression14.errors.txt +++ b/tests/baselines/reference/parserArrowFunctionExpression14.errors.txt @@ -1,14 +1,23 @@ tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression14.ts(1,1): error TS2304: Cannot find name 'a'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression14.ts(1,30): error TS1109: Expression expected. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression14.ts(1,37): error TS1109: Expression expected. tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression14.ts(1,40): error TS2304: Cannot find name 'd'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression14.ts(1,44): error TS1005: ';' expected. tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression14.ts(1,46): error TS2304: Cannot find name 'e'. -==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression14.ts (3 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression14.ts (6 errors) ==== a() ? (b: number, c?: string): void => d() : e; ~ !!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS1109: Expression expected. + ~~ +!!! error TS1109: Expression expected. ~ !!! error TS2304: Cannot find name 'd'. + ~ +!!! error TS1005: ';' expected. ~ !!! error TS2304: Cannot find name 'e'. \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression14.js b/tests/baselines/reference/parserArrowFunctionExpression14.js index 2dcaae91f3506..7941718ae24a8 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression14.js +++ b/tests/baselines/reference/parserArrowFunctionExpression14.js @@ -3,4 +3,6 @@ a() ? (b: number, c?: string): void => d() : e; //// [parserArrowFunctionExpression14.js] -a() ? function (b, c) { return d(); } : e; +a() ? : void ; +d(); +e; diff --git a/tests/baselines/reference/parserArrowFunctionExpression14.symbols b/tests/baselines/reference/parserArrowFunctionExpression14.symbols index 95584e9f223be..75c6d5ff8b7ff 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression14.symbols +++ b/tests/baselines/reference/parserArrowFunctionExpression14.symbols @@ -1,5 +1,4 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression14.ts === a() ? (b: number, c?: string): void => d() : e; ->b : Symbol(b, Decl(parserArrowFunctionExpression14.ts, 0, 7)) ->c : Symbol(c, Decl(parserArrowFunctionExpression14.ts, 0, 17)) - +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression14.types b/tests/baselines/reference/parserArrowFunctionExpression14.types index 1c6d22bb83dc0..4102193f96787 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression14.types +++ b/tests/baselines/reference/parserArrowFunctionExpression14.types @@ -1,11 +1,11 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression14.ts === a() ? (b: number, c?: string): void => d() : e; ->a() ? (b: number, c?: string): void => d() : e : any +>a() ? (b: number, c?: string): void : any >a() : any >a : any ->(b: number, c?: string): void => d() : (b: number, c?: string) => void ->b : number ->c : string +> : any +>void : undefined +> : any >d() : any >d : any >e : any diff --git a/tests/baselines/reference/parserArrowFunctionExpression15.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression15.errors.txt new file mode 100644 index 0000000000000..60def8ca15fa6 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression15.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts(1,10): error TS2304: Cannot find name 'param'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts(1,28): error TS2304: Cannot find name 'param'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts(1,34): error TS1005: ';' expected. + + +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts (3 errors) ==== + false ? (param): string => param : null + ~~~~~ +!!! error TS2304: Cannot find name 'param'. + ~~~~~ +!!! error TS2304: Cannot find name 'param'. + ~ +!!! error TS1005: ';' expected. + \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression15.js b/tests/baselines/reference/parserArrowFunctionExpression15.js index a18efc84f0975..047b09c6ddec0 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression15.js +++ b/tests/baselines/reference/parserArrowFunctionExpression15.js @@ -3,4 +3,5 @@ false ? (param): string => param : null //// [parserArrowFunctionExpression15.js] -false ? function (param) { return param; } : null; +false ? (param) : function (string) { return param; }; +null; diff --git a/tests/baselines/reference/parserArrowFunctionExpression15.symbols b/tests/baselines/reference/parserArrowFunctionExpression15.symbols index 7cb354c7dc912..7750b8d43be97 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression15.symbols +++ b/tests/baselines/reference/parserArrowFunctionExpression15.symbols @@ -1,5 +1,4 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts === false ? (param): string => param : null ->param : Symbol(param, Decl(parserArrowFunctionExpression15.ts, 0, 9)) ->param : Symbol(param, Decl(parserArrowFunctionExpression15.ts, 0, 9)) +>string : Symbol(string, Decl(parserArrowFunctionExpression15.ts, 0, 16)) diff --git a/tests/baselines/reference/parserArrowFunctionExpression15.types b/tests/baselines/reference/parserArrowFunctionExpression15.types index 4640763862112..ec808c729eece 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression15.types +++ b/tests/baselines/reference/parserArrowFunctionExpression15.types @@ -1,9 +1,11 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression15.ts === false ? (param): string => param : null ->false ? (param): string => param : null : (param: any) => string +>false ? (param): string => param : any >false : false ->(param): string => param : (param: any) => string +>(param) : any >param : any +>string => param : (string: any) => any +>string : any >param : any >null : null diff --git a/tests/baselines/reference/parserArrowFunctionExpression16.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression16.errors.txt new file mode 100644 index 0000000000000..740144391e298 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression16.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts(1,17): error TS2304: Cannot find name 'param'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts(1,35): error TS2304: Cannot find name 'param'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts(1,48): error TS1005: ';' expected. + + +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts (3 errors) ==== + true ? false ? (param): string => param : null : null + ~~~~~ +!!! error TS2304: Cannot find name 'param'. + ~~~~~ +!!! error TS2304: Cannot find name 'param'. + ~ +!!! error TS1005: ';' expected. + \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression16.js b/tests/baselines/reference/parserArrowFunctionExpression16.js index 8d0404c91c853..a2b2fff3aad85 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression16.js +++ b/tests/baselines/reference/parserArrowFunctionExpression16.js @@ -3,4 +3,5 @@ true ? false ? (param): string => param : null : null //// [parserArrowFunctionExpression16.js] -true ? false ? function (param) { return param; } : null : null; +true ? false ? (param) : function (string) { return param; } : null; +null; diff --git a/tests/baselines/reference/parserArrowFunctionExpression16.symbols b/tests/baselines/reference/parserArrowFunctionExpression16.symbols index f2a4ff04df134..684b74408ccd5 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression16.symbols +++ b/tests/baselines/reference/parserArrowFunctionExpression16.symbols @@ -1,5 +1,4 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts === true ? false ? (param): string => param : null : null ->param : Symbol(param, Decl(parserArrowFunctionExpression16.ts, 0, 16)) ->param : Symbol(param, Decl(parserArrowFunctionExpression16.ts, 0, 16)) +>string : Symbol(string, Decl(parserArrowFunctionExpression16.ts, 0, 23)) diff --git a/tests/baselines/reference/parserArrowFunctionExpression16.types b/tests/baselines/reference/parserArrowFunctionExpression16.types index fffd623adac0d..dbe5cc2e81733 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression16.types +++ b/tests/baselines/reference/parserArrowFunctionExpression16.types @@ -1,11 +1,13 @@ === tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression16.ts === true ? false ? (param): string => param : null : null ->true ? false ? (param): string => param : null : null : (param: any) => string +>true ? false ? (param): string => param : null : any >true : true ->false ? (param): string => param : null : (param: any) => string +>false ? (param): string => param : any >false : false ->(param): string => param : (param: any) => string +>(param) : any >param : any +>string => param : (string: any) => any +>string : any >param : any >null : null >null : null From fb6ba846138263e6501fcb707381ffaa8fec59e2 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 20 Apr 2022 16:16:51 -0700 Subject: [PATCH 7/7] Make (): unambiguous again --- src/compiler/parser.ts | 15 +++++---------- .../parserArrowFunctionExpression13.errors.txt | 9 +++------ .../reference/parserArrowFunctionExpression13.js | 2 +- .../parserArrowFunctionExpression13.types | 1 - 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 20cacf711592e..ffe5f079c8c78 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4452,7 +4452,7 @@ namespace ts { } function tryParseParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction: boolean): Expression | undefined { - const triState = isParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction); + const triState = isParenthesizedArrowFunctionExpression(); if (triState === Tristate.False) { // It's definitely not a parenthesized arrow function expression. return undefined; @@ -4471,9 +4471,9 @@ namespace ts { // False -> There *cannot* be a parenthesized arrow function here. // Unknown -> There *might* be a parenthesized arrow function here. // Speculatively look ahead to be sure, and rollback if not. - function isParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction: boolean): Tristate { + function isParenthesizedArrowFunctionExpression(): Tristate { if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken || token() === SyntaxKind.AsyncKeyword) { - return lookAhead(() => isParenthesizedArrowFunctionExpressionWorker(disallowReturnTypeInArrowFunction)); + return lookAhead(isParenthesizedArrowFunctionExpressionWorker); } if (token() === SyntaxKind.EqualsGreaterThanToken) { @@ -4486,7 +4486,7 @@ namespace ts { return Tristate.False; } - function isParenthesizedArrowFunctionExpressionWorker(disallowReturnTypeInArrowFunction: boolean) { + function isParenthesizedArrowFunctionExpressionWorker() { if (token() === SyntaxKind.AsyncKeyword) { nextToken(); if (scanner.hasPrecedingLineBreak()) { @@ -4508,13 +4508,8 @@ namespace ts { // but this is probably what the user intended. const third = nextToken(); switch (third) { - case SyntaxKind.ColonToken: - if (disallowReturnTypeInArrowFunction) { - // "a ? () : ..." - return Tristate.False; - } - return Tristate.True; case SyntaxKind.EqualsGreaterThanToken: + case SyntaxKind.ColonToken: case SyntaxKind.OpenBraceToken: return Tristate.True; default: diff --git a/tests/baselines/reference/parserArrowFunctionExpression13.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression13.errors.txt index d4ced1fae38a4..8e4df9842c146 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression13.errors.txt +++ b/tests/baselines/reference/parserArrowFunctionExpression13.errors.txt @@ -1,17 +1,14 @@ tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts(1,1): error TS2304: Cannot find name 'a'. tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts(1,11): error TS2304: Cannot find name 'a'. -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts(1,18): error TS1109: Expression expected. -tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts(1,19): error TS1005: ';' expected. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts(1,19): error TS1109: Expression expected. -==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts (4 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression13.ts (3 errors) ==== a ? () => a() : (): any => null; ~ !!! error TS2304: Cannot find name 'a'. ~ !!! error TS2304: Cannot find name 'a'. - ~ -!!! error TS1109: Expression expected. ~ -!!! error TS1005: ';' expected. +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression13.js b/tests/baselines/reference/parserArrowFunctionExpression13.js index f9b67bf58e336..5bc8a18e946c6 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression13.js +++ b/tests/baselines/reference/parserArrowFunctionExpression13.js @@ -3,5 +3,5 @@ a ? () => a() : (): any => null; //// [parserArrowFunctionExpression13.js] -a ? function () { return a(); } : (); +a ? function () { return a(); } : ; (function (any) { return null; }); diff --git a/tests/baselines/reference/parserArrowFunctionExpression13.types b/tests/baselines/reference/parserArrowFunctionExpression13.types index 7594e1e0469a7..6eaa57cd45d59 100644 --- a/tests/baselines/reference/parserArrowFunctionExpression13.types +++ b/tests/baselines/reference/parserArrowFunctionExpression13.types @@ -5,7 +5,6 @@ a ? () => a() : (): any => null; >() => a() : () => any >a() : any >a : any ->() : any > : any >any => null : (any: any) => any >any : any