From b9210e5698751db9be27394b4700b2279ae1a8e2 Mon Sep 17 00:00:00 2001 From: FluoriteCafe-work <202210574+FluoriteCafe-work@users.noreply.github.com> Date: Fri, 23 Jan 2026 07:42:17 +0000 Subject: [PATCH 1/9] chore: expose `extensionApi` --- src/languageServerApi/languageServerApiManager.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/languageServerApi/languageServerApiManager.ts b/src/languageServerApi/languageServerApiManager.ts index 494c08a4..28d2d20b 100644 --- a/src/languageServerApi/languageServerApiManager.ts +++ b/src/languageServerApi/languageServerApiManager.ts @@ -99,6 +99,10 @@ class LanguageServerApiManager { public isReady(timeout: number): Promise { return Promise.race([this.ready(), new Promise((resolve) => setTimeout(() => resolve(false), timeout))]); } + + public getExtensionApi() { + return this.extensionApi; + } } export const languageServerApiManager: LanguageServerApiManager = new LanguageServerApiManager(); From 2e2ffafc8d6da660d6df985e84abc26c2231afc4 Mon Sep 17 00:00:00 2001 From: FluoriteCafe-work <202210574+FluoriteCafe-work@users.noreply.github.com> Date: Fri, 23 Jan 2026 07:46:47 +0000 Subject: [PATCH 2/9] chore: move prechecks to `scan()` --- src/upgrade/upgradeManager.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/upgrade/upgradeManager.ts b/src/upgrade/upgradeManager.ts index 155eda17..71071ff4 100644 --- a/src/upgrade/upgradeManager.ts +++ b/src/upgrade/upgradeManager.ts @@ -45,16 +45,11 @@ class UpgradeManager { } public static scan() { - if (!shouldRunCheckup()) { - return; - } - workspace.workspaceFolders?.forEach((folder) => - UpgradeManager.runDependencyCheckup(folder) - ); - } + return instrumentOperation("java.dependency.scan", async (_operationId: string) => { + if (!shouldRunCheckup()) { + return; + } - private static async runDependencyCheckup(folder: WorkspaceFolder) { - return instrumentOperation("java.dependency.runDependencyCheckup", async (_operationId: string) => { if (!(await languageServerApiManager.ready())) { sendInfo(_operationId, { skipReason: "languageServerNotReady" }); return; @@ -66,6 +61,14 @@ class UpgradeManager { return; } + 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) => ({ From 0e7c8665fa2ac890d7c9bd1ef96d32a772aa1168 Mon Sep 17 00:00:00 2001 From: FluoriteCafe-work <202210574+FluoriteCafe-work@users.noreply.github.com> Date: Fri, 23 Jan 2026 07:48:42 +0000 Subject: [PATCH 3/9] feat: setup monitoring on `serverMode` --- src/upgrade/upgradeManager.ts | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/upgrade/upgradeManager.ts b/src/upgrade/upgradeManager.ts index 71071ff4..028a11c5 100644 --- a/src/upgrade/upgradeManager.ts +++ b/src/upgrade/upgradeManager.ts @@ -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"; @@ -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."; @@ -21,6 +23,8 @@ function shouldRunCheckup() { } class UpgradeManager { + private static watcherSetup = false; + public static initialize(context: ExtensionContext) { notificationManager.initialize(context); @@ -55,6 +59,8 @@ class UpgradeManager { return; } + UpgradeManager.setupWatcherForServerModeChange(); + const hasJavaError: boolean = await Jdtls.checkImportStatus(); if (hasJavaError) { sendInfo(_operationId, { skipReason: "hasJavaError" }); @@ -92,6 +98,23 @@ class UpgradeManager { } })(); } + + private static setupWatcherForServerModeChange() { + if (UpgradeManager.watcherSetup) { + return; + } + + const extensionApi = languageServerApiManager.getExtensionApi(); + if (extensionApi.onDidServerModeChange) { + const onDidServerModeChange: Event = extensionApi.onDidServerModeChange; + contextManager.context.subscriptions.push(onDidServerModeChange((mode: LanguageServerMode) => { + if (mode !== LanguageServerMode.LightWeight) { + UpgradeManager.scan(); + } + })); + UpgradeManager.watcherSetup = true; + } + } } export default UpgradeManager; \ No newline at end of file From 850bcd15feac04a24e2bec91fa9e0d88f7fe5da0 Mon Sep 17 00:00:00 2001 From: FluoriteCafe-work <202210574+FluoriteCafe-work@users.noreply.github.com> Date: Fri, 23 Jan 2026 07:51:01 +0000 Subject: [PATCH 4/9] fix: avoid repeated scan until workspace folder changes --- src/syncHandler.ts | 2 +- src/upgrade/upgradeManager.ts | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/syncHandler.ts b/src/syncHandler.ts index cbdd05eb..c74e5a1d 100644 --- a/src/syncHandler.ts +++ b/src/syncHandler.ts @@ -47,7 +47,7 @@ class SyncHandler implements Disposable { this.disposables.push(workspace.onDidChangeWorkspaceFolders(() => { this.refresh(); - setImmediate(() => upgradeManager.scan()); // Deferred + setImmediate(() => upgradeManager.scan(true)); // Deferred })); try { diff --git a/src/upgrade/upgradeManager.ts b/src/upgrade/upgradeManager.ts index 028a11c5..254c70bb 100644 --- a/src/upgrade/upgradeManager.ts +++ b/src/upgrade/upgradeManager.ts @@ -24,6 +24,7 @@ function shouldRunCheckup() { class UpgradeManager { private static watcherSetup = false; + private static scanned = false; public static initialize(context: ExtensionContext) { notificationManager.initialize(context); @@ -45,15 +46,19 @@ class UpgradeManager { })); // Defer the expensive scan operation to not block extension activation - setImmediate(() => UpgradeManager.scan()); + setImmediate(() => UpgradeManager.scan(false)); } - public static scan() { + public static scan(forceRescan: boolean) { return instrumentOperation("java.dependency.scan", async (_operationId: string) => { if (!shouldRunCheckup()) { return; } + if (forceRescan) { + UpgradeManager.scanned = false; + } + if (!(await languageServerApiManager.ready())) { sendInfo(_operationId, { skipReason: "languageServerNotReady" }); return; @@ -67,6 +72,11 @@ class UpgradeManager { return; } + if (UpgradeManager.scanned) { + return; + } + UpgradeManager.scanned = true; + workspace.workspaceFolders?.forEach((folder) => UpgradeManager.runDependencyCheckup(folder) ); @@ -109,7 +119,7 @@ class UpgradeManager { const onDidServerModeChange: Event = extensionApi.onDidServerModeChange; contextManager.context.subscriptions.push(onDidServerModeChange((mode: LanguageServerMode) => { if (mode !== LanguageServerMode.LightWeight) { - UpgradeManager.scan(); + UpgradeManager.scan(false); } })); UpgradeManager.watcherSetup = true; From fdf63c1189b9aa42a575641cea9a75bcec99b202 Mon Sep 17 00:00:00 2001 From: FluoriteCafe-work <202210574+FluoriteCafe-work@users.noreply.github.com> Date: Fri, 23 Jan 2026 07:54:13 +0000 Subject: [PATCH 5/9] feat: always setup watch after `ready()` `ready()` is idompotent and initializes `extensionApi`. --- src/upgrade/upgradeManager.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/upgrade/upgradeManager.ts b/src/upgrade/upgradeManager.ts index 254c70bb..5b27d0a9 100644 --- a/src/upgrade/upgradeManager.ts +++ b/src/upgrade/upgradeManager.ts @@ -59,19 +59,20 @@ class UpgradeManager { UpgradeManager.scanned = false; } - if (!(await languageServerApiManager.ready())) { + const readyResult = await languageServerApiManager.ready(); + this.setupWatcherForServerModeChange(); + + if (!readyResult) { sendInfo(_operationId, { skipReason: "languageServerNotReady" }); return; } - UpgradeManager.setupWatcherForServerModeChange(); - const hasJavaError: boolean = await Jdtls.checkImportStatus(); if (hasJavaError) { sendInfo(_operationId, { skipReason: "hasJavaError" }); return; } - + if (UpgradeManager.scanned) { return; } From 8838ec43048bb2f97b834fdce6eccbcce1a8ce49 Mon Sep 17 00:00:00 2001 From: FluoriteCafe-work <202210574+FluoriteCafe-work@users.noreply.github.com> Date: Fri, 23 Jan 2026 07:59:54 +0000 Subject: [PATCH 6/9] feat: tell telemetry of reason to trigger scan --- src/syncHandler.ts | 2 +- src/upgrade/upgradeManager.ts | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/syncHandler.ts b/src/syncHandler.ts index c74e5a1d..4b1d9b6e 100644 --- a/src/syncHandler.ts +++ b/src/syncHandler.ts @@ -47,7 +47,7 @@ class SyncHandler implements Disposable { this.disposables.push(workspace.onDidChangeWorkspaceFolders(() => { this.refresh(); - setImmediate(() => upgradeManager.scan(true)); // Deferred + setImmediate(() => upgradeManager.scan("workspaceFoldersChange", true)); // Deferred })); try { diff --git a/src/upgrade/upgradeManager.ts b/src/upgrade/upgradeManager.ts index 5b27d0a9..6653d2ac 100644 --- a/src/upgrade/upgradeManager.ts +++ b/src/upgrade/upgradeManager.ts @@ -46,11 +46,13 @@ class UpgradeManager { })); // Defer the expensive scan operation to not block extension activation - setImmediate(() => UpgradeManager.scan(false)); + setImmediate(() => UpgradeManager.scan("initialization", false)); } - public static scan(forceRescan: boolean) { + public static scan(triggerReason: string, forceRescan: boolean) { return instrumentOperation("java.dependency.scan", async (_operationId: string) => { + sendInfo(_operationId, { triggerReason }); + if (!shouldRunCheckup()) { return; } @@ -120,7 +122,7 @@ class UpgradeManager { const onDidServerModeChange: Event = extensionApi.onDidServerModeChange; contextManager.context.subscriptions.push(onDidServerModeChange((mode: LanguageServerMode) => { if (mode !== LanguageServerMode.LightWeight) { - UpgradeManager.scan(false); + UpgradeManager.scan(`languageServerModeChangeTo${mode}`, false); } })); UpgradeManager.watcherSetup = true; From 1db972f4457f5576eda834a317730c9379291b90 Mon Sep 17 00:00:00 2001 From: FluoriteCafe-work <202210574+FluoriteCafe-work@users.noreply.github.com> Date: Fri, 23 Jan 2026 08:00:21 +0000 Subject: [PATCH 7/9] chore: use `setImmediate` on `scan()` --- src/upgrade/upgradeManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/upgrade/upgradeManager.ts b/src/upgrade/upgradeManager.ts index 6653d2ac..f54b9e57 100644 --- a/src/upgrade/upgradeManager.ts +++ b/src/upgrade/upgradeManager.ts @@ -122,7 +122,7 @@ class UpgradeManager { const onDidServerModeChange: Event = extensionApi.onDidServerModeChange; contextManager.context.subscriptions.push(onDidServerModeChange((mode: LanguageServerMode) => { if (mode !== LanguageServerMode.LightWeight) { - UpgradeManager.scan(`languageServerModeChangeTo${mode}`, false); + setImmediate(() => UpgradeManager.scan(`languageServerModeChangeTo${mode}`, false)); } })); UpgradeManager.watcherSetup = true; From 7a9cc181e234838cbd1926f71f8a9a67fa716c90 Mon Sep 17 00:00:00 2001 From: FluoriteCafe-work <202210574+FluoriteCafe-work@users.noreply.github.com> Date: Fri, 23 Jan 2026 08:09:19 +0000 Subject: [PATCH 8/9] chore: lint --- src/upgrade/upgradeManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/upgrade/upgradeManager.ts b/src/upgrade/upgradeManager.ts index f54b9e57..a08e6ebd 100644 --- a/src/upgrade/upgradeManager.ts +++ b/src/upgrade/upgradeManager.ts @@ -74,7 +74,7 @@ class UpgradeManager { sendInfo(_operationId, { skipReason: "hasJavaError" }); return; } - + if (UpgradeManager.scanned) { return; } From e17d8b564900faa080c99105eb8f2da0d71dfd62 Mon Sep 17 00:00:00 2001 From: FluoriteCafe-work <202210574+FluoriteCafe-work@users.noreply.github.com> Date: Fri, 23 Jan 2026 09:11:07 +0000 Subject: [PATCH 9/9] chore: functions are to be called --- src/upgrade/upgradeManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/upgrade/upgradeManager.ts b/src/upgrade/upgradeManager.ts index a08e6ebd..94c628d7 100644 --- a/src/upgrade/upgradeManager.ts +++ b/src/upgrade/upgradeManager.ts @@ -83,7 +83,7 @@ class UpgradeManager { workspace.workspaceFolders?.forEach((folder) => UpgradeManager.runDependencyCheckup(folder) ); - }); + })(); } private static async runDependencyCheckup(folder: WorkspaceFolder) {