From af56b45938c347434ae343e0565e1c485c281ccf Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 5 Apr 2023 13:35:33 -0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Pick=20PR=20#53666=20(Disable=20?= =?UTF-8?q?JSX=20recovery=20hack=20when=20in=20u...)=20into=20release-5.0?= =?UTF-8?q?=20(#53676)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com> --- src/compiler/parser.ts | 8 +++++--- ...arseJsxElementInUnaryExpressionNoCrash1.errors.txt | 11 +++++++++++ .../parseJsxElementInUnaryExpressionNoCrash1.js | 7 +++++++ .../parseJsxElementInUnaryExpressionNoCrash1.symbols | 4 ++++ .../parseJsxElementInUnaryExpressionNoCrash1.types | 9 +++++++++ ...arseJsxElementInUnaryExpressionNoCrash2.errors.txt | 8 ++++++++ .../parseJsxElementInUnaryExpressionNoCrash2.js | 7 +++++++ .../parseJsxElementInUnaryExpressionNoCrash2.symbols | 4 ++++ .../parseJsxElementInUnaryExpressionNoCrash2.types | 8 ++++++++ .../parseJsxElementInUnaryExpressionNoCrash1.ts | 4 ++++ .../parseJsxElementInUnaryExpressionNoCrash2.ts | 4 ++++ 11 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.errors.txt create mode 100644 tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.js create mode 100644 tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.symbols create mode 100644 tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.types create mode 100644 tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.errors.txt create mode 100644 tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.js create mode 100644 tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.symbols create mode 100644 tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.types create mode 100644 tests/cases/compiler/parseJsxElementInUnaryExpressionNoCrash1.ts create mode 100644 tests/cases/compiler/parseJsxElementInUnaryExpressionNoCrash2.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index be81d789c57d0..cd0d806794c31 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5684,7 +5684,7 @@ namespace Parser { // Just like in parseUpdateExpression, we need to avoid parsing type assertions when // in JSX and we see an expression like "+ bar". if (languageVariant === LanguageVariant.JSX) { - return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); + return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true, /*topInvalidNodePosition*/ undefined, /*openingTag*/ undefined, /*mustBeUnary*/ true); } // This is modified UnaryExpression grammar in TypeScript // UnaryExpression (modified): @@ -5911,7 +5911,7 @@ namespace Parser { return finishNode(factoryCreatePropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true)), pos); } - function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean, topInvalidNodePosition?: number, openingTag?: JsxOpeningElement | JsxOpeningFragment): JsxElement | JsxSelfClosingElement | JsxFragment { + function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean, topInvalidNodePosition?: number, openingTag?: JsxOpeningElement | JsxOpeningFragment, mustBeUnary = false): JsxElement | JsxSelfClosingElement | JsxFragment { const pos = getNodePos(); const opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext); let result: JsxElement | JsxSelfClosingElement | JsxFragment; @@ -5968,7 +5968,9 @@ namespace Parser { // does less damage and we can report a better error. // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios // of one sort or another. - if (inExpressionContext && token() === SyntaxKind.LessThanToken) { + // If we are in a unary context, we can't do this recovery; the binary expression we return here is not + // a valid UnaryExpression and will cause problems later. + if (!mustBeUnary && inExpressionContext && token() === SyntaxKind.LessThanToken) { const topBadPos = typeof topInvalidNodePosition === "undefined" ? result.pos : topInvalidNodePosition; const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true, topBadPos)); if (invalidElement) { diff --git a/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.errors.txt b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.errors.txt new file mode 100644 index 0000000000000..6f638b4a2230f --- /dev/null +++ b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/a.js(1,4): error TS1003: Identifier expected. +tests/cases/compiler/a.js(1,5): error TS1109: Expression expected. + + +==== tests/cases/compiler/a.js (2 errors) ==== + ~< < + ~ +!!! error TS1003: Identifier expected. + +!!! error TS1109: Expression expected. + \ No newline at end of file diff --git a/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.js b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.js new file mode 100644 index 0000000000000..64357a51dc64e --- /dev/null +++ b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.js @@ -0,0 +1,7 @@ +//// [a.js] +~< < + + +//// [a.js] +~< /> < +; diff --git a/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.symbols b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.symbols new file mode 100644 index 0000000000000..e6ed11e193527 --- /dev/null +++ b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.symbols @@ -0,0 +1,4 @@ +=== tests/cases/compiler/a.js === + +~< < + diff --git a/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.types b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.types new file mode 100644 index 0000000000000..ec5c50b31c5b0 --- /dev/null +++ b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash1.types @@ -0,0 +1,9 @@ +=== tests/cases/compiler/a.js === +~< < +>~< < : boolean +>~< : number +>< : any +> : any + +> : any + diff --git a/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.errors.txt b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.errors.txt new file mode 100644 index 0000000000000..4ae236bce12a4 --- /dev/null +++ b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.errors.txt @@ -0,0 +1,8 @@ +tests/cases/compiler/a.js(1,9): error TS1109: Expression expected. + + +==== tests/cases/compiler/a.js (1 errors) ==== + ~<> < + +!!! error TS1109: Expression expected. + \ No newline at end of file diff --git a/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.js b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.js new file mode 100644 index 0000000000000..0a9f06793a66f --- /dev/null +++ b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.js @@ -0,0 +1,7 @@ +//// [a.js] +~<> < + + +//// [a.js] +~<> < +; diff --git a/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.symbols b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.symbols new file mode 100644 index 0000000000000..d6832b40cd279 --- /dev/null +++ b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.symbols @@ -0,0 +1,4 @@ +=== tests/cases/compiler/a.js === + +~<> < + diff --git a/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.types b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.types new file mode 100644 index 0000000000000..0c0fce49f7382 --- /dev/null +++ b/tests/baselines/reference/parseJsxElementInUnaryExpressionNoCrash2.types @@ -0,0 +1,8 @@ +=== tests/cases/compiler/a.js === +~<> < +>~<> < : boolean +>~<> : number +><> : any + +> : any + diff --git a/tests/cases/compiler/parseJsxElementInUnaryExpressionNoCrash1.ts b/tests/cases/compiler/parseJsxElementInUnaryExpressionNoCrash1.ts new file mode 100644 index 0000000000000..177022396f4ad --- /dev/null +++ b/tests/cases/compiler/parseJsxElementInUnaryExpressionNoCrash1.ts @@ -0,0 +1,4 @@ +// @allowJs: true +// @outDir: ./out +// @filename: a.js +~< < diff --git a/tests/cases/compiler/parseJsxElementInUnaryExpressionNoCrash2.ts b/tests/cases/compiler/parseJsxElementInUnaryExpressionNoCrash2.ts new file mode 100644 index 0000000000000..0fbf4b3eb2abb --- /dev/null +++ b/tests/cases/compiler/parseJsxElementInUnaryExpressionNoCrash2.ts @@ -0,0 +1,4 @@ +// @allowJs: true +// @outDir: ./out +// @filename: a.js +~<> <