Skip to content
4 changes: 4 additions & 0 deletions src/languageServerApi/languageServerApiManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ class LanguageServerApiManager {
public isReady(timeout: number): Promise<boolean> {
return Promise.race([this.ready(), new Promise<boolean>((resolve) => setTimeout(() => resolve(false), timeout))]);
}

public getExtensionApi() {
return this.extensionApi;
}
}

export const languageServerApiManager: LanguageServerApiManager = new LanguageServerApiManager();
2 changes: 1 addition & 1 deletion src/syncHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class SyncHandler implements Disposable {

this.disposables.push(workspace.onDidChangeWorkspaceFolders(() => {
this.refresh();
setImmediate(() => upgradeManager.scan()); // Deferred
setImmediate(() => upgradeManager.scan("workspaceFoldersChange", true)); // Deferred
}));

try {
Expand Down
65 changes: 52 additions & 13 deletions src/upgrade/upgradeManager.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import { commands, type ExtensionContext, workspace, type WorkspaceFolder } from "vscode";
import { commands, type ExtensionContext, type Event, workspace, type WorkspaceFolder } from "vscode";

import { Jdtls } from "../java/jdtls";
import { languageServerApiManager } from "../languageServerApi/languageServerApiManager";
Expand All @@ -12,6 +12,8 @@ import notificationManager from "./display/notificationManager";
import { Settings } from "../settings";
import assessmentManager, { getDirectDependencies } from "./assessmentManager";
import { checkOrInstallAppModExtensionForUpgrade, checkOrPopupToInstallAppModExtensionForModernization } from "./utility";
import { contextManager } from "../contextManager";
import { LanguageServerMode } from "../languageServerApi/LanguageServerMode";

const DEFAULT_UPGRADE_PROMPT = "Upgrade Java project dependency to latest version.";

Expand All @@ -21,6 +23,9 @@ function shouldRunCheckup() {
}

class UpgradeManager {
private static watcherSetup = false;
private static scanned = false;

public static initialize(context: ExtensionContext) {
notificationManager.initialize(context);

Expand All @@ -41,21 +46,25 @@ class UpgradeManager {
}));

// Defer the expensive scan operation to not block extension activation
setImmediate(() => UpgradeManager.scan());
setImmediate(() => UpgradeManager.scan("initialization", false));
}

public static scan() {
if (!shouldRunCheckup()) {
return;
}
workspace.workspaceFolders?.forEach((folder) =>
UpgradeManager.runDependencyCheckup(folder)
);
}
public static scan(triggerReason: string, forceRescan: boolean) {
return instrumentOperation("java.dependency.scan", async (_operationId: string) => {
sendInfo(_operationId, { triggerReason });

private static async runDependencyCheckup(folder: WorkspaceFolder) {
return instrumentOperation("java.dependency.runDependencyCheckup", async (_operationId: string) => {
if (!(await languageServerApiManager.ready())) {
if (!shouldRunCheckup()) {
return;
}

if (forceRescan) {
UpgradeManager.scanned = false;
}

const readyResult = await languageServerApiManager.ready();
this.setupWatcherForServerModeChange();

if (!readyResult) {
sendInfo(_operationId, { skipReason: "languageServerNotReady" });
return;
}
Expand All @@ -66,6 +75,19 @@ class UpgradeManager {
return;
}

if (UpgradeManager.scanned) {
return;
}
UpgradeManager.scanned = true;

workspace.workspaceFolders?.forEach((folder) =>
UpgradeManager.runDependencyCheckup(folder)
);
})();
}

private static async runDependencyCheckup(folder: WorkspaceFolder) {
return instrumentOperation("java.dependency.runDependencyCheckup", async (_operationId: string) => {
const projects = await Jdtls.getProjects(folder.uri.toString());
const projectDirectDepsResults = await Promise.allSettled(
projects.map(async (projectNode) => ({
Expand All @@ -89,6 +111,23 @@ class UpgradeManager {
}
})();
}

private static setupWatcherForServerModeChange() {
if (UpgradeManager.watcherSetup) {
return;
}

const extensionApi = languageServerApiManager.getExtensionApi();
if (extensionApi.onDidServerModeChange) {
const onDidServerModeChange: Event<string> = extensionApi.onDidServerModeChange;
contextManager.context.subscriptions.push(onDidServerModeChange((mode: LanguageServerMode) => {
if (mode !== LanguageServerMode.LightWeight) {
setImmediate(() => UpgradeManager.scan(`languageServerModeChangeTo${mode}`, false));
}
}));
UpgradeManager.watcherSetup = true;
}
}
}

export default UpgradeManager;
Loading