From 4afcb907ee46dc853cefb8fd844481a8182b3929 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Sat, 9 May 2020 16:35:37 +0100 Subject: [PATCH 1/6] Refactor classes that do not need a language client to not inherit from IFeature --- src/features/CodeActions.ts | 9 +-------- src/features/CustomViews.ts | 3 --- src/features/DebugSession.ts | 7 +------ src/features/Examples.ts | 8 +------- src/features/GenerateBugReport.ts | 7 +------ src/features/ISECompatibility.ts | 9 +-------- src/features/OpenInISE.ts | 7 +------ src/features/PesterTests.ts | 8 +------- src/features/RunCode.ts | 7 +------ src/main.ts | 27 ++++++++++++++++++--------- 10 files changed, 26 insertions(+), 66 deletions(-) diff --git a/src/features/CodeActions.ts b/src/features/CodeActions.ts index d830bba195..f45ef13249 100644 --- a/src/features/CodeActions.ts +++ b/src/features/CodeActions.ts @@ -3,15 +3,12 @@ *--------------------------------------------------------*/ import vscode = require("vscode"); -import { LanguageClient } from "vscode-languageclient"; import Window = vscode.window; -import { IFeature } from "../feature"; import { ILogger } from "../logging"; -export class CodeActionsFeature implements IFeature { +export class CodeActionsFeature implements vscode.Disposable { private applyEditsCommand: vscode.Disposable; private showDocumentationCommand: vscode.Disposable; - private languageClient: LanguageClient; constructor(private log: ILogger) { this.applyEditsCommand = vscode.commands.registerCommand("PowerShell.ApplyCodeActionEdits", (edit: any) => { @@ -37,10 +34,6 @@ export class CodeActionsFeature implements IFeature { this.showDocumentationCommand.dispose(); } - public setLanguageClient(languageclient: LanguageClient) { - this.languageClient = languageclient; - } - public showRuleDocumentation(ruleId: string) { const pssaDocBaseURL = "https://github.com/PowerShell/PSScriptAnalyzer/blob/master/RuleDocumentation"; diff --git a/src/features/CustomViews.ts b/src/features/CustomViews.ts index f5999877a7..8aeae561a7 100644 --- a/src/features/CustomViews.ts +++ b/src/features/CustomViews.ts @@ -10,7 +10,6 @@ import { IFeature } from "../feature"; export class CustomViewsFeature implements IFeature { private commands: vscode.Disposable[] = []; - private languageClient: LanguageClient; private contentProvider: PowerShellContentProvider; constructor() { @@ -65,8 +64,6 @@ export class CustomViewsFeature implements IFeature { args.id, args.appendedHtmlBodyContent); }); - - this.languageClient = languageClient; } } diff --git a/src/features/DebugSession.ts b/src/features/DebugSession.ts index b82596ae4c..57b5c500d9 100644 --- a/src/features/DebugSession.ts +++ b/src/features/DebugSession.ts @@ -325,10 +325,9 @@ export class DebugSessionFeature implements IFeature, DebugConfigurationProvider } } -export class SpecifyScriptArgsFeature implements IFeature { +export class SpecifyScriptArgsFeature implements vscode.Disposable { private command: vscode.Disposable; - private languageClient: LanguageClient; private context: vscode.ExtensionContext; constructor(context: vscode.ExtensionContext) { @@ -340,10 +339,6 @@ export class SpecifyScriptArgsFeature implements IFeature { }); } - public setLanguageClient(languageclient: LanguageClient) { - this.languageClient = languageclient; - } - public dispose() { this.command.dispose(); } diff --git a/src/features/Examples.ts b/src/features/Examples.ts index afedf8008a..63e69498af 100644 --- a/src/features/Examples.ts +++ b/src/features/Examples.ts @@ -4,10 +4,8 @@ import path = require("path"); import vscode = require("vscode"); -import { LanguageClient } from "vscode-languageclient"; -import { IFeature } from "../feature"; -export class ExamplesFeature implements IFeature { +export class ExamplesFeature implements vscode.Disposable { private command: vscode.Disposable; private examplesPath: string; @@ -21,10 +19,6 @@ export class ExamplesFeature implements IFeature { }); } - public setLanguageClient(languageclient: LanguageClient) { - // Eliminate tslint warning - } - public dispose() { this.command.dispose(); } diff --git a/src/features/GenerateBugReport.ts b/src/features/GenerateBugReport.ts index 6904095096..ff06ba7000 100644 --- a/src/features/GenerateBugReport.ts +++ b/src/features/GenerateBugReport.ts @@ -5,7 +5,6 @@ import cp = require("child_process"); import os = require("os"); import vscode = require("vscode"); -import { IFeature, LanguageClient } from "../feature"; import { SessionManager } from "../session"; import Settings = require("../settings"); @@ -27,7 +26,7 @@ const extensions = return 0; }); -export class GenerateBugReportFeature implements IFeature { +export class GenerateBugReportFeature implements vscode.Disposable { private command: vscode.Disposable; private powerShellProcess: cp.ChildProcess; @@ -83,10 +82,6 @@ ${this.generateExtensionTable(extensions)} this.command.dispose(); } - public setLanguageClient(languageclient: LanguageClient) { - // Eliminate tslint warning. - } - private generateExtensionTable(installedExtensions): string { if (!installedExtensions.length) { return "none"; diff --git a/src/features/ISECompatibility.ts b/src/features/ISECompatibility.ts index 6bdf3f1edf..6b247f0cb8 100644 --- a/src/features/ISECompatibility.ts +++ b/src/features/ISECompatibility.ts @@ -2,8 +2,6 @@ * Copyright (C) Microsoft Corporation. All rights reserved. *--------------------------------------------------------*/ import * as vscode from "vscode"; -import { LanguageClient } from "vscode-languageclient"; -import { IFeature } from "../feature"; import * as Settings from "../settings"; interface ISetting { @@ -15,7 +13,7 @@ interface ISetting { /** * A feature to implement commands to make code like the ISE and reset the settings. */ -export class ISECompatibilityFeature implements IFeature { +export class ISECompatibilityFeature implements vscode.Disposable { // Marking settings as public so we can use it within the tests without needing to duplicate the list of settings. public static settings: ISetting[] = [ { path: "workbench.activityBar", name: "visible", value: false }, @@ -27,7 +25,6 @@ export class ISECompatibilityFeature implements IFeature { ]; private iseCommandRegistration: vscode.Disposable; private defaultCommandRegistration: vscode.Disposable; - private languageClient: LanguageClient; constructor() { this.iseCommandRegistration = vscode.commands.registerCommand( @@ -41,10 +38,6 @@ export class ISECompatibilityFeature implements IFeature { this.defaultCommandRegistration.dispose(); } - public setLanguageClient(languageclient: LanguageClient) { - this.languageClient = languageclient; - } - private async EnableISEMode() { for (const iseSetting of ISECompatibilityFeature.settings) { await vscode.workspace.getConfiguration(iseSetting.path).update(iseSetting.name, iseSetting.value, true); diff --git a/src/features/OpenInISE.ts b/src/features/OpenInISE.ts index 1a0f1007dd..9459f85ac8 100644 --- a/src/features/OpenInISE.ts +++ b/src/features/OpenInISE.ts @@ -4,9 +4,8 @@ import ChildProcess = require("child_process"); import vscode = require("vscode"); -import { IFeature, LanguageClient } from "../feature"; -export class OpenInISEFeature implements IFeature { +export class OpenInISEFeature implements vscode.Disposable { private command: vscode.Disposable; constructor() { @@ -33,8 +32,4 @@ export class OpenInISEFeature implements IFeature { public dispose() { this.command.dispose(); } - - public setLanguageClient(languageClient: LanguageClient) { - // Not needed for this feature. - } } diff --git a/src/features/PesterTests.ts b/src/features/PesterTests.ts index de53100992..b6324447df 100644 --- a/src/features/PesterTests.ts +++ b/src/features/PesterTests.ts @@ -4,7 +4,6 @@ import * as path from "path"; import vscode = require("vscode"); -import { IFeature, LanguageClient } from "../feature"; import { SessionManager } from "../session"; import Settings = require("../settings"); import utils = require("../utils"); @@ -14,10 +13,9 @@ enum LaunchType { Run, } -export class PesterTestsFeature implements IFeature { +export class PesterTestsFeature implements vscode.Disposable { private command: vscode.Disposable; - private languageClient: LanguageClient; private invokePesterStubScriptPath: string; constructor(private sessionManager: SessionManager) { @@ -47,10 +45,6 @@ export class PesterTestsFeature implements IFeature { this.command.dispose(); } - public setLanguageClient(languageClient: LanguageClient) { - this.languageClient = languageClient; - } - private launchAllTestsInActiveEditor(launchType: LaunchType, fileUri: vscode.Uri) { const uriString = fileUri.toString(); const launchConfig = this.createLaunchConfig(uriString, launchType); diff --git a/src/features/RunCode.ts b/src/features/RunCode.ts index 5aabd946f7..e8a900389d 100644 --- a/src/features/RunCode.ts +++ b/src/features/RunCode.ts @@ -14,10 +14,9 @@ enum LaunchType { Run, } -export class RunCodeFeature implements IFeature { +export class RunCodeFeature implements vscode.Disposable { private command: vscode.Disposable; - private languageClient: LanguageClient; constructor(private sessionManager: SessionManager) { this.command = vscode.commands.registerCommand( @@ -31,10 +30,6 @@ export class RunCodeFeature implements IFeature { this.command.dispose(); } - public setLanguageClient(languageClient: LanguageClient) { - this.languageClient = languageClient; - } - private async launchTask( runInDebugger: boolean, scriptToRun: string, diff --git a/src/main.ts b/src/main.ts index f5c25465c8..69751a4974 100644 --- a/src/main.ts +++ b/src/main.ts @@ -50,6 +50,7 @@ const AI_KEY: string = "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217"; let logger: Logger; let sessionManager: SessionManager; let extensionFeatures: IFeature[] = []; +let commandRegistrations: vscode.Disposable[] = []; let telemetryReporter: TelemetryReporter; const documentSelector: DocumentSelector = [ @@ -139,26 +140,30 @@ export function activate(context: vscode.ExtensionContext): void { PackageJSON.version, telemetryReporter); - // Create features - extensionFeatures = [ - new ConsoleFeature(logger), + // Register commands that do not require Language client + commandRegistrations = [ new ExamplesFeature(), - new OpenInISEFeature(), new GenerateBugReportFeature(sessionManager), + new ISECompatibilityFeature(), + new OpenInISEFeature(), + new PesterTestsFeature(sessionManager), + new RunCodeFeature(sessionManager), + new CodeActionsFeature(logger), + new SpecifyScriptArgsFeature(context), + ] + + // Create features that require language client + extensionFeatures = [ + new ConsoleFeature(logger), new ExpandAliasFeature(logger), new GetCommandsFeature(logger), - new ISECompatibilityFeature(), new ShowHelpFeature(logger), new FindModuleFeature(), - new PesterTestsFeature(sessionManager), - new RunCodeFeature(sessionManager), new ExtensionCommandsFeature(logger), - new CodeActionsFeature(logger), new NewFileOrProjectFeature(), new RemoteFilesFeature(), new DebugSessionFeature(context, sessionManager, logger), new PickPSHostProcessFeature(), - new SpecifyScriptArgsFeature(context), new HelpCompletionFeature(logger), new CustomViewsFeature(), new PickRunspaceFeature(), @@ -206,6 +211,10 @@ export function deactivate(): void { feature.dispose(); }); + commandRegistrations.forEach((commandRegistration) => { + commandRegistration.dispose(); + }); + // Dispose of the current session sessionManager.dispose(); From 57b714bc5c3624d520760fe2189cbf9fe48d4c17 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Mon, 8 Jun 2020 21:45:56 +0100 Subject: [PATCH 2/6] Use base class LanguageClientConsumer --- src/features/Console.ts | 11 +++-------- src/features/CustomViews.ts | 4 +++- src/features/DebugSession.ts | 13 ++++++++----- src/features/ExpandAlias.ts | 11 +++-------- src/features/ExtensionCommands.ts | 10 +++------- src/features/FindModule.ts | 8 ++++---- src/features/GetCommands.ts | 5 +++-- src/features/HelpCompletion.ts | 5 +++-- src/features/NewFileOrProject.ts | 7 ++++--- src/features/RemoteFiles.ts | 7 ++++--- src/features/ShowHelp.ts | 10 +++------- src/languageClientConsumer.ts | 22 ++++++++++++++++++++++ src/main.ts | 1 - 13 files changed, 63 insertions(+), 51 deletions(-) create mode 100644 src/languageClientConsumer.ts diff --git a/src/features/Console.ts b/src/features/Console.ts index 39a4861cd0..798ee9db4e 100644 --- a/src/features/Console.ts +++ b/src/features/Console.ts @@ -8,6 +8,7 @@ import { ICheckboxQuickPickItem, showCheckboxQuickPick } from "../controls/check import { IFeature } from "../feature"; import { Logger } from "../logging"; import Settings = require("../settings"); +import { LanguageClientConsumer } from "../languageClientConsumer"; export const EvaluateRequestType = new RequestType("evaluate"); export const OutputNotificationType = new NotificationType("output"); @@ -197,19 +198,14 @@ function onInputEntered(responseText: string): IShowInputPromptResponseBody { } } -export class ConsoleFeature implements IFeature { +export class ConsoleFeature extends LanguageClientConsumer implements IFeature { private commands: vscode.Disposable[]; - private languageClient: LanguageClient; private resolveStatusBarPromise: (value?: {} | PromiseLike<{}>) => void; constructor(private log: Logger) { + super(); this.commands = [ vscode.commands.registerCommand("PowerShell.RunSelection", async () => { - if (this.languageClient === undefined) { - this.log.writeAndShowError(`<${ConsoleFeature.name}>: ` + - "Unable to instantiate; language client undefined."); - return; - } if (vscode.window.activeTerminal && vscode.window.activeTerminal.name !== "PowerShell Integrated Console") { @@ -257,7 +253,6 @@ export class ConsoleFeature implements IFeature { public setLanguageClient(languageClient: LanguageClient) { this.languageClient = languageClient; - this.languageClient.onRequest( ShowChoicePromptRequestType, (promptDetails) => showChoicePrompt(promptDetails, this.languageClient)); diff --git a/src/features/CustomViews.ts b/src/features/CustomViews.ts index 8aeae561a7..ac0470787c 100644 --- a/src/features/CustomViews.ts +++ b/src/features/CustomViews.ts @@ -6,13 +6,15 @@ import * as path from "path"; import * as vscode from "vscode"; import { LanguageClient, RequestType } from "vscode-languageclient"; import { IFeature } from "../feature"; +import { LanguageClientConsumer } from "../languageClientConsumer"; -export class CustomViewsFeature implements IFeature { +export class CustomViewsFeature extends LanguageClientConsumer implements IFeature { private commands: vscode.Disposable[] = []; private contentProvider: PowerShellContentProvider; constructor() { + super(); this.contentProvider = new PowerShellContentProvider(); this.commands.push( vscode.workspace.registerTextDocumentContentProvider( diff --git a/src/features/DebugSession.ts b/src/features/DebugSession.ts index 57b5c500d9..48dbfb0391 100644 --- a/src/features/DebugSession.ts +++ b/src/features/DebugSession.ts @@ -14,11 +14,13 @@ import Settings = require("../settings"); import utils = require("../utils"); import { NamedPipeDebugAdapter } from "../debugAdapter"; import { Logger } from "../logging"; +import { LanguageClientConsumer } from "../languageClientConsumer"; export const StartDebuggerNotificationType = new NotificationType("powerShell/startDebugger"); -export class DebugSessionFeature implements IFeature, DebugConfigurationProvider, vscode.DebugAdapterDescriptorFactory { +export class DebugSessionFeature extends LanguageClientConsumer + implements IFeature, DebugConfigurationProvider, vscode.DebugAdapterDescriptorFactory { private sessionCount: number = 1; private command: vscode.Disposable; @@ -26,6 +28,7 @@ export class DebugSessionFeature implements IFeature, DebugConfigurationProvider private tempSessionDetails: utils.IEditorServicesSessionDetails; constructor(context: ExtensionContext, private sessionManager: SessionManager, private logger: Logger) { + super(); // Register a debug configuration provider context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider("PowerShell", this)); context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory("PowerShell", this)) @@ -386,14 +389,14 @@ interface IGetPSHostProcessesResponseBody { hostProcesses: IPSHostProcessInfo[]; } -export class PickPSHostProcessFeature implements IFeature { +export class PickPSHostProcessFeature extends LanguageClientConsumer implements IFeature { private command: vscode.Disposable; - private languageClient: LanguageClient; private waitingForClientToken: vscode.CancellationTokenSource; private getLanguageClientResolve: (value?: LanguageClient | Thenable) => void; constructor() { + super(); this.command = vscode.commands.registerCommand("PowerShell.PickPSHostProcess", () => { @@ -517,14 +520,14 @@ interface IRunspace { export const GetRunspaceRequestType = new RequestType("powerShell/getRunspace"); -export class PickRunspaceFeature implements IFeature { +export class PickRunspaceFeature extends LanguageClientConsumer implements IFeature { private command: vscode.Disposable; - private languageClient: LanguageClient; private waitingForClientToken: vscode.CancellationTokenSource; private getLanguageClientResolve: (value?: LanguageClient | Thenable) => void; constructor() { + super(); this.command = vscode.commands.registerCommand("PowerShell.PickRunspace", (processId) => { return this.getLanguageClient() diff --git a/src/features/ExpandAlias.ts b/src/features/ExpandAlias.ts index ec1568e098..9005a77788 100644 --- a/src/features/ExpandAlias.ts +++ b/src/features/ExpandAlias.ts @@ -5,22 +5,17 @@ import vscode = require("vscode"); import Window = vscode.window; import { LanguageClient, NotificationType, RequestType } from "vscode-languageclient"; -import { IFeature } from "../feature"; import { Logger } from "../logging"; +import { LanguageClientConsumer } from "../languageClientConsumer"; export const ExpandAliasRequestType = new RequestType("powerShell/expandAlias"); -export class ExpandAliasFeature implements IFeature { +export class ExpandAliasFeature extends LanguageClientConsumer { private command: vscode.Disposable; - private languageClient: LanguageClient; constructor(private log: Logger) { + super(); this.command = vscode.commands.registerCommand("PowerShell.ExpandAlias", () => { - if (this.languageClient === undefined) { - this.log.writeAndShowError(`<${ExpandAliasFeature.name}>: ` + - "Unable to instantiate; language client undefined."); - return; - } const editor = Window.activeTextEditor; const document = editor.document; diff --git a/src/features/ExtensionCommands.ts b/src/features/ExtensionCommands.ts index 504d660dd1..4ccf6d79ac 100644 --- a/src/features/ExtensionCommands.ts +++ b/src/features/ExtensionCommands.ts @@ -11,6 +11,7 @@ import { LanguageClient, NotificationType, NotificationType0, import { IFeature } from "../feature"; import { Logger } from "../logging"; import Settings = require("../settings"); +import { LanguageClientConsumer } from "../languageClientConsumer"; export interface IExtensionCommand { name: string; @@ -173,20 +174,15 @@ interface IInvokeRegisteredEditorCommandParameter { commandName: string; } -export class ExtensionCommandsFeature implements IFeature { +export class ExtensionCommandsFeature extends LanguageClientConsumer implements IFeature { private command: vscode.Disposable; private command2: vscode.Disposable; - private languageClient: LanguageClient; private extensionCommands: IExtensionCommand[] = []; constructor(private log: Logger) { + super(); this.command = vscode.commands.registerCommand("PowerShell.ShowAdditionalCommands", () => { - if (this.languageClient === undefined) { - this.log.writeAndShowError(`<${ExtensionCommandsFeature.name}>: ` + - "Unable to instantiate; language client undefined."); - return; - } const editor = vscode.window.activeTextEditor; let start = editor.selection.start; diff --git a/src/features/FindModule.ts b/src/features/FindModule.ts index cb57f25994..8384ab3f7c 100644 --- a/src/features/FindModule.ts +++ b/src/features/FindModule.ts @@ -3,10 +3,10 @@ *--------------------------------------------------------*/ import vscode = require("vscode"); -import { LanguageClient, NotificationType, RequestType } from "vscode-languageclient"; -import Window = vscode.window; +import { LanguageClient, RequestType } from "vscode-languageclient"; import { IFeature } from "../feature"; import QuickPickItem = vscode.QuickPickItem; +import { LanguageClientConsumer } from "../languageClientConsumer"; export const FindModuleRequestType = new RequestType("powerShell/findModule"); @@ -14,13 +14,13 @@ export const FindModuleRequestType = export const InstallModuleRequestType = new RequestType("powerShell/installModule"); -export class FindModuleFeature implements IFeature { +export class FindModuleFeature extends LanguageClientConsumer implements IFeature { private command: vscode.Disposable; - private languageClient: LanguageClient; private cancelFindToken: vscode.CancellationTokenSource; constructor() { + super(); this.command = vscode.commands.registerCommand("PowerShell.PowerShellFindModule", () => { // It takes a while to get the list of PowerShell modules, display some UI to let user know this.cancelFindToken = new vscode.CancellationTokenSource(); diff --git a/src/features/GetCommands.ts b/src/features/GetCommands.ts index 12fff1d453..6d064824f6 100644 --- a/src/features/GetCommands.ts +++ b/src/features/GetCommands.ts @@ -5,6 +5,7 @@ import * as vscode from "vscode"; import { LanguageClient, RequestType0 } from "vscode-languageclient"; import { IFeature } from "../feature"; import { Logger } from "../logging"; +import { LanguageClientConsumer } from "../languageClientConsumer"; interface ICommand { name: string; @@ -23,13 +24,13 @@ export const GetCommandRequestType = new RequestType0("p /** * A PowerShell Command listing feature. Implements a treeview control. */ -export class GetCommandsFeature implements IFeature { +export class GetCommandsFeature extends LanguageClientConsumer implements IFeature { private command: vscode.Disposable; - private languageClient: LanguageClient; private commandsExplorerProvider: CommandsExplorerProvider; private commandsExplorerTreeView: vscode.TreeView; constructor(private log: Logger) { + super(); this.command = vscode.commands.registerCommand("PowerShell.RefreshCommandsExplorer", () => this.CommandExplorerRefresh()); this.commandsExplorerProvider = new CommandsExplorerProvider(); diff --git a/src/features/HelpCompletion.ts b/src/features/HelpCompletion.ts index 97255bfc67..6916d56dc8 100644 --- a/src/features/HelpCompletion.ts +++ b/src/features/HelpCompletion.ts @@ -8,6 +8,7 @@ import { LanguageClient, RequestType } from "vscode-languageclient"; import { IFeature } from "../feature"; import { Logger } from "../logging"; import Settings = require("../settings"); +import { LanguageClientConsumer } from "../languageClientConsumer"; export const CommentHelpRequestType = new RequestType("powerShell/getCommentHelp"); @@ -24,13 +25,13 @@ interface ICommentHelpRequestResult { enum SearchState { Searching, Locked, Found } -export class HelpCompletionFeature implements IFeature { +export class HelpCompletionFeature extends LanguageClientConsumer implements IFeature { private helpCompletionProvider: HelpCompletionProvider; - private languageClient: LanguageClient; private disposable: Disposable; private settings: Settings.ISettings; constructor(private log: Logger) { + super(); this.settings = Settings.load(); if (this.settings.helpCompletion !== Settings.HelpCompletion.Disabled) { diff --git a/src/features/NewFileOrProject.ts b/src/features/NewFileOrProject.ts index 1a4f2f5083..41a977ac3a 100644 --- a/src/features/NewFileOrProject.ts +++ b/src/features/NewFileOrProject.ts @@ -3,17 +3,18 @@ *--------------------------------------------------------*/ import vscode = require("vscode"); -import { LanguageClient, NotificationType, RequestType } from "vscode-languageclient"; +import { LanguageClient, RequestType } from "vscode-languageclient"; import { IFeature } from "../feature"; +import { LanguageClientConsumer } from "../languageClientConsumer"; -export class NewFileOrProjectFeature implements IFeature { +export class NewFileOrProjectFeature extends LanguageClientConsumer implements IFeature { private readonly loadIcon = " $(sync) "; private command: vscode.Disposable; - private languageClient: LanguageClient; private waitingForClientToken: vscode.CancellationTokenSource; constructor() { + super(); this.command = vscode.commands.registerCommand("PowerShell.NewProjectFromTemplate", () => { diff --git a/src/features/RemoteFiles.ts b/src/features/RemoteFiles.ts index 19c74b5ad7..233bb0fdfa 100644 --- a/src/features/RemoteFiles.ts +++ b/src/features/RemoteFiles.ts @@ -5,8 +5,9 @@ import os = require("os"); import path = require("path"); import vscode = require("vscode"); -import { LanguageClient, NotificationType, RequestType, TextDocumentIdentifier } from "vscode-languageclient"; +import { LanguageClient, NotificationType, TextDocumentIdentifier } from "vscode-languageclient"; import { IFeature } from "../feature"; +import { LanguageClientConsumer } from "../languageClientConsumer"; // NOTE: The following two DidSaveTextDocument* types will // be removed when #593 gets fixed. @@ -22,12 +23,12 @@ export const DidSaveTextDocumentNotificationType = new NotificationType( "textDocument/didSave"); -export class RemoteFilesFeature implements IFeature { +export class RemoteFilesFeature extends LanguageClientConsumer implements IFeature { private tempSessionPathPrefix: string; - private languageClient: LanguageClient; constructor() { + super(); // Get the common PowerShell Editor Services temporary file path // so that remote files from previous sessions can be closed. this.tempSessionPathPrefix = diff --git a/src/features/ShowHelp.ts b/src/features/ShowHelp.ts index fd185eb05a..1705ee147f 100644 --- a/src/features/ShowHelp.ts +++ b/src/features/ShowHelp.ts @@ -6,22 +6,18 @@ import vscode = require("vscode"); import { LanguageClient, NotificationType } from "vscode-languageclient"; import { IFeature } from "../feature"; import { Logger } from "../logging"; +import { LanguageClientConsumer } from "../languageClientConsumer"; export const ShowHelpNotificationType = new NotificationType("powerShell/showHelp"); -export class ShowHelpFeature implements IFeature { +export class ShowHelpFeature extends LanguageClientConsumer implements IFeature { private command: vscode.Disposable; private deprecatedCommand: vscode.Disposable; - private languageClient: LanguageClient; constructor(private log: Logger) { + super(); this.command = vscode.commands.registerCommand("PowerShell.ShowHelp", (item?) => { - if (this.languageClient === undefined) { - this.log.writeAndShowError(`<${ShowHelpFeature.name}>: ` + - "Unable to instantiate; language client undefined."); - return; - } if (!item || !item.Name) { const editor = vscode.window.activeTextEditor; diff --git a/src/languageClientConsumer.ts b/src/languageClientConsumer.ts new file mode 100644 index 0000000000..dcbf63b1c8 --- /dev/null +++ b/src/languageClientConsumer.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/ + +import { LanguageClient, IFeature } from "./feature"; +import { window } from "vscode"; + +export class LanguageClientConsumer { + private _languageClient: LanguageClient; + + public get languageClient(): LanguageClient { + if (!this._languageClient) { + window.showInformationMessage( + "PowerShell extension has not finished starting up yet. Please try again in a few moments."); + } + return this._languageClient; + } + + public set languageClient(value: LanguageClient) { + this._languageClient = value; + } +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 6bb982b5f7..c1e95204f8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -34,7 +34,6 @@ import { Logger, LogLevel } from "./logging"; import { SessionManager } from "./session"; import Settings = require("./settings"); import { PowerShellLanguageId } from "./utils"; -import utils = require("./utils"); // The most reliable way to get the name and version of the current extension. // tslint:disable-next-line: no-var-requires From a50af97d6a7f912f965ee4c4aa2401120326dd8c Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Wed, 10 Jun 2020 21:35:18 +0100 Subject: [PATCH 3/6] Remove IFeature by making languageClientConsumer abstract --- src/feature.ts | 12 ------------ src/features/Console.ts | 3 +-- src/features/CustomViews.ts | 3 +-- src/features/DebugSession.ts | 7 +++---- src/features/ExtensionCommands.ts | 3 +-- src/features/FindModule.ts | 3 +-- src/features/GetCommands.ts | 3 +-- src/features/HelpCompletion.ts | 3 +-- src/features/NewFileOrProject.ts | 3 +-- src/features/RemoteFiles.ts | 3 +-- src/features/RunCode.ts | 1 - src/features/ShowHelp.ts | 3 +-- src/languageClientConsumer.ts | 14 ++++++++------ src/main.ts | 14 +++++++------- src/session.ts | 14 +++++++------- 15 files changed, 34 insertions(+), 55 deletions(-) delete mode 100644 src/feature.ts diff --git a/src/feature.ts b/src/feature.ts deleted file mode 100644 index f946a8a482..0000000000 --- a/src/feature.ts +++ /dev/null @@ -1,12 +0,0 @@ -/*--------------------------------------------------------- - * Copyright (C) Microsoft Corporation. All rights reserved. - *--------------------------------------------------------*/ - -import vscode = require("vscode"); -import { LanguageClient } from "vscode-languageclient"; -export { LanguageClient } from "vscode-languageclient"; - -export interface IFeature extends vscode.Disposable { - setLanguageClient(languageclient: LanguageClient); - dispose(); -} diff --git a/src/features/Console.ts b/src/features/Console.ts index 798ee9db4e..e0ded7190a 100644 --- a/src/features/Console.ts +++ b/src/features/Console.ts @@ -5,7 +5,6 @@ import vscode = require("vscode"); import { LanguageClient, NotificationType, RequestType } from "vscode-languageclient"; import { ICheckboxQuickPickItem, showCheckboxQuickPick } from "../controls/checkboxQuickPick"; -import { IFeature } from "../feature"; import { Logger } from "../logging"; import Settings = require("../settings"); import { LanguageClientConsumer } from "../languageClientConsumer"; @@ -198,7 +197,7 @@ function onInputEntered(responseText: string): IShowInputPromptResponseBody { } } -export class ConsoleFeature extends LanguageClientConsumer implements IFeature { +export class ConsoleFeature extends LanguageClientConsumer { private commands: vscode.Disposable[]; private resolveStatusBarPromise: (value?: {} | PromiseLike<{}>) => void; diff --git a/src/features/CustomViews.ts b/src/features/CustomViews.ts index ac0470787c..d0e4990de1 100644 --- a/src/features/CustomViews.ts +++ b/src/features/CustomViews.ts @@ -5,10 +5,9 @@ import * as path from "path"; import * as vscode from "vscode"; import { LanguageClient, RequestType } from "vscode-languageclient"; -import { IFeature } from "../feature"; import { LanguageClientConsumer } from "../languageClientConsumer"; -export class CustomViewsFeature extends LanguageClientConsumer implements IFeature { +export class CustomViewsFeature extends LanguageClientConsumer { private commands: vscode.Disposable[] = []; private contentProvider: PowerShellContentProvider; diff --git a/src/features/DebugSession.ts b/src/features/DebugSession.ts index 48dbfb0391..0b185948b8 100644 --- a/src/features/DebugSession.ts +++ b/src/features/DebugSession.ts @@ -6,7 +6,6 @@ import vscode = require("vscode"); import { CancellationToken, DebugConfiguration, DebugConfigurationProvider, ExtensionContext, WorkspaceFolder } from "vscode"; import { LanguageClient, NotificationType, RequestType } from "vscode-languageclient"; -import { IFeature } from "../feature"; import { getPlatformDetails, OperatingSystem } from "../platform"; import { PowerShellProcess} from "../process"; import { SessionManager, SessionStatus } from "../session"; @@ -20,7 +19,7 @@ export const StartDebuggerNotificationType = new NotificationType("powerShell/startDebugger"); export class DebugSessionFeature extends LanguageClientConsumer - implements IFeature, DebugConfigurationProvider, vscode.DebugAdapterDescriptorFactory { + implements DebugConfigurationProvider, vscode.DebugAdapterDescriptorFactory { private sessionCount: number = 1; private command: vscode.Disposable; @@ -389,7 +388,7 @@ interface IGetPSHostProcessesResponseBody { hostProcesses: IPSHostProcessInfo[]; } -export class PickPSHostProcessFeature extends LanguageClientConsumer implements IFeature { +export class PickPSHostProcessFeature extends LanguageClientConsumer { private command: vscode.Disposable; private waitingForClientToken: vscode.CancellationTokenSource; @@ -520,7 +519,7 @@ interface IRunspace { export const GetRunspaceRequestType = new RequestType("powerShell/getRunspace"); -export class PickRunspaceFeature extends LanguageClientConsumer implements IFeature { +export class PickRunspaceFeature extends LanguageClientConsumer { private command: vscode.Disposable; private waitingForClientToken: vscode.CancellationTokenSource; diff --git a/src/features/ExtensionCommands.ts b/src/features/ExtensionCommands.ts index 4ccf6d79ac..7bc004482c 100644 --- a/src/features/ExtensionCommands.ts +++ b/src/features/ExtensionCommands.ts @@ -8,7 +8,6 @@ import * as path from "path"; import * as vscode from "vscode"; import { LanguageClient, NotificationType, NotificationType0, Position, Range, RequestType } from "vscode-languageclient"; -import { IFeature } from "../feature"; import { Logger } from "../logging"; import Settings = require("../settings"); import { LanguageClientConsumer } from "../languageClientConsumer"; @@ -174,7 +173,7 @@ interface IInvokeRegisteredEditorCommandParameter { commandName: string; } -export class ExtensionCommandsFeature extends LanguageClientConsumer implements IFeature { +export class ExtensionCommandsFeature extends LanguageClientConsumer { private command: vscode.Disposable; private command2: vscode.Disposable; diff --git a/src/features/FindModule.ts b/src/features/FindModule.ts index 8384ab3f7c..a626c3784d 100644 --- a/src/features/FindModule.ts +++ b/src/features/FindModule.ts @@ -4,7 +4,6 @@ import vscode = require("vscode"); import { LanguageClient, RequestType } from "vscode-languageclient"; -import { IFeature } from "../feature"; import QuickPickItem = vscode.QuickPickItem; import { LanguageClientConsumer } from "../languageClientConsumer"; @@ -14,7 +13,7 @@ export const FindModuleRequestType = export const InstallModuleRequestType = new RequestType("powerShell/installModule"); -export class FindModuleFeature extends LanguageClientConsumer implements IFeature { +export class FindModuleFeature extends LanguageClientConsumer { private command: vscode.Disposable; private cancelFindToken: vscode.CancellationTokenSource; diff --git a/src/features/GetCommands.ts b/src/features/GetCommands.ts index 6d064824f6..a050bfbdd0 100644 --- a/src/features/GetCommands.ts +++ b/src/features/GetCommands.ts @@ -3,7 +3,6 @@ *--------------------------------------------------------*/ import * as vscode from "vscode"; import { LanguageClient, RequestType0 } from "vscode-languageclient"; -import { IFeature } from "../feature"; import { Logger } from "../logging"; import { LanguageClientConsumer } from "../languageClientConsumer"; @@ -24,7 +23,7 @@ export const GetCommandRequestType = new RequestType0("p /** * A PowerShell Command listing feature. Implements a treeview control. */ -export class GetCommandsFeature extends LanguageClientConsumer implements IFeature { +export class GetCommandsFeature extends LanguageClientConsumer { private command: vscode.Disposable; private commandsExplorerProvider: CommandsExplorerProvider; private commandsExplorerTreeView: vscode.TreeView; diff --git a/src/features/HelpCompletion.ts b/src/features/HelpCompletion.ts index 6916d56dc8..d97a8e1ebd 100644 --- a/src/features/HelpCompletion.ts +++ b/src/features/HelpCompletion.ts @@ -5,7 +5,6 @@ import { Disposable, EndOfLine, Position, Range, SnippetString, TextDocument, TextDocumentChangeEvent, window, workspace } from "vscode"; import { LanguageClient, RequestType } from "vscode-languageclient"; -import { IFeature } from "../feature"; import { Logger } from "../logging"; import Settings = require("../settings"); import { LanguageClientConsumer } from "../languageClientConsumer"; @@ -25,7 +24,7 @@ interface ICommentHelpRequestResult { enum SearchState { Searching, Locked, Found } -export class HelpCompletionFeature extends LanguageClientConsumer implements IFeature { +export class HelpCompletionFeature extends LanguageClientConsumer { private helpCompletionProvider: HelpCompletionProvider; private disposable: Disposable; private settings: Settings.ISettings; diff --git a/src/features/NewFileOrProject.ts b/src/features/NewFileOrProject.ts index 41a977ac3a..38c2649a6b 100644 --- a/src/features/NewFileOrProject.ts +++ b/src/features/NewFileOrProject.ts @@ -4,10 +4,9 @@ import vscode = require("vscode"); import { LanguageClient, RequestType } from "vscode-languageclient"; -import { IFeature } from "../feature"; import { LanguageClientConsumer } from "../languageClientConsumer"; -export class NewFileOrProjectFeature extends LanguageClientConsumer implements IFeature { +export class NewFileOrProjectFeature extends LanguageClientConsumer { private readonly loadIcon = " $(sync) "; private command: vscode.Disposable; diff --git a/src/features/RemoteFiles.ts b/src/features/RemoteFiles.ts index 233bb0fdfa..9d0474d477 100644 --- a/src/features/RemoteFiles.ts +++ b/src/features/RemoteFiles.ts @@ -6,7 +6,6 @@ import os = require("os"); import path = require("path"); import vscode = require("vscode"); import { LanguageClient, NotificationType, TextDocumentIdentifier } from "vscode-languageclient"; -import { IFeature } from "../feature"; import { LanguageClientConsumer } from "../languageClientConsumer"; // NOTE: The following two DidSaveTextDocument* types will @@ -23,7 +22,7 @@ export const DidSaveTextDocumentNotificationType = new NotificationType( "textDocument/didSave"); -export class RemoteFilesFeature extends LanguageClientConsumer implements IFeature { +export class RemoteFilesFeature extends LanguageClientConsumer { private tempSessionPathPrefix: string; diff --git a/src/features/RunCode.ts b/src/features/RunCode.ts index e8a900389d..e279efa2b5 100644 --- a/src/features/RunCode.ts +++ b/src/features/RunCode.ts @@ -4,7 +4,6 @@ import * as path from "path"; import vscode = require("vscode"); -import { IFeature, LanguageClient } from "../feature"; import { SessionManager } from "../session"; import Settings = require("../settings"); import utils = require("../utils"); diff --git a/src/features/ShowHelp.ts b/src/features/ShowHelp.ts index 1705ee147f..f345f00aa8 100644 --- a/src/features/ShowHelp.ts +++ b/src/features/ShowHelp.ts @@ -4,14 +4,13 @@ import vscode = require("vscode"); import { LanguageClient, NotificationType } from "vscode-languageclient"; -import { IFeature } from "../feature"; import { Logger } from "../logging"; import { LanguageClientConsumer } from "../languageClientConsumer"; export const ShowHelpNotificationType = new NotificationType("powerShell/showHelp"); -export class ShowHelpFeature extends LanguageClientConsumer implements IFeature { +export class ShowHelpFeature extends LanguageClientConsumer { private command: vscode.Disposable; private deprecatedCommand: vscode.Disposable; diff --git a/src/languageClientConsumer.ts b/src/languageClientConsumer.ts index dcbf63b1c8..64085ce991 100644 --- a/src/languageClientConsumer.ts +++ b/src/languageClientConsumer.ts @@ -2,21 +2,23 @@ * Copyright (C) Microsoft Corporation. All rights reserved. *--------------------------------------------------------*/ -import { LanguageClient, IFeature } from "./feature"; import { window } from "vscode"; +import { LanguageClient } from "vscode-languageclient"; -export class LanguageClientConsumer { - private _languageClient: LanguageClient; +export abstract class LanguageClientConsumer { + + abstract setLanguageClient(languageclient: LanguageClient): void; + abstract dispose(): void; public get languageClient(): LanguageClient { - if (!this._languageClient) { + if (!this.languageClient) { window.showInformationMessage( "PowerShell extension has not finished starting up yet. Please try again in a few moments."); } - return this._languageClient; + return this.languageClient; } public set languageClient(value: LanguageClient) { - this._languageClient = value; + this.languageClient = value; } } \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index c1e95204f8..39cca55512 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,7 +8,6 @@ import path = require("path"); import vscode = require("vscode"); import TelemetryReporter from "vscode-extension-telemetry"; import { DocumentSelector } from "vscode-languageclient"; -import { IFeature } from "./feature"; import { CodeActionsFeature } from "./features/CodeActions"; import { ConsoleFeature } from "./features/Console"; import { CustomViewsFeature } from "./features/CustomViews"; @@ -34,6 +33,7 @@ import { Logger, LogLevel } from "./logging"; import { SessionManager } from "./session"; import Settings = require("./settings"); import { PowerShellLanguageId } from "./utils"; +import { LanguageClientConsumer } from "./languageClientConsumer"; // The most reliable way to get the name and version of the current extension. // tslint:disable-next-line: no-var-requires @@ -44,7 +44,7 @@ const AI_KEY: string = "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217"; let logger: Logger; let sessionManager: SessionManager; -let extensionFeatures: IFeature[] = []; +let languageClientConsumers: LanguageClientConsumer[] = []; let commandRegistrations: vscode.Disposable[] = []; let telemetryReporter: TelemetryReporter; @@ -146,8 +146,8 @@ export function activate(context: vscode.ExtensionContext): void { new SpecifyScriptArgsFeature(context), ] - // Create features that require language client - extensionFeatures = [ + // Features and command registrations that require language client + languageClientConsumers = [ new ConsoleFeature(logger), new ExpandAliasFeature(logger), new GetCommandsFeature(logger), @@ -163,7 +163,7 @@ export function activate(context: vscode.ExtensionContext): void { new PickRunspaceFeature(), ]; - sessionManager.setExtensionFeatures(extensionFeatures); + sessionManager.setLanguageClientConsumers(languageClientConsumers); if (extensionSettings.startAutomatically) { sessionManager.start(); @@ -201,8 +201,8 @@ function checkForUpdatedVersion(context: vscode.ExtensionContext, version: strin export function deactivate(): void { // Clean up all extension features - extensionFeatures.forEach((feature) => { - feature.dispose(); + languageClientConsumers.forEach((languageClientConsumer) => { + languageClientConsumer.dispose(); }); commandRegistrations.forEach((commandRegistration) => { diff --git a/src/session.ts b/src/session.ts index dad8410194..4859697296 100644 --- a/src/session.ts +++ b/src/session.ts @@ -9,7 +9,6 @@ import * as semver from "semver"; import vscode = require("vscode"); import TelemetryReporter from "vscode-extension-telemetry"; import { Message } from "vscode-jsonrpc"; -import { IFeature } from "./feature"; import { Logger } from "./logging"; import { PowerShellProcess } from "./process"; import Settings = require("./settings"); @@ -24,6 +23,7 @@ import { GitHubReleaseInformation, InvokePowerShellUpdateCheck } from "./feature import { getPlatformDetails, IPlatformDetails, IPowerShellExeDetails, OperatingSystem, PowerShellExeFinder } from "./platform"; +import { LanguageClientConsumer } from "./languageClientConsumer"; export enum SessionStatus { NeverStarted, @@ -44,7 +44,7 @@ export class SessionManager implements Middleware { private suppressRestartPrompt: boolean; private focusConsoleOnExecute: boolean; private platformDetails: IPlatformDetails; - private extensionFeatures: IFeature[] = []; + private languageClientConsumers: LanguageClientConsumer[] = []; private statusBarItem: vscode.StatusBarItem; private languageServerProcess: PowerShellProcess; private debugSessionProcess: PowerShellProcess; @@ -100,8 +100,8 @@ export class SessionManager implements Middleware { this.registeredCommands.forEach((command) => { command.dispose(); }); } - public setExtensionFeatures(extensionFeatures: IFeature[]) { - this.extensionFeatures = extensionFeatures; + public setLanguageClientConsumers(languageClientConsumers: LanguageClientConsumer[]) { + this.languageClientConsumers = languageClientConsumers; } public start(exeNameOverride?: string) { @@ -591,7 +591,7 @@ export class SessionManager implements Middleware { // Send the new LanguageClient to extension features // so that they can register their message handlers // before the connection is established. - this.updateExtensionFeatures(this.languageServerClient); + this.updateLanguageClientConsumers(this.languageServerClient); this.languageServerClient.onNotification( RunspaceChangedEventType, (runspaceDetails) => { this.setStatusBarVersionString(runspaceDetails); }); @@ -606,8 +606,8 @@ export class SessionManager implements Middleware { } } - private updateExtensionFeatures(languageClient: LanguageClient) { - this.extensionFeatures.forEach((feature) => { + private updateLanguageClientConsumers(languageClient: LanguageClient) { + this.languageClientConsumers.forEach((feature) => { feature.setLanguageClient(languageClient); }); } From c8eedbb59fd4800f135c6d325fc58a970831f483 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Wed, 10 Jun 2020 22:10:37 +0100 Subject: [PATCH 4/6] Provide base implementation for setLanguageClient to remove repeated code in some implementations --- src/features/ExpandAlias.ts | 6 +----- src/features/FindModule.ts | 6 +----- src/features/RemoteFiles.ts | 6 +----- src/features/ShowHelp.ts | 5 +---- src/languageClientConsumer.ts | 13 +++++++++---- 5 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/features/ExpandAlias.ts b/src/features/ExpandAlias.ts index 9005a77788..6323af0a58 100644 --- a/src/features/ExpandAlias.ts +++ b/src/features/ExpandAlias.ts @@ -4,7 +4,7 @@ import vscode = require("vscode"); import Window = vscode.window; -import { LanguageClient, NotificationType, RequestType } from "vscode-languageclient"; +import { RequestType } from "vscode-languageclient"; import { Logger } from "../logging"; import { LanguageClientConsumer } from "../languageClientConsumer"; @@ -45,8 +45,4 @@ export class ExpandAliasFeature extends LanguageClientConsumer { public dispose() { this.command.dispose(); } - - public setLanguageClient(languageclient: LanguageClient) { - this.languageClient = languageclient; - } } diff --git a/src/features/FindModule.ts b/src/features/FindModule.ts index a626c3784d..66817519f1 100644 --- a/src/features/FindModule.ts +++ b/src/features/FindModule.ts @@ -3,7 +3,7 @@ *--------------------------------------------------------*/ import vscode = require("vscode"); -import { LanguageClient, RequestType } from "vscode-languageclient"; +import { RequestType } from "vscode-languageclient"; import QuickPickItem = vscode.QuickPickItem; import { LanguageClientConsumer } from "../languageClientConsumer"; @@ -52,10 +52,6 @@ export class FindModuleFeature extends LanguageClientConsumer { }); } - public setLanguageClient(languageclient: LanguageClient) { - this.languageClient = languageclient; - } - public dispose() { this.command.dispose(); } diff --git a/src/features/RemoteFiles.ts b/src/features/RemoteFiles.ts index 9d0474d477..bf3b9878d4 100644 --- a/src/features/RemoteFiles.ts +++ b/src/features/RemoteFiles.ts @@ -5,7 +5,7 @@ import os = require("os"); import path = require("path"); import vscode = require("vscode"); -import { LanguageClient, NotificationType, TextDocumentIdentifier } from "vscode-languageclient"; +import { NotificationType, TextDocumentIdentifier } from "vscode-languageclient"; import { LanguageClientConsumer } from "../languageClientConsumer"; // NOTE: The following two DidSaveTextDocument* types will @@ -53,10 +53,6 @@ export class RemoteFilesFeature extends LanguageClientConsumer { this.closeRemoteFiles(); } - public setLanguageClient(languageclient: LanguageClient) { - this.languageClient = languageclient; - } - private isDocumentRemote(doc: vscode.TextDocument) { return doc.fileName.toLowerCase().startsWith(this.tempSessionPathPrefix); } diff --git a/src/features/ShowHelp.ts b/src/features/ShowHelp.ts index f345f00aa8..5a715de48f 100644 --- a/src/features/ShowHelp.ts +++ b/src/features/ShowHelp.ts @@ -3,7 +3,7 @@ *--------------------------------------------------------*/ import vscode = require("vscode"); -import { LanguageClient, NotificationType } from "vscode-languageclient"; +import { NotificationType } from "vscode-languageclient"; import { Logger } from "../logging"; import { LanguageClientConsumer } from "../languageClientConsumer"; @@ -38,7 +38,4 @@ export class ShowHelpFeature extends LanguageClientConsumer { this.deprecatedCommand.dispose(); } - public setLanguageClient(languageclient: LanguageClient) { - this.languageClient = languageclient; - } } diff --git a/src/languageClientConsumer.ts b/src/languageClientConsumer.ts index 64085ce991..acf3ec2217 100644 --- a/src/languageClientConsumer.ts +++ b/src/languageClientConsumer.ts @@ -7,18 +7,23 @@ import { LanguageClient } from "vscode-languageclient"; export abstract class LanguageClientConsumer { - abstract setLanguageClient(languageclient: LanguageClient): void; + private _languageClient: LanguageClient; + + public setLanguageClient(languageClient: LanguageClient) { + this.languageClient = languageClient; + } + abstract dispose(): void; public get languageClient(): LanguageClient { - if (!this.languageClient) { + if (!this._languageClient) { window.showInformationMessage( "PowerShell extension has not finished starting up yet. Please try again in a few moments."); } - return this.languageClient; + return this._languageClient; } public set languageClient(value: LanguageClient) { - this.languageClient = value; + this._languageClient = value; } } \ No newline at end of file From 110482096f3cbbdd29319fe84b9020560d0700ba Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Thu, 23 Jul 2020 11:37:02 +0100 Subject: [PATCH 5/6] Adapt ExternalApi.ts and PowerShellNotebooks.ts --- src/features/ExternalApi.ts | 10 +++------- src/features/PowerShellNotebooks.ts | 10 +++------- src/main.ts | 4 ++-- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/features/ExternalApi.ts b/src/features/ExternalApi.ts index d662d39c66..bb9da17b9b 100644 --- a/src/features/ExternalApi.ts +++ b/src/features/ExternalApi.ts @@ -4,7 +4,7 @@ import * as vscode from "vscode"; import { v4 as uuidv4 } from 'uuid'; import { LanguageClient } from "vscode-languageclient"; -import { IFeature } from "../feature"; +import { LanguageClientConsumer } from "../languageClientConsumer"; import { Logger } from "../logging"; import { SessionManager } from "../session"; @@ -15,12 +15,12 @@ export interface IExternalPowerShellDetails { architecture: string; } -export class ExternalApiFeature implements IFeature { +export class ExternalApiFeature extends LanguageClientConsumer { private commands: vscode.Disposable[]; - private languageClient: LanguageClient; private static readonly registeredExternalExtension: Map = new Map(); constructor(private sessionManager: SessionManager, private log: Logger) { + super(); this.commands = [ /* DESCRIPTION: @@ -141,10 +141,6 @@ export class ExternalApiFeature implements IFeature { command.dispose(); } } - - public setLanguageClient(languageclient: LanguageClient) { - this.languageClient = languageclient; - } } interface IExternalExtension { diff --git a/src/features/PowerShellNotebooks.ts b/src/features/PowerShellNotebooks.ts index 36fc7281cb..6915d85e55 100644 --- a/src/features/PowerShellNotebooks.ts +++ b/src/features/PowerShellNotebooks.ts @@ -4,16 +4,15 @@ import * as vscode from "vscode"; import { CommentType } from "../settings"; -import { IFeature, LanguageClient } from "../feature"; import { EvaluateRequestType } from "./Console"; +import { LanguageClientConsumer } from "../languageClientConsumer"; import Settings = require("../settings"); import { ILogger } from "../logging"; -export class PowerShellNotebooksFeature implements vscode.NotebookContentProvider, vscode.NotebookKernel, IFeature { +export class PowerShellNotebooksFeature extends LanguageClientConsumer implements vscode.NotebookContentProvider, vscode.NotebookKernel { private readonly showNotebookModeCommand: vscode.Disposable; private readonly hideNotebookModeCommand: vscode.Disposable; - private languageClient: LanguageClient; private _onDidChangeNotebook = new vscode.EventEmitter(); public onDidChangeNotebook: vscode.Event = this._onDidChangeNotebook.event; @@ -23,6 +22,7 @@ export class PowerShellNotebooksFeature implements vscode.NotebookContentProvide public preloads?: vscode.Uri[]; public constructor(private logger: ILogger, skipRegisteringCommands?: boolean) { + super(); // VS Code Notebook API uses this property for handling cell execution. this.kernel = this; @@ -191,10 +191,6 @@ export class PowerShellNotebooksFeature implements vscode.NotebookContentProvide this.hideNotebookModeCommand.dispose(); } - public setLanguageClient(languageClient: LanguageClient) { - this.languageClient = languageClient; - } - private async _save(document: vscode.NotebookDocument, targetResource: vscode.Uri, _token: vscode.CancellationToken): Promise { this.logger.writeDiagnostic(`Saving Notebook: ${targetResource.toString()}`); diff --git a/src/main.ts b/src/main.ts index 85e87f7194..c3ffecefab 100644 --- a/src/main.ts +++ b/src/main.ts @@ -171,7 +171,7 @@ export function activate(context: vscode.ExtensionContext): void { try { context.subscriptions.push(vscode.notebook.registerNotebookContentProvider("PowerShellNotebookMode", powerShellNotebooksFeature)); - extensionFeatures.push(powerShellNotebooksFeature); + languageClientConsumers.push(powerShellNotebooksFeature); } catch (e) { // This would happen if VS Code changes their API. powerShellNotebooksFeature.dispose(); @@ -179,7 +179,7 @@ export function activate(context: vscode.ExtensionContext): void { } } - sessionManager.setExtensionFeatures(languageClientConsumers); + sessionManager.setLanguageClientConsumers(languageClientConsumers); if (extensionSettings.startAutomatically) { sessionManager.start(); From 5b9b99db0aab05b16fd0712b7b257efa667de838 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 23 Jul 2020 08:42:14 -0700 Subject: [PATCH 6/6] newline --- src/languageClientConsumer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languageClientConsumer.ts b/src/languageClientConsumer.ts index acf3ec2217..e518cc7ec6 100644 --- a/src/languageClientConsumer.ts +++ b/src/languageClientConsumer.ts @@ -26,4 +26,4 @@ export abstract class LanguageClientConsumer { public set languageClient(value: LanguageClient) { this._languageClient = value; } -} \ No newline at end of file +}