Skip to content

Commit bbaf322

Browse files
committed
Merge pull request #4464 from Microsoft/cacheTypeInstantiations
Cache anonymous object type instantiations
2 parents d29c210 + 32f37bb commit bbaf322

10 files changed

+187
-0
lines changed

src/compiler/checker.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4487,6 +4487,15 @@ namespace ts {
44874487
}
44884488

44894489
function instantiateAnonymousType(type: ObjectType, mapper: TypeMapper): ObjectType {
4490+
if (mapper.instantiations) {
4491+
let cachedType = mapper.instantiations[type.id];
4492+
if (cachedType) {
4493+
return cachedType;
4494+
}
4495+
}
4496+
else {
4497+
mapper.instantiations = [];
4498+
}
44904499
// Mark the anonymous type as instantiated such that our infinite instantiation detection logic can recognize it
44914500
let result = <ResolvedType>createObjectType(TypeFlags.Anonymous | TypeFlags.Instantiated, type.symbol);
44924501
result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol);
@@ -4497,6 +4506,7 @@ namespace ts {
44974506
let numberIndexType = getIndexTypeOfType(type, IndexKind.Number);
44984507
if (stringIndexType) result.stringIndexType = instantiateType(stringIndexType, mapper);
44994508
if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper);
4509+
mapper.instantiations[type.id] = result;
45004510
return result;
45014511
}
45024512

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1953,6 +1953,7 @@ namespace ts {
19531953
/* @internal */
19541954
export interface TypeMapper {
19551955
(t: TypeParameter): Type;
1956+
instantiations?: Type[]; // Cache of instantiations created using this type mapper.
19561957
context?: InferenceContext; // The inference context this mapper was created from.
19571958
// Only inference mappers have this set (in createInferenceMapper).
19581959
// The identity mapper and regular instantiation mappers do not need it.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//// [typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts]
2+
type TreeNode = {
3+
name: string;
4+
parent: TreeNode;
5+
}
6+
7+
var nodes: TreeNode[];
8+
nodes.map(n => n.name);
9+
10+
11+
//// [typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.js]
12+
var nodes;
13+
nodes.map(function (n) { return n.name; });
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
=== tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts ===
2+
type TreeNode = {
3+
>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 0))
4+
5+
name: string;
6+
>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 17))
7+
8+
parent: TreeNode;
9+
>parent : Symbol(parent, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 1, 17))
10+
>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 0))
11+
}
12+
13+
var nodes: TreeNode[];
14+
>nodes : Symbol(nodes, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 5, 3))
15+
>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 0))
16+
17+
nodes.map(n => n.name);
18+
>nodes.map : Symbol(Array.map, Decl(lib.d.ts, 1115, 92))
19+
>nodes : Symbol(nodes, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 5, 3))
20+
>map : Symbol(Array.map, Decl(lib.d.ts, 1115, 92))
21+
>n : Symbol(n, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 6, 10))
22+
>n.name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 17))
23+
>n : Symbol(n, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 6, 10))
24+
>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 17))
25+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=== tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts ===
2+
type TreeNode = {
3+
>TreeNode : { name: string; parent: TreeNode; }
4+
5+
name: string;
6+
>name : string
7+
8+
parent: TreeNode;
9+
>parent : { name: string; parent: TreeNode; }
10+
>TreeNode : { name: string; parent: TreeNode; }
11+
}
12+
13+
var nodes: TreeNode[];
14+
>nodes : { name: string; parent: TreeNode; }[]
15+
>TreeNode : { name: string; parent: TreeNode; }
16+
17+
nodes.map(n => n.name);
18+
>nodes.map(n => n.name) : string[]
19+
>nodes.map : <U>(callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any) => U[]
20+
>nodes : { name: string; parent: TreeNode; }[]
21+
>map : <U>(callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any) => U[]
22+
>n => n.name : (n: { name: string; parent: TreeNode; }) => string
23+
>n : { name: string; parent: TreeNode; }
24+
>n.name : string
25+
>n : { name: string; parent: TreeNode; }
26+
>name : string
27+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//// [typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts]
2+
type TreeNode = {
3+
name: string;
4+
parent: TreeNode;
5+
}
6+
7+
type TreeNodeMiddleman = {
8+
name: string;
9+
parent: TreeNode;
10+
}
11+
12+
var nodes: TreeNodeMiddleman[];
13+
nodes.map(n => n.name);
14+
15+
16+
//// [typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.js]
17+
var nodes;
18+
nodes.map(function (n) { return n.name; });
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts ===
2+
type TreeNode = {
3+
>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 0, 0))
4+
5+
name: string;
6+
>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 0, 17))
7+
8+
parent: TreeNode;
9+
>parent : Symbol(parent, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 1, 17))
10+
>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 0, 0))
11+
}
12+
13+
type TreeNodeMiddleman = {
14+
>TreeNodeMiddleman : Symbol(TreeNodeMiddleman, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 3, 1))
15+
16+
name: string;
17+
>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 5, 26))
18+
19+
parent: TreeNode;
20+
>parent : Symbol(parent, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 6, 17))
21+
>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 0, 0))
22+
}
23+
24+
var nodes: TreeNodeMiddleman[];
25+
>nodes : Symbol(nodes, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 10, 3))
26+
>TreeNodeMiddleman : Symbol(TreeNodeMiddleman, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 3, 1))
27+
28+
nodes.map(n => n.name);
29+
>nodes.map : Symbol(Array.map, Decl(lib.d.ts, 1115, 92))
30+
>nodes : Symbol(nodes, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 10, 3))
31+
>map : Symbol(Array.map, Decl(lib.d.ts, 1115, 92))
32+
>n : Symbol(n, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 11, 10))
33+
>n.name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 5, 26))
34+
>n : Symbol(n, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 11, 10))
35+
>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 5, 26))
36+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
=== tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts ===
2+
type TreeNode = {
3+
>TreeNode : { name: string; parent: TreeNode; }
4+
5+
name: string;
6+
>name : string
7+
8+
parent: TreeNode;
9+
>parent : { name: string; parent: TreeNode; }
10+
>TreeNode : { name: string; parent: TreeNode; }
11+
}
12+
13+
type TreeNodeMiddleman = {
14+
>TreeNodeMiddleman : { name: string; parent: { name: string; parent: TreeNode; }; }
15+
16+
name: string;
17+
>name : string
18+
19+
parent: TreeNode;
20+
>parent : { name: string; parent: TreeNode; }
21+
>TreeNode : { name: string; parent: TreeNode; }
22+
}
23+
24+
var nodes: TreeNodeMiddleman[];
25+
>nodes : { name: string; parent: { name: string; parent: TreeNode; }; }[]
26+
>TreeNodeMiddleman : { name: string; parent: { name: string; parent: TreeNode; }; }
27+
28+
nodes.map(n => n.name);
29+
>nodes.map(n => n.name) : string[]
30+
>nodes.map : <U>(callbackfn: (value: { name: string; parent: { name: string; parent: TreeNode; }; }, index: number, array: { name: string; parent: { name: string; parent: TreeNode; }; }[]) => U, thisArg?: any) => U[]
31+
>nodes : { name: string; parent: { name: string; parent: TreeNode; }; }[]
32+
>map : <U>(callbackfn: (value: { name: string; parent: { name: string; parent: TreeNode; }; }, index: number, array: { name: string; parent: { name: string; parent: TreeNode; }; }[]) => U, thisArg?: any) => U[]
33+
>n => n.name : (n: { name: string; parent: { name: string; parent: TreeNode; }; }) => string
34+
>n : { name: string; parent: { name: string; parent: TreeNode; }; }
35+
>n.name : string
36+
>n : { name: string; parent: { name: string; parent: TreeNode; }; }
37+
>name : string
38+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type TreeNode = {
2+
name: string;
3+
parent: TreeNode;
4+
}
5+
6+
var nodes: TreeNode[];
7+
nodes.map(n => n.name);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
type TreeNode = {
2+
name: string;
3+
parent: TreeNode;
4+
}
5+
6+
type TreeNodeMiddleman = {
7+
name: string;
8+
parent: TreeNode;
9+
}
10+
11+
var nodes: TreeNodeMiddleman[];
12+
nodes.map(n => n.name);

0 commit comments

Comments
 (0)