diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b448910799401..766aac9e595b8 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5201,6 +5201,7 @@ namespace Parser { switch (fourth) { case SyntaxKind.EqualsToken: case SyntaxKind.GreaterThanToken: + case SyntaxKind.SlashToken: return false; default: return true; 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/baselines/reference/parseJsxExtends1.js b/tests/baselines/reference/parseJsxExtends1.js new file mode 100644 index 0000000000000..893228c3f6855 --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends1.js @@ -0,0 +1,18 @@ +//// [index.tsx] +declare const React: any; + +export function Foo() { + // No error; "const" is lowercase and therefore intrinsic. + return +} + + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Foo = void 0; +function Foo() { + // 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 new file mode 100644 index 0000000000000..7b4981044b6b3 --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends1.symbols @@ -0,0 +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, 25)) + + // No error; "const" is lowercase and therefore intrinsic. + return +>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 new file mode 100644 index 0000000000000..5e605aa1e2515 --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends1.types @@ -0,0 +1,15 @@ +=== 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 +>T : true +>extends : true +} + diff --git a/tests/baselines/reference/parseJsxExtends2.errors.txt b/tests/baselines/reference/parseJsxExtends2.errors.txt new file mode 100644 index 0000000000000..d482f0277abe5 --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends2.errors.txt @@ -0,0 +1,13 @@ +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'. + } + \ 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..7a09169319c6c --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends2.js @@ -0,0 +1,18 @@ +//// [index.tsx] +declare const React: any; + +export function Foo() { + // Error: T is not declared. + return +} + + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Foo = void 0; +function Foo() { + // 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 new file mode 100644 index 0000000000000..b222fb8d35cc8 --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends2.symbols @@ -0,0 +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, 25)) + + // Error: T is not declared. + return +>extends : Symbol(extends, Decl(index.tsx, 4, 13)) +} + diff --git a/tests/baselines/reference/parseJsxExtends2.types b/tests/baselines/reference/parseJsxExtends2.types new file mode 100644 index 0000000000000..b9dcb4f5958d0 --- /dev/null +++ b/tests/baselines/reference/parseJsxExtends2.types @@ -0,0 +1,14 @@ +=== 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 +>extends : true +} + diff --git a/tests/cases/compiler/parseJsxExtends1.ts b/tests/cases/compiler/parseJsxExtends1.ts new file mode 100644 index 0000000000000..7dbf396d6efc8 --- /dev/null +++ b/tests/cases/compiler/parseJsxExtends1.ts @@ -0,0 +1,9 @@ +// @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 new file mode 100644 index 0000000000000..10309c2b6dc53 --- /dev/null +++ b/tests/cases/compiler/parseJsxExtends2.ts @@ -0,0 +1,9 @@ +// @jsx: react +// @filename: index.tsx + +declare const React: any; + +export function Foo() { + // Error: T is not declared. + return +} 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([]); 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([]);