Skip to content

Commit b98c800

Browse files
authored
Merge branch 'main' into wenyt/fixui
2 parents d2aaddc + abf89fd commit b98c800

File tree

4 files changed

+203
-53
lines changed

4 files changed

+203
-53
lines changed

package-lock.json

Lines changed: 42 additions & 49 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/commands.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ export namespace Commands {
2626

2727
export const VIEW_PACKAGE_INTERNAL_REFRESH = "_java.view.package.internal.refresh";
2828

29+
export const VIEW_PACKAGE_INTERNAL_ADD_PROJECTS = "_java.view.package.internal.addProjects";
30+
2931
export const VIEW_PACKAGE_OUTLINE = "java.view.package.outline";
3032

3133
export const VIEW_PACKAGE_REVEAL_FILE_OS = "java.view.package.revealFileInOS";

src/languageServerApi/languageServerApiManager.ts

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class LanguageServerApiManager {
1313
private extensionApi: any;
1414

1515
private isServerReady: boolean = false;
16+
private isServerRunning: boolean = false;
17+
private serverReadyWaitStarted: boolean = false;
1618

1719
public async ready(): Promise<boolean> {
1820
if (this.isServerReady) {
@@ -28,11 +30,49 @@ class LanguageServerApiManager {
2830
return false;
2931
}
3032

33+
// Use serverRunning() if available (API >= 0.14) for progressive loading.
34+
// This resolves when the server process is alive and can handle requests,
35+
// even if project imports haven't completed yet. This enables the tree view
36+
// to show projects incrementally as they are imported.
37+
if (!this.isServerRunning && this.extensionApi.serverRunning) {
38+
await this.extensionApi.serverRunning();
39+
this.isServerRunning = true;
40+
return true;
41+
}
42+
if (this.isServerRunning) {
43+
return true;
44+
}
45+
46+
// Fallback for older API versions: wait for full server readiness
3147
await this.extensionApi.serverReady();
3248
this.isServerReady = true;
3349
return true;
3450
}
3551

52+
/**
53+
* Start a background wait for full server readiness (import complete).
54+
* When the server finishes importing, trigger a full refresh to replace
55+
* progressive placeholder items with proper data from the server.
56+
* Guarded so it only starts once regardless of call order.
57+
*/
58+
private startServerReadyWait(): void {
59+
if (this.serverReadyWaitStarted || this.isServerReady) {
60+
return;
61+
}
62+
if (this.extensionApi?.serverReady) {
63+
this.serverReadyWaitStarted = true;
64+
this.extensionApi.serverReady()
65+
.then(() => {
66+
this.isServerReady = true;
67+
commands.executeCommand(Commands.VIEW_PACKAGE_INTERNAL_REFRESH, /* debounce = */false);
68+
})
69+
.catch((_error: unknown) => {
70+
// Server failed to become ready (e.g., startup failure).
71+
// Leave isServerReady as false; progressive items remain as-is.
72+
});
73+
}
74+
}
75+
3676
public async initializeJavaLanguageServerApis(): Promise<void> {
3777
if (this.isApiInitialized()) {
3878
return;
@@ -49,18 +89,39 @@ class LanguageServerApiManager {
4989
}
5090

5191
this.extensionApi = extensionApi;
92+
// Start background wait for full server readiness unconditionally.
93+
// This ensures isServerReady is set and final refresh fires even
94+
// if onDidProjectsImport sets isServerRunning before ready() runs.
95+
this.startServerReadyWait();
96+
5297
if (extensionApi.onDidClasspathUpdate) {
5398
const onDidClasspathUpdate: Event<Uri> = extensionApi.onDidClasspathUpdate;
54-
contextManager.context.subscriptions.push(onDidClasspathUpdate(() => {
55-
commands.executeCommand(Commands.VIEW_PACKAGE_INTERNAL_REFRESH, /* debounce = */true);
99+
contextManager.context.subscriptions.push(onDidClasspathUpdate((uri: Uri) => {
100+
if (this.isServerReady) {
101+
// Server is fully ready — do a normal refresh to get full project data.
102+
commands.executeCommand(Commands.VIEW_PACKAGE_INTERNAL_REFRESH, /* debounce = */true);
103+
} else {
104+
// During import, the server is blocked and can't respond to queries.
105+
// Don't clear progressive items. Try to add the project if not
106+
// already present (typically a no-op since ProjectsImported fires first).
107+
commands.executeCommand(Commands.VIEW_PACKAGE_INTERNAL_ADD_PROJECTS, [uri.toString()]);
108+
}
56109
syncHandler.updateFileWatcher(Settings.autoRefresh());
57110
}));
58111
}
59112

60113
if (extensionApi.onDidProjectsImport) {
61114
const onDidProjectsImport: Event<Uri[]> = extensionApi.onDidProjectsImport;
62-
contextManager.context.subscriptions.push(onDidProjectsImport(() => {
63-
commands.executeCommand(Commands.VIEW_PACKAGE_INTERNAL_REFRESH, /* debounce = */true);
115+
contextManager.context.subscriptions.push(onDidProjectsImport((uris: Uri[]) => {
116+
// Server is sending project data, so it's definitely running.
117+
// Mark as running so ready() returns immediately on subsequent calls.
118+
this.isServerRunning = true;
119+
// During import, the JDTLS server is blocked by Eclipse workspace
120+
// operations and cannot respond to queries. Instead of triggering
121+
// a refresh (which queries the server), directly add projects to
122+
// the tree view from the notification data.
123+
const projectUris = uris.map(u => u.toString());
124+
commands.executeCommand(Commands.VIEW_PACKAGE_INTERNAL_ADD_PROJECTS, projectUris);
64125
syncHandler.updateFileWatcher(Settings.autoRefresh());
65126
}));
66127
}
@@ -91,6 +152,14 @@ class LanguageServerApiManager {
91152
return this.extensionApi !== undefined;
92153
}
93154

155+
/**
156+
* Returns true if the server has fully completed initialization (import finished).
157+
* During progressive loading, this returns false even though ready() has resolved.
158+
*/
159+
public isFullyReady(): boolean {
160+
return this.isServerReady;
161+
}
162+
94163
/**
95164
* Check if the language server is ready in the given timeout.
96165
* @param timeout the timeout in milliseconds to wait

0 commit comments

Comments
 (0)