From ff695f6e3e4d554a78ddb7456c568e3696aa3b5e Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Tue, 14 Jul 2020 13:28:42 +0800 Subject: [PATCH 1/2] Adopt language server's LightWeight APIs Signed-off-by: Sheng Chen --- package.json | 30 +++++++++++--- src/commands.ts | 2 + src/extension.ts | 63 ++++++++++++++++++++++++++++- src/views/dependencyDataProvider.ts | 20 +++++++-- src/views/dependencyExplorer.ts | 6 ++- src/views/lightWeightNode.ts | 30 ++++++++++++++ 6 files changed, 140 insertions(+), 11 deletions(-) create mode 100644 src/views/lightWeightNode.ts diff --git a/package.json b/package.json index 81deb9e0..725428aa 100644 --- a/package.json +++ b/package.json @@ -152,6 +152,26 @@ }, "menus": { "commandPalette": [ + { + "command": "java.view.package.refresh", + "when": "java:serverMode != LightWeight" + }, + { + "command": "java.view.package.changeToHierarchicalPackageView", + "when": "java:serverMode != LightWeight" + }, + { + "command": "java.view.package.changeToFlatPackageView", + "when": "java:serverMode != LightWeight" + }, + { + "command": "java.view.package.linkWithFolderExplorer", + "when": "java:serverMode != LightWeight" + }, + { + "command": "java.view.package.unlinkWithFolderExplorer", + "when": "java:serverMode != LightWeight" + }, { "command": "java.view.package.revealFileInOS", "when": "never" @@ -184,27 +204,27 @@ "view/title": [ { "command": "java.view.package.refresh", - "when": "view == javaProjectExplorer", + "when": "view == javaProjectExplorer && java:serverMode!= LightWeight", "group": "navigation@2" }, { "command": "java.view.package.changeToHierarchicalPackageView", - "when": "view == javaProjectExplorer && config.java.dependency.packagePresentation == flat", + "when": "view == javaProjectExplorer && config.java.dependency.packagePresentation == flat && java:serverMode!= LightWeight", "group": "navigation@1" }, { "command": "java.view.package.changeToFlatPackageView", - "when": "view == javaProjectExplorer && config.java.dependency.packagePresentation != flat", + "when": "view == javaProjectExplorer && config.java.dependency.packagePresentation != flat && java:serverMode!= LightWeight", "group": "navigation@1" }, { "command": "java.view.package.linkWithFolderExplorer", - "when": "view == javaProjectExplorer && config.java.dependency.syncWithFolderExplorer != true", + "when": "view == javaProjectExplorer && config.java.dependency.syncWithFolderExplorer != true && java:serverMode!= LightWeight", "group": "navigation@0" }, { "command": "java.view.package.unlinkWithFolderExplorer", - "when": "view == javaProjectExplorer && config.java.dependency.syncWithFolderExplorer == true", + "when": "view == javaProjectExplorer && config.java.dependency.syncWithFolderExplorer == true && java:serverMode!= LightWeight", "group": "navigation@0" } ], diff --git a/src/commands.ts b/src/commands.ts index 338f1620..f5a968a7 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -48,6 +48,8 @@ export namespace Commands { export const JAVA_GETPACKAGEDATA = "java.getPackageData"; + export const JAVA_SWITCH_SERVER_MODE = "java.project.switch.server.mode"; + export const JAVA_RESOLVEPATH = "java.resolvePath"; export const VSCODE_OPEN_FOLDER = "vscode.openFolder"; diff --git a/src/extension.ts b/src/extension.ts index b2b17b1c..c49a8930 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,8 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. -import { Extension, ExtensionContext, extensions } from "vscode"; -import { dispose as disposeTelemetryWrapper, initializeFromJsonFile, instrumentOperation } from "vscode-extension-telemetry-wrapper"; +import { commands, Event, Extension, ExtensionContext, extensions, Uri } from "vscode"; +import { dispose as disposeTelemetryWrapper, initializeFromJsonFile, instrumentOperation, instrumentOperationAsVsCodeCommand } from "vscode-extension-telemetry-wrapper"; +import { Commands } from "./commands"; import { Context } from "./constants"; import { contextManager } from "./contextManager"; import { LibraryController } from "./controllers/libraryController"; @@ -17,6 +18,38 @@ export async function activate(context: ExtensionContext): Promise { } async function activateExtension(_operationId: string, context: ExtensionContext): Promise { + const extension: Extension | undefined = extensions.getExtension("redhat.java"); + if (extension && extension.isActive) { + const extensionApi: any = extension.exports; + if (!extensionApi) { + return; + } + + serverMode = extensionApi.serverMode; + + if (extensionApi.onDidClasspathUpdate) { + const onDidClasspathUpdate: Event = extensionApi.onDidClasspathUpdate; + context.subscriptions.push(onDidClasspathUpdate(async () => { + await commands.executeCommand(Commands.VIEW_PACKAGE_REFRESH, /* debounce = */true); + })); + } + + if (extensionApi.onDidServerModeChange) { + const onDidServerModeChange: Event = extensionApi.onDidServerModeChange; + context.subscriptions.push(onDidServerModeChange(async (mode: string) => { + serverMode = mode; + commands.executeCommand(Commands.VIEW_PACKAGE_REFRESH, /* debounce = */false); + })); + } + + if (extensionApi.onDidProjectsImport) { + const onDidProjectsImport: Event = extensionApi.onDidProjectsImport; + context.subscriptions.push(onDidProjectsImport(async () => { + commands.executeCommand(Commands.VIEW_PACKAGE_REFRESH, /* debounce = */true); + })); + } + } + Settings.initialize(context); contextManager.initialize(context); setMavenExtensionState(); @@ -28,6 +61,13 @@ async function activateExtension(_operationId: string, context: ExtensionContext contextManager.setContextValue(Context.EXTENSION_ACTIVATED, true); initExpService(context); + + context.subscriptions.push(instrumentOperationAsVsCodeCommand(Commands.JAVA_SWITCH_SERVER_MODE, async () => { + if (isSwitchingServer()) { + return; + } + await commands.executeCommand("java.server.mode.switch"); + })); } // determine if the add dependency shortcut will show or not @@ -47,3 +87,22 @@ function setMavenExtensionState() { export async function deactivate() { await disposeTelemetryWrapper(); } + +export function isStandardServerReady(): boolean { + // undefined serverMode indicates an older version language server + if (serverMode === undefined) { + return true; + } + + if (serverMode !== "Standard") { + return false; + } + + return true; +} + +export function isSwitchingServer(): boolean { + return serverMode === "Hybrid"; +} + +let serverMode: string | undefined; diff --git a/src/views/dependencyDataProvider.ts b/src/views/dependencyDataProvider.ts index ea737d43..449200cd 100644 --- a/src/views/dependencyDataProvider.ts +++ b/src/views/dependencyDataProvider.ts @@ -3,16 +3,18 @@ import * as _ from "lodash"; import { - commands, Event, EventEmitter, ExtensionContext, ProviderResult, Range, - Selection, TextEditorRevealType, TreeDataProvider, TreeItem, Uri, window, workspace, + commands, Event, EventEmitter, ExtensionContext, extensions, ProviderResult, + Range, Selection, TextEditorRevealType, TreeDataProvider, TreeItem, Uri, window, workspace, } from "vscode"; import { instrumentOperation, instrumentOperationAsVsCodeCommand } from "vscode-extension-telemetry-wrapper"; import { Commands } from "../commands"; +import { isStandardServerReady, isSwitchingServer } from "../extension"; import { Jdtls } from "../java/jdtls"; import { INodeData, NodeKind } from "../java/nodeData"; import { Settings } from "../settings"; import { DataNode } from "./dataNode"; import { ExplorerNode } from "./explorerNode"; +import { LightWeightNode } from "./lightWeightNode"; import { ProjectNode } from "./projectNode"; import { WorkspaceNode } from "./workspaceNode"; @@ -87,7 +89,19 @@ export class DependencyDataProvider implements TreeDataProvider { return element.getTreeItem(); } - public getChildren(element?: ExplorerNode): ProviderResult { + public async getChildren(element?: ExplorerNode): Promise { + if (isSwitchingServer()) { + await new Promise((resolve: () => void): void => { + extensions.getExtension("redhat.java")!.exports.onDidServerModeChange(resolve); + }); + } + + if (!isStandardServerReady()) { + return [ + new LightWeightNode(), + ]; + } + if (!this._rootItems || !element) { return this.getRootNodes(); } else { diff --git a/src/views/dependencyExplorer.ts b/src/views/dependencyExplorer.ts index 044ea222..abbd4985 100644 --- a/src/views/dependencyExplorer.ts +++ b/src/views/dependencyExplorer.ts @@ -2,10 +2,10 @@ // Licensed under the MIT license. import { Disposable, ExtensionContext, TextEditor, TreeView, TreeViewVisibilityChangeEvent, Uri, window } from "vscode"; +import { isStandardServerReady } from "../extension"; import { Jdtls } from "../java/jdtls"; import { INodeData } from "../java/nodeData"; import { Settings } from "../settings"; -import { DataNode } from "./dataNode"; import { DependencyDataProvider } from "./dependencyDataProvider"; import { ExplorerNode } from "./explorerNode"; @@ -51,6 +51,10 @@ export class DependencyExplorer implements Disposable { } public async reveal(uri: Uri): Promise { + if (!isStandardServerReady()) { + return; + } + const paths: INodeData[] = await Jdtls.resolvePath(uri.toString()); if (!paths || paths.length === 0) { return; diff --git a/src/views/lightWeightNode.ts b/src/views/lightWeightNode.ts new file mode 100644 index 00000000..d6a1fc66 --- /dev/null +++ b/src/views/lightWeightNode.ts @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +import * as _ from "lodash"; +import { ProviderResult, ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode"; +import { Commands } from "../commands"; +import { ExplorerNode } from "./explorerNode"; + +export class LightWeightNode extends ExplorerNode { + constructor() { + super(null); + } + + public getTreeItem(): TreeItem | Promise { + return { + label: "Click to load dependencies...", + collapsibleState: TreeItemCollapsibleState.None, + command: { + command: Commands.JAVA_SWITCH_SERVER_MODE, + title: "Switch to Standard mode", + }, + tooltip: "Switch the Java Language Server to Standard mode to show all the dependencies", + iconPath: new ThemeIcon("info"), + }; + } + + public getChildren(): ProviderResult { + return null; + } +} From 3599f67f69e13ad64a9b4fd430cb5f49b0dd8686 Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Tue, 14 Jul 2020 14:01:45 +0800 Subject: [PATCH 2/2] Address comments --- src/commands.ts | 7 ++++++- src/extension.ts | 4 ++-- src/views/lightWeightNode.ts | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/commands.ts b/src/commands.ts index f5a968a7..e68846c5 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -48,7 +48,12 @@ export namespace Commands { export const JAVA_GETPACKAGEDATA = "java.getPackageData"; - export const JAVA_SWITCH_SERVER_MODE = "java.project.switch.server.mode"; + export const JAVA_PROJECT_SWITCH_SERVER_MODE = "java.project.switch.server.mode"; + + /** + * command from VS Code Java to switch the language server mode + */ + export const JAVA_SWITCH_SERVER_MODE = "java.server.mode.switch"; export const JAVA_RESOLVEPATH = "java.resolvePath"; diff --git a/src/extension.ts b/src/extension.ts index c49a8930..88eda211 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -62,11 +62,11 @@ async function activateExtension(_operationId: string, context: ExtensionContext initExpService(context); - context.subscriptions.push(instrumentOperationAsVsCodeCommand(Commands.JAVA_SWITCH_SERVER_MODE, async () => { + context.subscriptions.push(instrumentOperationAsVsCodeCommand(Commands.JAVA_PROJECT_SWITCH_SERVER_MODE, async () => { if (isSwitchingServer()) { return; } - await commands.executeCommand("java.server.mode.switch"); + await commands.executeCommand(Commands.JAVA_SWITCH_SERVER_MODE, "Standard" /*mode*/); })); } diff --git a/src/views/lightWeightNode.ts b/src/views/lightWeightNode.ts index d6a1fc66..f6b37314 100644 --- a/src/views/lightWeightNode.ts +++ b/src/views/lightWeightNode.ts @@ -16,7 +16,7 @@ export class LightWeightNode extends ExplorerNode { label: "Click to load dependencies...", collapsibleState: TreeItemCollapsibleState.None, command: { - command: Commands.JAVA_SWITCH_SERVER_MODE, + command: Commands.JAVA_PROJECT_SWITCH_SERVER_MODE, title: "Switch to Standard mode", }, tooltip: "Switch the Java Language Server to Standard mode to show all the dependencies",