diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts index 784ee840363..fda1febfb04 100644 --- a/src/compiler/symbolWalker.ts +++ b/src/compiler/symbolWalker.ts @@ -13,23 +13,23 @@ namespace ts { return getSymbolWalker; function getSymbolWalker(accept: (symbol: Symbol) => boolean = () => true): SymbolWalker { - let visitedTypes: Type[] = []; - let visitedSymbols: Symbol[] = []; + let visitedTypes = createMap(); // Key is id as string + let visitedSymbols = createMap(); // Key is id as string return { walkType: type => { - visitedTypes = []; - visitedSymbols = []; + visitedTypes.clear(); + visitedSymbols.clear(); visitType(type); - return { visitedTypes, visitedSymbols }; + return { visitedTypes: arrayFrom(visitedTypes.values()), visitedSymbols: arrayFrom(visitedSymbols.values()) }; }, walkSymbol: symbol => { - visitedTypes = []; - visitedSymbols = []; + visitedTypes.clear(); + visitedSymbols.clear(); visitSymbol(symbol); - return { visitedTypes, visitedSymbols }; + return { visitedTypes: arrayFrom(visitedTypes.values()), visitedSymbols: arrayFrom(visitedSymbols.values()) }; }, }; @@ -37,10 +37,12 @@ namespace ts { if (!type) { return; } - if (contains(visitedTypes, type)) { + + const typeIdString = type.id.toString(); + if (visitedTypes.has(typeIdString)) { return; } - visitedTypes.push(type); + visitedTypes.set(typeIdString, type); // Reuse visitSymbol to visit the type's symbol, // but be sure to bail on recuring into the type if accept declines the symbol. @@ -134,10 +136,11 @@ namespace ts { if (!symbol) { return; } - if (contains(visitedSymbols, symbol)) { + const symbolIdString = getSymbolId(symbol).toString(); + if (visitedSymbols.has(symbolIdString)) { return; } - visitedSymbols.push(symbol); + visitedSymbols.set(symbolIdString, symbol); if (!accept(symbol)) { return true; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 34ae124d636..2182f02afe0 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2673,8 +2673,10 @@ namespace ts { /* @internal */ export interface SymbolWalker { - walkType(root: Type) : { visitedTypes: Type[], visitedSymbols: Symbol[] }; - walkSymbol(root: Symbol) : { visitedTypes: Type[], visitedSymbols: Symbol[] }; + /** Note: Return values are not ordered. */ + walkType(root: Type) : { visitedTypes: ReadonlyArray, visitedSymbols: ReadonlyArray }; + /** Note: Return values are not ordered. */ + walkSymbol(root: Symbol) : { visitedTypes: ReadonlyArray, visitedSymbols: ReadonlyArray }; } export interface SymbolDisplayBuilder {