Skip to content

Commit

Permalink
Properly re-scan > token in type argument list determination logic (#…
Browse files Browse the repository at this point in the history
…49560) (#49570)

* Properly re-scan '>' token in type argument list determination logic

* Add regression test
  • Loading branch information
DanielRosenwasser committed Jun 16, 2022
1 parent 4d2983a commit dfe885b
Show file tree
Hide file tree
Showing 6 changed files with 614 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/compiler/parser.ts
Expand Up @@ -5705,10 +5705,11 @@ namespace ts {
nextToken();

const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType);
if (!parseExpected(SyntaxKind.GreaterThanToken)) {
if (reScanGreaterToken() !== SyntaxKind.GreaterThanToken) {
// If it doesn't have the closing `>` then it's definitely not an type argument list.
return undefined;
}
nextToken();

// We successfully parsed a type argument list. The next token determines whether we want to
// treat it as such. If the type argument list is followed by `(` or a template literal, as in
Expand Down
144 changes: 143 additions & 1 deletion tests/baselines/reference/instantiationExpressionErrors.errors.txt
Expand Up @@ -8,9 +8,40 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(26,24): error TS2558: Expected 0 type arguments, but got 1.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(31,2): error TS2554: Expected 0 arguments, but got 1.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(35,12): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(48,12): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(49,1): error TS2304: Cannot find name 'let'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(49,5): error TS1005: ',' expected.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(51,12): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(52,1): error TS2304: Cannot find name 'interface'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(52,11): error TS1005: ',' expected.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(52,11): error TS7005: Variable 'I' implicitly has an 'any' type.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(52,13): error TS1005: ',' expected.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(54,11): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(55,6): error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(57,11): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(57,11): error TS2365: Operator '>' cannot be applied to types 'boolean' and '() => void'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(60,11): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(60,11): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'typeof C'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(63,11): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(64,1): error TS2304: Cannot find name 'bar'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(66,11): error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(67,1): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(67,6): error TS2304: Cannot find name 'bar'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(70,27): error TS2693: 'string' only refers to a type, but is being used as a value here.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(71,5): error TS2304: Cannot find name 'static'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(71,12): error TS1005: ';' expected.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(75,27): error TS2693: 'string' only refers to a type, but is being used as a value here.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(76,5): error TS2304: Cannot find name 'public'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(76,12): error TS1005: ';' expected.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(80,28): error TS2693: 'string' only refers to a type, but is being used as a value here.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(81,5): error TS2304: Cannot find name 'private'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(81,13): error TS1005: ';' expected.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(85,30): error TS2693: 'string' only refers to a type, but is being used as a value here.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(86,5): error TS2304: Cannot find name 'protected'.
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(86,15): error TS1005: ';' expected.


==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts (10 errors) ====
==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts (41 errors) ====
declare let f: { <T>(): T, g<U>(): U };

// Type arguments in member expressions
Expand Down Expand Up @@ -77,4 +108,115 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr

const x4 = f<true>
if (true) {}

const x5 = f<true>
~~~~~~
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
let yy = 0;
~~~
!!! error TS2304: Cannot find name 'let'.
~~
!!! error TS1005: ',' expected.

const x6 = f<true>
~~~~~~
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
interface I {}
~~~~~~~~~
!!! error TS2304: Cannot find name 'interface'.
~
!!! error TS1005: ',' expected.
~
!!! error TS7005: Variable 'I' implicitly has an 'any' type.
~
!!! error TS1005: ',' expected.

let x10 = f<true>
~~~~~~
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
this.bar()
~~~
!!! error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.

let x11 = f<true>
~~~~~~
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
~~~~~~~
function bar() {}
~~~~~~~~~~~~~~~~~
!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and '() => void'.

let x12 = f<true>
~~~~~~
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
~~~~~~~
class C {}
~~~~~~~~~~
!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and 'typeof C'.

let x13 = f<true>
~~~~~~
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
bar()
~~~
!!! error TS2304: Cannot find name 'bar'.

let x14 = f<true>
~~~~~~
!!! error TS2365: Operator '<' cannot be applied to types '{ <T>(): T; g<U>(): U; }' and 'boolean'.
void bar()
~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
~~~
!!! error TS2304: Cannot find name 'bar'.

class C1 {
static specialFoo = f<string>
~~~~~~
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
static bar = 123
~~~~~~
!!! error TS2304: Cannot find name 'static'.
~~~
!!! error TS1005: ';' expected.
}

class C2 {
public specialFoo = f<string>
~~~~~~
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
public bar = 123
~~~~~~
!!! error TS2304: Cannot find name 'public'.
~~~
!!! error TS1005: ';' expected.
}

class C3 {
private specialFoo = f<string>
~~~~~~
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
private bar = 123
~~~~~~~
!!! error TS2304: Cannot find name 'private'.
~~~
!!! error TS1005: ';' expected.
}

class C4 {
protected specialFoo = f<string>
~~~~~~
!!! error TS2693: 'string' only refers to a type, but is being used as a value here.
protected bar = 123
~~~~~~~~~
!!! error TS2304: Cannot find name 'protected'.
~~~
!!! error TS1005: ';' expected.
}

// Repro from #49551

const enum MyVer { v1 = 1, v2 = 2 }
let ver = 21
const a = ver < (MyVer.v1 >= MyVer.v2 ? MyVer.v1 : MyVer.v2)

127 changes: 127 additions & 0 deletions tests/baselines/reference/instantiationExpressionErrors.js
Expand Up @@ -45,6 +45,53 @@ true;

const x4 = f<true>
if (true) {}

const x5 = f<true>
let yy = 0;

const x6 = f<true>
interface I {}

let x10 = f<true>
this.bar()

let x11 = f<true>
function bar() {}

let x12 = f<true>
class C {}

let x13 = f<true>
bar()

let x14 = f<true>
void bar()

class C1 {
static specialFoo = f<string>
static bar = 123
}

class C2 {
public specialFoo = f<string>
public bar = 123
}

class C3 {
private specialFoo = f<string>
private bar = 123
}

class C4 {
protected specialFoo = f<string>
protected bar = 123
}

// Repro from #49551

const enum MyVer { v1 = 1, v2 = 2 }
let ver = 21
const a = ver < (MyVer.v1 >= MyVer.v2 ? MyVer.v1 : MyVer.v2)


//// [instantiationExpressionErrors.js]
Expand Down Expand Up @@ -78,6 +125,57 @@ true;
// Parsed as instantiation expression
var x4 = (f);
if (true) { }
var x5 = f < true >
let, yy = 0;
var x6 = f < true >
interface, I, _c = void 0;
var x10 = f < true >
this.bar();
var x11 = f < true >
function bar() { };
var x12 = f < true > /** @class */ (function () {
function C() {
}
return C;
}());
var x13 = f < true >
bar();
var x14 = f < true >
void bar();
var C1 = /** @class */ (function () {
function C1() {
this.bar = 123;
}
C1.specialFoo = f < string >
static;
return C1;
}());
var C2 = /** @class */ (function () {
function C2() {
this.specialFoo = f < string >
public;
this.bar = 123;
}
return C2;
}());
var C3 = /** @class */ (function () {
function C3() {
this.specialFoo = f < string >
private;
this.bar = 123;
}
return C3;
}());
var C4 = /** @class */ (function () {
function C4() {
this.specialFoo = f < string >
protected;
this.bar = 123;
}
return C4;
}());
var ver = 21;
var a = ver < (1 /* MyVer.v1 */ >= 2 /* MyVer.v2 */ ? 1 /* MyVer.v1 */ : 2 /* MyVer.v2 */);


//// [instantiationExpressionErrors.d.ts]
Expand Down Expand Up @@ -113,3 +211,32 @@ declare const x4: {
(): true;
g<U>(): U;
};
declare const x5: boolean, yy = 0;
declare const x6: boolean, I: any;
declare let x10: boolean;
declare let x11: boolean;
declare let x12: boolean;
declare let x13: boolean;
declare let x14: boolean;
declare class C1 {
static specialFoo: boolean;
bar: number;
}
declare class C2 {
specialFoo: boolean;
bar: number;
}
declare class C3 {
private specialFoo;
bar: number;
}
declare class C4 {
protected specialFoo: boolean;
bar: number;
}
declare const enum MyVer {
v1 = 1,
v2 = 2
}
declare let ver: number;
declare const a: boolean;

0 comments on commit dfe885b

Please sign in to comment.