Make removeSubtypes resilient to reentry

This commit is contained in:
Jason Freeman 2015-05-07 11:39:28 -07:00
parent 7a5804cf45
commit d8ef7b612a
5 changed files with 164 additions and 0 deletions

View File

@ -3572,7 +3572,18 @@ module ts {
return false;
}
// Since removeSubtypes checks the subtype relation, and the subtype relation on a union
// may attempt to reduce a union, it is possible that removeSubtypes could be called
// recursively on the same set of types.
let removeSubtypesStack: string[] = [];
function removeSubtypes(types: Type[]) {
let typeListId = getTypeListId(types);
if (removeSubtypesStack.lastIndexOf(typeListId) >= 0) {
return;
}
removeSubtypesStack.push(typeListId);
let i = types.length;
while (i > 0) {
i--;
@ -3580,6 +3591,8 @@ module ts {
types.splice(i, 1);
}
}
removeSubtypesStack.pop();
}
function containsAnyType(types: Type[]) {

View File

@ -0,0 +1,43 @@
//// [unionTypeWithRecursiveSubtypeReduction.ts]
class Module {
public members: Class[];
}
class Namespace {
public members: (Class | Property)[];
}
class Class {
public parent: Namespace;
}
class Property {
public parent: Module | Class;
}
var t: Class | Property;
t.parent;
//// [unionTypeWithRecursiveSubtypeReduction.js]
var Module = (function () {
function Module() {
}
return Module;
})();
var Namespace = (function () {
function Namespace() {
}
return Namespace;
})();
var Class = (function () {
function Class() {
}
return Class;
})();
var Property = (function () {
function Property() {
}
return Property;
})();
var t;
t.parent;

View File

@ -0,0 +1,45 @@
=== tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction.ts ===
class Module {
>Module : Symbol(Module, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 0, 0))
public members: Class[];
>members : Symbol(members, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 0, 14))
>Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 6, 1))
}
class Namespace {
>Namespace : Symbol(Namespace, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 2, 1))
public members: (Class | Property)[];
>members : Symbol(members, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 4, 17))
>Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 6, 1))
>Property : Symbol(Property, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 10, 1))
}
class Class {
>Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 6, 1))
public parent: Namespace;
>parent : Symbol(parent, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 8, 13))
>Namespace : Symbol(Namespace, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 2, 1))
}
class Property {
>Property : Symbol(Property, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 10, 1))
public parent: Module | Class;
>parent : Symbol(parent, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 12, 16))
>Module : Symbol(Module, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 0, 0))
>Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 6, 1))
}
var t: Class | Property;
>t : Symbol(t, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 16, 3))
>Class : Symbol(Class, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 6, 1))
>Property : Symbol(Property, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 10, 1))
t.parent;
>t.parent : Symbol(parent, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 8, 13), Decl(unionTypeWithRecursiveSubtypeReduction.ts, 12, 16))
>t : Symbol(t, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 16, 3))
>parent : Symbol(parent, Decl(unionTypeWithRecursiveSubtypeReduction.ts, 8, 13), Decl(unionTypeWithRecursiveSubtypeReduction.ts, 12, 16))

View File

@ -0,0 +1,45 @@
=== tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction.ts ===
class Module {
>Module : Module
public members: Class[];
>members : Class[]
>Class : Class
}
class Namespace {
>Namespace : Namespace
public members: (Class | Property)[];
>members : (Class | Property)[]
>Class : Class
>Property : Property
}
class Class {
>Class : Class
public parent: Namespace;
>parent : Namespace
>Namespace : Namespace
}
class Property {
>Property : Property
public parent: Module | Class;
>parent : Module | Class
>Module : Module
>Class : Class
}
var t: Class | Property;
>t : Class | Property
>Class : Class
>Property : Property
t.parent;
>t.parent : Class | Namespace
>t : Class | Property
>parent : Class | Namespace

View File

@ -0,0 +1,18 @@
class Module {
public members: Class[];
}
class Namespace {
public members: (Class | Property)[];
}
class Class {
public parent: Namespace;
}
class Property {
public parent: Module | Class;
}
var t: Class | Property;
t.parent;