From 9ca13c7042089765abc789f26e9cfe848a0186e4 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 26 Jan 2023 19:15:13 -0800 Subject: [PATCH 1/6] Add failing tests --- tests/cases/fourslash/jsxElementExtendsNoCrash1.ts | 6 ++++++ tests/cases/fourslash/jsxElementExtendsNoCrash2.ts | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 tests/cases/fourslash/jsxElementExtendsNoCrash1.ts create mode 100644 tests/cases/fourslash/jsxElementExtendsNoCrash2.ts diff --git a/tests/cases/fourslash/jsxElementExtendsNoCrash1.ts b/tests/cases/fourslash/jsxElementExtendsNoCrash1.ts new file mode 100644 index 0000000000000..6959cc9ce40e8 --- /dev/null +++ b/tests/cases/fourslash/jsxElementExtendsNoCrash1.ts @@ -0,0 +1,6 @@ +/// + +// @filename: index.tsx +//// + +verify.getSuggestionDiagnostics([]); diff --git a/tests/cases/fourslash/jsxElementExtendsNoCrash2.ts b/tests/cases/fourslash/jsxElementExtendsNoCrash2.ts new file mode 100644 index 0000000000000..4c42f85626517 --- /dev/null +++ b/tests/cases/fourslash/jsxElementExtendsNoCrash2.ts @@ -0,0 +1,6 @@ +/// + +// @filename: index.tsx +//// + +verify.getSuggestionDiagnostics([]); From a122a31e7f4d0bfa30887d718a0ef765a8bcce57 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 26 Jan 2023 19:20:12 -0800 Subject: [PATCH 2/6] Add plain parser test --- .../reference/parseJsxExtends1.errors.txt | 13 +++++++++++++ tests/baselines/reference/parseJsxExtends1.js | 16 ++++++++++++++++ .../baselines/reference/parseJsxExtends1.symbols | 8 ++++++++ tests/baselines/reference/parseJsxExtends1.types | 10 ++++++++++ .../reference/parseJsxExtends2.errors.txt | 13 +++++++++++++ tests/baselines/reference/parseJsxExtends2.js | 16 ++++++++++++++++ .../baselines/reference/parseJsxExtends2.symbols | 8 ++++++++ tests/baselines/reference/parseJsxExtends2.types | 10 ++++++++++ tests/cases/compiler/parseJsxExtends1.ts | 6 ++++++ tests/cases/compiler/parseJsxExtends2.ts | 6 ++++++ 10 files changed, 106 insertions(+) create mode 100644 tests/baselines/reference/parseJsxExtends1.errors.txt create mode 100644 tests/baselines/reference/parseJsxExtends1.js create mode 100644 tests/baselines/reference/parseJsxExtends1.symbols create mode 100644 tests/baselines/reference/parseJsxExtends1.types create mode 100644 tests/baselines/reference/parseJsxExtends2.errors.txt create mode 100644 tests/baselines/reference/parseJsxExtends2.js create mode 100644 tests/baselines/reference/parseJsxExtends2.symbols create mode 100644 tests/baselines/reference/parseJsxExtends2.types create mode 100644 tests/cases/compiler/parseJsxExtends1.ts create mode 100644 tests/cases/compiler/parseJsxExtends2.ts diff --git a/tests/baselines/reference/parseJsxExtends1.errors.txt b/tests/baselines/reference/parseJsxExtends1.errors.txt new file mode 100644 index 0000000000000..617d4927aac5a --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends1.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/index.tsx(2,29): error TS1161: Unterminated regular expression literal. +tests/cases/compiler/index.tsx(3,1): error TS1005: ',' expected. + + +==== tests/cases/compiler/index.tsx (2 errors) ==== + export function Foo() { + return + +!!! error TS1161: Unterminated regular expression literal. + } + ~ +!!! error TS1005: ',' expected. + \ No newline at end of file diff --git a/tests/baselines/reference/parseJsxExtends1.js b/tests/baselines/reference/parseJsxExtends1.js new file mode 100644 index 0000000000000..542b7f726fc4f --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends1.js @@ -0,0 +1,16 @@ +//// [index.tsx] +export function Foo() { + return +} + + +//// [index.jsx] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Foo = void 0; +function Foo() { + return function () { + return ; + }; +} +exports.Foo = Foo; diff --git a/tests/baselines/reference/parseJsxExtends1.symbols b/tests/baselines/reference/parseJsxExtends1.symbols new file mode 100644 index 0000000000000..ef7299a5c9837 --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends1.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/index.tsx === +export function Foo() { +>Foo : Symbol(Foo, Decl(index.tsx, 0, 0)) + + return +>T : Symbol(T, Decl(index.tsx, 1, 12)) +} + diff --git a/tests/baselines/reference/parseJsxExtends1.types b/tests/baselines/reference/parseJsxExtends1.types new file mode 100644 index 0000000000000..03425efb2db40 --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends1.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/index.tsx === +export function Foo() { +>Foo : () => () => any + + return +> : () => any +>/> : RegExp +} +> : any + diff --git a/tests/baselines/reference/parseJsxExtends2.errors.txt b/tests/baselines/reference/parseJsxExtends2.errors.txt new file mode 100644 index 0000000000000..4d4481488055b --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends2.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/index.tsx(2,23): error TS1161: Unterminated regular expression literal. +tests/cases/compiler/index.tsx(3,1): error TS1005: ',' expected. + + +==== tests/cases/compiler/index.tsx (2 errors) ==== + export function Foo() { + return + +!!! error TS1161: Unterminated regular expression literal. + } + ~ +!!! error TS1005: ',' expected. + \ No newline at end of file diff --git a/tests/baselines/reference/parseJsxExtends2.js b/tests/baselines/reference/parseJsxExtends2.js new file mode 100644 index 0000000000000..3381d90d2e0fd --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends2.js @@ -0,0 +1,16 @@ +//// [index.tsx] +export function Foo() { + return +} + + +//// [index.jsx] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Foo = void 0; +function Foo() { + return function () { + return ; + }; +} +exports.Foo = Foo; diff --git a/tests/baselines/reference/parseJsxExtends2.symbols b/tests/baselines/reference/parseJsxExtends2.symbols new file mode 100644 index 0000000000000..8953c3f972177 --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends2.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/index.tsx === +export function Foo() { +>Foo : Symbol(Foo, Decl(index.tsx, 0, 0)) + + return +>T : Symbol(T, Decl(index.tsx, 1, 12)) +} + diff --git a/tests/baselines/reference/parseJsxExtends2.types b/tests/baselines/reference/parseJsxExtends2.types new file mode 100644 index 0000000000000..2fdbdc2e6e261 --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends2.types @@ -0,0 +1,10 @@ +=== tests/cases/compiler/index.tsx === +export function Foo() { +>Foo : () => () => any + + return +> : () => any +>/> : RegExp +} +> : any + diff --git a/tests/cases/compiler/parseJsxExtends1.ts b/tests/cases/compiler/parseJsxExtends1.ts new file mode 100644 index 0000000000000..b0adda26cce53 --- /dev/null +++ b/tests/cases/compiler/parseJsxExtends1.ts @@ -0,0 +1,6 @@ +// @jsx: preserve +// @filename: index.tsx + +export function Foo() { + return +} diff --git a/tests/cases/compiler/parseJsxExtends2.ts b/tests/cases/compiler/parseJsxExtends2.ts new file mode 100644 index 0000000000000..3af56ed098f70 --- /dev/null +++ b/tests/cases/compiler/parseJsxExtends2.ts @@ -0,0 +1,6 @@ +// @jsx: preserve +// @filename: index.tsx + +export function Foo() { + return +} From a188cca14c80acf6e860438b93b154f079de4768 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 26 Jan 2023 19:39:16 -0800 Subject: [PATCH 3/6] Prevent valid JSX from being seen as the start of a generic arrow function --- src/compiler/parser.ts | 16 +++++----------- .../reference/parseJsxExtends1.errors.txt | 13 ------------- tests/baselines/reference/parseJsxExtends1.js | 4 +--- .../baselines/reference/parseJsxExtends1.symbols | 3 ++- tests/baselines/reference/parseJsxExtends1.types | 9 +++++---- .../reference/parseJsxExtends2.errors.txt | 11 ++++------- tests/baselines/reference/parseJsxExtends2.js | 4 +--- .../baselines/reference/parseJsxExtends2.symbols | 2 +- tests/baselines/reference/parseJsxExtends2.types | 8 ++++---- 9 files changed, 23 insertions(+), 47 deletions(-) delete mode 100644 tests/baselines/reference/parseJsxExtends1.errors.txt diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b448910799401..7474f6328830a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5193,7 +5193,7 @@ namespace Parser { // JSX overrides if (languageVariant === LanguageVariant.JSX) { - const isArrowFunctionInJsx = lookAhead(() => { + return lookAhead(() => { parseOptional(SyntaxKind.ConstKeyword); const third = nextToken(); if (third === SyntaxKind.ExtendsKeyword) { @@ -5201,22 +5201,16 @@ namespace Parser { switch (fourth) { case SyntaxKind.EqualsToken: case SyntaxKind.GreaterThanToken: - return false; + return Tristate.False; default: - return true; + return Tristate.Unknown; } } else if (third === SyntaxKind.CommaToken || third === SyntaxKind.EqualsToken) { - return true; + return Tristate.True; } - return false; + return Tristate.False; }); - - if (isArrowFunctionInJsx) { - return Tristate.True; - } - - return Tristate.False; } // This *could* be a parenthesized arrow function. diff --git a/tests/baselines/reference/parseJsxExtends1.errors.txt b/tests/baselines/reference/parseJsxExtends1.errors.txt deleted file mode 100644 index 617d4927aac5a..0000000000000 --- a/tests/baselines/reference/parseJsxExtends1.errors.txt +++ /dev/null @@ -1,13 +0,0 @@ -tests/cases/compiler/index.tsx(2,29): error TS1161: Unterminated regular expression literal. -tests/cases/compiler/index.tsx(3,1): error TS1005: ',' expected. - - -==== tests/cases/compiler/index.tsx (2 errors) ==== - export function Foo() { - return - -!!! error TS1161: Unterminated regular expression literal. - } - ~ -!!! error TS1005: ',' expected. - \ No newline at end of file diff --git a/tests/baselines/reference/parseJsxExtends1.js b/tests/baselines/reference/parseJsxExtends1.js index 542b7f726fc4f..f20b1cdd9df74 100644 --- a/tests/baselines/reference/parseJsxExtends1.js +++ b/tests/baselines/reference/parseJsxExtends1.js @@ -9,8 +9,6 @@ export function Foo() { Object.defineProperty(exports, "__esModule", { value: true }); exports.Foo = void 0; function Foo() { - return function () { - return ; - }; + return ; } exports.Foo = Foo; diff --git a/tests/baselines/reference/parseJsxExtends1.symbols b/tests/baselines/reference/parseJsxExtends1.symbols index ef7299a5c9837..5628d6cd505d1 100644 --- a/tests/baselines/reference/parseJsxExtends1.symbols +++ b/tests/baselines/reference/parseJsxExtends1.symbols @@ -3,6 +3,7 @@ export function Foo() { >Foo : Symbol(Foo, Decl(index.tsx, 0, 0)) return ->T : Symbol(T, Decl(index.tsx, 1, 12)) +>T : Symbol(T, Decl(index.tsx, 1, 17)) +>extends : Symbol(extends, Decl(index.tsx, 1, 19)) } diff --git a/tests/baselines/reference/parseJsxExtends1.types b/tests/baselines/reference/parseJsxExtends1.types index 03425efb2db40..e9c75a9635580 100644 --- a/tests/baselines/reference/parseJsxExtends1.types +++ b/tests/baselines/reference/parseJsxExtends1.types @@ -1,10 +1,11 @@ === tests/cases/compiler/index.tsx === export function Foo() { ->Foo : () => () => any +>Foo : () => any return -> : () => any ->/> : RegExp +> : error +>const : any +>T : true +>extends : true } -> : any diff --git a/tests/baselines/reference/parseJsxExtends2.errors.txt b/tests/baselines/reference/parseJsxExtends2.errors.txt index 4d4481488055b..09b7ebb632f8b 100644 --- a/tests/baselines/reference/parseJsxExtends2.errors.txt +++ b/tests/baselines/reference/parseJsxExtends2.errors.txt @@ -1,13 +1,10 @@ -tests/cases/compiler/index.tsx(2,23): error TS1161: Unterminated regular expression literal. -tests/cases/compiler/index.tsx(3,1): error TS1005: ',' expected. +tests/cases/compiler/index.tsx(2,13): error TS2304: Cannot find name 'T'. -==== tests/cases/compiler/index.tsx (2 errors) ==== +==== tests/cases/compiler/index.tsx (1 errors) ==== export function Foo() { return - -!!! error TS1161: Unterminated regular expression literal. + ~ +!!! error TS2304: Cannot find name 'T'. } - ~ -!!! error TS1005: ',' expected. \ No newline at end of file diff --git a/tests/baselines/reference/parseJsxExtends2.js b/tests/baselines/reference/parseJsxExtends2.js index 3381d90d2e0fd..5f5f019bd7144 100644 --- a/tests/baselines/reference/parseJsxExtends2.js +++ b/tests/baselines/reference/parseJsxExtends2.js @@ -9,8 +9,6 @@ export function Foo() { Object.defineProperty(exports, "__esModule", { value: true }); exports.Foo = void 0; function Foo() { - return function () { - return ; - }; + return ; } exports.Foo = Foo; diff --git a/tests/baselines/reference/parseJsxExtends2.symbols b/tests/baselines/reference/parseJsxExtends2.symbols index 8953c3f972177..79827f185d4b8 100644 --- a/tests/baselines/reference/parseJsxExtends2.symbols +++ b/tests/baselines/reference/parseJsxExtends2.symbols @@ -3,6 +3,6 @@ export function Foo() { >Foo : Symbol(Foo, Decl(index.tsx, 0, 0)) return ->T : Symbol(T, Decl(index.tsx, 1, 12)) +>extends : Symbol(extends, Decl(index.tsx, 1, 13)) } diff --git a/tests/baselines/reference/parseJsxExtends2.types b/tests/baselines/reference/parseJsxExtends2.types index 2fdbdc2e6e261..33ae73c3a177d 100644 --- a/tests/baselines/reference/parseJsxExtends2.types +++ b/tests/baselines/reference/parseJsxExtends2.types @@ -1,10 +1,10 @@ === tests/cases/compiler/index.tsx === export function Foo() { ->Foo : () => () => any +>Foo : () => any return -> : () => any ->/> : RegExp +> : any +>T : any +>extends : true } -> : any From c705d8cd6ca5cff62b5cd73bca85c698a4cb21ff Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 26 Jan 2023 20:06:26 -0800 Subject: [PATCH 4/6] Make test clearer --- tests/baselines/reference/parseJsxExtends1.js | 8 ++++++-- tests/baselines/reference/parseJsxExtends1.symbols | 10 +++++++--- tests/baselines/reference/parseJsxExtends1.types | 4 ++++ tests/baselines/reference/parseJsxExtends2.errors.txt | 5 ++++- tests/baselines/reference/parseJsxExtends2.js | 8 ++++++-- tests/baselines/reference/parseJsxExtends2.symbols | 8 ++++++-- tests/baselines/reference/parseJsxExtends2.types | 4 ++++ tests/cases/compiler/parseJsxExtends1.ts | 5 ++++- tests/cases/compiler/parseJsxExtends2.ts | 5 ++++- 9 files changed, 45 insertions(+), 12 deletions(-) diff --git a/tests/baselines/reference/parseJsxExtends1.js b/tests/baselines/reference/parseJsxExtends1.js index f20b1cdd9df74..893228c3f6855 100644 --- a/tests/baselines/reference/parseJsxExtends1.js +++ b/tests/baselines/reference/parseJsxExtends1.js @@ -1,14 +1,18 @@ //// [index.tsx] +declare const React: any; + export function Foo() { + // No error; "const" is lowercase and therefore intrinsic. return } -//// [index.jsx] +//// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Foo = void 0; function Foo() { - return ; + // No error; "const" is lowercase and therefore intrinsic. + return React.createElement("const", { T: true, extends: true }); } exports.Foo = Foo; diff --git a/tests/baselines/reference/parseJsxExtends1.symbols b/tests/baselines/reference/parseJsxExtends1.symbols index 5628d6cd505d1..7b4981044b6b3 100644 --- a/tests/baselines/reference/parseJsxExtends1.symbols +++ b/tests/baselines/reference/parseJsxExtends1.symbols @@ -1,9 +1,13 @@ === tests/cases/compiler/index.tsx === +declare const React: any; +>React : Symbol(React, Decl(index.tsx, 0, 13)) + export function Foo() { ->Foo : Symbol(Foo, Decl(index.tsx, 0, 0)) +>Foo : Symbol(Foo, Decl(index.tsx, 0, 25)) + // No error; "const" is lowercase and therefore intrinsic. return ->T : Symbol(T, Decl(index.tsx, 1, 17)) ->extends : Symbol(extends, Decl(index.tsx, 1, 19)) +>T : Symbol(T, Decl(index.tsx, 4, 17)) +>extends : Symbol(extends, Decl(index.tsx, 4, 19)) } diff --git a/tests/baselines/reference/parseJsxExtends1.types b/tests/baselines/reference/parseJsxExtends1.types index e9c75a9635580..5e605aa1e2515 100644 --- a/tests/baselines/reference/parseJsxExtends1.types +++ b/tests/baselines/reference/parseJsxExtends1.types @@ -1,7 +1,11 @@ === tests/cases/compiler/index.tsx === +declare const React: any; +>React : any + export function Foo() { >Foo : () => any + // No error; "const" is lowercase and therefore intrinsic. return > : error >const : any diff --git a/tests/baselines/reference/parseJsxExtends2.errors.txt b/tests/baselines/reference/parseJsxExtends2.errors.txt index 09b7ebb632f8b..d482f0277abe5 100644 --- a/tests/baselines/reference/parseJsxExtends2.errors.txt +++ b/tests/baselines/reference/parseJsxExtends2.errors.txt @@ -1,8 +1,11 @@ -tests/cases/compiler/index.tsx(2,13): error TS2304: Cannot find name 'T'. +tests/cases/compiler/index.tsx(5,13): error TS2304: Cannot find name 'T'. ==== tests/cases/compiler/index.tsx (1 errors) ==== + declare const React: any; + export function Foo() { + // Error: T is not declared. return ~ !!! error TS2304: Cannot find name 'T'. diff --git a/tests/baselines/reference/parseJsxExtends2.js b/tests/baselines/reference/parseJsxExtends2.js index 5f5f019bd7144..7a09169319c6c 100644 --- a/tests/baselines/reference/parseJsxExtends2.js +++ b/tests/baselines/reference/parseJsxExtends2.js @@ -1,14 +1,18 @@ //// [index.tsx] +declare const React: any; + export function Foo() { + // Error: T is not declared. return } -//// [index.jsx] +//// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Foo = void 0; function Foo() { - return ; + // Error: T is not declared. + return React.createElement(T, { extends: true }); } exports.Foo = Foo; diff --git a/tests/baselines/reference/parseJsxExtends2.symbols b/tests/baselines/reference/parseJsxExtends2.symbols index 79827f185d4b8..b222fb8d35cc8 100644 --- a/tests/baselines/reference/parseJsxExtends2.symbols +++ b/tests/baselines/reference/parseJsxExtends2.symbols @@ -1,8 +1,12 @@ === tests/cases/compiler/index.tsx === +declare const React: any; +>React : Symbol(React, Decl(index.tsx, 0, 13)) + export function Foo() { ->Foo : Symbol(Foo, Decl(index.tsx, 0, 0)) +>Foo : Symbol(Foo, Decl(index.tsx, 0, 25)) + // Error: T is not declared. return ->extends : Symbol(extends, Decl(index.tsx, 1, 13)) +>extends : Symbol(extends, Decl(index.tsx, 4, 13)) } diff --git a/tests/baselines/reference/parseJsxExtends2.types b/tests/baselines/reference/parseJsxExtends2.types index 33ae73c3a177d..b9dcb4f5958d0 100644 --- a/tests/baselines/reference/parseJsxExtends2.types +++ b/tests/baselines/reference/parseJsxExtends2.types @@ -1,7 +1,11 @@ === tests/cases/compiler/index.tsx === +declare const React: any; +>React : any + export function Foo() { >Foo : () => any + // Error: T is not declared. return > : any >T : any diff --git a/tests/cases/compiler/parseJsxExtends1.ts b/tests/cases/compiler/parseJsxExtends1.ts index b0adda26cce53..7dbf396d6efc8 100644 --- a/tests/cases/compiler/parseJsxExtends1.ts +++ b/tests/cases/compiler/parseJsxExtends1.ts @@ -1,6 +1,9 @@ -// @jsx: preserve +// @jsx: react // @filename: index.tsx +declare const React: any; + export function Foo() { + // No error; "const" is lowercase and therefore intrinsic. return } diff --git a/tests/cases/compiler/parseJsxExtends2.ts b/tests/cases/compiler/parseJsxExtends2.ts index 3af56ed098f70..10309c2b6dc53 100644 --- a/tests/cases/compiler/parseJsxExtends2.ts +++ b/tests/cases/compiler/parseJsxExtends2.ts @@ -1,6 +1,9 @@ -// @jsx: preserve +// @jsx: react // @filename: index.tsx +declare const React: any; + export function Foo() { + // Error: T is not declared. return } From 431668be0262f01ab28d987ae369d5017b6bd43c Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 27 Jan 2023 10:07:16 -0800 Subject: [PATCH 5/6] PR feedback --- src/compiler/parser.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 7474f6328830a..766aac9e595b8 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5193,7 +5193,7 @@ namespace Parser { // JSX overrides if (languageVariant === LanguageVariant.JSX) { - return lookAhead(() => { + const isArrowFunctionInJsx = lookAhead(() => { parseOptional(SyntaxKind.ConstKeyword); const third = nextToken(); if (third === SyntaxKind.ExtendsKeyword) { @@ -5201,16 +5201,23 @@ namespace Parser { switch (fourth) { case SyntaxKind.EqualsToken: case SyntaxKind.GreaterThanToken: - return Tristate.False; + case SyntaxKind.SlashToken: + return false; default: - return Tristate.Unknown; + return true; } } else if (third === SyntaxKind.CommaToken || third === SyntaxKind.EqualsToken) { - return Tristate.True; + return true; } - return Tristate.False; + return false; }); + + if (isArrowFunctionInJsx) { + return Tristate.True; + } + + return Tristate.False; } // This *could* be a parenthesized arrow function. From 7c43af896858b07147c03c094d8a8584f6c00c5f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 27 Jan 2023 10:41:26 -0800 Subject: [PATCH 6/6] Fix rangeOfTypeParameters to not exceed file length --- src/compiler/utilities.ts | 2 +- tests/cases/fourslash/jsxElementExtendsNoCrash3.ts | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/jsxElementExtendsNoCrash3.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 57c7bf9aa8329..dd340dbfe8d22 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -9079,7 +9079,7 @@ export function rangeOfNode(node: Node): TextRange { export function rangeOfTypeParameters(sourceFile: SourceFile, typeParameters: NodeArray): TextRange { // Include the `<>` const pos = typeParameters.pos - 1; - const end = skipTrivia(sourceFile.text, typeParameters.end) + 1; + const end = Math.min(sourceFile.text.length, skipTrivia(sourceFile.text, typeParameters.end) + 1); return { pos, end }; } diff --git a/tests/cases/fourslash/jsxElementExtendsNoCrash3.ts b/tests/cases/fourslash/jsxElementExtendsNoCrash3.ts new file mode 100644 index 0000000000000..c4b85cb423046 --- /dev/null +++ b/tests/cases/fourslash/jsxElementExtendsNoCrash3.ts @@ -0,0 +1,6 @@ +/// + +// @filename: index.tsx +//// + +verify.getSuggestionDiagnostics([]);