Skip to content

Commit 6acb418

Browse files
author
Andy Hanson
committed
Minor cleanup to symbolWalker
1 parent 0ac8406 commit 6acb418

File tree

2 files changed

+43
-49
lines changed

2 files changed

+43
-49
lines changed

src/compiler/core.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -994,11 +994,6 @@ namespace ts {
994994

995995
/**
996996
* Gets the owned, enumerable property keys of a map-like.
997-
*
998-
* NOTE: This is intended for use with MapLike<T> objects. For Map<T> objects, use
999-
* Object.keys instead as it offers better performance.
1000-
*
1001-
* @param map A map-like.
1002997
*/
1003998
export function getOwnKeys<T>(map: MapLike<T>): string[] {
1004999
const keys: string[] = [];
@@ -1011,6 +1006,19 @@ namespace ts {
10111006
return keys;
10121007
}
10131008

1009+
export function getOwnValues<T>(sparseArray: T[]): T[];
1010+
export function getOwnValues<T>(map: MapLike<T>): T[];
1011+
export function getOwnValues<T>(map: MapLike<T>): T[] {
1012+
const values: T[] = [];
1013+
for (const key in map) {
1014+
if (hasOwnProperty.call(map, key)) {
1015+
values.push(map[key]);
1016+
}
1017+
}
1018+
1019+
return values;
1020+
}
1021+
10141022
/** Shims `Array.from`. */
10151023
export function arrayFrom<T, U>(iterator: Iterator<T>, map: (t: T) => U): U[];
10161024
export function arrayFrom<T>(iterator: Iterator<T>): T[];

src/compiler/symbolWalker.ts

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,29 @@ namespace ts {
1414
return getSymbolWalker;
1515

1616
function getSymbolWalker(accept: (symbol: Symbol) => boolean = () => true): SymbolWalker {
17-
const visitedTypes = createMap<Type>(); // Key is id as string
18-
const visitedSymbols = createMap<Symbol>(); // Key is id as string
17+
const visitedTypes: Type[] = []; // Sparse array from id to type
18+
const visitedSymbols: Symbol[] = []; // Sparse array from id to symbol
1919

2020
return {
2121
walkType: type => {
22-
visitedTypes.clear();
23-
visitedSymbols.clear();
24-
visitType(type);
25-
return { visitedTypes: arrayFrom(visitedTypes.values()), visitedSymbols: arrayFrom(visitedSymbols.values()) };
22+
try {
23+
visitType(type);
24+
return { visitedTypes: getOwnValues(visitedTypes), visitedSymbols: getOwnValues(visitedSymbols) };
25+
}
26+
finally {
27+
clear(visitedTypes);
28+
clear(visitedSymbols);
29+
}
2630
},
2731
walkSymbol: symbol => {
28-
visitedTypes.clear();
29-
visitedSymbols.clear();
30-
visitSymbol(symbol);
31-
return { visitedTypes: arrayFrom(visitedTypes.values()), visitedSymbols: arrayFrom(visitedSymbols.values()) };
32+
try {
33+
visitSymbol(symbol);
34+
return { visitedTypes: getOwnValues(visitedTypes), visitedSymbols: getOwnValues(visitedSymbols) };
35+
}
36+
finally {
37+
clear(visitedTypes);
38+
clear(visitedSymbols);
39+
}
3240
},
3341
};
3442

@@ -37,11 +45,10 @@ namespace ts {
3745
return;
3846
}
3947

40-
const typeIdString = type.id.toString();
41-
if (visitedTypes.has(typeIdString)) {
48+
if (visitedTypes[type.id]) {
4249
return;
4350
}
44-
visitedTypes.set(typeIdString, type);
51+
visitedTypes[type.id] = type;
4552

4653
// Reuse visitSymbol to visit the type's symbol,
4754
// but be sure to bail on recuring into the type if accept declines the symbol.
@@ -66,43 +73,22 @@ namespace ts {
6673
}
6774
}
6875
if (type.flags & TypeFlags.TypeParameter) {
69-
visitTypeParameter(type as TypeParameter);
76+
visitType(getConstraintFromTypeParameter(type as TypeParameter));
7077
}
7178
if (type.flags & TypeFlags.UnionOrIntersection) {
72-
visitUnionOrIntersectionType(type as UnionOrIntersectionType);
79+
forEach((type as UnionOrIntersectionType).types, visitType);
7380
}
7481
if (type.flags & TypeFlags.Index) {
75-
visitIndexType(type as IndexType);
82+
visitType((type as IndexType).type);
7683
}
7784
if (type.flags & TypeFlags.IndexedAccess) {
7885
visitIndexedAccessType(type as IndexedAccessType);
7986
}
8087
}
8188

82-
function visitTypeList(types: Type[]): void {
83-
if (!types) {
84-
return;
85-
}
86-
for (let i = 0; i < types.length; i++) {
87-
visitType(types[i]);
88-
}
89-
}
90-
9189
function visitTypeReference(type: TypeReference): void {
9290
visitType(type.target);
93-
visitTypeList(type.typeArguments);
94-
}
95-
96-
function visitTypeParameter(type: TypeParameter): void {
97-
visitType(getConstraintFromTypeParameter(type));
98-
}
99-
100-
function visitUnionOrIntersectionType(type: UnionOrIntersectionType): void {
101-
visitTypeList(type.types);
102-
}
103-
104-
function visitIndexType(type: IndexType): void {
105-
visitType(type.type);
91+
forEach(type.typeArguments, visitType);
10692
}
10793

10894
function visitIndexedAccessType(type: IndexedAccessType): void {
@@ -122,7 +108,7 @@ namespace ts {
122108
if (signature.typePredicate) {
123109
visitType(signature.typePredicate.type);
124110
}
125-
visitTypeList(signature.typeParameters);
111+
forEach(signature.typeParameters, visitType);
126112

127113
for (const parameter of signature.parameters){
128114
visitSymbol(parameter);
@@ -133,8 +119,8 @@ namespace ts {
133119

134120
function visitInterfaceType(interfaceT: InterfaceType): void {
135121
visitObjectType(interfaceT);
136-
visitTypeList(interfaceT.typeParameters);
137-
visitTypeList(getBaseTypes(interfaceT));
122+
forEach(interfaceT.typeParameters, visitType);
123+
forEach(getBaseTypes(interfaceT), visitType);
138124
visitType(interfaceT.thisType);
139125
}
140126

@@ -161,11 +147,11 @@ namespace ts {
161147
if (!symbol) {
162148
return;
163149
}
164-
const symbolIdString = getSymbolId(symbol).toString();
165-
if (visitedSymbols.has(symbolIdString)) {
150+
const symbolId = getSymbolId(symbol);
151+
if (visitedSymbols[symbolId]) {
166152
return;
167153
}
168-
visitedSymbols.set(symbolIdString, symbol);
154+
visitedSymbols[symbolId] = symbol;
169155
if (!accept(symbol)) {
170156
return true;
171157
}

0 commit comments

Comments
 (0)