diff --git a/README.md b/README.md index 01476fc07..264af03d6 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,6 @@ The following settings are supported: * `java.eclipse.downloadSources`: Enable/disable download of Maven source artifacts for Eclipse projects. * `java.references.includeDecompiledSources`: Include the decompiled sources when finding references. Defaults to true. * `java.project.sourcePaths`: Relative paths to the workspace where stores the source files. `Only` effective in the `WORKSPACE` scope. The setting will `NOT` affect Maven or Gradle project. -* `java.typeHierarchy.lazyLoad`: Enable/disable lazy loading the content in type hierarchy. Lazy loading could save a lot of loading time but every type should be expanded manually to load its content. * `java.codeGeneration.insertionLocation`: Specifies the insertion location of the code generated by source actions. Defaults to `afterCursor`. - `afterCursor`: Insert the generated code after the member where the cursor is located. - `beforeCursor`: Insert the generated code before the member where the cursor is located. diff --git a/package.json b/package.json index 3651eecd5..f7bfec19c 100644 --- a/package.json +++ b/package.json @@ -1604,13 +1604,6 @@ "scope": "window", "order": 65 }, - "java.typeHierarchy.lazyLoad": { - "type": "boolean", - "default": false, - "description": "Enable/disable lazy loading the content in type hierarchy. Lazy loading could save a lot of loading time but every type should be expanded manually to load its content.", - "scope": "window", - "order": 70 - }, "java.inlayHints.parameterNames.enabled": { "type": "string", "enum": [ @@ -1839,37 +1832,6 @@ "title": "%java.action.navigateToSuperImplementation%", "category": "Java" }, - { - "command": "java.action.showTypeHierarchy", - "title": "%java.action.showTypeHierarchy%", - "category": "Java" - }, - { - "command": "java.action.showClassHierarchy", - "title": "%java.action.showClassHierarchy%", - "icon": "$(type-hierarchy)", - "enablement": "typeHierarchyDirection != both && typeHierarchySymbolKind != 10", - "category": "Java" - }, - { - "command": "java.action.showSupertypeHierarchy", - "title": "%java.action.showSupertypeHierarchy%", - "icon": "$(type-hierarchy-super)", - "enablement": "typeHierarchyDirection != parents", - "category": "Java" - }, - { - "command": "java.action.showSubtypeHierarchy", - "title": "%java.action.showSubtypeHierarchy%", - "icon": "$(type-hierarchy-sub)", - "enablement": "typeHierarchyDirection != children", - "category": "Java" - }, - { - "command": "java.action.changeBaseType", - "title": "%java.action.changeBaseType%", - "category": "Java" - }, { "command": "java.project.createModuleInfo.command", "title": "%java.project.createModuleInfo.command%", @@ -2019,11 +1981,6 @@ "when": "javaLSReady && editorTextFocus && editorLangId == java", "group": "navigation@90" }, - { - "command": "java.action.showTypeHierarchy", - "when": "javaLSReady && editorTextFocus && editorLangId == java", - "group": "0_navigation@3" - }, { "command": "java.action.copyFullyQualifiedName", "when": "javaLSReady && editorTextFocus && editorLangId == java", @@ -2063,26 +2020,6 @@ "command": "java.project.listSourcePaths.command", "when": "javaLSReady" }, - { - "command": "java.action.showTypeHierarchy", - "when": "javaLSReady && editorIsOpen" - }, - { - "command": "java.action.showClassHierarchy", - "when": "false" - }, - { - "command": "java.action.showSubtypeHierarchy", - "when": "false" - }, - { - "command": "java.action.showSupertypeHierarchy", - "when": "false" - }, - { - "command": "java.action.changeBaseType", - "when": "false" - }, { "command": "java.project.updateSourceAttachment.command", "when": "false" @@ -2123,30 +2060,6 @@ "command": "java.dashboard.dumpState", "when": "false" } - ], - "view/title": [ - { - "command": "java.action.showClassHierarchy", - "group": "navigation@-1", - "when": "view == references-view.tree && reference-list.hasResult && reference-list.source == javaTypeHierarchy && typeHierarchySymbolKind != 10" - }, - { - "command": "java.action.showSupertypeHierarchy", - "group": "navigation@0", - "when": "view == references-view.tree && reference-list.hasResult && reference-list.source == javaTypeHierarchy" - }, - { - "command": "java.action.showSubtypeHierarchy", - "group": "navigation@1", - "when": "view == references-view.tree && reference-list.hasResult && reference-list.source == javaTypeHierarchy" - } - ], - "view/item/context": [ - { - "command": "java.action.changeBaseType", - "group": "1", - "when": "view == references-view.tree && reference-list.hasResult && reference-list.source == javaTypeHierarchy && viewItem != 'false'" - } ] } }, diff --git a/package.nls.json b/package.nls.json index c695cfe3e..8709bc914 100644 --- a/package.nls.json +++ b/package.nls.json @@ -17,11 +17,6 @@ "java.project.listSourcePaths": "List All Java Source Paths", "java.show.server.task.status": "Show Build Job Status", "java.action.navigateToSuperImplementation": "Go to Super Implementation", - "java.action.showTypeHierarchy": "Show Type Hierarchy", - "java.action.showClassHierarchy": "Show Class Hierarchy", - "java.action.showSupertypeHierarchy": "Show Supertype Hierarchy", - "java.action.showSubtypeHierarchy": "Show Subtype Hierarchy", - "java.action.changeBaseType": "Base on this Type", "java.project.createModuleInfo.command": "Create module-info.java", "java.clean.sharedIndexes": "Clean Shared Indexes", "java.server.restart": "Restart Java Language Server", diff --git a/package.nls.ko.json b/package.nls.ko.json index 0b185fa05..ee5a41634 100644 --- a/package.nls.ko.json +++ b/package.nls.ko.json @@ -17,11 +17,6 @@ "java.project.listSourcePaths": "모든 Java 소스 경로 표시", "java.show.server.task.status": "빌드 작업 상태 표시", "java.action.navigateToSuperImplementation": "상위 구현으로 이동", - "java.action.showTypeHierarchy": "Type 계층 구조 표시", - "java.action.showClassHierarchy": "Class 계층 구조 표시", - "java.action.showSupertypeHierarchy": "Supertype 계층 구조 표시", - "java.action.showSubtypeHierarchy": "Subtype 계층 구조 표시", - "java.action.changeBaseType": "이 타입을 기준으로", "java.project.createModuleInfo.command": "module-info.java 생성", "java.clean.sharedIndexes": "공유 인덱스 정리", "java.server.restart": "Java Language Server 다시 시작", diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json index 2526d4c36..6616e3073 100644 --- a/package.nls.zh-cn.json +++ b/package.nls.zh-cn.json @@ -17,11 +17,6 @@ "java.project.listSourcePaths": "列出所有 Java 源代码路径", "java.show.server.task.status": "显示工作状态", "java.action.navigateToSuperImplementation": "转到父类实现", - "java.action.showTypeHierarchy": "显示类型层次结构", - "java.action.showClassHierarchy": "显示类的继承关系", - "java.action.showSupertypeHierarchy": "显示父类层次结构", - "java.action.showSubtypeHierarchy": "显示子类层次结构", - "java.action.changeBaseType": "基于此类型", "java.project.createModuleInfo.command": "创建 module-info.java", "java.clean.sharedIndexes": "清理共享的索引文件", "java.action.filesExplorerPasteAction": "将剪贴板文本粘贴到文件中", diff --git a/package.nls.zh-tw.json b/package.nls.zh-tw.json index 808fc1d97..5fbc00d4c 100644 --- a/package.nls.zh-tw.json +++ b/package.nls.zh-tw.json @@ -17,11 +17,6 @@ "java.project.listSourcePaths": "列出所有 Java 始碼路徑", "java.show.server.task.status": "顯示建置工作狀態", "java.action.navigateToSuperImplementation": "移到父類別中的實作", - "java.action.showTypeHierarchy": "顯示型別階層結構", - "java.action.showClassHierarchy": "顯示類別階層結構", - "java.action.showSupertypeHierarchy": "顯示父類別階層結構", - "java.action.showSubtypeHierarchy": "顯示子類別階層結構", - "java.action.changeBaseType": "以此型別為基礎", "java.project.createModuleInfo.command": "創建 module-info.java", "java.action.filesExplorerPasteAction": "將剪貼簿文字貼到文件中", "java.action.doCleanup": "執行清理操作" diff --git a/src/commands.ts b/src/commands.ts index ab5aa0543..9e388b24c 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -228,34 +228,6 @@ export namespace Commands { * Navigate To Super Method Command. */ export const NAVIGATE_TO_SUPER_IMPLEMENTATION_COMMAND = 'java.action.navigateToSuperImplementation'; - /** - * Open Type Hierarchy of given Selection. - */ - export const SHOW_TYPE_HIERARCHY = 'java.action.showTypeHierarchy'; - /** - * Show SuperType Hierarchy of given Selection. - */ - export const SHOW_SUPERTYPE_HIERARCHY = 'java.action.showSupertypeHierarchy'; - /** - * Show SubType Hierarchy of given Selection. - */ - export const SHOW_SUBTYPE_HIERARCHY = 'java.action.showSubtypeHierarchy'; - /** - * Show Type Hierarchy of given Selection. - */ - export const SHOW_CLASS_HIERARCHY = 'java.action.showClassHierarchy'; - /** - * Change the base type of Type Hierarchy. - */ - export const CHANGE_BASE_TYPE = 'java.action.changeBaseType'; - /** - * Open the given TypeHierarchy Item. - */ - export const OPEN_TYPE_HIERARCHY = 'java.navigate.openTypeHierarchy'; - /** - * Resolve the given TypeHierarchy Item. - */ - export const RESOLVE_TYPE_HIERARCHY = 'java.navigate.resolveTypeHierarchy'; /** * Show server task status */ diff --git a/src/standardLanguageClient.ts b/src/standardLanguageClient.ts index 231600ff5..9742ae24f 100644 --- a/src/standardLanguageClient.ts +++ b/src/standardLanguageClient.ts @@ -32,8 +32,6 @@ import { snippetCompletionProvider } from "./snippetCompletionProvider"; import * as sourceAction from './sourceAction'; import { askForProjects, projectConfigurationUpdate, upgradeGradle } from "./standardLanguageClientUtils"; import { TracingLanguageClient } from './TracingLanguageClient'; -import { TypeHierarchyDirection, TypeHierarchyItem } from "./typeHierarchy/protocol"; -import { typeHierarchyTree } from "./typeHierarchy/typeHierarchyTree"; import { getAllJavaProjects, getAllProjects, getJavaConfiguration, isPrereleaseOrInsiderVersion } from "./utils"; import { Telemetry } from "./telemetry"; import { TelemetryEvent } from "@redhat-developer/vscode-redhat-telemetry/lib"; @@ -490,33 +488,6 @@ export class StandardLanguageClient { } })); - context.subscriptions.push(commands.registerCommand(Commands.SHOW_TYPE_HIERARCHY, (location: any) => { - if (location instanceof Uri) { - typeHierarchyTree.setTypeHierarchy(new Location(location, window.activeTextEditor.selection.active), TypeHierarchyDirection.both); - } else { - if (window.activeTextEditor?.document?.languageId !== "java") { - return; - } - typeHierarchyTree.setTypeHierarchy(new Location(window.activeTextEditor.document.uri, window.activeTextEditor.selection.active), TypeHierarchyDirection.both); - } - })); - - context.subscriptions.push(commands.registerCommand(Commands.SHOW_CLASS_HIERARCHY, () => { - typeHierarchyTree.changeDirection(TypeHierarchyDirection.both); - })); - - context.subscriptions.push(commands.registerCommand(Commands.SHOW_SUPERTYPE_HIERARCHY, () => { - typeHierarchyTree.changeDirection(TypeHierarchyDirection.parents); - })); - - context.subscriptions.push(commands.registerCommand(Commands.SHOW_SUBTYPE_HIERARCHY, () => { - typeHierarchyTree.changeDirection(TypeHierarchyDirection.children); - })); - - context.subscriptions.push(commands.registerCommand(Commands.CHANGE_BASE_TYPE, async (item: TypeHierarchyItem) => { - typeHierarchyTree.changeBaseItem(item); - })); - context.subscriptions.push(commands.registerCommand(Commands.BUILD_PROJECT, async (uris: Uri[] | Uri, isFullBuild: boolean, token: CancellationToken) => { let resources: Uri[] = []; if (uris instanceof Uri) { diff --git a/src/typeHierarchy/model.ts b/src/typeHierarchy/model.ts deleted file mode 100644 index 2be703797..000000000 --- a/src/typeHierarchy/model.ts +++ /dev/null @@ -1,252 +0,0 @@ -import * as vscode from "vscode"; -import { TypeHierarchyDirection, TypeHierarchyItem } from "./protocol"; -import { SymbolItemNavigation, SymbolTreeInput, SymbolTreeModel } from "./references-view"; -import { getActiveLanguageClient } from "../extension"; -import { LanguageClient } from "vscode-languageclient/node"; -import { getRootItem, resolveTypeHierarchy, typeHierarchyDirectionToContextString } from "./util"; -import { CancellationToken, commands, workspace } from "vscode"; -import { getThemeIcon } from "../themeUtils"; - -export class TypeHierarchyTreeInput implements SymbolTreeInput { - readonly contextValue: string = "javaTypeHierarchy"; - readonly title: string; - readonly baseItem: TypeHierarchyItem; - private client: LanguageClient; - private rootItem: TypeHierarchyItem; - - constructor(readonly location: vscode.Location, readonly direction: TypeHierarchyDirection, readonly token: CancellationToken, item: TypeHierarchyItem) { - this.baseItem = item; - const isMethodHierarchy: boolean = item.data["method"] !== undefined; - let methodName: string; - if (isMethodHierarchy) { - methodName = item.data["method_name"]; - } - switch (direction) { - case TypeHierarchyDirection.both: - this.title = isMethodHierarchy ? `Method Hierarchy for ${methodName}` : "Class Hierarchy"; - break; - case TypeHierarchyDirection.parents: - this.title = isMethodHierarchy ? `Supertype (Method) Hierarchy for ${methodName}` : "Supertype Hierarchy"; - break; - case TypeHierarchyDirection.children: - this.title = isMethodHierarchy ? `Subtype (Method) Hierarchy for ${methodName}` : "Subtype Hierarchy"; - break; - default: - return; - } - - } - - async resolve(): Promise> { - if (!this.client) { - this.client = await getActiveLanguageClient(); - } - // workaround: await a second to make sure the success of reveal operation on baseItem, see: https://github.com/microsoft/vscode/issues/114989 - await new Promise((resolve) => setTimeout(() => { - resolve(); - }, 1000)); - - this.rootItem = (this.direction === TypeHierarchyDirection.both) ? await getRootItem(this.client, this.baseItem, this.token) : this.baseItem; - const model: TypeHierarchyModel = new TypeHierarchyModel(this.rootItem, this.direction, this.baseItem); - const provider = new TypeHierarchyTreeDataProvider(model, this.client, this.token); - const treeModel: SymbolTreeModel = { - provider: provider, - message: undefined, - navigation: model, - dispose() { - provider.dispose(); - } - }; - commands.executeCommand('setContext', 'typeHierarchyDirection', typeHierarchyDirectionToContextString(this.direction)); - commands.executeCommand('setContext', 'typeHierarchySymbolKind', this.baseItem.kind); - return treeModel; - } - - with(location: vscode.Location): TypeHierarchyTreeInput { - return new TypeHierarchyTreeInput(location, this.direction, this.token, this.baseItem); - } -} - -export class TypeHierarchyModel implements SymbolItemNavigation { - public readonly onDidChange = new vscode.EventEmitter(); - public readonly onDidChangeEvent = this.onDidChange.event; - - constructor(private rootItem: TypeHierarchyItem, private direction: TypeHierarchyDirection, private baseItem: TypeHierarchyItem) { } - - public getBaseItem(): TypeHierarchyItem { - return this.baseItem; - } - - public getDirection(): TypeHierarchyDirection { - return this.direction; - } - - public getRootItem(): TypeHierarchyItem { - return this.rootItem; - } - - location(item: TypeHierarchyItem) { - return new vscode.Location(vscode.Uri.parse(item.uri), item.range); - } - - nearest(uri: vscode.Uri, _position: vscode.Position): TypeHierarchyItem | undefined { - return this.baseItem; - } - - next(from: TypeHierarchyItem): TypeHierarchyItem { - return from; - } - - previous(from: TypeHierarchyItem): TypeHierarchyItem { - return from; - } -} - -class TypeHierarchyTreeDataProvider implements vscode.TreeDataProvider { - private readonly emitter: vscode.EventEmitter = new vscode.EventEmitter(); - private readonly modelListener: vscode.Disposable; - private lazyLoad: boolean; - public readonly onDidChangeTreeData: vscode.Event = this.emitter.event; - - constructor(readonly model: TypeHierarchyModel, readonly client: LanguageClient, readonly token: CancellationToken) { - this.modelListener = model.onDidChangeEvent(e => this.emitter.fire(e instanceof TypeHierarchyItem ? e : undefined)); - this.lazyLoad = workspace.getConfiguration().get("java.typeHierarchy.lazyLoad"); - } - - dispose(): void { - this.emitter.dispose(); - this.modelListener.dispose(); - } - - async getTreeItem(element: TypeHierarchyItem): Promise { - if (!element) { - return undefined; - } - const treeItem: vscode.TreeItem = (element === this.model.getBaseItem()) ? new vscode.TreeItem({ label: element.name, highlights: [[0, element.name.length]] }) : new vscode.TreeItem(element.name); - treeItem.contextValue = (element === this.model.getBaseItem() || !element.uri) ? "false" : "true"; - treeItem.description = element.detail; - treeItem.iconPath = getThemeIcon(element.kind); - treeItem.command = (element.uri) ? { - command: 'vscode.open', - title: 'Open Type Definition Location', - arguments: [ - vscode.Uri.parse(element.uri), { selection: element.selectionRange } - ] - } : undefined; - // workaround: set a specific id to refresh the collapsible state for treeItems, see: https://github.com/microsoft/vscode/issues/114614#issuecomment-763428052 - treeItem.id = `${element.data["element"]}${Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)}`; - if (element.expand) { - treeItem.collapsibleState = vscode.TreeItemCollapsibleState.Expanded; - } else if (this.model.getDirection() === TypeHierarchyDirection.children || this.model.getDirection() === TypeHierarchyDirection.both) { - // For an unresolved baseItem, will make it collapsed to show it early. It will be automatically expanded by model.nearest() - if (element === this.model.getBaseItem()) { - if (!element.children) { - treeItem.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed; - } else if (element.children.length === 0) { - treeItem.collapsibleState = vscode.TreeItemCollapsibleState.None; - } else { - treeItem.collapsibleState = vscode.TreeItemCollapsibleState.Expanded; - } - } else { - if (!element.children) { - if (this.lazyLoad) { - treeItem.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed; - return treeItem; - } - const resolvedItem = await resolveTypeHierarchy(this.client, element, this.model.getDirection(), this.token); - if (!resolvedItem) { - return undefined; - } - element.children = resolvedItem.children; - } - treeItem.collapsibleState = (element.children.length === 0) ? vscode.TreeItemCollapsibleState.None : vscode.TreeItemCollapsibleState.Collapsed; - } - } else if (this.model.getDirection() === TypeHierarchyDirection.parents) { - if (element === this.model.getBaseItem()) { - if (!element.parents) { - treeItem.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed; - } else if (element.parents.length === 0) { - treeItem.collapsibleState = vscode.TreeItemCollapsibleState.None; - } else { - treeItem.collapsibleState = vscode.TreeItemCollapsibleState.Expanded; - } - } else { - if (!element.parents) { - if (this.lazyLoad) { - treeItem.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed; - return treeItem; - } - const resolvedItem = await resolveTypeHierarchy(this.client, element, this.model.getDirection(), this.token); - if (!resolvedItem) { - return undefined; - } - element.parents = resolvedItem.parents; - } - treeItem.collapsibleState = (element.parents.length === 0) ? vscode.TreeItemCollapsibleState.None : vscode.TreeItemCollapsibleState.Collapsed; - } - } - return treeItem; - } - - async getChildren(element?: TypeHierarchyItem | undefined): Promise { - if (!element) { - return [this.model.getRootItem()]; - } - if (this.model.getDirection() === TypeHierarchyDirection.children || this.model.getDirection() === TypeHierarchyDirection.both) { - if (!element.children) { - if (TypeHierarchyTreeDataProvider.isAllowedType(element)) { - return [TypeHierarchyTreeDataProvider.getFakeItem(element)]; - } - const resolvedItem = await resolveTypeHierarchy(this.client, element, this.model.getDirection(), this.token); - if (!resolvedItem) { - return undefined; - } - element.children = resolvedItem.children; - if (element.children.length === 0) { - this.emitter.fire(element); - } - } - return element.children; - } else if (this.model.getDirection() === TypeHierarchyDirection.parents) { - if (!element.parents) { - const resolvedItem = await resolveTypeHierarchy(this.client, element, this.model.getDirection(), this.token); - if (!resolvedItem) { - return undefined; - } - element.parents = resolvedItem.parents; - if (element.parents.length === 0) { - this.emitter.fire(element); - } - } - return element.parents; - } - return undefined; - } - - private static isAllowedType(item: TypeHierarchyItem): boolean { - if (item.name === "Object" && item.detail === "java.lang") { - return true; - } - return false; - } - - private static getFakeItem(item: TypeHierarchyItem): TypeHierarchyItem { - let message: string; - if (item.name === "Object" && item.detail === "java.lang") { - message = "All classes are subtypes of java.lang.Object."; - } - return { - name: message, - kind: undefined, - children: [], - parents: [], - detail: undefined, - uri: undefined, - range: undefined, - selectionRange: undefined, - data: undefined, - deprecated: false, - expand: false, - }; - } -} diff --git a/src/typeHierarchy/protocol.ts b/src/typeHierarchy/protocol.ts deleted file mode 100644 index de4621147..000000000 --- a/src/typeHierarchy/protocol.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as vscode from "vscode"; -import { Range, SymbolKind } from "vscode-languageclient"; - -export enum TypeHierarchyDirection { - children, - parents, - both -} - -export class LSPTypeHierarchyItem { - name: string; - detail: string; - kind: SymbolKind; - deprecated: boolean; - uri: string; - range: Range; - selectionRange: Range; - parents: LSPTypeHierarchyItem[]; - children: LSPTypeHierarchyItem[]; - data: any; -} - -export class TypeHierarchyItem { - name: string; - detail: string; - kind: vscode.SymbolKind; - deprecated: boolean; - uri: string; - range: vscode.Range; - selectionRange: vscode.Range; - parents: TypeHierarchyItem[]; - children: TypeHierarchyItem[]; - data: any; - expand: boolean; -} diff --git a/src/typeHierarchy/references-view.d.ts b/src/typeHierarchy/references-view.d.ts deleted file mode 100644 index e61177b90..000000000 --- a/src/typeHierarchy/references-view.d.ts +++ /dev/null @@ -1,139 +0,0 @@ -/* --------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; - -/** - * This interface describes the shape for the references viewlet API. It consists - * of a single `setInput` function which must be called with a full implementation - * of the `SymbolTreeInput`-interface. To acquire this API use the default mechanics, e.g: - * - * ```ts - * // get references viewlet API - * const api = await vscode.extensions.getExtension('ms-vscode.references-view').activate(); - * - * // instantiate and set input which updates the view - * const myInput: SymbolTreeInput = ... - * api.setInput(myInput) - * ``` - */ -export interface SymbolTree { - - /** - * Set the contents of the references viewlet. - * - * @param input A symbol tree input object - */ - setInput(input: SymbolTreeInput): void; -} - -/** - * A symbol tree input is the entry point for populating the references viewlet. - * Inputs must be anchored at a code location, they must have a title, and they - * must resolve to a model. - */ -export interface SymbolTreeInput { - - /** - * The value of the `reference-list.source` context key. Use this to control - * input dependent commands. - */ - readonly contextValue: string; - - /** - * The (short) title of this input, like "Implementations" or "Callers Of" - */ - readonly title: string; - - /** - * The location at which this position is anchored. Locations are validated and inputs - * with "funny" locations might be ignored - */ - readonly location: vscode.Location; - - /** - * Resolve this input to a model that contains the actual data. When there are no result - * than `undefined` or `null` should be returned. - */ - resolve(): vscode.ProviderResult>; - - /** - * This function is called when re-running from history. The symbols tree has tracked - * the original location of this input and that is now passed to this input. The - * implementation of this function should return a clone where the `location`-property - * uses the provided `location` - * - * @param location The location at which the new input should be anchored. - * @returns A new input which location is anchored at the position. - */ - with(location: vscode.Location): SymbolTreeInput; -} - -/** - * A symbol tree model which is used to populate the symbols tree. - */ -export interface SymbolTreeModel { - - /** - * A tree data provider which is used to populate the symbols tree. - */ - provider: vscode.TreeDataProvider; - - /** - * An optional message that is displayed above the tree. Whenever the provider - * fires a change event this message is read again. - */ - message: string | undefined; - - /** - * Optional support for symbol navigation. When implemented, navigation commands like - * "Go to Next" and "Go to Previous" will be working with this model. - */ - navigation?: SymbolItemNavigation; - - /** - * Optional support for editor highlights. WHen implemented, the editor will highlight - * symbol ranges in the source code. - */ - highlights?: SymbolItemEditorHighlights; - - /** - * Optional dispose function which is invoked when this model is - * needed anymore - */ - dispose?(): void; -} - -/** - * Interface to support the built-in symbol navigation. - */ -export interface SymbolItemNavigation { - /** - * Return the item that is the nearest to the given location or `undefined` - */ - nearest(uri: vscode.Uri, position: vscode.Position): T | undefined; - /** - * Return the next item from the given item or the item itself. - */ - next(from: T): T; - /** - * Return the previous item from the given item or the item itself. - */ - previous(from: T): T; - /** - * Return the location of the given item. - */ - location(item: T): vscode.Location | undefined; -} - -/** - * Interface to support the built-in editor highlights. - */ -export interface SymbolItemEditorHighlights { - /** - * Given an item and an uri return an array of ranges to highlight. - */ - getEditorHighlights(item: T, uri: vscode.Uri): vscode.Range[] | undefined; -} diff --git a/src/typeHierarchy/typeHierarchyTree.ts b/src/typeHierarchy/typeHierarchyTree.ts deleted file mode 100644 index d2870de6b..000000000 --- a/src/typeHierarchy/typeHierarchyTree.ts +++ /dev/null @@ -1,118 +0,0 @@ -import * as vscode from "vscode"; -import { Position, TextDocumentIdentifier, TextDocumentPositionParams } from "vscode-languageclient"; -import { LanguageClient } from "vscode-languageclient/node"; -import { Commands } from "../commands"; -import { getActiveLanguageClient } from "../extension"; -import { showNoLocationFound } from "../standardLanguageClient"; -import { TypeHierarchyTreeInput } from "./model"; -import { LSPTypeHierarchyItem, TypeHierarchyDirection, TypeHierarchyItem } from "./protocol"; -import { SymbolTree } from "./references-view"; -import { toTypeHierarchyItem } from "./util"; - -export class TypeHierarchyTree { - private api: SymbolTree; - private direction: TypeHierarchyDirection; - private client: LanguageClient; - private cancelTokenSource: vscode.CancellationTokenSource; - private location: vscode.Location; - private baseItem: TypeHierarchyItem; - public initialized: boolean; - - constructor() { - this.initialized = false; - } - - public async initialize() { - // It uses a new publisher id in June 2022 Update, check both old/new id for compatibility - // See https://github.com/microsoft/vscode/pull/152213 - const referencesViewExt = vscode.extensions.getExtension('vscode.references-view') - ?? vscode.extensions.getExtension('ms-vscode.references-view'); - this.api = await referencesViewExt?.activate(); - this.client = await getActiveLanguageClient(); - this.initialized = true; - } - - public async setTypeHierarchy(location: vscode.Location, direction: TypeHierarchyDirection): Promise { - if (!this.initialized) { - await this.initialize(); - } - if (!this.api) { - return; - } - if (this.cancelTokenSource) { - this.cancelTokenSource.cancel(); - } - this.cancelTokenSource = new vscode.CancellationTokenSource(); - const textDocument: TextDocumentIdentifier = TextDocumentIdentifier.create(location.uri.toString()); - const position: Position = Position.create(location.range.start.line, location.range.start.character); - const params: TextDocumentPositionParams = { - textDocument: textDocument, - position: position, - }; - let lspItem: LSPTypeHierarchyItem; - try { - lspItem = await vscode.commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.OPEN_TYPE_HIERARCHY, JSON.stringify(params), JSON.stringify(direction), JSON.stringify(0), this.cancelTokenSource.token); - } catch (e) { - // operation cancelled - return; - } - if (!lspItem) { - showNoLocationFound('No Type Hierarchy found'); - return; - } - const symbolKind = this.client.protocol2CodeConverter.asSymbolKind(lspItem.kind); - if (direction === TypeHierarchyDirection.both && symbolKind === vscode.SymbolKind.Interface) { - direction = TypeHierarchyDirection.children; - } - const item: TypeHierarchyItem = toTypeHierarchyItem(this.client, lspItem, direction); - const input: TypeHierarchyTreeInput = new TypeHierarchyTreeInput(location, direction, this.cancelTokenSource.token, item); - this.location = location; - this.direction = direction; - this.baseItem = item; - this.api.setInput(input); - } - - public changeDirection(direction: TypeHierarchyDirection): void { - if (!this.api) { - return; - } - if (this.cancelTokenSource) { - this.cancelTokenSource.cancel(); - } - this.cancelTokenSource = new vscode.CancellationTokenSource(); - this.baseItem.children = undefined; - this.baseItem.parents = undefined; - const input: TypeHierarchyTreeInput = new TypeHierarchyTreeInput(this.location, direction, this.cancelTokenSource.token, this.baseItem); - this.direction = direction; - this.api.setInput(input); - } - - public async changeBaseItem(item: TypeHierarchyItem): Promise { - if (!this.api) { - return; - } - if (this.cancelTokenSource) { - this.cancelTokenSource.cancel(); - } - this.cancelTokenSource = new vscode.CancellationTokenSource(); - item.parents = undefined; - item.children = undefined; - const location: vscode.Location = new vscode.Location(vscode.Uri.parse(item.uri), item.selectionRange); - const newLocation: vscode.Location = (await this.isValidRequestPosition(location.uri, location.range.start)) ? location : this.location; - const input: TypeHierarchyTreeInput = new TypeHierarchyTreeInput(newLocation, this.direction, this.cancelTokenSource.token, item); - this.location = newLocation; - this.baseItem = item; - this.api.setInput(input); - } - - private async isValidRequestPosition(uri: vscode.Uri, position: vscode.Position) { - const doc = await vscode.workspace.openTextDocument(uri); - let range = doc.getWordRangeAtPosition(position); - if (!range) { - range = doc.getWordRangeAtPosition(position, /[^\s]+/); - } - return Boolean(range); - } -} - -export const typeHierarchyTree: TypeHierarchyTree = new TypeHierarchyTree(); diff --git a/src/typeHierarchy/util.ts b/src/typeHierarchy/util.ts deleted file mode 100644 index 2f3463780..000000000 --- a/src/typeHierarchy/util.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { CancellationToken, commands, SymbolKind } from "vscode"; -import { LanguageClient } from "vscode-languageclient/node"; -import { Commands } from "../commands"; -import { LSPTypeHierarchyItem, TypeHierarchyDirection, TypeHierarchyItem } from "./protocol"; - -export function toSingleLSPTypeHierarchyItem(client: LanguageClient, typeHierarchyItem: TypeHierarchyItem): LSPTypeHierarchyItem { - if (!typeHierarchyItem) { - return undefined; - } - return { - name: typeHierarchyItem.name, - detail: typeHierarchyItem.detail, - kind: client.code2ProtocolConverter.asSymbolKind(typeHierarchyItem.kind), - deprecated: typeHierarchyItem.deprecated, - uri: typeHierarchyItem.uri, - range: client.code2ProtocolConverter.asRange(typeHierarchyItem.range), - selectionRange: client.code2ProtocolConverter.asRange(typeHierarchyItem.selectionRange), - parents: undefined, - children: undefined, - data: typeHierarchyItem.data, - }; -} - -export function toTypeHierarchyItem(client: LanguageClient, lspTypeHierarchyItem: LSPTypeHierarchyItem, direction: TypeHierarchyDirection): TypeHierarchyItem { - if (!lspTypeHierarchyItem) { - return undefined; - } - let parents: TypeHierarchyItem[]; - let children: TypeHierarchyItem[]; - if (direction === TypeHierarchyDirection.parents || direction === TypeHierarchyDirection.both) { - if (lspTypeHierarchyItem.parents) { - parents = []; - for (const parent of lspTypeHierarchyItem.parents) { - parents.push(toTypeHierarchyItem(client, parent, TypeHierarchyDirection.parents)); - } - parents = parents.sort((a, b) => { - return (a.kind.toString() === b.kind.toString()) ? a.name.localeCompare(b.name) : b.kind.toString().localeCompare(a.kind.toString()); - }); - } - } - if (direction === TypeHierarchyDirection.children || direction === TypeHierarchyDirection.both) { - if (lspTypeHierarchyItem.children) { - children = []; - for (const child of lspTypeHierarchyItem.children) { - children.push(toTypeHierarchyItem(client, child, TypeHierarchyDirection.children)); - } - children = children.sort((a, b) => { - return (a.kind.toString() === b.kind.toString()) ? a.name.localeCompare(b.name) : b.kind.toString().localeCompare(a.kind.toString()); - }); - } - } - return { - name: lspTypeHierarchyItem.name, - detail: lspTypeHierarchyItem.detail, - kind: client.protocol2CodeConverter.asSymbolKind(lspTypeHierarchyItem.kind), - deprecated: lspTypeHierarchyItem.deprecated, - uri: lspTypeHierarchyItem.uri, - range: client.protocol2CodeConverter.asRange(lspTypeHierarchyItem.range), - selectionRange: client.protocol2CodeConverter.asRange(lspTypeHierarchyItem.selectionRange), - parents: parents, - children: children, - data: lspTypeHierarchyItem.data, - expand: false, - }; -} - -export function typeHierarchyDirectionToContextString(direction: TypeHierarchyDirection): string { - switch (direction) { - case TypeHierarchyDirection.children: - return "children"; - case TypeHierarchyDirection.parents: - return "parents"; - case TypeHierarchyDirection.both: - return "both"; - default: - return undefined; - } -} - -export async function resolveTypeHierarchy(client: LanguageClient, typeHierarchyItem: TypeHierarchyItem, direction: TypeHierarchyDirection, token: CancellationToken): Promise { - const lspTypeHierarchyItem = toSingleLSPTypeHierarchyItem(client, typeHierarchyItem); - let resolvedLSPItem: LSPTypeHierarchyItem; - try { - resolvedLSPItem = await commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.RESOLVE_TYPE_HIERARCHY, JSON.stringify(lspTypeHierarchyItem), JSON.stringify(direction), JSON.stringify(1), token); - } catch (e) { - // operation cancelled - return undefined; - } - const resolvedItem = toTypeHierarchyItem(client, resolvedLSPItem, direction); - if (!resolvedItem) { - return undefined; - } - resolvedItem.expand = typeHierarchyItem.expand; - return resolvedItem; -} - -export async function getRootItem(client: LanguageClient, typeHierarchyItem: TypeHierarchyItem, token: CancellationToken): Promise { - if (!typeHierarchyItem) { - return undefined; - } - if (!typeHierarchyItem.parents) { - const resolvedItem = await resolveTypeHierarchy(client, typeHierarchyItem, TypeHierarchyDirection.parents, token); - if (!resolvedItem || !resolvedItem.parents) { - return typeHierarchyItem; - } else { - typeHierarchyItem.parents = resolvedItem.parents; - } - } - if (typeHierarchyItem.parents.length === 0) { - return typeHierarchyItem; - } else { - for (const parent of typeHierarchyItem.parents) { - if (parent.kind === SymbolKind.Class || parent.kind === SymbolKind.Null) { - parent.children = [typeHierarchyItem]; - parent.expand = true; - return getRootItem(client, parent, token); - } - } - return typeHierarchyItem; - } -} diff --git a/test/standard-mode-suite/extension.test.ts b/test/standard-mode-suite/extension.test.ts index 9b5371122..094d581e8 100644 --- a/test/standard-mode-suite/extension.test.ts +++ b/test/standard-mode-suite/extension.test.ts @@ -48,7 +48,6 @@ suite('Java Language Extension - Standard', () => { Commands.APPLY_REFACTORING_COMMAND, Commands.APPLY_WORKSPACE_EDIT, Commands.BUILD_PROJECT, - Commands.CHANGE_BASE_TYPE, Commands.CHOOSE_IMPORTS, Commands.CLEAN_SHARED_INDEXES, Commands.CLEAN_WORKSPACE, @@ -92,7 +91,7 @@ suite('Java Language Extension - Standard', () => { Commands.OPEN_SERVER_LOG, Commands.OPEN_SERVER_STDOUT_LOG, Commands.OPEN_SERVER_STDERR_LOG, - Commands.OPEN_TYPE_HIERARCHY, + "java.navigate.openTypeHierarchy", Commands.ORGANIZE_IMPORTS, Commands.ORGANIZE_IMPORTS_SILENTLY, Commands.OVERRIDE_METHODS_PROMPT, @@ -103,7 +102,7 @@ suite('Java Language Extension - Standard', () => { Commands.REMOVE_FROM_SOURCEPATH_CMD, Commands.RENAME_COMMAND, "java.project.resolveStackTraceLocation", - Commands.RESOLVE_TYPE_HIERARCHY, + "java.navigate.resolveTypeHierarchy", Commands.RESOLVE_WORKSPACE_SYMBOL, Commands.RUNTIME_VALIDATION_OPEN, Commands.RESTART_LANGUAGE_SERVER, @@ -115,10 +114,6 @@ suite('Java Language Extension - Standard', () => { "java.completion.onDidSelect", "java.decompile", "java.protobuf.generateSources", - Commands.SHOW_TYPE_HIERARCHY, - Commands.SHOW_SUBTYPE_HIERARCHY, - Commands.SHOW_SUPERTYPE_HIERARCHY, - Commands.SHOW_CLASS_HIERARCHY, Commands.SHOW_EXTEND_OUTLINE, Commands.UPGRADE_GRADLE_WRAPPER, Commands.UPGRADE_GRADLE_WRAPPER_CMD,