From 3bfd8d4e7e4eb596d7b709abfa1670ec5a514fb6 Mon Sep 17 00:00:00 2001 From: charburgx Date: Mon, 17 Oct 2022 12:19:05 -0500 Subject: [PATCH] refactor: encapsulate tree localization --- packages/api/src/index.ts | 2 +- packages/api/src/localizedTree.ts | 53 +++++++++++-------- .../src/state/stateManager.ts | 2 - .../src/view/typeTreeView.ts | 15 +++--- 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index 39d4604..429582b 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -3,4 +3,4 @@ export { getSymbolType, multilineTypeToString, pseudoBigIntToString, getNodeType export { recursivelyExpandType } from "./merge" export { generateTypeTree, getTypeInfoChildren } from "./tree" export { TypeInfo, SymbolInfo, SignatureInfo, TypeId, IndexInfo, TypeInfoKind, TypeParameterInfo, SourceFileLocation } from "./types" -export { localizeTypeInfo, LocalizedTypeInfo, TypeInfoMap, generateTypeInfoMap, getLocalizedTypeInfoChildren } from "./localizedTree" \ No newline at end of file +export { TypeInfoLocalizer, LocalizedTypeInfo, TypeInfoMap } from "./localizedTree" \ No newline at end of file diff --git a/packages/api/src/localizedTree.ts b/packages/api/src/localizedTree.ts index 513c05d..6d3f8b5 100644 --- a/packages/api/src/localizedTree.ts +++ b/packages/api/src/localizedTree.ts @@ -6,22 +6,41 @@ import { getTypeInfoChildren } from "./tree" import { getEmptyTypeId, isEmpty, isNonEmpty, pseudoBigIntToString, wrapSafe } from "./util" import { unwatchFile } from "fs" -export function localizeTypeInfo(info: TypeInfo, typeInfoMap: TypeInfoMap): LocalizedTypeInfo { - return _localizeTypeInfo(info, { typeInfoMap }) -} +export class TypeInfoLocalizer { + typeInfoMap: TypeInfoMap + + constructor(private typeInfo: TypeInfo) { + this.typeInfoMap = generateTypeInfoMap(typeInfo) + } -export function getLocalizedTypeInfoChildren(info: LocalizedTypeInfo, typeInfoMap: TypeInfoMap): LocalizedTypeInfo[] { - return info.children?.map( - ({info, localizedInfo, opts}) => { - assert(info || localizedInfo, "Either info or localized info must be provided") + localize(info: TypeInfo) { + return _localizeTypeInfo(info, { typeInfoMap: this.typeInfoMap }) + } - if(localizedInfo) { - return localizedInfo + localizeChildren(info: LocalizedTypeInfo): LocalizedTypeInfo[] { + return info.children?.map( + ({info, localizedInfo, opts}) => { + assert(info || localizedInfo, "Either info or localized info must be provided") + + if(localizedInfo) { + return localizedInfo + } + + return _localizeTypeInfo(info!, { typeInfoMap: this.typeInfoMap }, opts) } + ) ?? [] + } +} - return _localizeTypeInfo(info!, { typeInfoMap }, opts) - } - ) ?? [] + +function generateTypeInfoMap(tree: TypeInfo, cache?: TypeInfoMap): TypeInfoMap { + cache ??= new Map() + + if(tree.kind === 'reference') { return cache } + cache.set(tree.id, tree) + getTypeInfoChildren(tree).forEach(c => generateTypeInfoMap(c, cache)) + + return cache } type TypePurpose = 'return'|'index_type'|'index_value_type'|'conditional_check'|'conditional_extends'|'conditional_true'|'conditional_false'|'keyof'|'indexed_access_index'|'indexed_access_base'|'parameter_default'|'parameter_base_constraint'|'class_constructor'|'class_base_type'|'class_implementations'|'object_class'|'type_parameter_list'|'type_argument_list'|'parameter_value' @@ -445,16 +464,6 @@ function localizePurpose(purpose: TypePurpose): string { return nameByPurpose[purpose] } -export function generateTypeInfoMap(tree: TypeInfo, cache?: TypeInfoMap): TypeInfoMap { - cache ??= new Map() - - if(tree.kind === 'reference') { return cache } - cache.set(tree.id, tree) - getTypeInfoChildren(tree).forEach(c => generateTypeInfoMap(c, cache)) - - return cache -} - function getTypeLocations(info: TypeInfo): SourceFileLocation[]|undefined { const baseLocations = wrapSafe(getLocations)(info.typeSymbolMeta ?? info.aliasSymbolMeta ?? info.symbolMeta) diff --git a/packages/typescript-explorer/src/state/stateManager.ts b/packages/typescript-explorer/src/state/stateManager.ts index c1a9298..b4ae6f0 100644 --- a/packages/typescript-explorer/src/state/stateManager.ts +++ b/packages/typescript-explorer/src/state/stateManager.ts @@ -18,8 +18,6 @@ export class StateManager { return } - console.log("change selection", e) - getQuickInfoAtPosition(e.textEditor.document.fileName, e.selections[0].start) .then((body) => { const { __displayTree } = body ?? {} diff --git a/packages/typescript-explorer/src/view/typeTreeView.ts b/packages/typescript-explorer/src/view/typeTreeView.ts index 86cb14a..965dba4 100644 --- a/packages/typescript-explorer/src/view/typeTreeView.ts +++ b/packages/typescript-explorer/src/view/typeTreeView.ts @@ -1,4 +1,4 @@ -import { TypeInfo, TypeId, getTypeInfoChildren, SymbolInfo, SignatureInfo, IndexInfo, pseudoBigIntToString, LocalizedTypeInfo, localizeTypeInfo, TypeInfoMap, generateTypeInfoMap, getLocalizedTypeInfoChildren, SourceFileLocation } from '@ts-expand-type/api' +import { TypeInfo, TypeId, getTypeInfoChildren, SymbolInfo, SignatureInfo, IndexInfo, pseudoBigIntToString, LocalizedTypeInfo, TypeInfoMap, SourceFileLocation, TypeInfoLocalizer } from '@ts-expand-type/api' import assert = require('assert'); import * as vscode from 'vscode' import { StateManager } from '../state/stateManager'; @@ -9,14 +9,15 @@ const { None: NoChildren, Expanded, Collapsed } = vscode.TreeItemCollapsibleStat export class TypeTreeProvider implements vscode.TreeDataProvider { constructor(private stateManager: StateManager) { } - private typeInfoMap: TypeInfoMap = new Map() + // private typeInfoMap: TypeInfoMap = new Map() + private typeInfoLocalizer: TypeInfoLocalizer|undefined private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter() readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event refresh(): void { - this.typeInfoMap.clear() - this._onDidChangeTreeData.fire(); + this.typeInfoLocalizer = undefined + this._onDidChangeTreeData.fire() } getTreeItem(element: TypeTreeItem) { @@ -28,12 +29,12 @@ export class TypeTreeProvider implements vscode.TreeDataProvider { const typeInfo = this.stateManager.getTypeTree() if(!typeInfo) { return [] } - this.typeInfoMap = generateTypeInfoMap(typeInfo) - const localizedTypeInfo = localizeTypeInfo(typeInfo, this.typeInfoMap) + this.typeInfoLocalizer = new TypeInfoLocalizer(typeInfo) + const localizedTypeInfo = this.typeInfoLocalizer.localize(typeInfo) return [this.createTypeNode(localizedTypeInfo, /* root */ undefined)] } else { - return getLocalizedTypeInfoChildren(element.typeInfo, this.typeInfoMap).map(info => this.createTypeNode(info, element)) + return this.typeInfoLocalizer!.localizeChildren(element.typeInfo).map(info => this.createTypeNode(info, element)) } }