Skip to content

Commit 6be98fa

Browse files
authored
Merge pull request microsoft#21470 from Microsoft/optimizeInstantiation
Skip unnecessary type and symbol instantiations
2 parents 12ebbbc + e3e8496 commit 6be98fa

1 file changed

Lines changed: 26 additions & 8 deletions

File tree

src/compiler/checker.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8330,11 +8330,18 @@ namespace ts {
83308330

83318331
function instantiateList<T>(items: T[], mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T[] {
83328332
if (items && items.length) {
8333-
const result: T[] = [];
8334-
for (const v of items) {
8335-
result.push(instantiator(v, mapper));
8333+
for (let i = 0; i < items.length; i++) {
8334+
const item = items[i];
8335+
const mapped = instantiator(item, mapper);
8336+
if (item !== mapped) {
8337+
const result = i === 0 ? [] : items.slice(0, i);
8338+
result.push(mapped);
8339+
for (i++; i < items.length; i++) {
8340+
result.push(instantiator(items[i], mapper));
8341+
}
8342+
return result;
8343+
}
83368344
}
8337-
return result;
83388345
}
83398346
return items;
83408347
}
@@ -8456,8 +8463,13 @@ namespace ts {
84568463
}
84578464

84588465
function instantiateSymbol(symbol: Symbol, mapper: TypeMapper): Symbol {
8466+
const links = getSymbolLinks(symbol);
8467+
if (links.type && !maybeTypeOfKind(links.type, TypeFlags.Object | TypeFlags.TypeVariable | TypeFlags.Index)) {
8468+
// If the type of the symbol is already resolved, and if that type could not possibly
8469+
// be affected by instantiation, simply return the symbol itself.
8470+
return symbol;
8471+
}
84598472
if (getCheckFlags(symbol) & CheckFlags.Instantiated) {
8460-
const links = getSymbolLinks(symbol);
84618473
// If symbol being instantiated is itself a instantiation, fetch the original target and combine the
84628474
// type mappers. This ensures that original type identities are properly preserved and that aliases
84638475
// always reference a non-aliases.
@@ -8600,14 +8612,20 @@ namespace ts {
86008612
return getAnonymousTypeInstantiation(<MappedType>type, mapper);
86018613
}
86028614
if ((<ObjectType>type).objectFlags & ObjectFlags.Reference) {
8603-
return createTypeReference((<TypeReference>type).target, instantiateTypes((<TypeReference>type).typeArguments, mapper));
8615+
const typeArguments = (<TypeReference>type).typeArguments;
8616+
const newTypeArguments = instantiateTypes(typeArguments, mapper);
8617+
return newTypeArguments !== typeArguments ? createTypeReference((<TypeReference>type).target, newTypeArguments) : type;
86048618
}
86058619
}
86068620
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
8607-
return getUnionType(instantiateTypes((<UnionType>type).types, mapper), UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
8621+
const types = (<UnionType>type).types;
8622+
const newTypes = instantiateTypes(types, mapper);
8623+
return newTypes !== types ? getUnionType(newTypes, UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
86088624
}
86098625
if (type.flags & TypeFlags.Intersection) {
8610-
return getIntersectionType(instantiateTypes((<IntersectionType>type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
8626+
const types = (<IntersectionType>type).types;
8627+
const newTypes = instantiateTypes(types, mapper);
8628+
return newTypes !== types ? getIntersectionType(newTypes, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)) : type;
86118629
}
86128630
if (type.flags & TypeFlags.Index) {
86138631
return getIndexType(instantiateType((<IndexType>type).type, mapper));

0 commit comments

Comments
 (0)