diff --git a/package.json b/package.json index b57b73bf..eb4dcff1 100644 --- a/package.json +++ b/package.json @@ -88,6 +88,12 @@ "command": "java.project.update", "title": "%contributes.commands.java.project.update%" }, + { + "command": "java.project.reloadProjectFromActiveFile", + "title": "%contributes.commands.java.project.reloadProjectFromActiveFile%", + "category": "Java", + "icon": "$(sync)" + }, { "command": "java.project.rebuild", "title": "%contributes.commands.java.project.rebuild%" @@ -282,6 +288,10 @@ } ], "commandPalette": [ + { + "command": "java.project.reloadProjectFromActiveFile", + "when": "false" + }, { "command": "java.view.package.exportJar", "when": "java:serverMode == Standard && !java:noJavaProjects" @@ -383,6 +393,13 @@ "group": "navigation@100" } ], + "editor/title": [ + { + "command": "java.project.reloadProjectFromActiveFile", + "when": "java:reloadProjectActive && javaLSReady", + "group": "navigation" + } + ], "editor/title/context": [ { "command": "java.view.package.revealInProjectExplorer", diff --git a/package.nls.json b/package.nls.json index 95206a17..df8d0d19 100644 --- a/package.nls.json +++ b/package.nls.json @@ -9,6 +9,7 @@ "contributes.commands.java.project.clean.workspace": "Clean Workspace", "contributes.commands.java.project.rebuild": "Rebuild Project", "contributes.commands.java.project.update": "Reload Project", + "contributes.commands.java.project.reloadProjectFromActiveFile": "Reload Java Project", "contributes.commands.java.view.package.revealInProjectExplorer": "Reveal in Java Project Explorer", "contributes.commands.java.view.package.changeToFlatPackageView":"Flat View", "contributes.commands.java.view.package.changeToHierarchicalPackageView":"Hierarchical View", diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json index e816f6ed..741c137f 100644 --- a/package.nls.zh-cn.json +++ b/package.nls.zh-cn.json @@ -9,6 +9,7 @@ "contributes.commands.java.project.clean.workspace": "清理工作空间", "contributes.commands.java.project.rebuild": "重新构建项目", "contributes.commands.java.project.update": "重新加载项目", + "contributes.commands.java.project.reloadProjectFromActiveFile": "重新加载 Java 项目", "contributes.commands.java.view.package.revealInProjectExplorer": "在 Java 项目视图中显示", "contributes.commands.java.view.package.changeToFlatPackageView":"平行显示", "contributes.commands.java.view.package.changeToHierarchicalPackageView":"层级显示", diff --git a/package.nls.zh-tw.json b/package.nls.zh-tw.json index bcb6cf9d..2a48fb6d 100644 --- a/package.nls.zh-tw.json +++ b/package.nls.zh-tw.json @@ -9,6 +9,7 @@ "contributes.commands.java.project.clean.workspace": "清理工作區", "contributes.commands.java.project.rebuild": "重新建置專案", "contributes.commands.java.project.update": "重新載入專案", + "contributes.commands.java.project.reloadProjectFromActiveFile": "重新載入 Java 專案", "contributes.commands.java.view.package.revealInProjectExplorer": "在 Java 專案視圖中顯示", "contributes.commands.java.view.package.changeToFlatPackageView":"平行顯示", "contributes.commands.java.view.package.changeToHierarchicalPackageView":"階層顯示", diff --git a/src/commands.ts b/src/commands.ts index bf090287..60a2a179 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -64,6 +64,8 @@ export namespace Commands { export const JAVA_PROJECT_UPDATE = "java.project.update"; + export const JAVA_PROJECT_RELOAD_ACTIVE_FILE = "java.project.reloadProjectFromActiveFile"; + export const JAVA_PROJECT_REBUILD = "java.project.rebuild"; export const JAVA_PROJECT_EXPLORER_FOCUS = "javaProjectExplorer.focus"; diff --git a/src/constants.ts b/src/constants.ts index 36b81729..349f6f08 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -6,6 +6,7 @@ export namespace Context { export const LANGUAGE_SUPPORT_INSTALLED: string = "java:languageSupportInstalled"; export const NO_JAVA_PROJECT: string = "java:noJavaProjects"; export const WORKSPACE_CONTAINS_BUILD_FILES: string = "java:workspaceContainsBuildFiles"; + export const RELOAD_PROJECT_ACTIVE: string = "java:reloadProjectActive"; } export namespace Explorer { @@ -31,3 +32,8 @@ export namespace Explorer { export namespace ExtensionName { export const JAVA_LANGUAGE_SUPPORT: string = "redhat.java"; } + +/** + * The files names for all the build files we support. + */ +export const buildFiles = ["pom.xml", "build.gradle", "settings.gradle", "build.gradle.kts", "settings.gradle.kts"]; diff --git a/src/extension.ts b/src/extension.ts index bc437ff9..21c98971 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,11 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. -import { commands, Extension, ExtensionContext, extensions, tasks, Uri, workspace } from "vscode"; -import { dispose as disposeTelemetryWrapper, initializeFromJsonFile, instrumentOperation, sendInfo } from "vscode-extension-telemetry-wrapper"; + +import * as path from "path"; +import { commands, Diagnostic, Extension, ExtensionContext, extensions, languages, tasks, TextDocument, TextEditor, Uri, window, workspace } from "vscode"; +import { dispose as disposeTelemetryWrapper, initializeFromJsonFile, instrumentOperation, instrumentOperationAsVsCodeCommand, sendInfo } from "vscode-extension-telemetry-wrapper"; import { Commands, contextManager } from "../extension.bundle"; import { BuildTaskProvider } from "./tasks/build/buildTaskProvider"; -import { Context, ExtensionName } from "./constants"; +import { buildFiles, Context, ExtensionName } from "./constants"; import { LibraryController } from "./controllers/libraryController"; import { ProjectController } from "./controllers/projectController"; import { init as initExpService } from "./ExperimentationService"; @@ -40,6 +42,28 @@ async function activateExtension(_operationId: string, context: ExtensionContext context.subscriptions.push(syncHandler); context.subscriptions.push(tasks.registerTaskProvider(ExportJarTaskProvider.exportJarType, new ExportJarTaskProvider())); context.subscriptions.push(tasks.registerTaskProvider(BuildTaskProvider.type, new BuildTaskProvider())); + + context.subscriptions.push(window.onDidChangeActiveTextEditor((e: TextEditor | undefined) => { + setContextForReloadProject(e?.document); + })); + context.subscriptions.push(languages.onDidChangeDiagnostics(() => { + setContextForReloadProject(window.activeTextEditor?.document); + })); + instrumentOperationAsVsCodeCommand(Commands.JAVA_PROJECT_RELOAD_ACTIVE_FILE, (uri?: Uri) => { + if (!uri) { + const activeDocument = window.activeTextEditor?.document; + if (!activeDocument) { + return; + } + uri = activeDocument.uri; + } + + if (!buildFiles.includes(path.basename(uri.fsPath))) { + return; + } + + commands.executeCommand(Commands.JAVA_PROJECT_CONFIGURATION_UPDATE, uri); + }); } // this method is called when your extension is deactivated @@ -61,3 +85,23 @@ function addExtensionChangeListener(context: ExtensionContext): void { context.subscriptions.push(extensionChangeListener); } } + +/** + * Set the context value when reload diagnostic is detected for the active + * build file. + */ +function setContextForReloadProject(document: TextDocument | undefined): void { + if (!document || !buildFiles.includes(path.basename(document.fileName))) { + contextManager.setContextValue(Context.RELOAD_PROJECT_ACTIVE, false); + return; + } + + const diagnostics: Diagnostic[] = languages.getDiagnostics(document.uri); + for (const diagnostic of diagnostics) { + if (diagnostic.message.startsWith("The build file has been changed")) { + contextManager.setContextValue(Context.RELOAD_PROJECT_ACTIVE, true); + return; + } + } + contextManager.setContextValue(Context.RELOAD_PROJECT_ACTIVE, false); +} diff --git a/test/maven-suite/context.test.ts b/test/maven-suite/context.test.ts new file mode 100644 index 00000000..c0d8848a --- /dev/null +++ b/test/maven-suite/context.test.ts @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +import * as path from "path"; +import * as assert from "assert"; +import { Diagnostic, DiagnosticSeverity, languages, Position, Range, Uri, window } from "vscode"; +import { contextManager } from "../../extension.bundle"; +import { setupTestEnv, Uris } from "../shared"; +import { sleep } from "../util"; + +// tslint:disable: only-arrow-functions +suite("Context Manager Tests", () => { + + suiteSetup(setupTestEnv); + + test("Can set reload project context correctly", async function() { + assert.strictEqual(!!contextManager.getContextValue("java:reloadProjectActive"), false); + + const pomUri = Uri.file(path.join(Uris.MAVEN_PROJECT_NODE, "pom.xml")); + await window.showTextDocument(pomUri); + assert.strictEqual(!!contextManager.getContextValue("java:reloadProjectActive"), false); + + const collection = languages.createDiagnosticCollection("test-collection"); + collection.set(pomUri, [new Diagnostic( + new Range(new Position(0, 0), new Position(0, 0)), + "The build file has been changed and may need reload to make it effective.", + DiagnosticSeverity.Information + )]); + await sleep(1000); + assert.strictEqual(!!contextManager.getContextValue("java:reloadProjectActive"), true); + + await window.showTextDocument(Uri.file(Uris.MAVEN_MAIN_CLASS)); + assert.strictEqual(!!contextManager.getContextValue("java:reloadProjectActive"), false); + }); +});