Skip to content

Commit

Permalink
Move recursion limiter to individual resolve* functions
Browse files Browse the repository at this point in the history
  • Loading branch information
sandersn committed Dec 22, 2017
1 parent 988f9ac commit fb3042c
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 85 deletions.
4 changes: 2 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5754,6 +5754,7 @@ namespace ts {
if (source.symbol && members === getMembersOfSymbol(source.symbol)) {
members = createSymbolTable(source.declaredProperties);
}
setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
const thisArgument = lastOrUndefined(typeArguments);
for (const baseType of baseTypes) {
const instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType;
Expand Down Expand Up @@ -6007,6 +6008,7 @@ namespace ts {
if (symbol.exports) {
members = getExportsOfSymbol(symbol);
}
setStructuredTypeMembers(type, members, emptyArray, emptyArray, undefined, undefined);
if (symbol.flags & SymbolFlags.Class) {
const classType = getDeclaredTypeOfClassOrInterface(symbol);
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
Expand Down Expand Up @@ -6171,8 +6173,6 @@ namespace ts {

function resolveStructuredTypeMembers(type: StructuredType): ResolvedType {
if (!(<ResolvedType>type).members) {
const earlySymbols = (type.symbol && type.symbol.members) || emptySymbols;
setStructuredTypeMembers(type, earlySymbols, emptyArray, emptyArray, undefined, undefined);
if (type.flags & TypeFlags.Object) {
if ((<ObjectType>type).objectFlags & ObjectFlags.Reference) {
resolveTypeReferenceMembers(<TypeReference>type);
Expand Down
20 changes: 13 additions & 7 deletions tests/baselines/reference/dynamicNames.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,21 @@ export const o1_s2 = o1[s2];
export const o2: T0 = o1;

// recursive declarations
declare const rI: RI;
interface RI {
x: "a";
// (type parameter indirection courtesy of #20400)
declare const rI: RI<"a">;
rI.x
interface RI<T extends "a" | "b"> {
x: T;
[rI.x]: "b";
}

declare const rC: RC;
declare class RC {
x: "a";
declare const rC: RC<"a">;
rC.x
declare class RC<T extends "a" | "b"> {
x: T;
[rC.x]: "b";
}
}


//// [module.js]
"use strict";
Expand Down Expand Up @@ -205,6 +209,8 @@ exports.o1_c4 = exports.o1[exports.c4];
exports.o1_c5 = exports.o1[exports.c5];
exports.o1_s2 = exports.o1[exports.s2];
exports.o2 = exports.o1;
rI.x;
rC.x;


//// [module.d.ts]
Expand Down
56 changes: 36 additions & 20 deletions tests/baselines/reference/dynamicNames.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -443,34 +443,50 @@ export const o2: T0 = o1;
>o1 : Symbol(o1, Decl(main.ts, 101, 12))

// recursive declarations
declare const rI: RI;
>rI : Symbol(rI, Decl(main.ts, 115, 13))
>RI : Symbol(RI, Decl(main.ts, 115, 21))
// (type parameter indirection courtesy of #20400)
declare const rI: RI<"a">;
>rI : Symbol(rI, Decl(main.ts, 116, 13))
>RI : Symbol(RI, Decl(main.ts, 117, 4))

interface RI {
>RI : Symbol(RI, Decl(main.ts, 115, 21))
rI.x
>rI.x : Symbol(RI.x, Decl(main.ts, 118, 35))
>rI : Symbol(rI, Decl(main.ts, 116, 13))
>x : Symbol(RI.x, Decl(main.ts, 118, 35))

x: "a";
>x : Symbol(RI.x, Decl(main.ts, 116, 14))
interface RI<T extends "a" | "b"> {
>RI : Symbol(RI, Decl(main.ts, 117, 4))
>T : Symbol(T, Decl(main.ts, 118, 13))

x: T;
>x : Symbol(RI.x, Decl(main.ts, 118, 35))
>T : Symbol(T, Decl(main.ts, 118, 13))

[rI.x]: "b";
>rI.x : Symbol(RI.x, Decl(main.ts, 116, 14))
>rI : Symbol(rI, Decl(main.ts, 115, 13))
>x : Symbol(RI.x, Decl(main.ts, 116, 14))
>rI.x : Symbol(RI.x, Decl(main.ts, 118, 35))
>rI : Symbol(rI, Decl(main.ts, 116, 13))
>x : Symbol(RI.x, Decl(main.ts, 118, 35))
}

declare const rC: RC;
>rC : Symbol(rC, Decl(main.ts, 121, 13))
>RC : Symbol(RC, Decl(main.ts, 121, 21))
declare const rC: RC<"a">;
>rC : Symbol(rC, Decl(main.ts, 123, 13))
>RC : Symbol(RC, Decl(main.ts, 124, 4))

rC.x
>rC.x : Symbol(RC.x, Decl(main.ts, 125, 39))
>rC : Symbol(rC, Decl(main.ts, 123, 13))
>x : Symbol(RC.x, Decl(main.ts, 125, 39))

declare class RC {
>RC : Symbol(RC, Decl(main.ts, 121, 21))
declare class RC<T extends "a" | "b"> {
>RC : Symbol(RC, Decl(main.ts, 124, 4))
>T : Symbol(T, Decl(main.ts, 125, 17))

x: "a";
>x : Symbol(RC.x, Decl(main.ts, 122, 18))
x: T;
>x : Symbol(RC.x, Decl(main.ts, 125, 39))
>T : Symbol(T, Decl(main.ts, 125, 17))

[rC.x]: "b";
>rC.x : Symbol(RC.x, Decl(main.ts, 122, 18))
>rC : Symbol(rC, Decl(main.ts, 121, 13))
>x : Symbol(RC.x, Decl(main.ts, 122, 18))
>rC.x : Symbol(RC.x, Decl(main.ts, 125, 39))
>rC : Symbol(rC, Decl(main.ts, 123, 13))
>x : Symbol(RC.x, Decl(main.ts, 125, 39))
}

48 changes: 32 additions & 16 deletions tests/baselines/reference/dynamicNames.types
Original file line number Diff line number Diff line change
Expand Up @@ -519,34 +519,50 @@ export const o2: T0 = o1;
>o1 : { [c4]: number; [c5]: string; [s2]: boolean; }

// recursive declarations
declare const rI: RI;
>rI : RI
>RI : RI
// (type parameter indirection courtesy of #20400)
declare const rI: RI<"a">;
>rI : RI<"a">
>RI : RI<T>

interface RI {
>RI : RI

x: "a";
rI.x
>rI.x : "a"
>rI : RI<"a">
>x : "a"

interface RI<T extends "a" | "b"> {
>RI : RI<T>
>T : T

x: T;
>x : T
>T : T

[rI.x]: "b";
>rI.x : "a"
>rI : RI
>rI : RI<"a">
>x : "a"
}

declare const rC: RC;
>rC : RC
>RC : RC

declare class RC {
>RC : RC
declare const rC: RC<"a">;
>rC : RC<"a">
>RC : RC<T>

x: "a";
rC.x
>rC.x : "a"
>rC : RC<"a">
>x : "a"

declare class RC<T extends "a" | "b"> {
>RC : RC<T>
>T : T

x: T;
>x : T
>T : T

[rC.x]: "b";
>rC.x : "a"
>rC : RC
>rC : RC<"a">
>x : "a"
}

10 changes: 0 additions & 10 deletions tests/baselines/reference/mutuallyRecursiveInference.errors.txt

This file was deleted.

50 changes: 47 additions & 3 deletions tests/baselines/reference/mutuallyRecursiveInference.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,51 @@
//// [mutuallyRecursiveInference.ts]
interface T<A> { a: A }
interface L<RT> extends T<RT['a']> {}
interface X extends L<X> {}
class T<A> {
a: A;
b: any
}
class L<RT extends { a: 'a' | 'b', b: any }> extends T<RT[RT['a']]> {
m() { this.a }
}
class X extends L<X> {
a: 'a' | 'b'
b: number
m2() {
this.a
}
}


//// [mutuallyRecursiveInference.js]
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var T = /** @class */ (function () {
function T() {
}
return T;
}());
var L = /** @class */ (function (_super) {
__extends(L, _super);
function L() {
return _super !== null && _super.apply(this, arguments) || this;
}
L.prototype.m = function () { this.a; };
return L;
}(T));
var X = /** @class */ (function (_super) {
__extends(X, _super);
function X() {
return _super !== null && _super.apply(this, arguments) || this;
}
X.prototype.m2 = function () {
this.a;
};
return X;
}(L));
54 changes: 42 additions & 12 deletions tests/baselines/reference/mutuallyRecursiveInference.symbols
Original file line number Diff line number Diff line change
@@ -1,18 +1,48 @@
=== tests/cases/compiler/mutuallyRecursiveInference.ts ===
interface T<A> { a: A }
class T<A> {
>T : Symbol(T, Decl(mutuallyRecursiveInference.ts, 0, 0))
>A : Symbol(A, Decl(mutuallyRecursiveInference.ts, 0, 12))
>a : Symbol(T.a, Decl(mutuallyRecursiveInference.ts, 0, 16))
>A : Symbol(A, Decl(mutuallyRecursiveInference.ts, 0, 12))
>A : Symbol(A, Decl(mutuallyRecursiveInference.ts, 0, 8))

interface L<RT> extends T<RT['a']> {}
>L : Symbol(L, Decl(mutuallyRecursiveInference.ts, 0, 23))
>RT : Symbol(RT, Decl(mutuallyRecursiveInference.ts, 1, 12))
a: A;
>a : Symbol(T.a, Decl(mutuallyRecursiveInference.ts, 0, 12))
>A : Symbol(A, Decl(mutuallyRecursiveInference.ts, 0, 8))

b: any
>b : Symbol(T.b, Decl(mutuallyRecursiveInference.ts, 1, 9))
}
class L<RT extends { a: 'a' | 'b', b: any }> extends T<RT[RT['a']]> {
>L : Symbol(L, Decl(mutuallyRecursiveInference.ts, 3, 1))
>RT : Symbol(RT, Decl(mutuallyRecursiveInference.ts, 4, 8))
>a : Symbol(a, Decl(mutuallyRecursiveInference.ts, 4, 20))
>b : Symbol(b, Decl(mutuallyRecursiveInference.ts, 4, 34))
>T : Symbol(T, Decl(mutuallyRecursiveInference.ts, 0, 0))
>RT : Symbol(RT, Decl(mutuallyRecursiveInference.ts, 1, 12))
>RT : Symbol(RT, Decl(mutuallyRecursiveInference.ts, 4, 8))
>RT : Symbol(RT, Decl(mutuallyRecursiveInference.ts, 4, 8))

m() { this.a }
>m : Symbol(L.m, Decl(mutuallyRecursiveInference.ts, 4, 69))
>this.a : Symbol(T.a, Decl(mutuallyRecursiveInference.ts, 0, 12))
>this : Symbol(L, Decl(mutuallyRecursiveInference.ts, 3, 1))
>a : Symbol(T.a, Decl(mutuallyRecursiveInference.ts, 0, 12))
}
class X extends L<X> {
>X : Symbol(X, Decl(mutuallyRecursiveInference.ts, 6, 1))
>L : Symbol(L, Decl(mutuallyRecursiveInference.ts, 3, 1))
>X : Symbol(X, Decl(mutuallyRecursiveInference.ts, 6, 1))

a: 'a' | 'b'
>a : Symbol(X.a, Decl(mutuallyRecursiveInference.ts, 7, 22))

b: number
>b : Symbol(X.b, Decl(mutuallyRecursiveInference.ts, 8, 16))

m2() {
>m2 : Symbol(X.m2, Decl(mutuallyRecursiveInference.ts, 9, 13))

interface X extends L<X> {}
>X : Symbol(X, Decl(mutuallyRecursiveInference.ts, 1, 37))
>L : Symbol(L, Decl(mutuallyRecursiveInference.ts, 0, 23))
>X : Symbol(X, Decl(mutuallyRecursiveInference.ts, 1, 37))
this.a
>this.a : Symbol(X.a, Decl(mutuallyRecursiveInference.ts, 7, 22))
>this : Symbol(X, Decl(mutuallyRecursiveInference.ts, 6, 1))
>a : Symbol(X.a, Decl(mutuallyRecursiveInference.ts, 7, 22))
}
}

40 changes: 35 additions & 5 deletions tests/baselines/reference/mutuallyRecursiveInference.types
Original file line number Diff line number Diff line change
@@ -1,18 +1,48 @@
=== tests/cases/compiler/mutuallyRecursiveInference.ts ===
interface T<A> { a: A }
class T<A> {
>T : T<A>
>A : A

a: A;
>a : A
>A : A

interface L<RT> extends T<RT['a']> {}
b: any
>b : any
}
class L<RT extends { a: 'a' | 'b', b: any }> extends T<RT[RT['a']]> {
>L : L<RT>
>RT : RT
>T : T<A>
>a : "a" | "b"
>b : any
>T : T<RT[RT["a"]]>
>RT : RT
>RT : RT

interface X extends L<X> {}
m() { this.a }
>m : () => void
>this.a : RT[RT["a"]]
>this : this
>a : RT[RT["a"]]
}
class X extends L<X> {
>X : X
>L : L<RT>
>L : L<X>
>X : X

a: 'a' | 'b'
>a : "a" | "b"

b: number
>b : number

m2() {
>m2 : () => void

this.a
>this.a : "a" | "b"
>this : this
>a : "a" | "b"
}
}

Loading

0 comments on commit fb3042c

Please sign in to comment.