Do not parse template arguments in JavaScript files. (#36673)

Fixes #36662.
This commit is contained in:
Martin Probst 2020-11-19 20:41:35 +01:00 committed by GitHub
parent 2cc67ec0a6
commit 6b04f50394
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 69 additions and 38 deletions

View File

@ -4909,7 +4909,7 @@ namespace ts {
}
const tagName = parseJsxElementName();
const typeArguments = tryParseTypeArguments();
const typeArguments = (contextFlags & NodeFlags.JavaScriptFile) === 0 ? tryParseTypeArguments() : undefined;
const attributes = parseJsxAttributes();
let node: JsxOpeningLikeElement;
@ -5174,7 +5174,8 @@ namespace ts {
expression = parseMemberExpressionRest(pos, expression, /*allowOptionalChain*/ true);
const questionDotToken = parseOptionalToken(SyntaxKind.QuestionDotToken);
// handle 'foo<<T>()'
if (token() === SyntaxKind.LessThanToken || token() === SyntaxKind.LessThanLessThanToken) {
// parse template arguments only in TypeScript files (not in JavaScript files).
if ((contextFlags & NodeFlags.JavaScriptFile) === 0 && (token() === SyntaxKind.LessThanToken || token() === SyntaxKind.LessThanLessThanToken)) {
// See if this is the start of a generic invocation. If so, consume it and
// keep checking for postfix expressions. Otherwise, it's just a '<' that's
// part of an arithmetic expression. Break out so we consume it higher in the
@ -5220,6 +5221,11 @@ namespace ts {
}
function parseTypeArgumentsInExpression() {
if ((contextFlags & NodeFlags.JavaScriptFile) !== 0) {
// TypeArguments must not be parsed in JavaScript files to avoid ambiguity with binary operators.
return undefined;
}
if (reScanLessThanToken() !== SyntaxKind.LessThanToken) {
return undefined;
}

View File

@ -1,8 +1,8 @@
Syntactic Diagnostics for file '/tests/cases/fourslash/getJavaScriptSyntacticDiagnostics14.ts':
/tests/cases/fourslash/a.js(1,5): error TS8011: Type arguments can only be used in TypeScript files.
/tests/cases/fourslash/a.js(1,13): error TS1109: Expression expected.
==== /tests/cases/fourslash/a.js (1 errors) ====
Foo<number>();
~~~~~~
!!! error TS8011: Type arguments can only be used in TypeScript files.
~
!!! error TS1109: Expression expected.

View File

@ -1,19 +1,30 @@
tests/cases/compiler/a.jsx(1,5): error TS8011: Type arguments can only be used in TypeScript files.
tests/cases/compiler/a.jsx(2,5): error TS8011: Type arguments can only be used in TypeScript files.
tests/cases/compiler/a.jsx(3,6): error TS8011: Type arguments can only be used in TypeScript files.
tests/cases/compiler/a.jsx(4,6): error TS8011: Type arguments can only be used in TypeScript files.
tests/cases/compiler/a.jsx(1,13): error TS1109: Expression expected.
tests/cases/compiler/a.jsx(4,5): error TS1003: Identifier expected.
tests/cases/compiler/a.jsx(4,14): error TS17002: Expected corresponding JSX closing tag for 'number'.
tests/cases/compiler/a.jsx(4,20): 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.
tests/cases/compiler/a.jsx(6,1): error TS1005: '</' expected.
==== tests/cases/compiler/a.jsx (4 errors) ====
==== tests/cases/compiler/a.jsx (7 errors) ====
Foo<number>();
~~~~~~
!!! error TS8011: Type arguments can only be used in TypeScript files.
~
!!! error TS1109: Expression expected.
Foo<number>(1);
Foo<number>``;
~~~~~~
!!! error TS8011: Type arguments can only be used in TypeScript files.
<Foo<number>></Foo>;
~~~~~~
!!! error TS8011: Type arguments can only be used in TypeScript files.
~
!!! error TS1003: Identifier expected.
~~~~~~
!!! error TS17002: Expected corresponding JSX closing tag for 'number'.
~
!!! error TS2657: JSX expressions must have one parent element.
<Foo<number>/>;
~
!!! error TS1003: Identifier expected.
~~~~~~
!!! error TS8011: Type arguments can only be used in TypeScript files.
!!! error TS17008: JSX element 'number' has no corresponding closing tag.
!!! error TS1005: '</' expected.

View File

@ -1,15 +1,15 @@
//// [a.jsx]
Foo<number>();
Foo<number>(1);
Foo<number>``;
<Foo<number>></Foo>;
<Foo<number>/>;
<Foo<number>/>;
//// [a.js]
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
};
Foo();
Foo(__makeTemplateObject([""], [""]));
<Foo></Foo>;
<Foo />;
Foo < number > ();
Foo < number > (1);
Foo < number > "";
<Foo />, <number>></Foo>;
<Foo />, <number>/>;
</>;

View File

@ -1,4 +1,8 @@
tests/cases/conformance/jsx/file.jsx(4,17): error TS8011: Type arguments can only be used in TypeScript files.
tests/cases/conformance/jsx/file.jsx(4,9): error TS2695: Left side of comma operator is unused and has no side effects.
tests/cases/conformance/jsx/file.jsx(4,16): error TS1003: Identifier expected.
tests/cases/conformance/jsx/file.jsx(4,17): error TS2693: 'Prop' only refers to a type, but is being used as a value here.
tests/cases/conformance/jsx/file.jsx(4,17): error TS17008: JSX element 'Prop' has no corresponding closing tag.
tests/cases/conformance/jsx/file.jsx(5,1): error TS1005: '</' expected.
==== tests/cases/conformance/jsx/component.d.ts (0 errors) ====
@ -12,11 +16,19 @@ tests/cases/conformance/jsx/file.jsx(4,17): error TS8011: Type arguments can onl
b: string
}
==== tests/cases/conformance/jsx/file.jsx (1 errors) ====
==== tests/cases/conformance/jsx/file.jsx (5 errors) ====
import { MyComp, Prop } from "./component";
import * as React from "react";
let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
~~~~~~~
!!! error TS2695: Left side of comma operator is unused and has no side effects.
~
!!! error TS1003: Identifier expected.
~~~~
!!! error TS8011: Type arguments can only be used in TypeScript files.
!!! error TS2693: 'Prop' only refers to a type, but is being used as a value here.
~~~~
!!! error TS17008: JSX element 'Prop' has no corresponding closing tag.
!!! error TS1005: '</' expected.

View File

@ -23,4 +23,5 @@ let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
exports.__esModule = true;
var component_1 = require("./component");
var React = require("react");
var x = <component_1.MyComp a={10} b="hi"/>; // error, no type arguments in js
var x = <component_1.MyComp />, <Prop> a={10} b="hi" />; // error, no type arguments in js
</>;

View File

@ -36,7 +36,4 @@ import * as React from "react";
let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
>x : Symbol(x, Decl(file.jsx, 3, 3))
>MyComp : Symbol(MyComp, Decl(file.jsx, 0, 8))
>Prop : Symbol(Prop, Decl(file.jsx, 0, 16))
>a : Symbol(a, Decl(file.jsx, 3, 21))
>b : Symbol(b, Decl(file.jsx, 3, 28))

View File

@ -30,9 +30,12 @@ import * as React from "react";
let x = <MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js
>x : JSX.Element
><MyComp<Prop> a={10} b="hi" /> : JSX.Element
><MyComp<Prop> a={10} b="hi" />; // error, no type arguments in js : JSX.Element
><MyComp : JSX.Element
>MyComp : typeof MyComp
>a : number
><Prop> a={10} b="hi" />; // error, no type arguments in js : JSX.Element
>Prop : any
>10 : 10
>b : string
> : any

View File

@ -2,6 +2,7 @@
// @noTypesAndSymbols: true
// @filename: a.jsx
Foo<number>();
Foo<number>(1);
Foo<number>``;
<Foo<number>></Foo>;
<Foo<number>/>;
<Foo<number>/>;