diff --git a/vscode/src/commands/cache.ts b/vscode/src/commands/cache.ts index a9d0cdd3..140f8c17 100644 --- a/vscode/src/commands/cache.ts +++ b/vscode/src/commands/cache.ts @@ -14,16 +14,16 @@ limitations under the License. */ import { commands, window } from "vscode"; -import { globalVars } from "../extension"; import { builtInCommands, extCommands } from "./commands"; import { ICommand } from "./types"; import { l10n } from "../localiser"; import * as fs from 'fs'; import * as path from 'path'; +import { globalState } from "../globalState"; const deleteCache = async () => { // TODO: Change workspace path to userdir path - const storagePath = globalVars.extensionInfo.getWorkspaceStorage()?.fsPath; + const storagePath = globalState.getExtensionContextInfo().getWorkspaceStorage()?.fsPath; if (!storagePath) { window.showErrorMessage(l10n.value("jdk.extension.cache.error_msg.cannotFindWrkSpacePath")); return; @@ -38,9 +38,9 @@ const deleteCache = async () => { if (confirmation === yes) { const reloadWindowActionLabel = l10n.value("jdk.extension.cache.label.reloadWindow"); try { - await globalVars.clientPromise.stopClient(); - globalVars.deactivated = true; - await globalVars.nbProcessManager?.killProcess(false); + await globalState.getClientPromise().stopClient(); + globalState.setDeactivated(true); + await globalState.getNbProcessManager()?.killProcess(false); await fs.promises.rmdir(userDir, { recursive: true }); await window.showInformationMessage(l10n.value("jdk.extension.message.cacheDeleted"), reloadWindowActionLabel); } catch (err) { diff --git a/vscode/src/commands/create.ts b/vscode/src/commands/create.ts index 9b0d66e1..3f41b08e 100644 --- a/vscode/src/commands/create.ts +++ b/vscode/src/commands/create.ts @@ -20,12 +20,12 @@ import { l10n } from "../localiser"; import * as os from 'os'; import * as fs from 'fs'; import { ICommand } from "./types"; -import { globalVars } from "../extension"; import { getContextUri, isNbCommandRegistered } from "./utils"; import { isString } from "../utils"; +import { globalState } from "../globalState"; const newFromTemplate = async (ctx: any, template: any) => { - const client: LanguageClient = await globalVars.clientPromise.client; + const client: LanguageClient = await globalState.getClientPromise().client; if (await isNbCommandRegistered(nbCommands.newFromTemplate)) { const workspaces = workspace.workspaceFolders; @@ -72,7 +72,7 @@ const newFromTemplate = async (ctx: any, template: any) => { } const newProject = async (ctx: any) => { - const client: LanguageClient = await globalVars.clientPromise.client; + const client: LanguageClient = await globalState.getClientPromise().client; if (await isNbCommandRegistered(nbCommands.newProject)) { const res = await commands.executeCommand(nbCommands.newProject, getContextUri(ctx)?.toString()); if (isString(res)) { diff --git a/vscode/src/commands/navigation.ts b/vscode/src/commands/navigation.ts index 76bb2bcf..c46da232 100644 --- a/vscode/src/commands/navigation.ts +++ b/vscode/src/commands/navigation.ts @@ -19,12 +19,12 @@ import { l10n } from "../localiser"; import * as path from 'path'; import { ICommand } from "./types"; import { LanguageClient } from "vscode-languageclient/node"; -import { globalVars } from "../extension"; import { LOGGER } from '../logger'; import { getContextUri, isNbCommandRegistered, wrapCommandWithProgress } from "./utils"; +import { globalState } from "../globalState"; const goToTest = async (ctx: any) => { - let client: LanguageClient = await globalVars.clientPromise.client; + let client: LanguageClient = await globalState.getClientPromise().client; if (await isNbCommandRegistered(nbCommands.goToTest)) { try { const res: any = await commands.executeCommand(nbCommands.goToTest, getContextUri(ctx)?.toString()); diff --git a/vscode/src/commands/refactor.ts b/vscode/src/commands/refactor.ts index 42e62af4..b6b402b5 100644 --- a/vscode/src/commands/refactor.ts +++ b/vscode/src/commands/refactor.ts @@ -18,9 +18,9 @@ import { ICommand } from "./types"; import { extConstants } from "../constants"; import { builtInCommands, extCommands, nbCommands } from "./commands"; import { l10n } from "../localiser"; -import { globalVars } from "../extension"; import { WorkspaceEdit } from 'vscode-languageserver-protocol'; import { SymbolInformation } from 'vscode-languageclient'; +import { globalState } from "../globalState"; const goToSuperImplementationHandler = async () => { if (window.activeTextEditor?.document.languageId !== extConstants.LANGUAGE_ID) { @@ -48,7 +48,7 @@ const surroundWithHandler = async (items: any) => { const selected: any = await window.showQuickPick(items, { placeHolder: l10n.value('jdk.extension.command.quickPick.placeholder.surroundWith') }); if (selected) { if (selected.userData.edit) { - const client = await globalVars.clientPromise.client; + const client = await globalState.getClientPromise().client; const edit = await client.protocol2CodeConverter.asWorkspaceEdit(selected.userData.edit as WorkspaceEdit); await workspace.applyEdit(edit); await commands.executeCommand(builtInCommands.focusActiveEditorGroup); @@ -60,7 +60,7 @@ const surroundWithHandler = async (items: any) => { const codeGenerateHandler = async (command: any, data: any) => { const edit: any = await commands.executeCommand(command, data); if (edit) { - const client = await globalVars.clientPromise.client; + const client = await globalState.getClientPromise().client; const wsEdit = await client.protocol2CodeConverter.asWorkspaceEdit(edit as WorkspaceEdit); await workspace.applyEdit(wsEdit); await commands.executeCommand(builtInCommands.focusActiveEditorGroup); @@ -76,7 +76,7 @@ const completeAbstractMethodsHandler = async () => { } const workspaceSymbolsHandler = async (query: any) => { - const client = await globalVars.clientPromise.client; + const client = await globalState.getClientPromise().client; return (await client.sendRequest("workspace/symbol", { "query": query })) ?? []; } diff --git a/vscode/src/commands/runConfiguration.ts b/vscode/src/commands/runConfiguration.ts index 0d78fe64..5c4071fd 100644 --- a/vscode/src/commands/runConfiguration.ts +++ b/vscode/src/commands/runConfiguration.ts @@ -15,13 +15,13 @@ */ import { extCommands } from "./commands"; -import { globalVars } from "../extension"; import { configureRunSettings } from "../views/runConfiguration"; import { ICommand } from "./types"; +import { globalState } from "../globalState"; const configureRunSettingsHandler = (...params: any[]) => { - configureRunSettings(globalVars.extensionInfo.getExtensionContext(), params); + configureRunSettings(globalState.getExtensionContextInfo().getExtensionContext(), params); } diff --git a/vscode/src/commands/utilCommands.ts b/vscode/src/commands/utilCommands.ts index 36576b29..88d21270 100644 --- a/vscode/src/commands/utilCommands.ts +++ b/vscode/src/commands/utilCommands.ts @@ -13,21 +13,16 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { globalVars } from "../extension"; +import { globalState } from "../globalState"; import { extCommands } from "./commands"; import { ICommand } from "./types"; const startupConditionHandler = () => { - return globalVars.clientPromise.client; + return globalState.getClientPromise().client; } const addEventListenerHandler = async (eventName: any, listener: any) => { - let ls = globalVars.listeners.get(eventName); - if (!ls) { - ls = []; - globalVars.listeners.set(eventName, ls); - } - ls.push(listener); + globalState.addListener(eventName, listener); } diff --git a/vscode/src/commands/utils.ts b/vscode/src/commands/utils.ts index 15eae815..6e787523 100644 --- a/vscode/src/commands/utils.ts +++ b/vscode/src/commands/utils.ts @@ -17,9 +17,9 @@ import { commands, OutputChannel, ProgressLocation, Uri, window } from "vscode"; import { nbCommands } from "./commands"; import { ProjectActionParams } from "../lsp/protocol"; import { LanguageClient } from "vscode-languageclient/node"; -import { globalVars } from "../extension"; import { l10n } from "../localiser"; import { LOGGER } from "../logger"; +import { globalState } from "../globalState"; export const getContextUri = (ctx: any): Uri | undefined => { if (ctx?.fsPath) { @@ -78,7 +78,7 @@ export const wrapProjectActionWithProgress = (action: string, configuration: str export const wrapCommandWithProgress = (lsCommand: string, title: string, log?: OutputChannel, ...args: any[]): Thenable => { return window.withProgress({ location: ProgressLocation.Window }, p => { return new Promise(async (resolve, reject) => { - let c: LanguageClient = await globalVars.clientPromise.client; + let c: LanguageClient = await globalState.getClientPromise().client; if (await isNbCommandRegistered(lsCommand)) { p.report({ message: title }); c.outputChannel.show(true); diff --git a/vscode/src/configurations/handlers.ts b/vscode/src/configurations/handlers.ts index caf1ea4d..2263bd8a 100644 --- a/vscode/src/configurations/handlers.ts +++ b/vscode/src/configurations/handlers.ts @@ -18,10 +18,10 @@ import { ConfigurationTarget, extensions, workspace, WorkspaceConfiguration } fr import { builtInConfigKeys, configKeys } from "./configuration"; import { extConstants, NODE_WINDOWS_LABEL } from "../constants"; import * as os from 'os'; -import { globalVars } from "../extension"; import { LOGGER } from "../logger"; import * as path from 'path'; import * as fs from 'fs'; +import { globalState } from "../globalState"; export const getConfiguration = (key: string = extConstants.COMMAND_PREFIX): WorkspaceConfiguration => { return workspace.getConfiguration(key); @@ -114,11 +114,12 @@ export const isDarkColorThemeHandler = (): boolean => { } export const userdirHandler = (): string => { + const extensionContextInfo = globalState.getExtensionContextInfo(); const userdirScope = process.env['nbcode_userdir'] || getConfigurationValue(configKeys.userdir, "local"); - const workspaceStoragePath = globalVars.extensionInfo.getWorkspaceStorage()?.fsPath; + const workspaceStoragePath = extensionContextInfo.getWorkspaceStorage()?.fsPath; const userdirParentDir = userdirScope === "local" && workspaceStoragePath ? workspaceStoragePath - : globalVars.extensionInfo.getGlobalStorage().fsPath; + : extensionContextInfo.getGlobalStorage().fsPath; if (!userdirParentDir) { throw new Error(`Cannot create path for ${userdirScope} directory.`); diff --git a/vscode/src/configurations/listener.ts b/vscode/src/configurations/listener.ts index 646c1895..53363a9f 100644 --- a/vscode/src/configurations/listener.ts +++ b/vscode/src/configurations/listener.ts @@ -15,15 +15,15 @@ */ import { ConfigurationChangeEvent, ExtensionContext, workspace } from "vscode"; -import { globalVars } from "../extension"; import { userConfigsListened } from "./configuration"; import { Disposable } from "vscode-languageclient"; +import { globalState } from "../globalState"; const configChangeHandler = (params: ConfigurationChangeEvent) => { userConfigsListened.forEach((config: string) => { const doesAffect = params.affectsConfiguration(config); if (doesAffect) { - globalVars.clientPromise.restartExtension(globalVars.nbProcessManager, true); + globalState.getClientPromise().restartExtension(globalState.getNbProcessManager(), true); } }); } diff --git a/vscode/src/debugger/debugger.ts b/vscode/src/debugger/debugger.ts index 0ce68b2e..f71690e6 100644 --- a/vscode/src/debugger/debugger.ts +++ b/vscode/src/debugger/debugger.ts @@ -22,10 +22,10 @@ import { DebugConnector } from '../lsp/protocol'; import { extConstants } from '../constants'; import { l10n } from '../localiser'; import { StreamDebugAdapter } from './streamDebugAdapter'; -import { globalVars } from '../extension'; import { extCommands, nbCommands } from '../commands/commands'; import { argumentsNode, environmentVariablesNode, vmOptionsNode, workingDirectoryNode } from '../views/runConfiguration'; import { initializeRunConfiguration } from '../utils'; +import { globalState } from '../globalState'; export function registerDebugger(context: ExtensionContext): void { let debugTrackerFactory = new NetBeansDebugAdapterTrackerFactory(); @@ -50,8 +50,9 @@ class NetBeansDebugAdapterTrackerFactory implements vscode.DebugAdapterTrackerFa createDebugAdapterTracker(_session: vscode.DebugSession): vscode.ProviderResult { return { onDidSendMessage(message: any): void { - if (globalVars.testAdapter && message.type === 'event' && message.event === 'output') { - globalVars.testAdapter.testOutput(message.body.output); + const testAdapter = globalState.getTestAdapter(); + if (testAdapter && message.type === 'event' && message.event === 'output') { + testAdapter.testOutput(message.body.output); } } } @@ -64,7 +65,7 @@ class NetBeansDebugAdapterDescriptionFactory implements vscode.DebugAdapterDescr return new Promise((resolve, reject) => { let cnt = 10; const fnc = () => { - if (globalVars.debugPort < 0) { + if (globalState.getDebugPort() < 0) { if (cnt-- > 0) { setTimeout(fnc, 1000); } else { @@ -72,10 +73,10 @@ class NetBeansDebugAdapterDescriptionFactory implements vscode.DebugAdapterDescr } } else { // resolve(new vscode.DebugAdapterServer(debugPort)); - const socket = net.connect(globalVars.debugPort, "127.0.0.1", () => { }); + const socket = net.connect(globalState.getDebugPort(), "127.0.0.1", () => { }); socket.on("connect", () => { const adapter = new StreamDebugAdapter(); - socket.write(globalVars.debugHash ? globalVars.debugHash : ""); + socket.write(globalState?.getDebugHash() || ""); adapter.connect(socket, socket); resolve(new vscode.DebugAdapterInlineImplementation(adapter)); }); @@ -94,7 +95,7 @@ class NetBeansConfigurationInitialProvider implements vscode.DebugConfigurationP } async doProvideDebugConfigurations(folder: vscode.WorkspaceFolder | undefined, _token?: vscode.CancellationToken): Promise { - let c: LanguageClient = await globalVars.clientPromise.client; + let c: LanguageClient = await globalState.getClientPromise().client; if (!folder) { return []; } @@ -145,7 +146,7 @@ class NetBeansConfigurationDynamicProvider implements vscode.DebugConfigurationP } async doProvideDebugConfigurations(folder: vscode.WorkspaceFolder | undefined, context: ExtensionContext, commandValues: Map, _token?: vscode.CancellationToken): Promise { - let c: LanguageClient = await globalVars.clientPromise.client; + let c: LanguageClient = await globalState.getClientPromise().client; if (!folder) { return []; } diff --git a/vscode/src/extension.ts b/vscode/src/extension.ts index 852aff04..1dce05d3 100644 --- a/vscode/src/extension.ts +++ b/vscode/src/extension.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. + * Copyright (c) 2024, Oracle and/or its affiliates. * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -19,44 +19,25 @@ * under the License. */ -/* This file has been modified for Oracle Java SE extension */ - 'use strict'; -import { ExtensionContext, TextEditorDecorationType, Uri } from 'vscode'; -import { NbTestAdapter } from './views/TestViewController'; -import { SetTextEditorDecorationParams } from './lsp/protocol'; +import { ExtensionContext } from 'vscode'; import * as launchConfigurations from './launchConfigurations'; import { extConstants } from './constants'; -import { ExtensionInfo } from './extensionInfo'; -import { ClientPromise } from './lsp/clientPromise'; -import { NbProcessManager } from './lsp/nbProcessManager'; import { clientInit } from './lsp/initializer'; import { subscribeCommands } from './commands/register'; import { VSNetBeansAPI } from './lsp/types'; import { registerDebugger } from './debugger/debugger'; import { registerConfigChangeListeners } from './configurations/listener'; import { registerFileProviders } from './lsp/listeners/textDocumentContentProvider'; - -export namespace globalVars { - export const listeners = new Map(); - export let extensionInfo: ExtensionInfo; - export let clientPromise: ClientPromise; - export let debugPort: number = -1; - export let debugHash: string | undefined; - export let deactivated: boolean = true; - export let nbProcessManager: NbProcessManager | null; - export let testAdapter: NbTestAdapter | undefined; - export let decorations = new Map(); - export let decorationParamsByUri = new Map(); -} - +import { ExtensionContextInfo } from './extensionContextInfo'; +import { ClientPromise } from './lsp/clientPromise'; +import { globalState } from './globalState'; export function activate(context: ExtensionContext): VSNetBeansAPI { - globalVars.clientPromise = new ClientPromise(); - globalVars.extensionInfo = new ExtensionInfo(context); + globalState.initialize(new ExtensionContextInfo(context), new ClientPromise()); + globalState.getClientPromise().initialize(); - globalVars.clientPromise.initialize(); registerConfigChangeListeners(context); clientInit(); @@ -78,10 +59,10 @@ export function activate(context: ExtensionContext): VSNetBeansAPI { export function deactivate(): Thenable { - const process = globalVars.nbProcessManager?.getProcess(); + const process = globalState.getNbProcessManager()?.getProcess(); if (process != null) { process?.kill(); } - return globalVars.clientPromise.stopClient(); + return globalState.getClientPromise().stopClient(); } diff --git a/vscode/src/extensionInfo.ts b/vscode/src/extensionContextInfo.ts similarity index 96% rename from vscode/src/extensionInfo.ts rename to vscode/src/extensionContextInfo.ts index 65500f6e..da0cdeba 100644 --- a/vscode/src/extensionInfo.ts +++ b/vscode/src/extensionContextInfo.ts @@ -15,7 +15,7 @@ */ import { Disposable, ExtensionContext } from "vscode"; -export class ExtensionInfo { +export class ExtensionContextInfo { constructor(private context: ExtensionContext) { } getGlobalStorage = () => this.context.globalStorageUri; diff --git a/vscode/src/globalState.ts b/vscode/src/globalState.ts new file mode 100644 index 00000000..779e0b88 --- /dev/null +++ b/vscode/src/globalState.ts @@ -0,0 +1,145 @@ +/* + Copyright (c) 2023-2024, Oracle and/or its affiliates. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +import { TextEditorDecorationType, Uri } from 'vscode'; +import { NbTestAdapter } from './views/TestViewController'; +import { SetTextEditorDecorationParams } from './lsp/protocol'; +import { ExtensionContextInfo } from './extensionContextInfo'; +import { ClientPromise } from './lsp/clientPromise'; +import { NbProcessManager } from './lsp/nbProcessManager'; + +class GlobalState { + private initialized: boolean = false; + + private listeners: Map; + private extensionContextInfo!: ExtensionContextInfo; + private clientPromise!: ClientPromise; + private debugPort: number; + private debugHash?: string; + // TODO: Find a way in nbcode.ts processOnCloseHandler to handle exit code, + // so that deactivated can be removed from global state + private deactivated: boolean; + private nbProcessManager: NbProcessManager | null; + private testAdapter?: NbTestAdapter; + private decorations: Map; + private decorationParamsByUri: Map; + + public constructor() { + this.listeners = new Map(); + this.debugPort = -1; + this.deactivated = true; + this.nbProcessManager = null; + this.decorations = new Map(); + this.decorationParamsByUri = new Map(); + } + + public initialize(extensionContextInfo: ExtensionContextInfo, clientPromise: ClientPromise): void { + if (this.initialized) { + throw new Error('GlobalState has already been initialized'); + } + + this.clientPromise = clientPromise; + this.extensionContextInfo = extensionContextInfo; + this.initialized = true; + } + + public getListener(key: string): string[] | undefined { + return this.listeners.get(key); + } + + public getExtensionContextInfo(): ExtensionContextInfo { + return this.extensionContextInfo; + } + + public getClientPromise(): ClientPromise { + return this.clientPromise; + } + + public getDebugPort(): number { + return this.debugPort; + } + + public getDebugHash(): string | undefined { + return this.debugHash; + } + + public isDeactivated(): boolean { + return this.deactivated; + } + + public getNbProcessManager(): NbProcessManager | null { + return this.nbProcessManager; + } + + public getTestAdapter(): NbTestAdapter | undefined { + return this.testAdapter; + } + + public getDecoration(key: string): TextEditorDecorationType | undefined { + return this.decorations.get(key); + } + + public getDecorationParamsByUri(): ReadonlyMap { + return this.decorationParamsByUri; + } + + public getDecorationParamsByUriByKey(key: Uri): SetTextEditorDecorationParams | undefined { + return this.decorationParamsByUri.get(key); + } + + public addListener(key: string, value: string): void { + const existing = this.listeners.get(key) || []; + existing.push(value); + this.listeners.set(key, existing); + } + + public setDebugPort(port: number): void { + this.debugPort = port; + } + + public setDebugHash(hash: string): void { + this.debugHash = hash; + } + + public setDeactivated(state: boolean): void { + this.deactivated = state; + } + + public setNbProcessManager(manager: NbProcessManager | null): void { + this.nbProcessManager = manager; + } + + public setTestAdapter(adapter: NbTestAdapter | undefined): void { + this.testAdapter = adapter; + } + + public setDecoration(key: string, decoration: TextEditorDecorationType): void { + this.decorations.set(key, decoration); + } + + public setDecorationParams(uri: Uri, params: SetTextEditorDecorationParams): void { + this.decorationParamsByUri.set(uri, params); + } + + public removeDecoration(key: string): void { + this.decorations.delete(key); + } + + public removeDecorationParams(uri: Uri): void { + this.decorationParamsByUri.delete(uri); + } +} + +export const globalState = new GlobalState(); \ No newline at end of file diff --git a/vscode/src/lsp/clientPromise.ts b/vscode/src/lsp/clientPromise.ts index 960144ce..d24cdc2c 100644 --- a/vscode/src/lsp/clientPromise.ts +++ b/vscode/src/lsp/clientPromise.ts @@ -14,11 +14,11 @@ limitations under the License. */ import { commands } from "vscode"; -import { globalVars } from "../extension"; import { LOGGER } from "../logger"; import { NbProcessManager } from "./nbProcessManager"; import { clientInit } from "./initializer"; import { NbLanguageClient } from "./nbLanguageClient"; +import { globalState } from "../globalState"; export class ClientPromise { setClient!: [(c: NbLanguageClient) => void, (err: any) => void]; @@ -42,14 +42,15 @@ export class ClientPromise { } public initializedSuccessfully = (client: NbLanguageClient) => { - globalVars.clientPromise.setClient[0](client); + globalState.getClientPromise().setClient[0](client); commands.executeCommand('setContext', 'nbJdkReady', true); } public stopClient = async (): Promise => { - if (globalVars.testAdapter) { - globalVars.testAdapter.dispose(); - globalVars.testAdapter = undefined; + const testAdapter = globalState.getTestAdapter(); + if (testAdapter) { + testAdapter.dispose(); + globalState.setTestAdapter(undefined); } if (!this.client) { return Promise.resolve(); diff --git a/vscode/src/lsp/initializer.ts b/vscode/src/lsp/initializer.ts index 1c94aebc..793967bd 100644 --- a/vscode/src/lsp/initializer.ts +++ b/vscode/src/lsp/initializer.ts @@ -15,7 +15,6 @@ */ import { StreamInfo } from "vscode-languageclient/node"; import { getUserConfigLaunchOptionsDefaults } from "./launchOptions"; -import { globalVars } from "../extension"; import { LOGGER } from '../logger'; import { configKeys } from "../configurations/configuration"; import { enableDisableModules } from "./utils"; @@ -28,10 +27,11 @@ import { registerListenersAfterClientInit } from "../views/listener"; import { registerNotificationListeners } from "./listeners/notifications/register"; import { registerRequestListeners } from "./listeners/requests/register"; import { createViews } from "../views/initializer"; +import { globalState } from "../globalState"; const establishConnection = () => new Promise((resolve, reject) => { - const nbProcess = globalVars.nbProcessManager?.getProcess(); - const nbProcessManager = globalVars.nbProcessManager; + const nbProcessManager = globalState.getNbProcessManager(); + const nbProcess = nbProcessManager?.getProcess(); if (!nbProcessManager || !nbProcess) { reject(); @@ -49,7 +49,7 @@ const establishConnection = () => new Promise((resolve, reject) => { })).catch(err => { throw err }); } catch (err) { reject(err); - globalVars.nbProcessManager?.disconnect(); + globalState.getNbProcessManager()?.disconnect(); return; } }); @@ -60,14 +60,14 @@ const connectToServer = (nbProcess: ChildProcess): Promise => { reject('No stdout to parse!'); return; } - globalVars.debugPort = -1; + globalState.setDebugPort(-1); let lspServerStarted = false; nbProcess.stdout.on("data", (chunk) => { - if (globalVars.debugPort < 0) { + if (globalState.getDebugPort() < 0) { const info = chunk.toString().match(/Debug Server Adapter listening at port (\d*) with hash (.*)\n/); if (info) { - globalVars.debugPort = info[1]; - globalVars.debugHash = info[2]; + globalState.setDebugPort(info[1]); + globalState.setDebugHash(info[2]); } } if (!lspServerStarted) { @@ -91,7 +91,7 @@ const connectToServer = (nbProcess: ChildProcess): Promise => { const enableDisableNbjavacModule = () => { const userdirPath = getUserConfigLaunchOptionsDefaults()[configKeys.userdir].value const nbjavacValue = isNbJavacDisabledHandler(); - const extensionPath = globalVars.extensionInfo.getExtensionStorageUri().fsPath; + const extensionPath = globalState.getExtensionContextInfo().getExtensionStorageUri().fsPath; enableDisableModules(extensionPath, userdirPath, ['org.netbeans.libs.nbjavacapi'], !nbjavacValue); } @@ -102,7 +102,7 @@ const serverBuilder = () => { } export const clientInit = () => { - globalVars.deactivated = false; + globalState.setDeactivated(false); const connection: () => Promise = serverBuilder(); const client = NbLanguageClient.build(connection, LOGGER); @@ -115,7 +115,7 @@ export const clientInit = () => { registerRequestListeners(client); createViews(); LOGGER.log('Language Client: Ready'); - globalVars.clientPromise.initializedSuccessfully(client); + globalState.getClientPromise().initializedSuccessfully(client); - }).catch(globalVars.clientPromise.setClient[1]); + }).catch(globalState.getClientPromise().setClient[1]); } diff --git a/vscode/src/lsp/listeners/notifications/handlers.ts b/vscode/src/lsp/listeners/notifications/handlers.ts index 96bf257a..0db0c48e 100644 --- a/vscode/src/lsp/listeners/notifications/handlers.ts +++ b/vscode/src/lsp/listeners/notifications/handlers.ts @@ -21,8 +21,8 @@ import { isNbJavacDisabledHandler, updateConfigurationValue } from "../../../con import { l10n } from "../../../localiser"; import { configKeys } from "../../../configurations/configuration"; import { builtInCommands } from "../../../commands/commands"; -import { globalVars } from "../../../extension"; import { LOGGER } from '../../../logger'; +import { globalState } from "../../../globalState"; const checkInstallNbJavac = (msg: string) => { const NO_JAVA_SUPPORT = "Cannot initialize Java support"; @@ -74,32 +74,34 @@ const logMessageHandler = (param: any) => { } const testProgressHandler = (param: any) => { - if (globalVars.testAdapter) { - globalVars.testAdapter.testProgress(param.suite); + const testAdapter = globalState.getTestAdapter(); + if (testAdapter) { + testAdapter.testProgress(param.suite); } } const textEditorSetDecorationHandler = (param: any) => { - let decorationType = globalVars.decorations.get(param.key); + let decorationType = globalState.getDecoration(param.key); if (decorationType) { let editorsWithUri = window.visibleTextEditors.filter( editor => editor.document.uri.toString() == param.uri ); if (editorsWithUri.length > 0) { editorsWithUri[0].setDecorations(decorationType, asRanges(param.ranges)); - globalVars.decorationParamsByUri.set(editorsWithUri[0].document.uri, param); + globalState.setDecorationParams(editorsWithUri[0].document.uri, param); } } } const textEditorDecorationDisposeHandler = (param: any) => { - let decorationType = globalVars.decorations.get(param); + let decorationType = globalState.getDecoration(param); if (decorationType) { - globalVars.decorations.delete(param); + globalState.removeDecoration(param); decorationType.dispose(); - globalVars.decorationParamsByUri.forEach((value, key, map) => { + + globalState.getDecorationParamsByUri().forEach((value, key) => { if (value.key == param) { - map.delete(key); + globalState.removeDecorationParams(key); } }); } @@ -107,7 +109,7 @@ const textEditorDecorationDisposeHandler = (param: any) => { const telemetryEventHandler = (param: any) => { - const ls = globalVars.listeners.get(param); + const ls = globalState.getListener(param); if (ls) { for (const listener of ls) { commands.executeCommand(listener); diff --git a/vscode/src/lsp/listeners/requests/handlers.ts b/vscode/src/lsp/listeners/requests/handlers.ts index 918b2c61..da24cffa 100644 --- a/vscode/src/lsp/listeners/requests/handlers.ts +++ b/vscode/src/lsp/listeners/requests/handlers.ts @@ -14,7 +14,6 @@ limitations under the License. */ import { QuickPickItem, Uri, window, workspace, WorkspaceConfiguration } from "vscode"; -import { globalVars } from "../../../extension"; import { notificationOrRequestListenerType } from "../../types"; import { ExecInHtmlPageRequest, HtmlPageRequest, InputBoxRequest, InputBoxStep, MutliStepInputRequest, QuickPickRequest, QuickPickStep, SaveDocumentRequestParams, SaveDocumentsRequest, TextEditorDecorationCreateRequest, UpdateConfigurationRequest } from "../../protocol"; import { InputStep, MultiStepInput } from "../../../utils"; @@ -23,15 +22,16 @@ import { isError } from "../../../utils"; import { isString } from "../../../utils"; import { LOGGER } from "../../../logger"; import { execInHtmlPage, showHtmlPage } from "../../../webviews/nbWebviewHandler"; +import { globalState } from "../../../globalState"; const textEditorDecorationCreateRequestHandler = (param: any) => { let decorationType = window.createTextEditorDecorationType(param); - globalVars.decorations.set(decorationType.key, decorationType); + globalState.setDecoration(decorationType.key, decorationType); return decorationType.key; } const multiStepInputRequestHandler = async (param: any) => { - const client = await globalVars.clientPromise.client; + const client = await globalState.getClientPromise().client; const data: { [name: string]: readonly QuickPickItem[] | string } = {}; async function nextStep(input: MultiStepInput, step: number, state: { [name: string]: readonly QuickPickItem[] | string }): Promise { const inputStep = await client.sendRequest(MutliStepInputRequest.step, { inputId: param.id, step, data: state }); diff --git a/vscode/src/lsp/nbLanguageClient.ts b/vscode/src/lsp/nbLanguageClient.ts index a6cbfc12..c2f13885 100644 --- a/vscode/src/lsp/nbLanguageClient.ts +++ b/vscode/src/lsp/nbLanguageClient.ts @@ -21,7 +21,7 @@ import { extConstants } from "../constants"; import { userConfigsListenedByServer } from '../configurations/configuration'; import { restartWithJDKLater } from './utils'; import { ExtensionLogger } from '../logger'; -import { globalVars } from '../extension'; +import { globalState } from '../globalState'; export class NbLanguageClient extends LanguageClient { @@ -72,7 +72,7 @@ export class NbLanguageClient extends LanguageClient { }, closed: function (): CloseHandlerResult { logger.warn(`Connection to ${extConstants.SERVER_NAME} closed.`); - if (!globalVars.clientPromise.activationPending) { + if (!globalState.getClientPromise().activationPending) { restartWithJDKLater(10000, false); } return { action: CloseAction.DoNotRestart }; diff --git a/vscode/src/lsp/nbcode.ts b/vscode/src/lsp/nbcode.ts index f110f90b..681ed560 100644 --- a/vscode/src/lsp/nbcode.ts +++ b/vscode/src/lsp/nbcode.ts @@ -17,7 +17,6 @@ import { window } from "vscode"; import { configKeys } from "../configurations/configuration"; import { extConstants, NODE_WINDOWS_LABEL } from "../constants"; -import { globalVars } from "../extension"; import { prepareNbcodeLaunchOptions, getUserConfigLaunchOptionsDefaults } from "./launchOptions"; import { NbProcessManager } from "./nbProcessManager"; import { findNbcode } from "./utils"; @@ -25,12 +24,13 @@ import { l10n } from "../localiser"; import { jdkDownloaderPrompt } from "../webviews/jdkDownloader/prompt"; import { LOGGER } from "../logger"; import * as os from 'os'; +import { globalState } from "../globalState"; export const launchNbcode = (): void => { const ideLaunchOptions = prepareNbcodeLaunchOptions(); const userdir = getUserConfigLaunchOptionsDefaults()[configKeys.userdir].value; const specifiedJDK = getUserConfigLaunchOptionsDefaults()[configKeys.jdkHome].value; - const extensionPath = globalVars.extensionInfo.getExtensionStorageUri().fsPath; + const extensionPath = globalState.getExtensionContextInfo().getExtensionStorageUri().fsPath; const nbcodePath = findNbcode(extensionPath); const requiredJdk = specifiedJDK ? specifiedJDK : 'default system JDK'; @@ -42,8 +42,8 @@ export const launchNbcode = (): void => { LOGGER.log(launchMsg); window.setStatusBarMessage(launchMsg, 2000); - globalVars.nbProcessManager = new NbProcessManager(userdir, nbcodePath, ideLaunchOptions); - globalVars.nbProcessManager.startProcess(); + globalState.setNbProcessManager(new NbProcessManager(userdir, nbcodePath, ideLaunchOptions)); + globalState.getNbProcessManager()!.startProcess(); } @@ -65,7 +65,7 @@ export const attachNbProcessListeners = (nbProcessManager: NbProcessManager): vo const processOnDataHandler = (nbProcessManager: NbProcessManager, text: string, isOut: boolean) => { if (nbProcessManager) { - globalVars.clientPromise.activationPending = false; + globalState.getClientPromise().activationPending = false; } if(!text.match(/with hash/)){ LOGGER.logNoNL(text); @@ -82,14 +82,14 @@ const processOnDataHandler = (nbProcessManager: NbProcessManager, text: string, const processOnCloseHandler = (nbProcessManager: NbProcessManager, code: number): string | null => { - const globalnbProcessManager = globalVars.nbProcessManager; + const globalnbProcessManager = globalState.getNbProcessManager(); if (globalnbProcessManager == nbProcessManager) { - globalVars.nbProcessManager = null; + globalState.setNbProcessManager(null); if (code && code != 0) { window.showWarningMessage(l10n.value("jdk.extension.lspServer.warning_message.serverExited", { SERVER_NAME: extConstants.SERVER_NAME, code })); } } - if (nbProcessManager.getStdErr()?.match(/Cannot find java/) || (os.type() === NODE_WINDOWS_LABEL && !globalVars.deactivated)) { + if (nbProcessManager.getStdErr()?.match(/Cannot find java/) || (os.type() === NODE_WINDOWS_LABEL && !globalState.isDeactivated())) { jdkDownloaderPrompt(); } if (nbProcessManager.getStdOut() != null) { diff --git a/vscode/src/lsp/utils.ts b/vscode/src/lsp/utils.ts index 807cf0a3..82f66e1f 100644 --- a/vscode/src/lsp/utils.ts +++ b/vscode/src/lsp/utils.ts @@ -16,9 +16,9 @@ import * as fs from 'fs'; import * as path from 'path'; import * as os from 'os'; -import { globalVars } from '../extension'; import { LOGGER } from '../logger'; import { extConstants } from '../constants'; +import { globalState } from '../globalState'; export const enableDisableModules = ( extensionPath: string, @@ -62,7 +62,7 @@ export const findNbcode = (extensionPath: string): string => { export const restartWithJDKLater = (time: number, notifyKill: boolean): void => { LOGGER.log(`Restart of ${extConstants.SERVER_NAME} requested in ${time / 1000} s.`); - const nbProcessManager = globalVars.nbProcessManager; + const nbProcessManager = globalState.getNbProcessManager(); - setTimeout(() => globalVars.clientPromise.restartExtension(nbProcessManager, notifyKill), time); + setTimeout(() => globalState.getClientPromise().restartExtension(nbProcessManager, notifyKill), time); }; \ No newline at end of file diff --git a/vscode/src/test/testutils.ts b/vscode/src/test/testutils.ts index 8fff619f..fd436180 100644 --- a/vscode/src/test/testutils.ts +++ b/vscode/src/test/testutils.ts @@ -34,8 +34,8 @@ import { EXAMPLE_POM, MAIN_JAVA, MAIN_TEST_JAVA, SAMPLE_APP_JAVA, SAMPLE_BUILD_G import { NbLanguageClient } from "../lsp/nbLanguageClient"; import { extConstants } from "../constants"; import { l10n } from "../localiser"; -import { globalVars } from "../extension"; import { nbCommands } from "../commands/commands"; +import { globalState } from "../globalState"; /** * Folder path currently opened in VSCode workspace @@ -339,10 +339,10 @@ export const awaitClient = async () : Promise => { return Promise.reject(new Error(l10n.value("jdk.extension.notInstalled.label"))); } if(extension.isActive){ - return globalVars.clientPromise.client; + return globalState.getClientPromise().client; } const waitForExtenstionActivation : Thenable = extension.activate().then(async () => { - return await globalVars.clientPromise.client; + return await globalState.getClientPromise().client; }); return Promise.resolve(waitForExtenstionActivation); } diff --git a/vscode/src/views/initializer.ts b/vscode/src/views/initializer.ts index 88228d67..e45c8b2d 100644 --- a/vscode/src/views/initializer.ts +++ b/vscode/src/views/initializer.ts @@ -13,24 +13,23 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { ExtensionContext, window, commands, TreeView, TextEditor, workspace } from "vscode"; -import { globalVars } from "../extension"; +import { ExtensionContext, window, commands, TreeView, TextEditor } from "vscode"; import { runConfigurationNodeProvider } from "./runConfiguration"; import { NbLanguageClient } from "../lsp/nbLanguageClient"; import { TreeViewService, Visualizer } from "./projects"; -import { extConstants } from "../constants"; import { builtInCommands, extCommands } from "../commands/commands"; import { getConfigurationValue } from "../configurations/handlers"; import { configKeys } from "../configurations/configuration"; import { initializeRunConfiguration } from "../utils"; import { NbTestAdapter } from "./TestViewController"; +import { globalState } from "../globalState"; export async function createViews() { - const context = globalVars.extensionInfo.getExtensionContext(); + const context = globalState.getExtensionContextInfo().getExtensionContext(); createRunConfigurationView(context); - const client = await globalVars.clientPromise.client; + const client = await globalState.getClientPromise().client; createProjectView(client); - globalVars.testAdapter = new NbTestAdapter(); + globalState.setTestAdapter(new NbTestAdapter()); } function createRunConfigurationView(context: ExtensionContext) { @@ -61,12 +60,12 @@ async function createProjectView(client: NbLanguageClient) { } tv.reveal(vis, { select: true, focus: false, expand: false }); } - globalVars.extensionInfo.pushSubscription(window.onDidChangeActiveTextEditor(ed => { + globalState.getExtensionContextInfo().pushSubscription(window.onDidChangeActiveTextEditor(ed => { if (getConfigurationValue(configKeys.revealInActivteProj)) { revealActiveEditor(ed); } })); - globalVars.extensionInfo.pushSubscription(commands.registerCommand(extCommands.selectEditorProjs, () => revealActiveEditor())); + globalState.getExtensionContextInfo().pushSubscription(commands.registerCommand(extCommands.selectEditorProjs, () => revealActiveEditor())); // attempt to reveal NOW: if (getConfigurationValue(configKeys.revealInActivteProj)) { diff --git a/vscode/src/views/listener.ts b/vscode/src/views/listener.ts index ed2c7612..ea32461a 100644 --- a/vscode/src/views/listener.ts +++ b/vscode/src/views/listener.ts @@ -15,16 +15,16 @@ */ import { Disposable, TextEditor, window } from "vscode"; -import { globalVars } from "../extension"; import { asRanges } from "../lsp/protocol"; +import { globalState } from "../globalState"; const visibleTextEditorsChangeHandler = (editors: readonly TextEditor[]) => { editors.forEach((editor: any) => { - let decorationParams = globalVars.decorationParamsByUri.get(editor.document.uri); + let decorationParams = globalState.getDecorationParamsByUriByKey(editor.document.uri); if (decorationParams) { - let decorationType = globalVars.decorations.get(decorationParams.key); + let decorationType = globalState.getDecoration(decorationParams.key); if (decorationType) { editor.setDecorations(decorationType, asRanges(decorationParams.ranges)); } @@ -38,6 +38,6 @@ const afterInitlisteners: Disposable[] = [visibleTextEditorsChangeListener]; export const registerListenersAfterClientInit = () => { afterInitlisteners.forEach(listener => { - globalVars.extensionInfo.pushSubscription(listener); + globalState.getExtensionContextInfo().pushSubscription(listener); }); } \ No newline at end of file diff --git a/vscode/src/webviews/nbWebviewHandler.ts b/vscode/src/webviews/nbWebviewHandler.ts index b2f53864..f9397954 100644 --- a/vscode/src/webviews/nbWebviewHandler.ts +++ b/vscode/src/webviews/nbWebviewHandler.ts @@ -15,19 +15,20 @@ */ import { commands, Uri, ViewColumn, Webview, window, workspace } from "vscode"; import { HtmlPageParams } from "../lsp/protocol"; -import { globalVars } from "../extension"; import { nbCommands } from "../commands/commands"; +import { globalState } from "../globalState"; const webviews = new Map(); export const showHtmlPage = async (params: HtmlPageParams): Promise => { return new Promise(resolve => { let data = params.text; + const extensionContext = globalState.getExtensionContextInfo(); const match = /(.*)<\/title>/i.exec(data); const name = match && match.length > 1 ? match[1] : ''; - const resourceDir = Uri.joinPath(globalVars.extensionInfo.getGlobalStorage(), params.id); + const resourceDir = Uri.joinPath(extensionContext.getGlobalStorage(), params.id); // TODO: @vscode/codeicons is a devDependency not a prod dependency. So do we ever reach this code? - const distPath = Uri.joinPath(globalVars.extensionInfo.getExtensionStorageUri(), 'node_modules', '@vscode/codicons', 'dist'); + const distPath = Uri.joinPath(extensionContext.getExtensionStorageUri(), 'node_modules', '@vscode/codicons', 'dist'); workspace.fs.createDirectory(resourceDir); let view = window.createWebviewPanel('htmlView', name, ViewColumn.Beside, { enableScripts: true,