From 6765a6eb371136c1b50db7457a3e777952095a09 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Fri, 27 Jan 2023 11:27:05 -0500 Subject: [PATCH] Return the API before importing the projects This also has the side effect that extensions that depend on vscode-java can start up sooner. Fixes #2900 Signed-off-by: David Thompson --- src/extension.ts | 18 ++++++++++-------- src/standardLanguageClient.ts | 6 ++---- src/syntaxLanguageClient.ts | 18 ++++-------------- test/lightweight-mode-suite/publicApi.test.ts | 10 +++++----- .../gotoSuperImplementation.test.ts | 6 ++++-- test/standard-mode-suite/publicApi.test.ts | 11 ++++++----- 6 files changed, 31 insertions(+), 38 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 5c950e73d..e77282eb8 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -243,12 +243,16 @@ export function activate(context: ExtensionContext): Promise { }; apiManager.initialize(requirements, serverMode); + resolve(apiManager.getApiInstance()); + // the promise is resolved + // no need to pass `resolve` into any code past this point, + // since `resolve` is a no-op from now on if (requireSyntaxServer) { if (process.env['SYNTAXLS_CLIENT_PORT']) { - syntaxClient.initialize(requirements, clientOptions, resolve); + syntaxClient.initialize(requirements, clientOptions); } else { - syntaxClient.initialize(requirements, clientOptions, resolve, prepareExecutable(requirements, syntaxServerWorkspacePath, getJavaConfig(requirements.java_home), context, true)); + syntaxClient.initialize(requirements, clientOptions, prepareExecutable(requirements, syntaxServerWorkspacePath, getJavaConfig(requirements.java_home), context, true)); } syntaxClient.start(); serverStatusBarProvider.showLightWeightStatus(); @@ -347,7 +351,7 @@ export function activate(context: ExtensionContext): Promise { } if (choice === "Yes") { - await startStandardServer(context, requirements, clientOptions, workspacePath, resolve); + await startStandardServer(context, requirements, clientOptions, workspacePath); } }); @@ -372,10 +376,8 @@ export function activate(context: ExtensionContext): Promise { const importOnStartup = config.get(importOnStartupSection); if (importOnStartup === "disabled" || env.uiKind === UIKind.Web && env.appName.includes("Visual Studio Code")) { - syntaxClient.resolveApi(resolve); requireStandardServer = false; } else if (importOnStartup === "interactive" && await workspaceContainsBuildFiles()) { - syntaxClient.resolveApi(resolve); requireStandardServer = await promptUserForStandardServer(config); } else { requireStandardServer = true; @@ -383,7 +385,7 @@ export function activate(context: ExtensionContext): Promise { } if (requireStandardServer) { - await startStandardServer(context, requirements, clientOptions, workspacePath, resolve); + await startStandardServer(context, requirements, clientOptions, workspacePath); } const onDidGrantWorkspaceTrust = (workspace as any).onDidGrantWorkspaceTrust; @@ -411,7 +413,7 @@ export function activate(context: ExtensionContext): Promise { }); } -async function startStandardServer(context: ExtensionContext, requirements: requirements.RequirementsData, clientOptions: LanguageClientOptions, workspacePath: string, resolve: (value?: ExtensionAPI | PromiseLike) => void) { +async function startStandardServer(context: ExtensionContext, requirements: requirements.RequirementsData, clientOptions: LanguageClientOptions, workspacePath: string) { if (standardClient.getClientStatus() !== ClientStatus.uninitialized) { return; } @@ -426,7 +428,7 @@ async function startStandardServer(context: ExtensionContext, requirements: requ apiManager.getApiInstance().serverMode = ServerMode.hybrid; apiManager.fireDidServerModeChange(ServerMode.hybrid); } - await standardClient.initialize(context, requirements, clientOptions, workspacePath, jdtEventEmitter, resolve); + await standardClient.initialize(context, requirements, clientOptions, workspacePath, jdtEventEmitter); standardClient.start(); serverStatusBarProvider.showStandardStatus(); } diff --git a/src/standardLanguageClient.ts b/src/standardLanguageClient.ts index b2a36c5eb..1e8f2e120 100644 --- a/src/standardLanguageClient.ts +++ b/src/standardLanguageClient.ts @@ -11,7 +11,7 @@ import { apiManager } from "./apiManager"; import * as buildPath from './buildpath'; import { javaRefactorKinds, RefactorDocumentProvider } from "./codeActionProvider"; import { Commands } from "./commands"; -import { ClientStatus, ExtensionAPI } from "./extension.api"; +import { ClientStatus } from "./extension.api"; import * as fileEventHandler from './fileEventHandler'; import { gradleCodeActionMetadata, GradleCodeActionProvider } from "./gradle/gradleCodeActionProvider"; import { JavaInlayHintsProvider } from "./inlayHintsProvider"; @@ -56,7 +56,7 @@ export class StandardLanguageClient { private languageClient: LanguageClient; private status: ClientStatus = ClientStatus.uninitialized; - public async initialize(context: ExtensionContext, requirements: RequirementsData, clientOptions: LanguageClientOptions, workspacePath: string, jdtEventEmitter: EventEmitter, resolve: (value: ExtensionAPI) => void): Promise { + public async initialize(context: ExtensionContext, requirements: RequirementsData, clientOptions: LanguageClientOptions, workspacePath: string, jdtEventEmitter: EventEmitter): Promise { if (this.status !== ClientStatus.uninitialized) { return; } @@ -139,13 +139,11 @@ export class StandardLanguageClient { serverStatus.updateServerStatus(ServerStatusKind.ready); commands.executeCommand('setContext', 'javaLSReady', true); apiManager.updateStatus(ClientStatus.started); - resolve(apiManager.getApiInstance()); break; case 'Error': this.status = ClientStatus.error; serverStatus.updateServerStatus(ServerStatusKind.error); apiManager.updateStatus(ClientStatus.error); - resolve(apiManager.getApiInstance()); break; case 'ProjectStatus': if (report.message === "WARNING") { diff --git a/src/syntaxLanguageClient.ts b/src/syntaxLanguageClient.ts index 0bc7bf477..86ab55450 100644 --- a/src/syntaxLanguageClient.ts +++ b/src/syntaxLanguageClient.ts @@ -5,10 +5,11 @@ import { DidChangeConfigurationNotification, LanguageClientOptions } from "vscod import { LanguageClient, ServerOptions, StreamInfo } from "vscode-languageclient/node"; import { apiManager } from "./apiManager"; import { ClientErrorHandler } from "./clientErrorHandler"; -import { ClientStatus, ExtensionAPI } from "./extension.api"; +import { ClientStatus } from "./extension.api"; import { logger } from "./log"; import { OutputInfoCollector } from "./outputInfoCollector"; import { StatusNotification } from "./protocol"; +import { RequirementsData } from "./requirements"; import { ServerMode } from "./settings"; import { snippetCompletionProvider } from "./snippetCompletionProvider"; import { getJavaConfig } from "./utils"; @@ -19,7 +20,7 @@ export class SyntaxLanguageClient { private languageClient: LanguageClient; private status: ClientStatus = ClientStatus.uninitialized; - public initialize(requirements, clientOptions: LanguageClientOptions, resolve: (value: ExtensionAPI) => void, serverOptions?: ServerOptions) { + public initialize(requirements: RequirementsData, clientOptions: LanguageClientOptions, serverOptions?: ServerOptions) { const newClientOptions: LanguageClientOptions = Object.assign({}, clientOptions, { middleware: { workspace: { @@ -75,7 +76,7 @@ export class SyntaxLanguageClient { break; } if (apiManager.getApiInstance().serverMode === ServerMode.lightWeight) { - this.resolveApiOnReady(resolve); + apiManager.fireDidServerModeChange(ServerMode.lightWeight); } }); }); @@ -111,15 +112,4 @@ export class SyntaxLanguageClient { return this.languageClient; } - public resolveApi(resolve: (value: ExtensionAPI) => void): void { - apiManager.getApiInstance().serverMode = ServerMode.lightWeight; - apiManager.fireDidServerModeChange(ServerMode.lightWeight); - this.resolveApiOnReady(resolve); - } - - private resolveApiOnReady(resolve: (value: ExtensionAPI) => void): void { - if ([ClientStatus.started, ClientStatus.error].includes(this.status)) { - resolve(apiManager.getApiInstance()); - } - } } diff --git a/test/lightweight-mode-suite/publicApi.test.ts b/test/lightweight-mode-suite/publicApi.test.ts index b1ee770b2..3a67f7bba 100644 --- a/test/lightweight-mode-suite/publicApi.test.ts +++ b/test/lightweight-mode-suite/publicApi.test.ts @@ -1,13 +1,13 @@ 'use strict'; import * as assert from 'assert'; +import * as fse from 'fs-extra'; import * as path from 'path'; -import { ExtensionAPI, extensionApiVersion, ClasspathResult } from '../../src/extension.api'; -import { Uri, DocumentSymbol, extensions, commands } from 'vscode'; +import { commands, DocumentSymbol, extensions, Uri } from 'vscode'; +import { Commands } from '../../src/commands'; +import { ClasspathResult, ExtensionAPI, extensionApiVersion } from '../../src/extension.api'; import { ServerMode } from '../../src/settings'; -import * as fse from 'fs-extra'; import { getJavaConfiguration } from '../../src/utils'; -import { Commands } from '../../src/commands'; import { constants } from '../common'; const pomPath: string = path.join(constants.projectFsPath, 'pom.xml'); @@ -31,7 +31,7 @@ suite('Public APIs - LightWeight', () => { test('status should be correct', async function () { const api: ExtensionAPI = extensions.getExtension('redhat.java').exports; - assert.equal(api.status, 'Started'); + assert.equal(api.status, 'Starting'); }); test('registerHoverCommand should work', async function () { diff --git a/test/standard-mode-suite/gotoSuperImplementation.test.ts b/test/standard-mode-suite/gotoSuperImplementation.test.ts index 109e5ace1..34a1285d1 100644 --- a/test/standard-mode-suite/gotoSuperImplementation.test.ts +++ b/test/standard-mode-suite/gotoSuperImplementation.test.ts @@ -2,8 +2,9 @@ import * as assert from 'assert'; import * as path from 'path'; -import { Uri, extensions, commands, TextDocument, workspace, window, Selection, Position } from 'vscode'; +import { commands, extensions, Position, Selection, TextDocument, Uri, window, workspace } from 'vscode'; import { Commands } from '../../src/commands'; +import { ExtensionAPI } from '../../src/extension.api'; const projectFsPath: string = path.join(__dirname, '..', '..', '..', 'test', 'resources', 'projects', 'maven', 'salut'); const fileFsPath: string = path.join(projectFsPath, 'src', 'main', 'java', 'java', 'Foo3.java'); @@ -11,7 +12,8 @@ const fileFsPath: string = path.join(projectFsPath, 'src', 'main', 'java', 'java suite('Goto Super Implementation', () => { suiteSetup(async function() { - await extensions.getExtension('redhat.java').activate(); + const api: ExtensionAPI = await extensions.getExtension('redhat.java').activate(); + await api.serverReady(); }); test('go to super implementation should work', async function () { diff --git a/test/standard-mode-suite/publicApi.test.ts b/test/standard-mode-suite/publicApi.test.ts index e349a81dc..2141aa486 100644 --- a/test/standard-mode-suite/publicApi.test.ts +++ b/test/standard-mode-suite/publicApi.test.ts @@ -1,15 +1,15 @@ 'use strict'; import * as assert from 'assert'; +import * as fse from 'fs-extra'; import * as path from 'path'; -import { ExtensionAPI, extensionApiVersion, ClasspathResult } from '../../src/extension.api'; -import { Uri, DocumentSymbol, extensions, commands } from 'vscode'; +import { env } from 'process'; +import { commands, DocumentSymbol, extensions, Uri } from 'vscode'; +import { Commands } from '../../src/commands'; +import { ClasspathResult, ExtensionAPI, extensionApiVersion } from '../../src/extension.api'; import { ServerMode } from '../../src/settings'; -import * as fse from 'fs-extra'; import { getJavaConfiguration } from '../../src/utils'; -import { Commands } from '../../src/commands'; import { constants } from '../common'; -import { env } from 'process'; const pomPath: string = path.join(constants.projectFsPath, 'pom.xml'); const gradleTestFolder: string = path.join(constants.projectFsPath, 'testGradle'); @@ -34,6 +34,7 @@ suite('Public APIs - Standard', () => { test('status should be correct', async function () { const api: ExtensionAPI = extensions.getExtension('redhat.java').exports; + await api.serverReady(); assert.equal(api.status, 'Started'); });