Skip to content

Commit 3eaadc6

Browse files
committed
in isRelatedTo, skip repeated comparisons of generic types
1 parent eef7d8b commit 3eaadc6

File tree

1 file changed

+30
-3
lines changed

1 file changed

+30
-3
lines changed

src/compiler/checker.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5364,7 +5364,7 @@ namespace ts {
53645364
return <InterfaceTypeWithDeclaredMembers>type;
53655365
}
53665366

5367-
function getTypeWithThisArgument(type: Type, thisArgument?: Type): Type {
5367+
function getTypeWithThisArgument(type: Type, thisArgument: Type): Type {
53685368
if (getObjectFlags(type) & ObjectFlags.Reference) {
53695369
const target = (<TypeReference>type).target;
53705370
const typeArguments = (<TypeReference>type).typeArguments;
@@ -8830,6 +8830,8 @@ namespace ts {
88308830
let sourceStack: Type[];
88318831
let targetStack: Type[];
88328832
let maybeCount = 0;
8833+
let maybeReferenceKeys: string[];
8834+
let maybeReferenceCount = 0;
88338835
let depth = 0;
88348836
let expandingFlags = 0;
88358837
let overflow = false;
@@ -9197,6 +9199,30 @@ namespace ts {
91979199
if (overflow) {
91989200
return Ternary.False;
91999201
}
9202+
9203+
if (getObjectFlags(source) & ObjectFlags.Reference &&
9204+
getObjectFlags(target) & ObjectFlags.Reference &&
9205+
(source as TypeReference).typeArguments && (source as TypeReference).typeArguments.length > 0 &&
9206+
arrayIsEqualTo((source as TypeReference).typeArguments, (target as TypeReference).typeArguments, (a1, m1) => a1 === m1)) {
9207+
// Same type arguments, let's see if we've already seen this pair before
9208+
// this is a copy of the normal code! It can probably be merged somehow.
9209+
const src = (source as TypeReference).target;
9210+
const trg = (target as TypeReference).target;
9211+
const id = relation !== identityRelation || src.id < trg.id ? src.id + "," + trg.id : trg.id + "," + src.id;
9212+
if (!maybeReferenceKeys) {
9213+
maybeReferenceKeys = [];
9214+
}
9215+
else {
9216+
for (let i = 0; i < maybeReferenceCount; i++) {
9217+
if (id === maybeReferenceKeys[i]) {
9218+
return Ternary.Maybe;
9219+
}
9220+
}
9221+
}
9222+
maybeReferenceKeys[maybeReferenceCount] = id;
9223+
maybeReferenceCount++;
9224+
}
9225+
92009226
const id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id;
92019227
const related = relation.get(id);
92029228
if (related !== undefined) {
@@ -9209,6 +9235,7 @@ namespace ts {
92099235
return related === RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False;
92109236
}
92119237
}
9238+
92129239
if (!maybeKeys) {
92139240
maybeKeys = [];
92149241
sourceStack = [];
@@ -21258,7 +21285,7 @@ namespace ts {
2125821285
checkExportsOnMergedDeclarations(node);
2125921286
const symbol = getSymbolOfNode(node);
2126021287
const type = <InterfaceType>getDeclaredTypeOfSymbol(symbol);
21261-
const typeWithThis = getTypeWithThisArgument(type);
21288+
const typeWithThis = getTypeWithThisArgument(type, type.thisType);
2126221289
const staticType = <ObjectType>getTypeOfSymbol(symbol);
2126321290
checkTypeParameterListsIdentical(symbol);
2126421291
checkClassForDuplicateDeclarations(node);
@@ -21506,7 +21533,7 @@ namespace ts {
2150621533
const firstInterfaceDecl = getDeclarationOfKind<InterfaceDeclaration>(symbol, SyntaxKind.InterfaceDeclaration);
2150721534
if (node === firstInterfaceDecl) {
2150821535
const type = <InterfaceType>getDeclaredTypeOfSymbol(symbol);
21509-
const typeWithThis = getTypeWithThisArgument(type);
21536+
const typeWithThis = getTypeWithThisArgument(type, type.thisType);
2151021537
// run subsequent checks only if first set succeeded
2151121538
if (checkInheritedPropertiesAreIdentical(type, node.name)) {
2151221539
for (const baseType of getBaseTypes(type)) {

0 commit comments

Comments
 (0)