mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-23 19:59:37 +00:00
Add base Disposable class to help manage disposables
This commit is contained in:
@@ -4,12 +4,12 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import { CancellationTokenSource, Disposable, EventEmitter, TextDocument, TextDocumentChangeEvent, TextDocumentContentChangeEvent, Uri, workspace } from 'vscode';
|
||||
import { CancellationTokenSource, EventEmitter, TextDocument, TextDocumentChangeEvent, TextDocumentContentChangeEvent, Uri, workspace } from 'vscode';
|
||||
import * as Proto from '../protocol';
|
||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
||||
import API from '../utils/api';
|
||||
import { Delayer } from '../utils/async';
|
||||
import { disposeAll } from '../utils/dispose';
|
||||
import { Disposable } from '../utils/dispose';
|
||||
import * as languageModeIds from '../utils/languageModeIds';
|
||||
import { ResourceMap } from '../utils/resourceMap';
|
||||
import * as typeConverters from '../utils/typeConverters';
|
||||
@@ -168,14 +168,13 @@ class GetErrRequest {
|
||||
}
|
||||
}
|
||||
|
||||
export default class BufferSyncSupport {
|
||||
export default class BufferSyncSupport extends Disposable {
|
||||
|
||||
private readonly client: ITypeScriptServiceClient;
|
||||
|
||||
private _validateJavaScript: boolean = true;
|
||||
private _validateTypeScript: boolean = true;
|
||||
private readonly modeIds: Set<string>;
|
||||
private readonly disposables: Disposable[] = [];
|
||||
private readonly syncedBuffers: SyncedBufferMap;
|
||||
private readonly pendingDiagnostics: PendingDiagnostics;
|
||||
private readonly diagnosticDelayer: Delayer<any>;
|
||||
@@ -186,6 +185,7 @@ export default class BufferSyncSupport {
|
||||
client: ITypeScriptServiceClient,
|
||||
modeIds: string[]
|
||||
) {
|
||||
super();
|
||||
this.client = client;
|
||||
this.modeIds = new Set<string>(modeIds);
|
||||
|
||||
@@ -196,10 +196,10 @@ export default class BufferSyncSupport {
|
||||
this.pendingDiagnostics = new PendingDiagnostics(pathNormalizer);
|
||||
|
||||
this.updateConfiguration();
|
||||
workspace.onDidChangeConfiguration(this.updateConfiguration, this, this.disposables);
|
||||
workspace.onDidChangeConfiguration(this.updateConfiguration, this, this._disposables);
|
||||
}
|
||||
|
||||
private readonly _onDelete = new EventEmitter<Uri>();
|
||||
private readonly _onDelete = this._register(new EventEmitter<Uri>());
|
||||
public readonly onDelete = this._onDelete.event;
|
||||
|
||||
public listen(): void {
|
||||
@@ -207,9 +207,9 @@ export default class BufferSyncSupport {
|
||||
return;
|
||||
}
|
||||
this.listening = true;
|
||||
workspace.onDidOpenTextDocument(this.openTextDocument, this, this.disposables);
|
||||
workspace.onDidCloseTextDocument(this.onDidCloseTextDocument, this, this.disposables);
|
||||
workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, this.disposables);
|
||||
workspace.onDidOpenTextDocument(this.openTextDocument, this, this._disposables);
|
||||
workspace.onDidCloseTextDocument(this.onDidCloseTextDocument, this, this._disposables);
|
||||
workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, this._disposables);
|
||||
workspace.textDocuments.forEach(this.openTextDocument, this);
|
||||
}
|
||||
|
||||
@@ -231,11 +231,6 @@ export default class BufferSyncSupport {
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
disposeAll(this.disposables);
|
||||
this._onDelete.dispose();
|
||||
}
|
||||
|
||||
public openTextDocument(document: TextDocument): void {
|
||||
if (!this.modeIds.has(document.languageId)) {
|
||||
return;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { disposeAll } from '../utils/dispose';
|
||||
import { Disposable } from '../utils/dispose';
|
||||
import * as languageModeIds from '../utils/languageModeIds';
|
||||
|
||||
const jsTsLanguageConfiguration: vscode.LanguageConfiguration = {
|
||||
@@ -64,10 +64,10 @@ const jsxTagsLanguageConfiguration: vscode.LanguageConfiguration = {
|
||||
],
|
||||
};
|
||||
|
||||
export class LanguageConfigurationManager {
|
||||
private readonly _registrations: vscode.Disposable[] = [];
|
||||
export class LanguageConfigurationManager extends Disposable {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const standardLanguages = [
|
||||
languageModeIds.javascript,
|
||||
languageModeIds.javascriptreact,
|
||||
@@ -82,10 +82,6 @@ export class LanguageConfigurationManager {
|
||||
}
|
||||
|
||||
private registerConfiguration(language: string, config: vscode.LanguageConfiguration) {
|
||||
this._registrations.push(vscode.languages.setLanguageConfiguration(language, config));
|
||||
}
|
||||
|
||||
dispose() {
|
||||
disposeAll(this._registrations);
|
||||
this._register(vscode.languages.setLanguageConfiguration(language, config));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,19 +8,19 @@ import * as Proto from '../protocol';
|
||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
||||
import API from '../utils/api';
|
||||
import { ConditionalRegistration, ConfigurationDependentRegistration, VersionDependentRegistration } from '../utils/dependentRegistration';
|
||||
import { disposeAll } from '../utils/dispose';
|
||||
import { Disposable } from '../utils/dispose';
|
||||
import * as typeConverters from '../utils/typeConverters';
|
||||
|
||||
class TagClosing {
|
||||
class TagClosing extends Disposable {
|
||||
|
||||
private _disposed = false;
|
||||
private _timeout: NodeJS.Timer | undefined = undefined;
|
||||
private _cancel: vscode.CancellationTokenSource | undefined = undefined;
|
||||
private readonly _disposables: vscode.Disposable[] = [];
|
||||
|
||||
constructor(
|
||||
private readonly client: ITypeScriptServiceClient
|
||||
) {
|
||||
super();
|
||||
vscode.workspace.onDidChangeTextDocument(
|
||||
event => this.onDidChangeTextDocument(event.document, event.contentChanges),
|
||||
null,
|
||||
@@ -28,10 +28,9 @@ class TagClosing {
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
super.dispose();
|
||||
this._disposed = true;
|
||||
|
||||
disposeAll(this._disposables);
|
||||
|
||||
if (this._timeout) {
|
||||
clearTimeout(this._timeout);
|
||||
this._timeout = undefined;
|
||||
@@ -136,24 +135,19 @@ class TagClosing {
|
||||
}
|
||||
}
|
||||
|
||||
export class ActiveDocumentDependentRegistration {
|
||||
export class ActiveDocumentDependentRegistration extends Disposable {
|
||||
private readonly _registration: ConditionalRegistration;
|
||||
private readonly _disposables: vscode.Disposable[] = [];
|
||||
|
||||
constructor(
|
||||
private readonly selector: vscode.DocumentSelector,
|
||||
register: () => vscode.Disposable,
|
||||
) {
|
||||
this._registration = new ConditionalRegistration(register);
|
||||
super();
|
||||
this._registration = this._register(new ConditionalRegistration(register));
|
||||
vscode.window.onDidChangeActiveTextEditor(this.update, this, this._disposables);
|
||||
this.update();
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
disposeAll(this._disposables);
|
||||
this._registration.dispose();
|
||||
}
|
||||
|
||||
private update() {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
const enabled = !!(editor && vscode.languages.match(this.selector, editor.document));
|
||||
|
||||
@@ -10,7 +10,7 @@ import { DiagnosticKind } from './features/diagnostics';
|
||||
import FileConfigurationManager from './features/fileConfigurationManager';
|
||||
import TypeScriptServiceClient from './typescriptServiceClient';
|
||||
import { CommandManager } from './utils/commandManager';
|
||||
import { disposeAll } from './utils/dispose';
|
||||
import { Disposable } from './utils/dispose';
|
||||
import * as fileSchemes from './utils/fileSchemes';
|
||||
import { LanguageDescription } from './utils/languageDescription';
|
||||
import { memoize } from './utils/memoize';
|
||||
@@ -21,8 +21,7 @@ import TypingsStatus from './utils/typingsStatus';
|
||||
const validateSetting = 'validate.enable';
|
||||
const suggestionSetting = 'suggestionActions.enabled';
|
||||
|
||||
export default class LanguageProvider {
|
||||
private readonly disposables: vscode.Disposable[] = [];
|
||||
export default class LanguageProvider extends Disposable {
|
||||
|
||||
constructor(
|
||||
private readonly client: TypeScriptServiceClient,
|
||||
@@ -32,7 +31,8 @@ export default class LanguageProvider {
|
||||
private readonly typingsStatus: TypingsStatus,
|
||||
private readonly fileConfigurationManager: FileConfigurationManager
|
||||
) {
|
||||
vscode.workspace.onDidChangeConfiguration(this.configurationChanged, this, this.disposables);
|
||||
super();
|
||||
vscode.workspace.onDidChangeConfiguration(this.configurationChanged, this, this._disposables);
|
||||
this.configurationChanged();
|
||||
|
||||
client.onReady(async () => {
|
||||
@@ -40,9 +40,6 @@ export default class LanguageProvider {
|
||||
});
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
disposeAll(this.disposables);
|
||||
}
|
||||
|
||||
@memoize
|
||||
private get documentSelector(): vscode.DocumentFilter[] {
|
||||
@@ -60,27 +57,27 @@ export default class LanguageProvider {
|
||||
|
||||
const cachedResponse = new CachedNavTreeResponse();
|
||||
|
||||
this.disposables.push((await import('./features/completions')).register(selector, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager));
|
||||
this.disposables.push((await import('./features/definitions')).register(selector, this.client));
|
||||
this.disposables.push((await import('./features/directiveCommentCompletions')).register(selector, this.client));
|
||||
this.disposables.push((await import('./features/documentHighlight')).register(selector, this.client));
|
||||
this.disposables.push((await import('./features/documentSymbol')).register(selector, this.client));
|
||||
this.disposables.push((await import('./features/folding')).register(selector, this.client));
|
||||
this.disposables.push((await import('./features/formatting')).register(selector, this.description.id, this.client, this.fileConfigurationManager));
|
||||
this.disposables.push((await import('./features/hover')).register(selector, this.client));
|
||||
this.disposables.push((await import('./features/implementations')).register(selector, this.client));
|
||||
this.disposables.push((await import('./features/implementationsCodeLens')).register(selector, this.description.id, this.client, cachedResponse));
|
||||
this.disposables.push((await import('./features/jsDocCompletions')).register(selector, this.client, this.commandManager));
|
||||
this.disposables.push((await import('./features/organizeImports')).register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter));
|
||||
this.disposables.push((await import('./features/quickFix')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.client.diagnosticsManager, this.telemetryReporter));
|
||||
this.disposables.push((await import('./features/refactor')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.telemetryReporter));
|
||||
this.disposables.push((await import('./features/references')).register(selector, this.client));
|
||||
this.disposables.push((await import('./features/referencesCodeLens')).register(selector, this.description.id, this.client, cachedResponse));
|
||||
this.disposables.push((await import('./features/rename')).register(selector, this.client));
|
||||
this.disposables.push((await import('./features/signatureHelp')).register(selector, this.client));
|
||||
this.disposables.push((await import('./features/tagClosing')).register(selector, this.description.id, this.client));
|
||||
this.disposables.push((await import('./features/typeDefinitions')).register(selector, this.client));
|
||||
this.disposables.push((await import('./features/workspaceSymbols')).register(this.client, this.description.modeIds));
|
||||
this._register((await import('./features/completions')).register(selector, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager));
|
||||
this._register((await import('./features/definitions')).register(selector, this.client));
|
||||
this._register((await import('./features/directiveCommentCompletions')).register(selector, this.client));
|
||||
this._register((await import('./features/documentHighlight')).register(selector, this.client));
|
||||
this._register((await import('./features/documentSymbol')).register(selector, this.client));
|
||||
this._register((await import('./features/folding')).register(selector, this.client));
|
||||
this._register((await import('./features/formatting')).register(selector, this.description.id, this.client, this.fileConfigurationManager));
|
||||
this._register((await import('./features/hover')).register(selector, this.client));
|
||||
this._register((await import('./features/implementations')).register(selector, this.client));
|
||||
this._register((await import('./features/implementationsCodeLens')).register(selector, this.description.id, this.client, cachedResponse));
|
||||
this._register((await import('./features/jsDocCompletions')).register(selector, this.client, this.commandManager));
|
||||
this._register((await import('./features/organizeImports')).register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter));
|
||||
this._register((await import('./features/quickFix')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.client.diagnosticsManager, this.telemetryReporter));
|
||||
this._register((await import('./features/refactor')).register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.telemetryReporter));
|
||||
this._register((await import('./features/references')).register(selector, this.client));
|
||||
this._register((await import('./features/referencesCodeLens')).register(selector, this.description.id, this.client, cachedResponse));
|
||||
this._register((await import('./features/rename')).register(selector, this.client));
|
||||
this._register((await import('./features/signatureHelp')).register(selector, this.client));
|
||||
this._register((await import('./features/tagClosing')).register(selector, this.description.id, this.client));
|
||||
this._register((await import('./features/typeDefinitions')).register(selector, this.client));
|
||||
this._register((await import('./features/workspaceSymbols')).register(this.client, this.description.modeIds));
|
||||
}
|
||||
|
||||
private configurationChanged(): void {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* https://github.com/Microsoft/TypeScript-Sublime-Plugin/blob/master/TypeScript%20Indent.tmPreferences
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import { Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DiagnosticTag, Disposable, Memento, Range, Uri, workspace } from 'vscode';
|
||||
import { Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DiagnosticTag, Memento, Range, Uri, workspace } from 'vscode';
|
||||
import { DiagnosticKind } from './features/diagnostics';
|
||||
import FileConfigurationManager from './features/fileConfigurationManager';
|
||||
import { register as registerUpdatePathsOnRename } from './features/updatePathsOnRename';
|
||||
@@ -18,7 +18,7 @@ import * as PConst from './protocol.const';
|
||||
import TypeScriptServiceClient from './typescriptServiceClient';
|
||||
import API from './utils/api';
|
||||
import { CommandManager } from './utils/commandManager';
|
||||
import { disposeAll } from './utils/dispose';
|
||||
import { Disposable } from './utils/dispose';
|
||||
import { LanguageDescription, DiagnosticLanguage } from './utils/languageDescription';
|
||||
import LogDirectoryProvider from './utils/logDirectoryProvider';
|
||||
import { TypeScriptServerPlugin } from './utils/plugins';
|
||||
@@ -36,13 +36,11 @@ const styleCheckDiagnostics = [
|
||||
7030 // not all code paths return a value
|
||||
];
|
||||
|
||||
export default class TypeScriptServiceClientHost {
|
||||
private readonly ataProgressReporter: AtaProgressReporter;
|
||||
export default class TypeScriptServiceClientHost extends Disposable {
|
||||
private readonly typingsStatus: TypingsStatus;
|
||||
private readonly client: TypeScriptServiceClient;
|
||||
private readonly languages: LanguageProvider[] = [];
|
||||
private readonly languagePerId = new Map<string, LanguageProvider>();
|
||||
private readonly disposables: Disposable[] = [];
|
||||
private readonly versionStatus: VersionStatus;
|
||||
private readonly fileConfigurationManager: FileConfigurationManager;
|
||||
|
||||
@@ -55,6 +53,7 @@ export default class TypeScriptServiceClientHost {
|
||||
private readonly commandManager: CommandManager,
|
||||
logDirectoryProvider: LogDirectoryProvider
|
||||
) {
|
||||
super();
|
||||
const handleProjectCreateOrDelete = () => {
|
||||
this.client.execute('reloadProjects', null, false);
|
||||
this.triggerAllDiagnostics();
|
||||
@@ -65,10 +64,10 @@ export default class TypeScriptServiceClientHost {
|
||||
}, 1500);
|
||||
};
|
||||
const configFileWatcher = workspace.createFileSystemWatcher('**/[tj]sconfig.json');
|
||||
this.disposables.push(configFileWatcher);
|
||||
configFileWatcher.onDidCreate(handleProjectCreateOrDelete, this, this.disposables);
|
||||
configFileWatcher.onDidDelete(handleProjectCreateOrDelete, this, this.disposables);
|
||||
configFileWatcher.onDidChange(handleProjectChange, this, this.disposables);
|
||||
this._register(configFileWatcher);
|
||||
configFileWatcher.onDidCreate(handleProjectCreateOrDelete, this, this._disposables);
|
||||
configFileWatcher.onDidDelete(handleProjectCreateOrDelete, this, this._disposables);
|
||||
configFileWatcher.onDidChange(handleProjectChange, this, this._disposables);
|
||||
|
||||
const allModeIds = this.getAllModeIds(descriptions);
|
||||
this.client = new TypeScriptServiceClient(
|
||||
@@ -77,30 +76,30 @@ export default class TypeScriptServiceClientHost {
|
||||
plugins,
|
||||
logDirectoryProvider,
|
||||
allModeIds);
|
||||
this.disposables.push(this.client);
|
||||
this._register(this.client);
|
||||
|
||||
this.client.onDiagnosticsReceived(({ kind, resource, diagnostics }) => {
|
||||
this.diagnosticsReceived(kind, resource, diagnostics);
|
||||
}, null, this.disposables);
|
||||
}, null, this._disposables);
|
||||
|
||||
this.client.onConfigDiagnosticsReceived(diag => this.configFileDiagnosticsReceived(diag), null, this.disposables);
|
||||
this.client.onResendModelsRequested(() => this.populateService(), null, this.disposables);
|
||||
this.client.onConfigDiagnosticsReceived(diag => this.configFileDiagnosticsReceived(diag), null, this._disposables);
|
||||
this.client.onResendModelsRequested(() => this.populateService(), null, this._disposables);
|
||||
|
||||
this.versionStatus = new VersionStatus(resource => this.client.toPath(resource));
|
||||
this.disposables.push(this.versionStatus);
|
||||
this._register(this.versionStatus);
|
||||
|
||||
this.typingsStatus = new TypingsStatus(this.client);
|
||||
this.ataProgressReporter = new AtaProgressReporter(this.client);
|
||||
this.fileConfigurationManager = new FileConfigurationManager(this.client);
|
||||
this._register(new AtaProgressReporter(this.client));
|
||||
this.typingsStatus = this._register(new TypingsStatus(this.client));
|
||||
this.fileConfigurationManager = this._register(new FileConfigurationManager(this.client));
|
||||
|
||||
for (const description of descriptions) {
|
||||
const manager = new LanguageProvider(this.client, description, this.commandManager, this.client.telemetryReporter, this.typingsStatus, this.fileConfigurationManager);
|
||||
this.languages.push(manager);
|
||||
this.disposables.push(manager);
|
||||
this._register(manager);
|
||||
this.languagePerId.set(description.id, manager);
|
||||
}
|
||||
|
||||
this.disposables.push(registerUpdatePathsOnRename(this.client, this.fileConfigurationManager, uri => this.handles(uri)));
|
||||
this._register(registerUpdatePathsOnRename(this.client, this.fileConfigurationManager, uri => this.handles(uri)));
|
||||
|
||||
this.client.ensureServiceStarted();
|
||||
this.client.onReady(() => {
|
||||
@@ -125,7 +124,7 @@ export default class TypeScriptServiceClientHost {
|
||||
};
|
||||
const manager = new LanguageProvider(this.client, description, this.commandManager, this.client.telemetryReporter, this.typingsStatus, this.fileConfigurationManager);
|
||||
this.languages.push(manager);
|
||||
this.disposables.push(manager);
|
||||
this._register(manager);
|
||||
this.languagePerId.set(description.id, manager);
|
||||
}
|
||||
});
|
||||
@@ -134,7 +133,7 @@ export default class TypeScriptServiceClientHost {
|
||||
this.triggerAllDiagnostics();
|
||||
});
|
||||
|
||||
workspace.onDidChangeConfiguration(this.configurationChanged, this, this.disposables);
|
||||
workspace.onDidChangeConfiguration(this.configurationChanged, this, this._disposables);
|
||||
this.configurationChanged();
|
||||
}
|
||||
|
||||
@@ -146,13 +145,6 @@ export default class TypeScriptServiceClientHost {
|
||||
return allModeIds;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
disposeAll(this.disposables);
|
||||
this.typingsStatus.dispose();
|
||||
this.ataProgressReporter.dispose();
|
||||
this.fileConfigurationManager.dispose();
|
||||
}
|
||||
|
||||
public get serviceClient(): TypeScriptServiceClient {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import * as cp from 'child_process';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { CancellationToken, commands, Disposable, env, EventEmitter, Memento, MessageItem, Uri, window, workspace } from 'vscode';
|
||||
import { CancellationToken, commands, env, EventEmitter, Memento, MessageItem, Uri, window, workspace } from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import BufferSyncSupport from './features/bufferSyncSupport';
|
||||
import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics';
|
||||
@@ -14,7 +14,7 @@ import * as Proto from './protocol';
|
||||
import { ITypeScriptServiceClient } from './typescriptService';
|
||||
import API from './utils/api';
|
||||
import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration';
|
||||
import { disposeAll } from './utils/dispose';
|
||||
import { Disposable } from './utils/dispose';
|
||||
import * as electron from './utils/electron';
|
||||
import * as fileSchemes from './utils/fileSchemes';
|
||||
import * as is from './utils/is';
|
||||
@@ -30,9 +30,6 @@ import { TypeScriptVersion, TypeScriptVersionProvider } from './utils/versionPro
|
||||
import { ICallback, Reader } from './utils/wireProtocol';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
interface CallbackItem {
|
||||
@@ -159,7 +156,7 @@ export interface TsDiagnostics {
|
||||
readonly diagnostics: Proto.Diagnostic[];
|
||||
}
|
||||
|
||||
export default class TypeScriptServiceClient implements ITypeScriptServiceClient {
|
||||
export default class TypeScriptServiceClient extends Disposable implements ITypeScriptServiceClient {
|
||||
private static readonly WALK_THROUGH_SNIPPET_SCHEME_COLON = `${fileSchemes.walkThroughSnippet}:`;
|
||||
|
||||
private pathSeparator: string;
|
||||
@@ -194,8 +191,6 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
|
||||
*/
|
||||
private _tsserverVersion: string | undefined;
|
||||
|
||||
private readonly disposables: Disposable[] = [];
|
||||
|
||||
public readonly bufferSyncSupport: BufferSyncSupport;
|
||||
public readonly diagnosticsManager: DiagnosticsManager;
|
||||
|
||||
@@ -206,6 +201,7 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
|
||||
private readonly logDirectoryProvider: LogDirectoryProvider,
|
||||
allModeIds: string[]
|
||||
) {
|
||||
super();
|
||||
this.pathSeparator = path.sep;
|
||||
this.lastStart = Date.now();
|
||||
|
||||
@@ -235,7 +231,7 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
|
||||
this.diagnosticsManager = new DiagnosticsManager('typescript');
|
||||
this.bufferSyncSupport.onDelete(resource => {
|
||||
this.diagnosticsManager.delete(resource);
|
||||
}, null, this.disposables);
|
||||
}, null, this._disposables);
|
||||
|
||||
workspace.onDidChangeConfiguration(() => {
|
||||
const oldConfiguration = this._configuration;
|
||||
@@ -256,9 +252,9 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
|
||||
this.restartTsServer();
|
||||
}
|
||||
}
|
||||
}, this, this.disposables);
|
||||
}, this, this._disposables);
|
||||
this.telemetryReporter = new TelemetryReporter(() => this._tsserverVersion || this._apiVersion.versionString);
|
||||
this.disposables.push(this.telemetryReporter);
|
||||
this._register(this.telemetryReporter);
|
||||
}
|
||||
|
||||
public get configuration() {
|
||||
@@ -266,22 +262,15 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
super.dispose();
|
||||
|
||||
this.bufferSyncSupport.dispose();
|
||||
this._onTsServerStarted.dispose();
|
||||
this._onDidBeginInstallTypings.dispose();
|
||||
this._onDidEndInstallTypings.dispose();
|
||||
this._onTypesInstallerInitializationFailed.dispose();
|
||||
|
||||
if (this.servicePromise) {
|
||||
this.servicePromise.then(childProcess => {
|
||||
childProcess.kill();
|
||||
}).then(undefined, () => void 0);
|
||||
}
|
||||
|
||||
disposeAll(this.disposables);
|
||||
this._onDiagnosticsReceived.dispose();
|
||||
this._onConfigDiagnosticsReceived.dispose();
|
||||
this._onResendModelsRequested.dispose();
|
||||
}
|
||||
|
||||
public restartTsServer(): void {
|
||||
@@ -302,28 +291,28 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
|
||||
}
|
||||
}
|
||||
|
||||
private readonly _onTsServerStarted = new EventEmitter<API>();
|
||||
private readonly _onTsServerStarted = this._register(new EventEmitter<API>());
|
||||
public readonly onTsServerStarted = this._onTsServerStarted.event;
|
||||
|
||||
private readonly _onDiagnosticsReceived = new EventEmitter<TsDiagnostics>();
|
||||
private readonly _onDiagnosticsReceived = this._register(new EventEmitter<TsDiagnostics>());
|
||||
public readonly onDiagnosticsReceived = this._onDiagnosticsReceived.event;
|
||||
|
||||
private readonly _onConfigDiagnosticsReceived = new EventEmitter<Proto.ConfigFileDiagnosticEvent>();
|
||||
private readonly _onConfigDiagnosticsReceived = this._register(new EventEmitter<Proto.ConfigFileDiagnosticEvent>());
|
||||
public readonly onConfigDiagnosticsReceived = this._onConfigDiagnosticsReceived.event;
|
||||
|
||||
private readonly _onResendModelsRequested = new EventEmitter<void>();
|
||||
private readonly _onResendModelsRequested = this._register(new EventEmitter<void>());
|
||||
public readonly onResendModelsRequested = this._onResendModelsRequested.event;
|
||||
|
||||
private readonly _onProjectLanguageServiceStateChanged = new EventEmitter<Proto.ProjectLanguageServiceStateEventBody>();
|
||||
private readonly _onProjectLanguageServiceStateChanged = this._register(new EventEmitter<Proto.ProjectLanguageServiceStateEventBody>());
|
||||
public readonly onProjectLanguageServiceStateChanged = this._onProjectLanguageServiceStateChanged.event;
|
||||
|
||||
private readonly _onDidBeginInstallTypings = new EventEmitter<Proto.BeginInstallTypesEventBody>();
|
||||
private readonly _onDidBeginInstallTypings = this._register(new EventEmitter<Proto.BeginInstallTypesEventBody>());
|
||||
public readonly onDidBeginInstallTypings = this._onDidBeginInstallTypings.event;
|
||||
|
||||
private readonly _onDidEndInstallTypings = new EventEmitter<Proto.EndInstallTypesEventBody>();
|
||||
private readonly _onDidEndInstallTypings = this._register(new EventEmitter<Proto.EndInstallTypesEventBody>());
|
||||
public readonly onDidEndInstallTypings = this._onDidEndInstallTypings.event;
|
||||
|
||||
private readonly _onTypesInstallerInitializationFailed = new EventEmitter<Proto.TypesInstallerInitializationFailedEventBody>();
|
||||
private readonly _onTypesInstallerInitializationFailed = this._register(new EventEmitter<Proto.TypesInstallerInitializationFailedEventBody>());
|
||||
public readonly onTypesInstallerInitializationFailed = this._onTypesInstallerInitializationFailed.event;
|
||||
|
||||
public get apiVersion(): API {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
||||
import API from './api';
|
||||
import { disposeAll } from './dispose';
|
||||
import { Disposable } from './dispose';
|
||||
|
||||
export class ConditionalRegistration {
|
||||
private registration: vscode.Disposable | undefined = undefined;
|
||||
@@ -36,15 +36,15 @@ export class ConditionalRegistration {
|
||||
}
|
||||
}
|
||||
|
||||
export class VersionDependentRegistration {
|
||||
export class VersionDependentRegistration extends Disposable {
|
||||
private readonly _registration: ConditionalRegistration;
|
||||
private readonly _disposables: vscode.Disposable[] = [];
|
||||
|
||||
constructor(
|
||||
private readonly client: ITypeScriptServiceClient,
|
||||
private readonly minVersion: API,
|
||||
register: () => vscode.Disposable,
|
||||
) {
|
||||
super();
|
||||
this._registration = new ConditionalRegistration(register);
|
||||
|
||||
this.update(client.apiVersion);
|
||||
@@ -55,7 +55,7 @@ export class VersionDependentRegistration {
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
disposeAll(this._disposables);
|
||||
super.dispose();
|
||||
this._registration.dispose();
|
||||
}
|
||||
|
||||
@@ -65,22 +65,22 @@ export class VersionDependentRegistration {
|
||||
}
|
||||
|
||||
|
||||
export class ConfigurationDependentRegistration {
|
||||
export class ConfigurationDependentRegistration extends Disposable {
|
||||
private readonly _registration: ConditionalRegistration;
|
||||
private readonly _disposables: vscode.Disposable[] = [];
|
||||
|
||||
constructor(
|
||||
private readonly language: string,
|
||||
private readonly configValue: string,
|
||||
register: () => vscode.Disposable,
|
||||
) {
|
||||
super();
|
||||
this._registration = new ConditionalRegistration(register);
|
||||
this.update();
|
||||
vscode.workspace.onDidChangeConfiguration(this.update, this, this._disposables);
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
disposeAll(this._disposables);
|
||||
super.dispose();
|
||||
this._registration.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export function disposeAll(disposables: vscode.Disposable[]) {
|
||||
function disposeAll(disposables: vscode.Disposable[]) {
|
||||
while (disposables.length) {
|
||||
const item = disposables.pop();
|
||||
if (item) {
|
||||
@@ -13,3 +13,26 @@ export function disposeAll(disposables: vscode.Disposable[]) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class Disposable {
|
||||
private _isDisposed = false;
|
||||
|
||||
protected _disposables: vscode.Disposable[] = [];
|
||||
|
||||
public dispose(): any {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
this._isDisposed = true;
|
||||
disposeAll(this._disposables);
|
||||
}
|
||||
|
||||
protected _register<T extends vscode.Disposable>(value: T): T {
|
||||
if (this._isDisposed) {
|
||||
value.dispose();
|
||||
} else {
|
||||
this._disposables.push(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user