Merge pull request #4464 from Microsoft/cacheTypeInstantiations

Cache anonymous object type instantiations
This commit is contained in:
Anders Hejlsberg 2015-08-26 13:29:54 -07:00
commit bbaf322ab7
10 changed files with 187 additions and 0 deletions

View File

@ -4487,6 +4487,15 @@ namespace ts {
}
function instantiateAnonymousType(type: ObjectType, mapper: TypeMapper): ObjectType {
if (mapper.instantiations) {
let cachedType = mapper.instantiations[type.id];
if (cachedType) {
return cachedType;
}
}
else {
mapper.instantiations = [];
}
// Mark the anonymous type as instantiated such that our infinite instantiation detection logic can recognize it
let result = <ResolvedType>createObjectType(TypeFlags.Anonymous | TypeFlags.Instantiated, type.symbol);
result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol);
@ -4497,6 +4506,7 @@ namespace ts {
let numberIndexType = getIndexTypeOfType(type, IndexKind.Number);
if (stringIndexType) result.stringIndexType = instantiateType(stringIndexType, mapper);
if (numberIndexType) result.numberIndexType = instantiateType(numberIndexType, mapper);
mapper.instantiations[type.id] = result;
return result;
}

View File

@ -1953,6 +1953,7 @@ namespace ts {
/* @internal */
export interface TypeMapper {
(t: TypeParameter): Type;
instantiations?: Type[]; // Cache of instantiations created using this type mapper.
context?: InferenceContext; // The inference context this mapper was created from.
// Only inference mappers have this set (in createInferenceMapper).
// The identity mapper and regular instantiation mappers do not need it.

View File

@ -0,0 +1,13 @@
//// [typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts]
type TreeNode = {
name: string;
parent: TreeNode;
}
var nodes: TreeNode[];
nodes.map(n => n.name);
//// [typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.js]
var nodes;
nodes.map(function (n) { return n.name; });

View File

@ -0,0 +1,25 @@
=== tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts ===
type TreeNode = {
>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 0))
name: string;
>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 17))
parent: TreeNode;
>parent : Symbol(parent, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 1, 17))
>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 0))
}
var nodes: TreeNode[];
>nodes : Symbol(nodes, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 5, 3))
>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 0))
nodes.map(n => n.name);
>nodes.map : Symbol(Array.map, Decl(lib.d.ts, 1115, 92))
>nodes : Symbol(nodes, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 5, 3))
>map : Symbol(Array.map, Decl(lib.d.ts, 1115, 92))
>n : Symbol(n, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 6, 10))
>n.name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 17))
>n : Symbol(n, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 6, 10))
>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts, 0, 17))

View File

@ -0,0 +1,27 @@
=== tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral01.ts ===
type TreeNode = {
>TreeNode : { name: string; parent: TreeNode; }
name: string;
>name : string
parent: TreeNode;
>parent : { name: string; parent: TreeNode; }
>TreeNode : { name: string; parent: TreeNode; }
}
var nodes: TreeNode[];
>nodes : { name: string; parent: TreeNode; }[]
>TreeNode : { name: string; parent: TreeNode; }
nodes.map(n => n.name);
>nodes.map(n => n.name) : string[]
>nodes.map : <U>(callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any) => U[]
>nodes : { name: string; parent: TreeNode; }[]
>map : <U>(callbackfn: (value: { name: string; parent: TreeNode; }, index: number, array: { name: string; parent: TreeNode; }[]) => U, thisArg?: any) => U[]
>n => n.name : (n: { name: string; parent: TreeNode; }) => string
>n : { name: string; parent: TreeNode; }
>n.name : string
>n : { name: string; parent: TreeNode; }
>name : string

View File

@ -0,0 +1,18 @@
//// [typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts]
type TreeNode = {
name: string;
parent: TreeNode;
}
type TreeNodeMiddleman = {
name: string;
parent: TreeNode;
}
var nodes: TreeNodeMiddleman[];
nodes.map(n => n.name);
//// [typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.js]
var nodes;
nodes.map(function (n) { return n.name; });

View File

@ -0,0 +1,36 @@
=== tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts ===
type TreeNode = {
>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 0, 0))
name: string;
>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 0, 17))
parent: TreeNode;
>parent : Symbol(parent, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 1, 17))
>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 0, 0))
}
type TreeNodeMiddleman = {
>TreeNodeMiddleman : Symbol(TreeNodeMiddleman, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 3, 1))
name: string;
>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 5, 26))
parent: TreeNode;
>parent : Symbol(parent, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 6, 17))
>TreeNode : Symbol(TreeNode, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 0, 0))
}
var nodes: TreeNodeMiddleman[];
>nodes : Symbol(nodes, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 10, 3))
>TreeNodeMiddleman : Symbol(TreeNodeMiddleman, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 3, 1))
nodes.map(n => n.name);
>nodes.map : Symbol(Array.map, Decl(lib.d.ts, 1115, 92))
>nodes : Symbol(nodes, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 10, 3))
>map : Symbol(Array.map, Decl(lib.d.ts, 1115, 92))
>n : Symbol(n, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 11, 10))
>n.name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 5, 26))
>n : Symbol(n, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 11, 10))
>name : Symbol(name, Decl(typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts, 5, 26))

View File

@ -0,0 +1,38 @@
=== tests/cases/compiler/typeArgumentInferenceWithRecursivelyReferencedTypeAliasToTypeLiteral02.ts ===
type TreeNode = {
>TreeNode : { name: string; parent: TreeNode; }
name: string;
>name : string
parent: TreeNode;
>parent : { name: string; parent: TreeNode; }
>TreeNode : { name: string; parent: TreeNode; }
}
type TreeNodeMiddleman = {
>TreeNodeMiddleman : { name: string; parent: { name: string; parent: TreeNode; }; }
name: string;
>name : string
parent: TreeNode;
>parent : { name: string; parent: TreeNode; }
>TreeNode : { name: string; parent: TreeNode; }
}
var nodes: TreeNodeMiddleman[];
>nodes : { name: string; parent: { name: string; parent: TreeNode; }; }[]
>TreeNodeMiddleman : { name: string; parent: { name: string; parent: TreeNode; }; }
nodes.map(n => n.name);
>nodes.map(n => n.name) : string[]
>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[]
>nodes : { name: string; parent: { name: string; parent: TreeNode; }; }[]
>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[]
>n => n.name : (n: { name: string; parent: { name: string; parent: TreeNode; }; }) => string
>n : { name: string; parent: { name: string; parent: TreeNode; }; }
>n.name : string
>n : { name: string; parent: { name: string; parent: TreeNode; }; }
>name : string

View File

@ -0,0 +1,7 @@
type TreeNode = {
name: string;
parent: TreeNode;
}
var nodes: TreeNode[];
nodes.map(n => n.name);

View File

@ -0,0 +1,12 @@
type TreeNode = {
name: string;
parent: TreeNode;
}
type TreeNodeMiddleman = {
name: string;
parent: TreeNode;
}
var nodes: TreeNodeMiddleman[];
nodes.map(n => n.name);