From 89a737c871fca68bd53c2a0aa387acd591153006 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 20 May 2021 07:20:57 -0700 Subject: [PATCH] Improve parser recovery for unclosed/mismatched JSX elements (#43780) * First draft Everything works, the error messages for unmatched opening elements could still use improvement, plus there is tonnes of unused and ugly code. 1. Make sure the parser can recover from all kinds of unclosed tags. 2. Improve the parse tree for unmatched opening tags. 3. Better errors at some point. * Lots of cleanup * Improve readability of construction/fix lint * improve line-length formatting --- src/compiler/parser.ts | 93 ++- src/harness/fourslashImpl.ts | 2 +- ...ilationTypeArgumentSyntaxOfCall.errors.txt | 4 +- .../reference/jsxAndTypeAssertion.js | 2 +- .../reference/jsxAndTypeAssertion.types | 2 +- .../jsxInvalidEsprimaTestSuite.errors.txt | 12 +- .../reference/jsxParsingError2.errors.txt | 22 +- tests/baselines/reference/jsxParsingError2.js | 3 +- .../reference/jsxParsingError2.types | 7 +- .../jsxUnclosedParserRecovery.errors.txt | 273 +++++++++ .../reference/jsxUnclosedParserRecovery.js | 277 +++++++++ .../jsxUnclosedParserRecovery.symbols | 314 ++++++++++ .../reference/jsxUnclosedParserRecovery.types | 541 ++++++++++++++++++ .../jsx/jsxUnclosedParserRecovery.ts | 140 +++++ 14 files changed, 1634 insertions(+), 58 deletions(-) create mode 100644 tests/baselines/reference/jsxUnclosedParserRecovery.errors.txt create mode 100644 tests/baselines/reference/jsxUnclosedParserRecovery.js create mode 100644 tests/baselines/reference/jsxUnclosedParserRecovery.symbols create mode 100644 tests/baselines/reference/jsxUnclosedParserRecovery.types create mode 100644 tests/cases/conformance/jsx/jsxUnclosedParserRecovery.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 82a32e47578..78e4e77b70a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4865,18 +4865,45 @@ namespace ts { return finishNode(factory.createPropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true)), pos); } - function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean, topInvalidNodePosition?: number): JsxElement | JsxSelfClosingElement | JsxFragment { + function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean, topInvalidNodePosition?: number, openingTag?: JsxOpeningElement | JsxOpeningFragment): JsxElement | JsxSelfClosingElement | JsxFragment { const pos = getNodePos(); const opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext); let result: JsxElement | JsxSelfClosingElement | JsxFragment; if (opening.kind === SyntaxKind.JsxOpeningElement) { - const children = parseJsxChildren(opening); - const closingElement = parseJsxClosingElement(inExpressionContext); + let children = parseJsxChildren(opening); + let closingElement: JsxClosingElement; - if (!tagNamesAreEquivalent(opening.tagName, closingElement.tagName)) { - parseErrorAtRange(closingElement, Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, getTextOfNodeFromSourceText(sourceText, opening.tagName)); + const lastChild: JsxChild | undefined = children[children.length - 1]; + if (lastChild?.kind === SyntaxKind.JsxElement + && !tagNamesAreEquivalent(lastChild.openingElement.tagName, lastChild.closingElement.tagName) + && tagNamesAreEquivalent(opening.tagName, lastChild.closingElement.tagName)) { + // when an unclosed JsxOpeningElement incorrectly parses its parent's JsxClosingElement, + // restructure (
(...
)) --> (
(...)
) + // (no need to error; the parent will error) + const end = lastChild.openingElement.end; // newly-created children and closing are both zero-width end/end + const newLast = finishNode(factory.createJsxElement( + lastChild.openingElement, + createNodeArray([], end, end), + finishNode(factory.createJsxClosingElement(finishNode(factory.createIdentifier(""), end, end)), end, end)), + lastChild.openingElement.pos, + end); + + children = createNodeArray([...children.slice(0, children.length - 1), newLast], children.pos, end); + closingElement = lastChild.closingElement; + } + else { + closingElement = parseJsxClosingElement(opening, inExpressionContext); + if (!tagNamesAreEquivalent(opening.tagName, closingElement.tagName)) { + if (openingTag && isJsxOpeningElement(openingTag) && tagNamesAreEquivalent(closingElement.tagName, openingTag.tagName)) { + // opening incorrectly matched with its parent's closing -- put error on opening + parseErrorAtRange(opening.tagName, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, opening.tagName)); + } + else { + // other opening/closing mismatches -- put error on closing + parseErrorAtRange(closingElement.tagName, Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, getTextOfNodeFromSourceText(sourceText, opening.tagName)); + } + } } - result = finishNode(factory.createJsxElement(opening, children, closingElement), pos); } else if (opening.kind === SyntaxKind.JsxOpeningFragment) { @@ -4941,7 +4968,7 @@ namespace ts { case SyntaxKind.OpenBraceToken: return parseJsxExpression(/*inExpressionContext*/ false); case SyntaxKind.LessThanToken: - return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false); + return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false, /*topInvalidNodePosition*/ undefined, openingTag); default: return Debug.assertNever(token); } @@ -4957,6 +4984,13 @@ namespace ts { const child = parseJsxChild(openingTag, currentToken = scanner.reScanJsxToken()); if (!child) break; list.push(child); + if (isJsxOpeningElement(openingTag) + && child?.kind === SyntaxKind.JsxElement + && !tagNamesAreEquivalent(child.openingElement.tagName, child.closingElement.tagName) + && tagNamesAreEquivalent(openingTag.tagName, child.closingElement.tagName)) { + // stop after parsing a mismatched child like
...(
) in order to reattach the higher + break; + } } parsingContext = saveParsingContext; @@ -4978,7 +5012,6 @@ namespace ts { scanJsxText(); return finishNode(factory.createJsxOpeningFragment(), pos); } - const tagName = parseJsxElementName(); const typeArguments = (contextFlags & NodeFlags.JavaScriptFile) === 0 ? tryParseTypeArguments() : undefined; const attributes = parseJsxAttributes(); @@ -4994,12 +5027,14 @@ namespace ts { } else { parseExpected(SyntaxKind.SlashToken); - if (inExpressionContext) { - parseExpected(SyntaxKind.GreaterThanToken); - } - else { - parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false); - scanJsxText(); + if (parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false)) { + // manually advance the scanner in order to look for jsx text inside jsx + if (inExpressionContext) { + nextToken(); + } + else { + scanJsxText(); + } } node = factory.createJsxSelfClosingElement(tagName, typeArguments, attributes); } @@ -5077,16 +5112,18 @@ namespace ts { return finishNode(factory.createJsxSpreadAttribute(expression), pos); } - function parseJsxClosingElement(inExpressionContext: boolean): JsxClosingElement { + function parseJsxClosingElement(open: JsxOpeningElement, inExpressionContext: boolean): JsxClosingElement { const pos = getNodePos(); parseExpected(SyntaxKind.LessThanSlashToken); const tagName = parseJsxElementName(); - if (inExpressionContext) { - parseExpected(SyntaxKind.GreaterThanToken); - } - else { - parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false); - scanJsxText(); + if (parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false)) { + // manually advance the scanner in order to look for jsx text inside jsx + if (inExpressionContext || !tagNamesAreEquivalent(open.tagName, tagName)) { + nextToken(); + } + else { + scanJsxText(); + } } return finishNode(factory.createJsxClosingElement(tagName), pos); } @@ -5097,12 +5134,14 @@ namespace ts { if (tokenIsIdentifierOrKeyword(token())) { parseErrorAtRange(parseJsxElementName(), Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment); } - if (inExpressionContext) { - parseExpected(SyntaxKind.GreaterThanToken); - } - else { - parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false); - scanJsxText(); + if (parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*shouldAdvance*/ false)) { + // manually advance the scanner in order to look for jsx text inside jsx + if (inExpressionContext) { + nextToken(); + } + else { + scanJsxText(); + } } return finishNode(factory.createJsxJsxClosingFragment(), pos); } diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 3ccaa6faee9..c0b7053f93b 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -3177,7 +3177,7 @@ namespace FourSlash { for (const markerName in map) { this.goToMarker(markerName); const actual = this.languageService.getJsxClosingTagAtPosition(this.activeFile.fileName, this.currentCaretPosition); - assert.deepEqual(actual, map[markerName]); + assert.deepEqual(actual, map[markerName], markerName); } } diff --git a/tests/baselines/reference/jsFileCompilationTypeArgumentSyntaxOfCall.errors.txt b/tests/baselines/reference/jsFileCompilationTypeArgumentSyntaxOfCall.errors.txt index a06a04a16d4..24dab988044 100644 --- a/tests/baselines/reference/jsFileCompilationTypeArgumentSyntaxOfCall.errors.txt +++ b/tests/baselines/reference/jsFileCompilationTypeArgumentSyntaxOfCall.errors.txt @@ -2,7 +2,7 @@ tests/cases/compiler/a.jsx(1,13): error TS1109: Expression expected. tests/cases/compiler/a.jsx(4,1): error TS2657: JSX expressions must have one parent element. tests/cases/compiler/a.jsx(4,5): error TS1003: Identifier expected. tests/cases/compiler/a.jsx(4,13): error TS1382: Unexpected token. Did you mean `{'>'}` or `>`? -tests/cases/compiler/a.jsx(4,14): error TS17002: Expected corresponding JSX closing tag for 'number'. +tests/cases/compiler/a.jsx(4,16): error TS17002: Expected corresponding JSX closing tag for 'number'. tests/cases/compiler/a.jsx(5,1): error TS2657: JSX expressions must have one parent element. tests/cases/compiler/a.jsx(5,5): error TS1003: Identifier expected. tests/cases/compiler/a.jsx(5,6): error TS17008: JSX element 'number' has no corresponding closing tag. @@ -23,7 +23,7 @@ tests/cases/compiler/a.jsx(6,1): error TS1005: ''}` or `>`? - ~~~~~~ + ~~~ !!! error TS17002: Expected corresponding JSX closing tag for 'number'. />; ~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/jsxAndTypeAssertion.js b/tests/baselines/reference/jsxAndTypeAssertion.js index ecfdce488ef..69a32009967 100644 --- a/tests/baselines/reference/jsxAndTypeAssertion.js +++ b/tests/baselines/reference/jsxAndTypeAssertion.js @@ -34,7 +34,7 @@ x = ; x = hello {} }; -x = }>hello}/> +x = }>hello}/>; x = }>hello{}}; diff --git a/tests/baselines/reference/jsxAndTypeAssertion.types b/tests/baselines/reference/jsxAndTypeAssertion.types index b9ba2f93f13..afc711dfab6 100644 --- a/tests/baselines/reference/jsxAndTypeAssertion.types +++ b/tests/baselines/reference/jsxAndTypeAssertion.types @@ -33,7 +33,7 @@ x = hello {{}} ; >foo : typeof foo x = {}}>hello; ->{}}>hello; : any +>{}}>hello : any >foo : typeof foo >test : any >{}}>hello : any diff --git a/tests/baselines/reference/jsxInvalidEsprimaTestSuite.errors.txt b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.errors.txt index ed0df0cdd66..12698255485 100644 --- a/tests/baselines/reference/jsxInvalidEsprimaTestSuite.errors.txt +++ b/tests/baselines/reference/jsxInvalidEsprimaTestSuite.errors.txt @@ -8,7 +8,7 @@ tests/cases/conformance/jsx/10.tsx(1,13): error TS1005: '>' expected. tests/cases/conformance/jsx/10.tsx(1,14): error TS2304: Cannot find name 'c'. tests/cases/conformance/jsx/10.tsx(1,16): error TS1109: Expression expected. tests/cases/conformance/jsx/11.tsx(1,2): error TS2304: Cannot find name 'a'. -tests/cases/conformance/jsx/11.tsx(1,8): error TS17002: Expected corresponding JSX closing tag for 'a.b.c'. +tests/cases/conformance/jsx/11.tsx(1,10): error TS17002: Expected corresponding JSX closing tag for 'a.b.c'. tests/cases/conformance/jsx/12.tsx(1,1): error TS1109: Expression expected. tests/cases/conformance/jsx/12.tsx(1,2): error TS1109: Expression expected. tests/cases/conformance/jsx/12.tsx(1,5): error TS1109: Expression expected. @@ -73,9 +73,9 @@ tests/cases/conformance/jsx/31.tsx(1,4): error TS1003: Identifier expected. tests/cases/conformance/jsx/4.tsx(1,6): error TS1005: '{' expected. tests/cases/conformance/jsx/5.tsx(1,2): error TS17008: JSX element 'a' has no corresponding closing tag. tests/cases/conformance/jsx/5.tsx(1,5): error TS1005: '; - ~~~~ + ~ !!! error TS17002: Expected corresponding JSX closing tag for 'a'. ==== tests/cases/conformance/jsx/7.tsx (1 errors) ==== ; + ~~ +!!! error TS1003: Identifier expected. + function noCloseAttrs() { } + var donkey =
+ bananas="please" + ~~~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. +
; + ~~ +!!! error TS1003: Identifier expected. + function noCloseTypeArgAttrs() { } + var donkey =
+ ; + ~~ +!!! error TS1005: '>' expected. + function noCloseBracket() { } + var donkey =
+ bananas="please"/ + ~~~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. +
; + ~~ +!!! error TS1005: '>' expected. + function noCloseBracketTypeArgAttrs() { } + var donkey =
+ + ~~~~~ +!!! error TS17008: JSX element 'diddy' has no corresponding closing tag. +
; + function noSelfclose() { } + var donkey =
+ bananas="please"> + ~~~~~ +!!! error TS17008: JSX element 'diddy' has no corresponding closing tag. + ~~~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. +
; + function noSelfcloseTypeArgAttrs() { } + + var donkey =
+ < + + ~ +!!! error TS1003: Identifier expected. + ~~~~~ +!!! error TS2749: 'diddy' refers to a value, but is being used as a type here. Did you mean 'typeof diddy'? + ~ +!!! error TS1005: '>' expected. +
; + function noNameTrailingTag() { } + var donkey =
+ + ~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. + ~~~~~ +!!! error TS2749: 'diddy' refers to a value, but is being used as a type here. Did you mean 'typeof diddy'? + ~ +!!! error TS1005: '>' expected. +
; + function noCloseTrailingTag() { } + var donkey =
+ + ~~~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. + + ~ +!!! error TS1003: Identifier expected. +
; + function noCloseTypeArgTrailingTag() { } + var donkey =
+ + ~ +!!! error TS1003: Identifier expected. +
; + function noCloseAttrsTrailingTag() { } + var donkey =
+ bananas="please" + ~~~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. + + ~ +!!! error TS1003: Identifier expected. +
; + function noCloseTypeArgAttrsTrailingTag() { } + var donkey =
+ + ~ +!!! error TS1005: '>' expected. +
; + function noCloseBracketTrailingTag() { } + var donkey =
+ bananas="please"/ + ~~~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. + + ~ +!!! error TS1005: '>' expected. +
; + function noCloseBracketTypeArgAttrsTrailingTag() { } + var donkey =
+ + ~~~~~ +!!! error TS17008: JSX element 'diddy' has no corresponding closing tag. + +
; + function noSelfcloseTrailingTag() { } + var donkey =
+ bananas="please"> + ~~~~~ +!!! error TS17008: JSX element 'diddy' has no corresponding closing tag. + ~~~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. + +
; + function noSelfcloseTypeArgAttrsTrailingTag() { } + + var donkey =
+ < + Cranky Wrinkly Funky + ~~~~~~ +!!! error TS2304: Cannot find name 'Cranky'. +
; + ~~ +!!! error TS1003: Identifier expected. + function noNameTrailingText() { } + var donkey =
+ ; + ~~ +!!! error TS1003: Identifier expected. + function noCloseTrailingText() { } + var donkey =
+ + ~~~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. + Cranky Wrinkly Funky +
; + ~~ +!!! error TS1003: Identifier expected. + function noCloseTypeArgTrailingText() { } + var donkey =
+ ; + ~~ +!!! error TS1003: Identifier expected. + function noCloseAttrsTrailingText() { } + var donkey =
+ bananas="please" + ~~~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. + Cranky Wrinkly Funky +
; + ~~ +!!! error TS1003: Identifier expected. + function noCloseTypeArgAttrsTrailingText() { } + var donkey =
+ ' expected. +
; + function noCloseBracketTrailingText() { } + var donkey =
+ bananas="please"/ + ~~~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. + Cranky Wrinkly Funky + ~~~~~~ +!!! error TS1005: '>' expected. +
; + function noCloseBracketTypeArgAttrsTrailingText() { } + var donkey =
+ + ~~~~~ +!!! error TS17008: JSX element 'diddy' has no corresponding closing tag. + Cranky Wrinkly Funky +
; + function noSelfcloseTrailingText() { } + var donkey =
+ bananas="please"> + ~~~~~ +!!! error TS17008: JSX element 'diddy' has no corresponding closing tag. + ~~~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. + Cranky Wrinkly Funky +
; + function noSelfcloseTypeArgAttrsTrailingText() { } + \ No newline at end of file diff --git a/tests/baselines/reference/jsxUnclosedParserRecovery.js b/tests/baselines/reference/jsxUnclosedParserRecovery.js new file mode 100644 index 00000000000..17cadbad9c2 --- /dev/null +++ b/tests/baselines/reference/jsxUnclosedParserRecovery.js @@ -0,0 +1,277 @@ +//// [jsxParserRecovery.tsx] +// should have no errors here; all these functions should parse and resolve +noName(); noClose(); noCloseTypeArg(); noCloseAttrs(); noCloseTypeArgAttrs(); noCloseBracket(); noCloseBracketTypeArgAttrs(); noSelfclose(); noSelfcloseTypeArgAttrs(); +noNameTrailingTag(); noCloseTrailingTag(); noCloseTypeArgTrailingTag(); noCloseAttrsTrailingTag(); noCloseTypeArgAttrsTrailingTag(); noCloseBracketTrailingTag(); noCloseBracketTypeArgAttrsTrailingTag(); // noSelfcloseTrailingTag(); noSelfcloseTypeArgAttrsTrailingTag(); +noNameTrailingText(); noCloseTrailingText(); noCloseTypeArgTrailingText(); noCloseAttrsTrailingText(); noCloseTypeArgAttrsTrailingText(); noCloseBracketTrailingText(); noCloseBracketTypeArgAttrsTrailingText(); // noSelfcloseTrailingText(); noSelfcloseTypeArgAttrsTrailingText(); + +function diddy() { + return null; +} + +var donkey =
+ < +
; +function noName() { } +var donkey =
+ ; +function noClose() { } +var donkey =
+ +
; +function noCloseTypeArg() { } +var donkey =
+ ; +function noCloseAttrs() { } +var donkey =
+ bananas="please" +
; +function noCloseTypeArgAttrs() { } +var donkey =
+ ; +function noCloseBracket() { } +var donkey =
+ bananas="please"/ +
; +function noCloseBracketTypeArgAttrs() { } +var donkey =
+ +
; +function noSelfclose() { } +var donkey =
+ bananas="please"> +
; +function noSelfcloseTypeArgAttrs() { } + +var donkey =
+ < + +
; +function noNameTrailingTag() { } +var donkey =
+ +
; +function noCloseTrailingTag() { } +var donkey =
+ + +
; +function noCloseTypeArgTrailingTag() { } +var donkey =
+ +
; +function noCloseAttrsTrailingTag() { } +var donkey =
+ bananas="please" + +
; +function noCloseTypeArgAttrsTrailingTag() { } +var donkey =
+ +
; +function noCloseBracketTrailingTag() { } +var donkey =
+ bananas="please"/ + +
; +function noCloseBracketTypeArgAttrsTrailingTag() { } +var donkey =
+ + +
; +function noSelfcloseTrailingTag() { } +var donkey =
+ bananas="please"> + +
; +function noSelfcloseTypeArgAttrsTrailingTag() { } + +var donkey =
+ < + Cranky Wrinkly Funky +
; +function noNameTrailingText() { } +var donkey =
+ ; +function noCloseTrailingText() { } +var donkey =
+ + Cranky Wrinkly Funky +
; +function noCloseTypeArgTrailingText() { } +var donkey =
+ ; +function noCloseAttrsTrailingText() { } +var donkey =
+ bananas="please" + Cranky Wrinkly Funky +
; +function noCloseTypeArgAttrsTrailingText() { } +var donkey =
+ ; +function noCloseBracketTrailingText() { } +var donkey =
+ bananas="please"/ + Cranky Wrinkly Funky +
; +function noCloseBracketTypeArgAttrsTrailingText() { } +var donkey =
+ + Cranky Wrinkly Funky +
; +function noSelfcloseTrailingText() { } +var donkey =
+ bananas="please"> + Cranky Wrinkly Funky +
; +function noSelfcloseTypeArgAttrsTrailingText() { } + + +//// [jsxParserRecovery.jsx] +// should have no errors here; all these functions should parse and resolve +noName(); +noClose(); +noCloseTypeArg(); +noCloseAttrs(); +noCloseTypeArgAttrs(); +noCloseBracket(); +noCloseBracketTypeArgAttrs(); +noSelfclose(); +noSelfcloseTypeArgAttrs(); +noNameTrailingTag(); +noCloseTrailingTag(); +noCloseTypeArgTrailingTag(); +noCloseAttrsTrailingTag(); +noCloseTypeArgAttrsTrailingTag(); +noCloseBracketTrailingTag(); +noCloseBracketTypeArgAttrsTrailingTag(); // noSelfcloseTrailingTag(); noSelfcloseTypeArgAttrsTrailingTag(); +noNameTrailingText(); +noCloseTrailingText(); +noCloseTypeArgTrailingText(); +noCloseAttrsTrailingText(); +noCloseTypeArgAttrsTrailingText(); +noCloseBracketTrailingText(); +noCloseBracketTypeArgAttrsTrailingText(); // noSelfcloseTrailingText(); noSelfcloseTypeArgAttrsTrailingText(); +function diddy() { + return null; +} +var donkey =
+ < /> +
; +function noName() { } +var donkey =
+ +
; +function noClose() { } +var donkey =
+ +
; +function noCloseTypeArg() { } +var donkey =
+ +
; +function noCloseAttrs() { } +var donkey =
+ +
; +function noCloseTypeArgAttrs() { } +var donkey =
+ +
; +function noCloseBracket() { } +var donkey =
+ +
; +function noCloseBracketTypeArgAttrs() { } +var donkey =
+
; +function noSelfclose() { } +var donkey =
+
; +function noSelfcloseTypeArgAttrs() { } +var donkey =
+ < /> +
; +function noNameTrailingTag() { } +var donkey =
+ +
; +function noCloseTrailingTag() { } +var donkey =
+ + +
; +function noCloseTypeArgTrailingTag() { } +var donkey =
+ + +
; +function noCloseAttrsTrailingTag() { } +var donkey =
+ + +
; +function noCloseTypeArgAttrsTrailingTag() { } +var donkey =
+ + +
; +function noCloseBracketTrailingTag() { } +var donkey =
+ + +
; +function noCloseBracketTypeArgAttrsTrailingTag() { } +var donkey =
+
; +function noSelfcloseTrailingTag() { } +var donkey =
+
; +function noSelfcloseTypeArgAttrsTrailingTag() { } +var donkey =
+ +
; +function noNameTrailingText() { } +var donkey =
+ +
; +function noCloseTrailingText() { } +var donkey =
+ +
; +function noCloseTypeArgTrailingText() { } +var donkey =
+ +
; +function noCloseAttrsTrailingText() { } +var donkey =
+ +
; +function noCloseTypeArgAttrsTrailingText() { } +var donkey =
+ + Cranky Wrinkly Funky +
; +function noCloseBracketTrailingText() { } +var donkey =
+ + Cranky Wrinkly Funky +
; +function noCloseBracketTypeArgAttrsTrailingText() { } +var donkey =
+
; +function noSelfcloseTrailingText() { } +var donkey =
+
; +function noSelfcloseTypeArgAttrsTrailingText() { } diff --git a/tests/baselines/reference/jsxUnclosedParserRecovery.symbols b/tests/baselines/reference/jsxUnclosedParserRecovery.symbols new file mode 100644 index 00000000000..5aa92ab78b5 --- /dev/null +++ b/tests/baselines/reference/jsxUnclosedParserRecovery.symbols @@ -0,0 +1,314 @@ +=== tests/cases/conformance/jsx/jsxParserRecovery.tsx === +// should have no errors here; all these functions should parse and resolve +noName(); noClose(); noCloseTypeArg(); noCloseAttrs(); noCloseTypeArgAttrs(); noCloseBracket(); noCloseBracketTypeArgAttrs(); noSelfclose(); noSelfcloseTypeArgAttrs(); +>noName : Symbol(noName, Decl(jsxParserRecovery.tsx, 11, 7)) +>noClose : Symbol(noClose, Decl(jsxParserRecovery.tsx, 15, 7)) +>noCloseTypeArg : Symbol(noCloseTypeArg, Decl(jsxParserRecovery.tsx, 19, 7)) +>noCloseAttrs : Symbol(noCloseAttrs, Decl(jsxParserRecovery.tsx, 23, 7)) +>noCloseTypeArgAttrs : Symbol(noCloseTypeArgAttrs, Decl(jsxParserRecovery.tsx, 27, 7)) +>noCloseBracket : Symbol(noCloseBracket, Decl(jsxParserRecovery.tsx, 31, 7)) +>noCloseBracketTypeArgAttrs : Symbol(noCloseBracketTypeArgAttrs, Decl(jsxParserRecovery.tsx, 35, 7)) +>noSelfclose : Symbol(noSelfclose, Decl(jsxParserRecovery.tsx, 39, 7)) +>noSelfcloseTypeArgAttrs : Symbol(noSelfcloseTypeArgAttrs, Decl(jsxParserRecovery.tsx, 43, 7)) + +noNameTrailingTag(); noCloseTrailingTag(); noCloseTypeArgTrailingTag(); noCloseAttrsTrailingTag(); noCloseTypeArgAttrsTrailingTag(); noCloseBracketTrailingTag(); noCloseBracketTypeArgAttrsTrailingTag(); // noSelfcloseTrailingTag(); noSelfcloseTypeArgAttrsTrailingTag(); +>noNameTrailingTag : Symbol(noNameTrailingTag, Decl(jsxParserRecovery.tsx, 49, 7)) +>noCloseTrailingTag : Symbol(noCloseTrailingTag, Decl(jsxParserRecovery.tsx, 54, 7)) +>noCloseTypeArgTrailingTag : Symbol(noCloseTypeArgTrailingTag, Decl(jsxParserRecovery.tsx, 59, 7)) +>noCloseAttrsTrailingTag : Symbol(noCloseAttrsTrailingTag, Decl(jsxParserRecovery.tsx, 64, 7)) +>noCloseTypeArgAttrsTrailingTag : Symbol(noCloseTypeArgAttrsTrailingTag, Decl(jsxParserRecovery.tsx, 69, 7)) +>noCloseBracketTrailingTag : Symbol(noCloseBracketTrailingTag, Decl(jsxParserRecovery.tsx, 74, 7)) +>noCloseBracketTypeArgAttrsTrailingTag : Symbol(noCloseBracketTypeArgAttrsTrailingTag, Decl(jsxParserRecovery.tsx, 79, 7)) + +noNameTrailingText(); noCloseTrailingText(); noCloseTypeArgTrailingText(); noCloseAttrsTrailingText(); noCloseTypeArgAttrsTrailingText(); noCloseBracketTrailingText(); noCloseBracketTypeArgAttrsTrailingText(); // noSelfcloseTrailingText(); noSelfcloseTypeArgAttrsTrailingText(); +>noNameTrailingText : Symbol(noNameTrailingText, Decl(jsxParserRecovery.tsx, 95, 7)) +>noCloseTrailingText : Symbol(noCloseTrailingText, Decl(jsxParserRecovery.tsx, 100, 7)) +>noCloseTypeArgTrailingText : Symbol(noCloseTypeArgTrailingText, Decl(jsxParserRecovery.tsx, 105, 7)) +>noCloseAttrsTrailingText : Symbol(noCloseAttrsTrailingText, Decl(jsxParserRecovery.tsx, 110, 7)) +>noCloseTypeArgAttrsTrailingText : Symbol(noCloseTypeArgAttrsTrailingText, Decl(jsxParserRecovery.tsx, 115, 7)) +>noCloseBracketTrailingText : Symbol(noCloseBracketTrailingText, Decl(jsxParserRecovery.tsx, 120, 7)) +>noCloseBracketTypeArgAttrsTrailingText : Symbol(noCloseBracketTypeArgAttrsTrailingText, Decl(jsxParserRecovery.tsx, 125, 7)) + +function diddy() { +>diddy : Symbol(diddy, Decl(jsxParserRecovery.tsx, 3, 209)) + + return null; +} + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + < +
; +function noName() { } +>noName : Symbol(noName, Decl(jsxParserRecovery.tsx, 11, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + ; +function noClose() { } +>noClose : Symbol(noClose, Decl(jsxParserRecovery.tsx, 15, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + +
; +function noCloseTypeArg() { } +>noCloseTypeArg : Symbol(noCloseTypeArg, Decl(jsxParserRecovery.tsx, 19, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + bananas : Symbol(bananas, Decl(jsxParserRecovery.tsx, 22, 10)) + +
; +function noCloseAttrs() { } +>noCloseAttrs : Symbol(noCloseAttrs, Decl(jsxParserRecovery.tsx, 23, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + bananas="please" +>bananas : Symbol(bananas, Decl(jsxParserRecovery.tsx, 26, 19)) + +
; +function noCloseTypeArgAttrs() { } +>noCloseTypeArgAttrs : Symbol(noCloseTypeArgAttrs, Decl(jsxParserRecovery.tsx, 27, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + ; +function noCloseBracket() { } +>noCloseBracket : Symbol(noCloseBracket, Decl(jsxParserRecovery.tsx, 31, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + bananas="please"/ +>bananas : Symbol(bananas, Decl(jsxParserRecovery.tsx, 34, 19)) + +
; +function noCloseBracketTypeArgAttrs() { } +>noCloseBracketTypeArgAttrs : Symbol(noCloseBracketTypeArgAttrs, Decl(jsxParserRecovery.tsx, 35, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + +
; +function noSelfclose() { } +>noSelfclose : Symbol(noSelfclose, Decl(jsxParserRecovery.tsx, 39, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + bananas="please"> +>bananas : Symbol(bananas, Decl(jsxParserRecovery.tsx, 42, 19)) + +
; +function noSelfcloseTypeArgAttrs() { } +>noSelfcloseTypeArgAttrs : Symbol(noSelfcloseTypeArgAttrs, Decl(jsxParserRecovery.tsx, 43, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + < + +
; +function noNameTrailingTag() { } +>noNameTrailingTag : Symbol(noNameTrailingTag, Decl(jsxParserRecovery.tsx, 49, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + +
; +function noCloseTrailingTag() { } +>noCloseTrailingTag : Symbol(noCloseTrailingTag, Decl(jsxParserRecovery.tsx, 54, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + + +
; +function noCloseTypeArgTrailingTag() { } +>noCloseTypeArgTrailingTag : Symbol(noCloseTypeArgTrailingTag, Decl(jsxParserRecovery.tsx, 59, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + bananas : Symbol(bananas, Decl(jsxParserRecovery.tsx, 62, 10)) + + +
; +function noCloseAttrsTrailingTag() { } +>noCloseAttrsTrailingTag : Symbol(noCloseAttrsTrailingTag, Decl(jsxParserRecovery.tsx, 64, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + bananas="please" +>bananas : Symbol(bananas, Decl(jsxParserRecovery.tsx, 67, 19)) + + +
; +function noCloseTypeArgAttrsTrailingTag() { } +>noCloseTypeArgAttrsTrailingTag : Symbol(noCloseTypeArgAttrsTrailingTag, Decl(jsxParserRecovery.tsx, 69, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + +
; +function noCloseBracketTrailingTag() { } +>noCloseBracketTrailingTag : Symbol(noCloseBracketTrailingTag, Decl(jsxParserRecovery.tsx, 74, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + bananas="please"/ +>bananas : Symbol(bananas, Decl(jsxParserRecovery.tsx, 77, 19)) + + +
; +function noCloseBracketTypeArgAttrsTrailingTag() { } +>noCloseBracketTypeArgAttrsTrailingTag : Symbol(noCloseBracketTypeArgAttrsTrailingTag, Decl(jsxParserRecovery.tsx, 79, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + + +
; +function noSelfcloseTrailingTag() { } +>noSelfcloseTrailingTag : Symbol(noSelfcloseTrailingTag, Decl(jsxParserRecovery.tsx, 84, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + bananas="please"> +>bananas : Symbol(bananas, Decl(jsxParserRecovery.tsx, 87, 19)) + + +
; +function noSelfcloseTypeArgAttrsTrailingTag() { } +>noSelfcloseTypeArgAttrsTrailingTag : Symbol(noSelfcloseTypeArgAttrsTrailingTag, Decl(jsxParserRecovery.tsx, 89, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + < + Cranky Wrinkly Funky +>Wrinkly : Symbol(Wrinkly, Decl(jsxParserRecovery.tsx, 94, 10)) +>Funky : Symbol(Funky, Decl(jsxParserRecovery.tsx, 94, 18)) + +
; +function noNameTrailingText() { } +>noNameTrailingText : Symbol(noNameTrailingText, Decl(jsxParserRecovery.tsx, 95, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + Cranky : Symbol(Cranky, Decl(jsxParserRecovery.tsx, 98, 10)) +>Wrinkly : Symbol(Wrinkly, Decl(jsxParserRecovery.tsx, 99, 10)) +>Funky : Symbol(Funky, Decl(jsxParserRecovery.tsx, 99, 18)) + +
; +function noCloseTrailingText() { } +>noCloseTrailingText : Symbol(noCloseTrailingText, Decl(jsxParserRecovery.tsx, 100, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + + Cranky Wrinkly Funky +>Cranky : Symbol(Cranky, Decl(jsxParserRecovery.tsx, 103, 19)) +>Wrinkly : Symbol(Wrinkly, Decl(jsxParserRecovery.tsx, 104, 10)) +>Funky : Symbol(Funky, Decl(jsxParserRecovery.tsx, 104, 18)) + +
; +function noCloseTypeArgTrailingText() { } +>noCloseTypeArgTrailingText : Symbol(noCloseTypeArgTrailingText, Decl(jsxParserRecovery.tsx, 105, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + bananas : Symbol(bananas, Decl(jsxParserRecovery.tsx, 108, 10)) + + Cranky Wrinkly Funky +>Cranky : Symbol(Cranky, Decl(jsxParserRecovery.tsx, 108, 27)) +>Wrinkly : Symbol(Wrinkly, Decl(jsxParserRecovery.tsx, 109, 10)) +>Funky : Symbol(Funky, Decl(jsxParserRecovery.tsx, 109, 18)) + +
; +function noCloseAttrsTrailingText() { } +>noCloseAttrsTrailingText : Symbol(noCloseAttrsTrailingText, Decl(jsxParserRecovery.tsx, 110, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + bananas="please" +>bananas : Symbol(bananas, Decl(jsxParserRecovery.tsx, 113, 19)) + + Cranky Wrinkly Funky +>Cranky : Symbol(Cranky, Decl(jsxParserRecovery.tsx, 113, 36)) +>Wrinkly : Symbol(Wrinkly, Decl(jsxParserRecovery.tsx, 114, 10)) +>Funky : Symbol(Funky, Decl(jsxParserRecovery.tsx, 114, 18)) + +
; +function noCloseTypeArgAttrsTrailingText() { } +>noCloseTypeArgAttrsTrailingText : Symbol(noCloseTypeArgAttrsTrailingText, Decl(jsxParserRecovery.tsx, 115, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + ; +function noCloseBracketTrailingText() { } +>noCloseBracketTrailingText : Symbol(noCloseBracketTrailingText, Decl(jsxParserRecovery.tsx, 120, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + bananas="please"/ +>bananas : Symbol(bananas, Decl(jsxParserRecovery.tsx, 123, 19)) + + Cranky Wrinkly Funky +
; +function noCloseBracketTypeArgAttrsTrailingText() { } +>noCloseBracketTypeArgAttrsTrailingText : Symbol(noCloseBracketTypeArgAttrsTrailingText, Decl(jsxParserRecovery.tsx, 125, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + + Cranky Wrinkly Funky +
; +function noSelfcloseTrailingText() { } +>noSelfcloseTrailingText : Symbol(noSelfcloseTrailingText, Decl(jsxParserRecovery.tsx, 130, 7)) + +var donkey =
+>donkey : Symbol(donkey, Decl(jsxParserRecovery.tsx, 9, 3), Decl(jsxParserRecovery.tsx, 13, 3), Decl(jsxParserRecovery.tsx, 17, 3), Decl(jsxParserRecovery.tsx, 21, 3), Decl(jsxParserRecovery.tsx, 25, 3) ... and 22 more) + + bananas="please"> +>bananas : Symbol(bananas, Decl(jsxParserRecovery.tsx, 133, 19)) + + Cranky Wrinkly Funky +
; +function noSelfcloseTypeArgAttrsTrailingText() { } +>noSelfcloseTypeArgAttrsTrailingText : Symbol(noSelfcloseTypeArgAttrsTrailingText, Decl(jsxParserRecovery.tsx, 135, 7)) + diff --git a/tests/baselines/reference/jsxUnclosedParserRecovery.types b/tests/baselines/reference/jsxUnclosedParserRecovery.types new file mode 100644 index 00000000000..0c836329c7c --- /dev/null +++ b/tests/baselines/reference/jsxUnclosedParserRecovery.types @@ -0,0 +1,541 @@ +=== tests/cases/conformance/jsx/jsxParserRecovery.tsx === +// should have no errors here; all these functions should parse and resolve +noName(); noClose(); noCloseTypeArg(); noCloseAttrs(); noCloseTypeArgAttrs(); noCloseBracket(); noCloseBracketTypeArgAttrs(); noSelfclose(); noSelfcloseTypeArgAttrs(); +>noName() : void +>noName : () => void +>noClose() : void +>noClose : () => void +>noCloseTypeArg() : void +>noCloseTypeArg : () => void +>noCloseAttrs() : void +>noCloseAttrs : () => void +>noCloseTypeArgAttrs() : void +>noCloseTypeArgAttrs : () => void +>noCloseBracket() : void +>noCloseBracket : () => void +>noCloseBracketTypeArgAttrs() : void +>noCloseBracketTypeArgAttrs : () => void +>noSelfclose() : void +>noSelfclose : () => void +>noSelfcloseTypeArgAttrs() : void +>noSelfcloseTypeArgAttrs : () => void + +noNameTrailingTag(); noCloseTrailingTag(); noCloseTypeArgTrailingTag(); noCloseAttrsTrailingTag(); noCloseTypeArgAttrsTrailingTag(); noCloseBracketTrailingTag(); noCloseBracketTypeArgAttrsTrailingTag(); // noSelfcloseTrailingTag(); noSelfcloseTypeArgAttrsTrailingTag(); +>noNameTrailingTag() : void +>noNameTrailingTag : () => void +>noCloseTrailingTag() : void +>noCloseTrailingTag : () => void +>noCloseTypeArgTrailingTag() : void +>noCloseTypeArgTrailingTag : () => void +>noCloseAttrsTrailingTag() : void +>noCloseAttrsTrailingTag : () => void +>noCloseTypeArgAttrsTrailingTag() : void +>noCloseTypeArgAttrsTrailingTag : () => void +>noCloseBracketTrailingTag() : void +>noCloseBracketTrailingTag : () => void +>noCloseBracketTypeArgAttrsTrailingTag() : void +>noCloseBracketTypeArgAttrsTrailingTag : () => void + +noNameTrailingText(); noCloseTrailingText(); noCloseTypeArgTrailingText(); noCloseAttrsTrailingText(); noCloseTypeArgAttrsTrailingText(); noCloseBracketTrailingText(); noCloseBracketTypeArgAttrsTrailingText(); // noSelfcloseTrailingText(); noSelfcloseTypeArgAttrsTrailingText(); +>noNameTrailingText() : void +>noNameTrailingText : () => void +>noCloseTrailingText() : void +>noCloseTrailingText : () => void +>noCloseTypeArgTrailingText() : void +>noCloseTypeArgTrailingText : () => void +>noCloseAttrsTrailingText() : void +>noCloseAttrsTrailingText : () => void +>noCloseTypeArgAttrsTrailingText() : void +>noCloseTypeArgAttrsTrailingText : () => void +>noCloseBracketTrailingText() : void +>noCloseBracketTrailingText : () => void +>noCloseBracketTypeArgAttrsTrailingText() : void +>noCloseBracketTypeArgAttrsTrailingText : () => void + +function diddy() { +>diddy : () => any + + return null; +>null : null +} + +var donkey =
+>donkey : any +>
<
: any +>div : any + + < +>< : any + +
; +> : any +>div : any + +function noName() { } +>noName : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + diddy : () => any + +
; +>div : any + +function noClose() { } +>noClose : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + +> : any +>diddy : () => any + +
; +>div : any + +function noCloseTypeArg() { } +>noCloseTypeArg : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + diddy : () => any +>bananas : string + +
; +>div : any + +function noCloseAttrs() { } +>noCloseAttrs : () => void + +var donkey =
+>donkey : any +>
bananas="please"
: any +>div : any + + bananas="please" +> bananas="please" : any +>diddy : () => any +>bananas : string + +
; +>div : any + +function noCloseTypeArgAttrs() { } +>noCloseTypeArgAttrs : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + diddy : () => any + +
; +>div : any + +function noCloseBracket() { } +>noCloseBracket : () => void + +var donkey =
+>donkey : any +>
bananas="please"/
: any +>div : any + + bananas="please"/ +> bananas="please"/ : any +>diddy : () => any +>bananas : string + +
; +>div : any + +function noCloseBracketTypeArgAttrs() { } +>noCloseBracketTypeArgAttrs : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + +> : any +>diddy : () => any + +
; +> : any +>div : any + +function noSelfclose() { } +>noSelfclose : () => void + +var donkey =
+>donkey : any +>
bananas="please">
: any +>div : any + + bananas="please"> +> bananas="please"> : any +>diddy : () => any +>bananas : string + +
; +> : any +>div : any + +function noSelfcloseTypeArgAttrs() { } +>noSelfcloseTypeArgAttrs : () => void + +var donkey =
+>donkey : any +>
<
: any +>div : any + + < +>< : any + + +> : any + +
; +>div : any + +function noNameTrailingTag() { } +>noNameTrailingTag : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + : any +>diddy : () => any + + +
; +>div : any + +function noCloseTrailingTag() { } +>noCloseTrailingTag : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + +> : any +>diddy : () => any + + +> : any +>diddy : () => any + +
; +>div : any + +function noCloseTypeArgTrailingTag() { } +>noCloseTypeArgTrailingTag : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + diddy : () => any +>bananas : string + + +> : any +>diddy : () => any + +
; +>div : any + +function noCloseAttrsTrailingTag() { } +>noCloseAttrsTrailingTag : () => void + +var donkey =
+>donkey : any +>
bananas="please"
: any +>div : any + + bananas="please" +> bananas="please" : any +>diddy : () => any +>bananas : string + + +> : any +>diddy : () => any + +
; +>div : any + +function noCloseTypeArgAttrsTrailingTag() { } +>noCloseTypeArgAttrsTrailingTag : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + diddy : () => any + + +> : any +>diddy : () => any + +
; +>div : any + +function noCloseBracketTrailingTag() { } +>noCloseBracketTrailingTag : () => void + +var donkey =
+>donkey : any +>
bananas="please"/
: any +>div : any + + bananas="please"/ +> bananas="please"/ : any +>diddy : () => any +>bananas : string + + +> : any +>diddy : () => any + +
; +>div : any + +function noCloseBracketTypeArgAttrsTrailingTag() { } +>noCloseBracketTypeArgAttrsTrailingTag : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + +> : any +>diddy : () => any + + +> : any + +
; +>div : any + +function noSelfcloseTrailingTag() { } +>noSelfcloseTrailingTag : () => void + +var donkey =
+>donkey : any +>
bananas="please">
: any +>div : any + + bananas="please"> +> bananas="please"> : any +>diddy : () => any +>bananas : string + + +> : any + +
; +>div : any + +function noSelfcloseTypeArgAttrsTrailingTag() { } +>noSelfcloseTypeArgAttrsTrailingTag : () => void + +var donkey =
+>donkey : any +>
< Cranky Wrinkly Funky
: any +>div : any + + < +>< Cranky Wrinkly Funky : any + + Cranky Wrinkly Funky +>Cranky : any +>Wrinkly : true +>Funky : true + +
; +>div : any + +function noNameTrailingText() { } +>noNameTrailingText : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + diddy : () => any + + Cranky Wrinkly Funky +>Cranky : true +>Wrinkly : true +>Funky : true + +
; +>div : any + +function noCloseTrailingText() { } +>noCloseTrailingText : () => void + +var donkey =
+>donkey : any +>
Cranky Wrinkly Funky
: any +>div : any + + +> Cranky Wrinkly Funky : any +>diddy : () => any + + Cranky Wrinkly Funky +>Cranky : true +>Wrinkly : true +>Funky : true + +
; +>div : any + +function noCloseTypeArgTrailingText() { } +>noCloseTypeArgTrailingText : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + diddy : () => any +>bananas : string + + Cranky Wrinkly Funky +>Cranky : true +>Wrinkly : true +>Funky : true + +
; +>div : any + +function noCloseAttrsTrailingText() { } +>noCloseAttrsTrailingText : () => void + +var donkey =
+>donkey : any +>
bananas="please" Cranky Wrinkly Funky
: any +>div : any + + bananas="please" +> bananas="please" Cranky Wrinkly Funky : any +>diddy : () => any +>bananas : string + + Cranky Wrinkly Funky +>Cranky : true +>Wrinkly : true +>Funky : true + +
; +>div : any + +function noCloseTypeArgAttrsTrailingText() { } +>noCloseTypeArgAttrsTrailingText : () => void + +var donkey =
+>donkey : any +>
: any +>div : any + + diddy : () => any + + Cranky Wrinkly Funky +
; +>div : any + +function noCloseBracketTrailingText() { } +>noCloseBracketTrailingText : () => void + +var donkey =
+>donkey : any +>
bananas="please"/ Cranky Wrinkly Funky
: any +>div : any + + bananas="please"/ +> bananas="please"/ : any +>diddy : () => any +>bananas : string + + Cranky Wrinkly Funky +
; +>div : any + +function noCloseBracketTypeArgAttrsTrailingText() { } +>noCloseBracketTypeArgAttrsTrailingText : () => void + +var donkey =
+>donkey : any +>
Cranky Wrinkly Funky
: any +>div : any + + +> : any +>diddy : () => any + + Cranky Wrinkly Funky +> : any + +
; +>div : any + +function noSelfcloseTrailingText() { } +>noSelfcloseTrailingText : () => void + +var donkey =
+>donkey : any +>
bananas="please"> Cranky Wrinkly Funky
: any +>div : any + + bananas="please"> +> bananas="please"> : any +>diddy : () => any +>bananas : string + + Cranky Wrinkly Funky +> : any + +
; +>div : any + +function noSelfcloseTypeArgAttrsTrailingText() { } +>noSelfcloseTypeArgAttrsTrailingText : () => void + diff --git a/tests/cases/conformance/jsx/jsxUnclosedParserRecovery.ts b/tests/cases/conformance/jsx/jsxUnclosedParserRecovery.ts new file mode 100644 index 00000000000..08b6149d37d --- /dev/null +++ b/tests/cases/conformance/jsx/jsxUnclosedParserRecovery.ts @@ -0,0 +1,140 @@ +// @Filename: jsxParserRecovery.tsx +// @jsx: preserve + +// should have no errors here; all these functions should parse and resolve +noName(); noClose(); noCloseTypeArg(); noCloseAttrs(); noCloseTypeArgAttrs(); noCloseBracket(); noCloseBracketTypeArgAttrs(); noSelfclose(); noSelfcloseTypeArgAttrs(); +noNameTrailingTag(); noCloseTrailingTag(); noCloseTypeArgTrailingTag(); noCloseAttrsTrailingTag(); noCloseTypeArgAttrsTrailingTag(); noCloseBracketTrailingTag(); noCloseBracketTypeArgAttrsTrailingTag(); // noSelfcloseTrailingTag(); noSelfcloseTypeArgAttrsTrailingTag(); +noNameTrailingText(); noCloseTrailingText(); noCloseTypeArgTrailingText(); noCloseAttrsTrailingText(); noCloseTypeArgAttrsTrailingText(); noCloseBracketTrailingText(); noCloseBracketTypeArgAttrsTrailingText(); // noSelfcloseTrailingText(); noSelfcloseTypeArgAttrsTrailingText(); + +function diddy() { + return null; +} + +var donkey =
+ < +
; +function noName() { } +var donkey =
+ ; +function noClose() { } +var donkey =
+ +
; +function noCloseTypeArg() { } +var donkey =
+ ; +function noCloseAttrs() { } +var donkey =
+ bananas="please" +
; +function noCloseTypeArgAttrs() { } +var donkey =
+ ; +function noCloseBracket() { } +var donkey =
+ bananas="please"/ +
; +function noCloseBracketTypeArgAttrs() { } +var donkey =
+ +
; +function noSelfclose() { } +var donkey =
+ bananas="please"> +
; +function noSelfcloseTypeArgAttrs() { } + +var donkey =
+ < + +
; +function noNameTrailingTag() { } +var donkey =
+ +
; +function noCloseTrailingTag() { } +var donkey =
+ + +
; +function noCloseTypeArgTrailingTag() { } +var donkey =
+ +
; +function noCloseAttrsTrailingTag() { } +var donkey =
+ bananas="please" + +
; +function noCloseTypeArgAttrsTrailingTag() { } +var donkey =
+ +
; +function noCloseBracketTrailingTag() { } +var donkey =
+ bananas="please"/ + +
; +function noCloseBracketTypeArgAttrsTrailingTag() { } +var donkey =
+ + +
; +function noSelfcloseTrailingTag() { } +var donkey =
+ bananas="please"> + +
; +function noSelfcloseTypeArgAttrsTrailingTag() { } + +var donkey =
+ < + Cranky Wrinkly Funky +
; +function noNameTrailingText() { } +var donkey =
+ ; +function noCloseTrailingText() { } +var donkey =
+ + Cranky Wrinkly Funky +
; +function noCloseTypeArgTrailingText() { } +var donkey =
+ ; +function noCloseAttrsTrailingText() { } +var donkey =
+ bananas="please" + Cranky Wrinkly Funky +
; +function noCloseTypeArgAttrsTrailingText() { } +var donkey =
+ ; +function noCloseBracketTrailingText() { } +var donkey =
+ bananas="please"/ + Cranky Wrinkly Funky +
; +function noCloseBracketTypeArgAttrsTrailingText() { } +var donkey =
+ + Cranky Wrinkly Funky +
; +function noSelfcloseTrailingText() { } +var donkey =
+ bananas="please"> + Cranky Wrinkly Funky +
; +function noSelfcloseTypeArgAttrsTrailingText() { }