diff --git a/client/src/common/client.ts b/client/src/common/client.ts index 8fd622253..1e4e7d990 100644 --- a/client/src/common/client.ts +++ b/client/src/common/client.ts @@ -1434,9 +1434,9 @@ export abstract class BaseLanguageClient implements FeatureClient<Middleware, La if (this._syncedDocuments) { this._syncedDocuments.clear(); } - // Dispose features in reverse order; + // Clear features in reverse order; for (const feature of Array.from(this._features.entries()).map(entry => entry[1]).reverse()) { - feature.dispose(); + feature.clear(); } if (mode === 'stop' && this._diagnostics !== undefined) { this._diagnostics.dispose(); diff --git a/client/src/common/configuration.ts b/client/src/common/configuration.ts index 666d32aee..0f30d482d 100644 --- a/client/src/common/configuration.ts +++ b/client/src/common/configuration.ts @@ -87,7 +87,7 @@ export class ConfigurationFeature implements StaticFeature { return result; } - public dispose(): void { + public clear(): void { } } @@ -149,11 +149,11 @@ export type $ConfigurationOptions = { export class SyncConfigurationFeature implements DynamicFeature<DidChangeConfigurationRegistrationOptions> { - private isDisposed: boolean; + private isCleared: boolean; private readonly _listeners: Map<string, Disposable>; constructor(private _client: FeatureClient<DidChangeConfigurationWorkspaceMiddleware, $ConfigurationOptions>) { - this.isDisposed = false; + this.isCleared = false; this._listeners = new Map(); } @@ -170,6 +170,7 @@ export class SyncConfigurationFeature implements DynamicFeature<DidChangeConfigu } public initialize(): void { + this.isCleared = false; let section = this._client.clientOptions.synchronize?.configurationSection; if (section !== undefined) { this.register({ @@ -199,16 +200,16 @@ export class SyncConfigurationFeature implements DynamicFeature<DidChangeConfigu } } - public dispose(): void { + public clear(): void { for (const disposable of this._listeners.values()) { disposable.dispose(); } this._listeners.clear(); - this.isDisposed = true; + this.isCleared = true; } private onDidChangeConfiguration(configurationSection: string | string[] | undefined, event: ConfigurationChangeEvent | undefined): void { - if (this.isDisposed) { + if (this.isCleared) { return; } let sections: string[] | undefined; diff --git a/client/src/common/diagnostic.ts b/client/src/common/diagnostic.ts index 1ce1fb1f5..82b3e3784 100644 --- a/client/src/common/diagnostic.ts +++ b/client/src/common/diagnostic.ts @@ -1056,12 +1056,12 @@ export class DiagnosticFeature extends TextDocumentLanguageFeature<DiagnosticOpt this.register({ id: id, registerOptions: options }); } - public dispose(): void { + public clear(): void { if (this.tabs !== undefined) { this.tabs.dispose(); this.tabs = undefined; } - super.dispose(); + super.clear(); } protected registerLanguageProvider(options: DiagnosticRegistrationOptions): [Disposable, DiagnosticProviderShape] { diff --git a/client/src/common/executeCommand.ts b/client/src/common/executeCommand.ts index 484ae9f30..cda8faad3 100644 --- a/client/src/common/executeCommand.ts +++ b/client/src/common/executeCommand.ts @@ -92,7 +92,7 @@ export class ExecuteCommandFeature implements DynamicFeature<ExecuteCommandRegis } } - public dispose(): void { + public clear(): void { this._commands.forEach((value) => { value.forEach(disposable => disposable.dispose()); }); diff --git a/client/src/common/features.ts b/client/src/common/features.ts index 2848a7a15..cbdd9f234 100644 --- a/client/src/common/features.ts +++ b/client/src/common/features.ts @@ -155,17 +155,18 @@ export interface StaticFeature { getState(): FeatureState; /** - * Called when the client is stopped to dispose this feature. Usually a feature - * un-registers listeners registered hooked up with the VS Code extension host. + * Called when the client is stopped or re-started to clear this feature. + * Usually a feature un-registers listeners registered hooked up with the + * VS Code extension host. */ - dispose(): void; + clear(): void; } export namespace StaticFeature { export function is (value: any): value is StaticFeature { const candidate: StaticFeature = value; return candidate !== undefined && candidate !== null && - Is.func(candidate.fillClientCapabilities) && Is.func(candidate.initialize) && Is.func(candidate.getState) && Is.func(candidate.dispose) && + Is.func(candidate.fillClientCapabilities) && Is.func(candidate.initialize) && Is.func(candidate.getState) && Is.func(candidate.clear) && (candidate.fillInitializeParams === undefined || Is.func(candidate.fillInitializeParams)); } } @@ -237,17 +238,18 @@ export interface DynamicFeature<RO> { unregister(id: string): void; /** - * Called when the client is stopped to dispose this feature. Usually a feature - * un-registers listeners registered hooked up with the VS Code extension host. + * Called when the client is stopped or re-started to clear this feature. + * Usually a feature un-registers listeners registered hooked up with the + * VS Code extension host. */ - dispose(): void; + clear(): void; } export namespace DynamicFeature { export function is<T>(value: any): value is DynamicFeature<T> { const candidate: DynamicFeature<T> = value; return candidate !== undefined && candidate !== null && - Is.func(candidate.fillClientCapabilities) && Is.func(candidate.initialize) && Is.func(candidate.getState) && Is.func(candidate.dispose) && + Is.func(candidate.fillClientCapabilities) && Is.func(candidate.initialize) && Is.func(candidate.getState) && Is.func(candidate.clear) && (candidate.fillInitializeParams === undefined || Is.func(candidate.fillInitializeParams)) && Is.func(candidate.register) && Is.func(candidate.unregister) && candidate.registrationType !== undefined; } @@ -285,7 +287,7 @@ export abstract class DynamicDocumentFeature<RO, MW, CO = object> implements Dyn public abstract registrationType: RegistrationType<RO>; public abstract register(data: RegistrationData<RO>): void; public abstract unregister(id: string): void; - public abstract dispose(): void; + public abstract clear(): void; /** * Returns the state the feature is in. @@ -424,7 +426,7 @@ export abstract class TextDocumentEventFeature<P extends { textDocument: TextDoc } } - public dispose(): void { + public clear(): void { this._selectors.clear(); this._onNotificationSent.dispose(); if (this._listener) { @@ -518,7 +520,7 @@ export abstract class TextDocumentLanguageFeature<PO, RO extends TextDocumentReg } } - public dispose(): void { + public clear(): void { this._registrations.forEach((value) => { value.disposable.dispose(); }); @@ -618,7 +620,7 @@ export abstract class WorkspaceFeature<RO, PR, M> implements DynamicFeature<RO> } } - public dispose(): void { + public clear(): void { this._registrations.forEach((registration) => { registration.disposable.dispose(); }); diff --git a/client/src/common/fileOperations.ts b/client/src/common/fileOperations.ts index 6f8b7ae4e..c9536c0e8 100644 --- a/client/src/common/fileOperations.ts +++ b/client/src/common/fileOperations.ts @@ -130,7 +130,7 @@ abstract class FileOperationFeature<I, E extends Event<I>> implements DynamicFea } } - public dispose(): void { + public clear(): void { this._filters.clear(); if (this._listener) { this._listener.dispose(); @@ -276,8 +276,8 @@ abstract class CachingNotificationFileOperationFeature<I, E extends { readonly f } } - public dispose(): void { - super.dispose(); + public clear(): void { + super.clear(); if (this._willListener) { this._willListener.dispose(); this._willListener = undefined; diff --git a/client/src/common/fileSystemWatcher.ts b/client/src/common/fileSystemWatcher.ts index a9b329ddd..0fa08d561 100644 --- a/client/src/common/fileSystemWatcher.ts +++ b/client/src/common/fileSystemWatcher.ts @@ -112,7 +112,7 @@ export class FileSystemWatcherFeature implements DynamicFeature<DidChangeWatched } } - public dispose(): void { + public clear(): void { this._watchers.forEach((disposables) => { for (let disposable of disposables) { disposable.dispose(); diff --git a/client/src/common/notebook.ts b/client/src/common/notebook.ts index b5909e6f8..252cdb0fc 100644 --- a/client/src/common/notebook.ts +++ b/client/src/common/notebook.ts @@ -964,7 +964,7 @@ export class NotebookDocumentSyncFeature implements DynamicFeature<proto.Noteboo provider && provider.dispose(); } - public dispose(): void { + public clear(): void { for (const provider of this.registrations.values()) { provider.dispose(); } diff --git a/client/src/common/progress.ts b/client/src/common/progress.ts index da947db6d..b179ea93a 100644 --- a/client/src/common/progress.ts +++ b/client/src/common/progress.ts @@ -45,7 +45,7 @@ export class ProgressFeature implements StaticFeature { client.onRequest(WorkDoneProgressCreateRequest.type, createHandler); } - public dispose(): void { + public clear(): void { for (const part of this.activeParts) { part.done(); } diff --git a/client/src/common/textSynchronization.ts b/client/src/common/textSynchronization.ts index e112cbf46..0c5339209 100644 --- a/client/src/common/textSynchronization.ts +++ b/client/src/common/textSynchronization.ts @@ -319,7 +319,7 @@ export class DidChangeTextDocumentFeature extends DynamicDocumentFeature<TextDoc } } - public dispose(): void { + public clear(): void { this._pendingTextDocumentChanges.clear(); this._changeData.clear(); this._syncKind = TextDocumentSyncKind.None; @@ -484,7 +484,7 @@ export class WillSaveWaitUntilFeature extends DynamicDocumentFeature<TextDocumen } } - public dispose(): void { + public clear(): void { this._selectors.clear(); if (this._listener) { this._listener.dispose(); diff --git a/client/src/common/workspaceFolder.ts b/client/src/common/workspaceFolder.ts index 386036b99..da7cbbe44 100644 --- a/client/src/common/workspaceFolder.ts +++ b/client/src/common/workspaceFolder.ts @@ -160,7 +160,7 @@ export class WorkspaceFoldersFeature implements DynamicFeature<void> { disposable.dispose(); } - public dispose(): void { + public clear(): void { for (let disposable of this._listeners.values()) { disposable.dispose(); } diff --git a/testbed/client/src/extension.ts b/testbed/client/src/extension.ts index 1e2b745ef..2c9305432 100644 --- a/testbed/client/src/extension.ts +++ b/testbed/client/src/extension.ts @@ -27,7 +27,7 @@ export async function activate(context: ExtensionContext) { { scheme: 'file', pattern: '**/.vscode/test.txt' } ], synchronize: { - configurationSection: 'testbed' + // configurationSection: 'testbed' // fileEvents: workspace.createFileSystemWatcher('**/*'), }, diagnosticCollectionName: 'markers', diff --git a/testbed/server/src/server.ts b/testbed/server/src/server.ts index 96ab34818..0d1378ac0 100644 --- a/testbed/server/src/server.ts +++ b/testbed/server/src/server.ts @@ -17,7 +17,7 @@ import { TextEdit, ProposedFeatures, DiagnosticTag, InsertTextFormat, SelectionRangeRequest, SelectionRange, InsertReplaceEdit, SemanticTokensClientCapabilities, SemanticTokensLegend, SemanticTokensBuilder, SemanticTokensRegistrationType, SemanticTokensRegistrationOptions, ProtocolNotificationType, ChangeAnnotation, WorkspaceChange, CompletionItemKind, DiagnosticSeverity, - DocumentDiagnosticReportKind, WorkspaceDiagnosticReport, NotebookDocuments, CompletionList, DocumentLinkResolveRequest + DocumentDiagnosticReportKind, WorkspaceDiagnosticReport, NotebookDocuments, CompletionList, DocumentLinkResolveRequest, DidChangeConfigurationNotification } from 'vscode-languageserver/node'; import { @@ -187,6 +187,7 @@ connection.onInitialize((params, cancel, progress): Thenable<InitializeResult> | }); connection.onInitialized((params) => { + void connection.client.register(DidChangeConfigurationNotification.type, undefined); connection.workspace.onDidChangeWorkspaceFolders((event) => { connection.console.log('Workspace folder changed received'); });