Skip to content

Commit 7c2644a

Browse files
committed
Perform depth check for all type instantiations
1 parent 6a81d4c commit 7c2644a

File tree

1 file changed

+57
-53
lines changed

1 file changed

+57
-53
lines changed

src/compiler/checker.ts

Lines changed: 57 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10294,65 +10294,69 @@ namespace ts {
1029410294
return getConditionalType(root, mapper);
1029510295
}
1029610296

10297-
function instantiateWithDepthCheck(type: Type, mapper: TypeMapper, instantiator: (type: Type, mapper: TypeMapper) => Type): Type {
10298-
if (instantiationDepth < 50) {
10299-
instantiationDepth++;
10300-
const result = instantiator(type, mapper);
10301-
instantiationDepth--;
10302-
return result;
10303-
}
10304-
// We have reached 50 recursive type instantiations and there is a very high likelyhood we're dealing
10305-
// with a combination of infinite generic types that perpetually generate new type identities. We stop
10306-
// the recursion here by yielding the error type.
10307-
return errorType;
10308-
}
10309-
1031010297
function instantiateType(type: Type, mapper: TypeMapper | undefined): Type;
1031110298
function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined;
1031210299
function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined {
10313-
if (type && mapper && mapper !== identityMapper) {
10314-
if (type.flags & TypeFlags.TypeParameter) {
10315-
return mapper(type);
10316-
}
10317-
if (type.flags & TypeFlags.Object) {
10318-
if ((<ObjectType>type).objectFlags & ObjectFlags.Anonymous) {
10319-
// If the anonymous type originates in a declaration of a function, method, class, or
10320-
// interface, in an object type literal, or in an object literal expression, we may need
10321-
// to instantiate the type because it might reference a type parameter.
10322-
return type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations ?
10323-
instantiateWithDepthCheck(type, mapper, getAnonymousTypeInstantiation) : type;
10324-
}
10325-
if ((<ObjectType>type).objectFlags & ObjectFlags.Mapped) {
10326-
return instantiateWithDepthCheck(type, mapper, getAnonymousTypeInstantiation);
10327-
}
10328-
if ((<ObjectType>type).objectFlags & ObjectFlags.Reference) {
10329-
const typeArguments = (<TypeReference>type).typeArguments;
10330-
const newTypeArguments = instantiateTypes(typeArguments, mapper);
10331-
return newTypeArguments !== typeArguments ? createTypeReference((<TypeReference>type).target, newTypeArguments) : type;
10332-
}
10333-
}
10334-
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
10335-
const types = (<UnionType>type).types;
10336-
const newTypes = instantiateTypes(types, mapper);
10337-
return newTypes !== types ? getUnionType(newTypes, UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
10338-
}
10339-
if (type.flags & TypeFlags.Intersection) {
10340-
const types = (<IntersectionType>type).types;
10341-
const newTypes = instantiateTypes(types, mapper);
10342-
return newTypes !== types ? getIntersectionType(newTypes, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
10343-
}
10344-
if (type.flags & TypeFlags.Index) {
10345-
return getIndexType(instantiateType((<IndexType>type).type, mapper));
10346-
}
10347-
if (type.flags & TypeFlags.IndexedAccess) {
10348-
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
10300+
if (!type || !mapper || mapper === identityMapper) {
10301+
return type;
10302+
}
10303+
if (instantiationDepth === 50) {
10304+
// We have reached 50 recursive type instantiations and there is a very high likelyhood we're dealing
10305+
// with a combination of infinite generic types that perpetually generate new type identities. We stop
10306+
// the recursion here by yielding the error type.
10307+
return errorType;
10308+
}
10309+
instantiationDepth++;
10310+
const result = instantiateTypeWorker(type, mapper);
10311+
instantiationDepth--;
10312+
return result;
10313+
}
10314+
10315+
function instantiateTypeWorker(type: Type, mapper: TypeMapper): Type {
10316+
const flags = type.flags;
10317+
if (flags & TypeFlags.TypeParameter) {
10318+
return mapper(type);
10319+
}
10320+
if (flags & TypeFlags.Object) {
10321+
const objectFlags = (<ObjectType>type).objectFlags;
10322+
if (objectFlags & ObjectFlags.Anonymous) {
10323+
// If the anonymous type originates in a declaration of a function, method, class, or
10324+
// interface, in an object type literal, or in an object literal expression, we may need
10325+
// to instantiate the type because it might reference a type parameter.
10326+
return type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations ?
10327+
getAnonymousTypeInstantiation(<AnonymousType>type, mapper) : type;
1034910328
}
10350-
if (type.flags & TypeFlags.Conditional) {
10351-
return instantiateWithDepthCheck(type, combineTypeMappers((<ConditionalType>type).mapper, mapper), getConditionalTypeInstantiation);
10329+
if (objectFlags & ObjectFlags.Mapped) {
10330+
return getAnonymousTypeInstantiation(<AnonymousType>type, mapper);
1035210331
}
10353-
if (type.flags & TypeFlags.Substitution) {
10354-
return instantiateType((<SubstitutionType>type).typeVariable, mapper);
10332+
if (objectFlags & ObjectFlags.Reference) {
10333+
const typeArguments = (<TypeReference>type).typeArguments;
10334+
const newTypeArguments = instantiateTypes(typeArguments, mapper);
10335+
return newTypeArguments !== typeArguments ? createTypeReference((<TypeReference>type).target, newTypeArguments) : type;
1035510336
}
10337+
return type;
10338+
}
10339+
if (flags & TypeFlags.Union && !(flags & TypeFlags.Primitive)) {
10340+
const types = (<UnionType>type).types;
10341+
const newTypes = instantiateTypes(types, mapper);
10342+
return newTypes !== types ? getUnionType(newTypes, UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
10343+
}
10344+
if (flags & TypeFlags.Intersection) {
10345+
const types = (<IntersectionType>type).types;
10346+
const newTypes = instantiateTypes(types, mapper);
10347+
return newTypes !== types ? getIntersectionType(newTypes, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
10348+
}
10349+
if (flags & TypeFlags.Index) {
10350+
return getIndexType(instantiateType((<IndexType>type).type, mapper));
10351+
}
10352+
if (flags & TypeFlags.IndexedAccess) {
10353+
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
10354+
}
10355+
if (flags & TypeFlags.Conditional) {
10356+
return getConditionalTypeInstantiation(<ConditionalType>type, combineTypeMappers((<ConditionalType>type).mapper, mapper));
10357+
}
10358+
if (flags & TypeFlags.Substitution) {
10359+
return instantiateType((<SubstitutionType>type).typeVariable, mapper);
1035610360
}
1035710361
return type;
1035810362
}

0 commit comments

Comments
 (0)