提交 6b7b5c0e 编写于 作者: M Matt Bierner

Extend lifecycle/Disposable in more places instead of re-implementing it

`lifecycle/Disposable` includes some important fixes that can help catch common programming mistakes
上级 680b30a3
......@@ -5,7 +5,7 @@
import 'vs/css!./list';
import { localize } from 'vs/nls';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
import { isNumber } from 'vs/base/common/types';
import { range, firstIndex, binarySearch } from 'vs/base/common/arrays';
import { memoize } from 'vs/base/common/decorators';
......@@ -226,9 +226,8 @@ function isInputElement(e: HTMLElement): boolean {
return e.tagName === 'INPUT' || e.tagName === 'TEXTAREA';
}
class KeyboardController<T> implements IDisposable {
class KeyboardController<T> extends Disposable {
private disposables: IDisposable[];
private openController: IOpenController;
constructor(
......@@ -236,8 +235,8 @@ class KeyboardController<T> implements IDisposable {
private view: ListView<T>,
options: IListOptions<T>
) {
super();
const multipleSelectionSupport = !(options.multipleSelectionSupport === false);
this.disposables = [];
this.openController = options.openController || DefaultOpenController;
......@@ -245,15 +244,15 @@ class KeyboardController<T> implements IDisposable {
.filter(e => !isInputElement(e.target as HTMLElement))
.map(e => new StandardKeyboardEvent(e));
onKeyDown.filter(e => e.keyCode === KeyCode.Enter).on(this.onEnter, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.UpArrow).on(this.onUpArrow, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.DownArrow).on(this.onDownArrow, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.PageUp).on(this.onPageUpArrow, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.PageDown).on(this.onPageDownArrow, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.Escape).on(this.onEscape, this, this.disposables);
this._register(onKeyDown.filter(e => e.keyCode === KeyCode.Enter).on(this.onEnter, this));
this._register(onKeyDown.filter(e => e.keyCode === KeyCode.UpArrow).on(this.onUpArrow, this));
this._register(onKeyDown.filter(e => e.keyCode === KeyCode.DownArrow).on(this.onDownArrow, this));
this._register(onKeyDown.filter(e => e.keyCode === KeyCode.PageUp).on(this.onPageUpArrow, this));
this._register(onKeyDown.filter(e => e.keyCode === KeyCode.PageDown).on(this.onPageDownArrow, this));
this._register(onKeyDown.filter(e => e.keyCode === KeyCode.Escape).on(this.onEscape, this));
if (multipleSelectionSupport) {
onKeyDown.filter(e => (platform.isMacintosh ? e.metaKey : e.ctrlKey) && e.keyCode === KeyCode.KEY_A).on(this.onCtrlA, this, this.disposables);
this._register(onKeyDown.filter(e => (platform.isMacintosh ? e.metaKey : e.ctrlKey) && e.keyCode === KeyCode.KEY_A).on(this.onCtrlA, this));
}
}
......@@ -312,10 +311,6 @@ class KeyboardController<T> implements IDisposable {
this.list.setSelection([], e.browserEvent);
this.view.domNode.focus();
}
dispose() {
this.disposables = dispose(this.disposables);
}
}
enum TypeLabelControllerState {
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { localize } from 'vs/nls';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Disposable } from 'vs/base/common/lifecycle';
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
import { Event } from 'vs/base/common/event';
import { BrowserWindow, app } from 'electron';
......@@ -22,18 +22,18 @@ type Credentials = {
password: string;
};
export class ProxyAuthHandler {
export class ProxyAuthHandler extends Disposable {
_serviceBrand: any;
private retryCount = 0;
private disposables: IDisposable[] = [];
constructor(
@IWindowsMainService private readonly windowsMainService: IWindowsMainService
) {
super();
const onLogin = Event.fromNodeEventEmitter<LoginEvent>(app, 'login', (event, webContents, req, authInfo, cb) => ({ event, webContents, req, authInfo, cb }));
onLogin(this.onLogin, this, this.disposables);
this._register(onLogin(this.onLogin, this));
}
private onLogin({ event, authInfo, cb }: LoginEvent): void {
......@@ -85,8 +85,4 @@ export class ProxyAuthHandler {
win.close();
});
}
dispose(): void {
this.disposables = dispose(this.disposables);
}
}
\ No newline at end of file
......@@ -9,7 +9,7 @@ import { createMatches } from 'vs/base/common/filters';
import * as strings from 'vs/base/common/strings';
import { Event, Emitter } from 'vs/base/common/event';
import { onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, dispose, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { addClass, append, $, hide, removeClass, show, toggleClass, getDomNodePagePosition, hasClass, addDisposableListener } from 'vs/base/browser/dom';
import { IListVirtualDelegate, IListEvent, IListRenderer, IListMouseEvent } from 'vs/base/browser/ui/list/list';
import { List } from 'vs/base/browser/ui/list/listWidget';
......@@ -226,7 +226,7 @@ const enum State {
Details
}
class SuggestionDetails {
class SuggestionDetails extends Disposable {
private el: HTMLElement;
private close: HTMLElement;
......@@ -236,8 +236,7 @@ class SuggestionDetails {
private type: HTMLElement;
private docs: HTMLElement;
private ariaLabel: string | null;
private disposables: IDisposable[];
private renderDisposeable: IDisposable;
private readonly renderDisposeable = this._register(new DisposableStore());
private borderWidth: number = 1;
constructor(
......@@ -247,16 +246,16 @@ class SuggestionDetails {
private readonly markdownRenderer: MarkdownRenderer,
private readonly triggerKeybindingLabel: string
) {
this.disposables = [];
super();
this.el = append(container, $('.details'));
this.disposables.push(toDisposable(() => container.removeChild(this.el)));
this._register(toDisposable(() => container.removeChild(this.el)));
this.body = $('.body');
this.scrollbar = new DomScrollableElement(this.body, {});
append(this.el, this.scrollbar.getDomNode());
this.disposables.push(this.scrollbar);
this._register(this.scrollbar);
this.header = append(this.body, $('.header'));
this.close = append(this.header, $('span.close'));
......@@ -268,11 +267,11 @@ class SuggestionDetails {
this.configureFont();
Event.chain<IConfigurationChangedEvent>(this.editor.onDidChangeConfiguration.bind(this.editor))
this._register(Event.chain<IConfigurationChangedEvent>(this.editor.onDidChangeConfiguration.bind(this.editor))
.filter(e => e.fontInfo)
.on(this.configureFont, this, this.disposables);
.on(this.configureFont, this));
markdownRenderer.onDidRenderCodeBlock(() => this.scrollbar.scanDomNode(), this, this.disposables);
this._register(markdownRenderer.onDidRenderCodeBlock(() => this.scrollbar.scanDomNode(), this));
}
get element() {
......@@ -280,7 +279,7 @@ class SuggestionDetails {
}
render(item: CompletionItem): void {
this.renderDisposeable = dispose(this.renderDisposeable);
this.renderDisposeable.clear();
if (!item || !canExpandCompletionItem(item)) {
this.type.textContent = '';
......@@ -297,7 +296,7 @@ class SuggestionDetails {
addClass(this.docs, 'markdown-docs');
this.docs.innerHTML = '';
const renderedContents = this.markdownRenderer.render(item.completion.documentation);
this.renderDisposeable = renderedContents;
this.renderDisposeable.add(renderedContents);
this.docs.appendChild(renderedContents.element);
}
......@@ -377,11 +376,6 @@ class SuggestionDetails {
this.close.style.height = lineHeightPx;
this.close.style.width = lineHeightPx;
}
dispose(): void {
this.disposables = dispose(this.disposables);
this.renderDisposeable = dispose(this.renderDisposeable);
}
}
export interface ISelectedSuggestion {
......
......@@ -8,7 +8,7 @@ import { IURLService } from 'vs/platform/url/common/url';
import product from 'vs/platform/product/node/product';
import { app } from 'electron';
import { URI } from 'vs/base/common/uri';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Disposable } from 'vs/base/common/lifecycle';
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
import { isWindows } from 'vs/base/common/platform';
import { coalesce } from 'vs/base/common/arrays';
......@@ -21,15 +21,14 @@ function uriFromRawUrl(url: string): URI | null {
}
}
export class ElectronURLListener {
private disposables: IDisposable[] = [];
export class ElectronURLListener extends Disposable {
constructor(
initial: string | string[],
@IURLService private readonly urlService: IURLService,
@IWindowsMainService windowsService: IWindowsMainService
) {
super();
const globalBuffer = ((<any>global).getOpenUrls() || []) as string[];
const rawBuffer = [
...(typeof initial === 'string' ? [initial] : initial),
......@@ -56,7 +55,7 @@ export class ElectronURLListener {
});
const onOpenUrl = Event.filter(Event.map(onOpenElectronUrl, uriFromRawUrl), uri => !!uri);
onOpenUrl(this.urlService.open, this.urlService, this.disposables);
this._register(onOpenUrl(this.urlService.open, this.urlService));
const isWindowReady = windowsService.getWindows()
.filter(w => w.isReady)
......@@ -68,8 +67,4 @@ export class ElectronURLListener {
Event.once(windowsService.onWindowReady)(flush);
}
}
dispose(): void {
this.disposables = dispose(this.disposables);
}
}
\ No newline at end of file
......@@ -5,7 +5,7 @@
import * as nls from 'vs/nls';
import * as os from 'os';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Disposable } from 'vs/base/common/lifecycle';
import { assign } from 'vs/base/common/objects';
import { URI } from 'vs/base/common/uri';
import product from 'vs/platform/product/node/product';
......@@ -24,12 +24,10 @@ import { mnemonicButtonLabel } from 'vs/base/common/labels';
import { isMacintosh, isLinux } from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log';
export class WindowsService implements IWindowsService, IURLHandler, IDisposable {
export class WindowsService extends Disposable implements IWindowsService, IURLHandler {
_serviceBrand: any;
private disposables: IDisposable[] = [];
private _activeWindowId: number | undefined;
readonly onWindowOpen: Event<number> = Event.filter(Event.fromNodeEventEmitter(app, 'browser-window-created', (_, w: Electron.BrowserWindow) => w.id), id => !!this.windowsMainService.getWindowById(id));
......@@ -52,11 +50,12 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
@IHistoryMainService private readonly historyService: IHistoryMainService,
@ILogService private readonly logService: ILogService
) {
super();
urlService.registerHandler(this);
// remember last active window id
Event.latch(Event.any(this.onWindowOpen, this.onWindowFocus))
(id => this._activeWindowId = id, null, this.disposables);
this._register(Event.latch(Event.any(this.onWindowOpen, this.onWindowFocus))
(id => this._activeWindowId = id, null));
}
async pickFileFolderAndOpen(options: INativeOpenDialogOptions): Promise<void> {
......@@ -460,8 +459,4 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
return undefined;
}
dispose(): void {
this.disposables = dispose(this.disposables);
}
}
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vs/base/common/event';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { Disposable } from 'vs/base/common/lifecycle';
import { URI, UriComponents } from 'vs/base/common/uri';
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
......@@ -13,10 +13,9 @@ import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
@extHostNamedCustomer(MainContext.MainThreadWindow)
export class MainThreadWindow implements MainThreadWindowShape {
export class MainThreadWindow extends Disposable implements MainThreadWindowShape {
private readonly proxy: ExtHostWindowShape;
private disposables: IDisposable[] = [];
private readonly _tunnels = new Map<number, Promise<RemoteTunnel>>();
constructor(
......@@ -26,14 +25,15 @@ export class MainThreadWindow implements MainThreadWindowShape {
@ITunnelService private readonly tunnelService: ITunnelService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService
) {
super();
this.proxy = extHostContext.getProxy(ExtHostContext.ExtHostWindow);
Event.latch(windowService.onDidChangeFocus)
(this.proxy.$onDidChangeWindowFocus, this.proxy, this.disposables);
this._register(Event.latch(windowService.onDidChangeFocus)
(this.proxy.$onDidChangeWindowFocus, this.proxy));
}
dispose(): void {
this.disposables = dispose(this.disposables);
super.dispose();
for (const tunnel of this._tunnels.values()) {
tunnel.then(tunnel => tunnel.dispose());
......
......@@ -6,7 +6,7 @@
import 'vs/css!./quickInput';
import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list';
import * as dom from 'vs/base/browser/dom';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { dispose, IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { WorkbenchList } from 'vs/platform/list/browser/listService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IQuickPickItem, IQuickPickItemButtonEvent, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput';
......@@ -211,7 +211,7 @@ class ListElementDelegate implements IListVirtualDelegate<ListElement> {
}
}
export class QuickInputList {
export class QuickInputList extends Disposable {
readonly id: string;
private container: HTMLElement;
......@@ -235,14 +235,14 @@ export class QuickInputList {
private _onLeave = new Emitter<void>();
onLeave: Event<void> = this._onLeave.event;
private _fireCheckedEvents = true;
private elementDisposables: IDisposable[] = [];
private disposables: IDisposable[] = [];
private readonly elementDisposables = this._register(new DisposableStore());
constructor(
private parent: HTMLElement,
id: string,
@IInstantiationService private readonly instantiationService: IInstantiationService
) {
super();
this.id = id;
this.container = dom.append(this.parent, $('.quick-input-list'));
const delegate = new ListElementDelegate();
......@@ -254,8 +254,8 @@ export class QuickInputList {
horizontalScrolling: false
} as IListOptions<ListElement>) as WorkbenchList<ListElement>;
this.list.getHTMLElement().id = id;
this.disposables.push(this.list);
this.disposables.push(this.list.onKeyDown(e => {
this._register(this.list);
this._register(this.list.onKeyDown(e => {
const event = new StandardKeyboardEvent(e);
switch (event.keyCode) {
case KeyCode.Space:
......@@ -282,13 +282,13 @@ export class QuickInputList {
break;
}
}));
this.disposables.push(this.list.onMouseDown(e => {
this._register(this.list.onMouseDown(e => {
if (e.browserEvent.button !== 2) {
// Works around / fixes #64350.
e.browserEvent.preventDefault();
}
}));
this.disposables.push(dom.addDisposableListener(this.container, dom.EventType.CLICK, e => {
this._register(dom.addDisposableListener(this.container, dom.EventType.CLICK, e => {
if (e.x || e.y) { // Avoid 'click' triggered by 'space' on checkbox.
this._onLeave.fire();
}
......@@ -360,7 +360,7 @@ export class QuickInputList {
}
setElements(inputElements: Array<IQuickPickItem | IQuickPickSeparator>): void {
this.elementDisposables = dispose(this.elementDisposables);
this.elementDisposables.clear();
const fireButtonTriggered = (event: IQuickPickItemButtonEvent<IQuickPickItem>) => this.fireButtonTriggered(event);
this.inputElements = inputElements;
this.elements = inputElements.reduce((result, item, index) => {
......@@ -379,7 +379,10 @@ export class QuickInputList {
}
return result;
}, [] as ListElement[]);
this.elementDisposables.push(...this.elements.map(element => element.onChecked(() => this.fireCheckedEvents())));
for (const element of this.elements) {
this.elementDisposables.add(element.onChecked(() => this.fireCheckedEvents()));
}
this.elementsToIndexes = this.elements.reduce((map, element, index) => {
map.set(element.item, index);
......@@ -556,11 +559,6 @@ export class QuickInputList {
return this.container.style.display !== 'none';
}
dispose() {
this.elementDisposables = dispose(this.elementDisposables);
this.disposables = dispose(this.disposables);
}
private fireCheckedEvents() {
if (this._fireCheckedEvents) {
this._onChangedAllVisibleChecked.fire(this.getAllVisibleChecked());
......
......@@ -9,7 +9,7 @@ import { Widget } from 'vs/base/browser/ui/widget';
import { Color } from 'vs/base/common/color';
import { Emitter, Event } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IDisposable } from 'vs/base/common/lifecycle';
import { mixin } from 'vs/base/common/objects';
import { isMacintosh } from 'vs/base/common/platform';
import { URI as uri } from 'vs/base/common/uri';
......@@ -103,7 +103,6 @@ export class SuggestEnabledInput extends Widget implements IThemable {
private _onInputDidChange = new Emitter<string | undefined>();
readonly onInputDidChange: Event<string | undefined> = this._onInputDidChange.event;
private disposables: IDisposable[] = [];
private readonly inputWidget: CodeEditorWidget;
private readonly inputModel: ITextModel;
private stylingContainer: HTMLDivElement;
......@@ -134,31 +133,31 @@ export class SuggestEnabledInput extends Widget implements IThemable {
contributions: [SuggestController, SnippetController2, ContextMenuController, MenuPreventer, SelectionClipboard],
isSimpleWidget: true,
});
this.disposables.push(this.inputWidget);
this._register(this.inputWidget);
let scopeHandle = uri.parse(resourceHandle);
this.inputModel = modelService.createModel('', null, scopeHandle, true);
this.inputWidget.setModel(this.inputModel);
this.disposables.push(this.inputWidget.onDidPaste(() => this.setValue(this.getValue()))); // setter cleanses
this._register(this.inputWidget.onDidPaste(() => this.setValue(this.getValue()))); // setter cleanses
this.disposables.push((this.inputWidget.onDidFocusEditorText(() => {
this._register((this.inputWidget.onDidFocusEditorText(() => {
if (options.focusContextKey) { options.focusContextKey.set(true); }
addClass(this.stylingContainer, 'synthetic-focus');
})));
this.disposables.push((this.inputWidget.onDidBlurEditorText(() => {
this._register((this.inputWidget.onDidBlurEditorText(() => {
if (options.focusContextKey) { options.focusContextKey.set(false); }
removeClass(this.stylingContainer, 'synthetic-focus');
})));
const onKeyDownMonaco = Event.chain(this.inputWidget.onKeyDown);
onKeyDownMonaco.filter(e => e.keyCode === KeyCode.Enter).on(e => { e.preventDefault(); this._onEnter.fire(); }, this, this.disposables);
onKeyDownMonaco.filter(e => e.keyCode === KeyCode.DownArrow && (isMacintosh ? e.metaKey : e.ctrlKey)).on(() => this._onShouldFocusResults.fire(), this, this.disposables);
this._register(onKeyDownMonaco.filter(e => e.keyCode === KeyCode.Enter).on(e => { e.preventDefault(); this._onEnter.fire(); }, this));
this._register(onKeyDownMonaco.filter(e => e.keyCode === KeyCode.DownArrow && (isMacintosh ? e.metaKey : e.ctrlKey)).on(() => this._onShouldFocusResults.fire(), this));
let preexistingContent = this.getValue();
const inputWidgetModel = this.inputWidget.getModel();
if (inputWidgetModel) {
this.disposables.push(inputWidgetModel.onDidChangeContent(() => {
this._register(inputWidgetModel.onDidChangeContent(() => {
let content = this.getValue();
this.placeholderText.style.visibility = content ? 'hidden' : 'visible';
if (preexistingContent.trim() === content.trim()) { return; }
......@@ -175,7 +174,7 @@ export class SuggestEnabledInput extends Widget implements IThemable {
this.setValue(options.value || '');
this.disposables.push(modes.CompletionProviderRegistry.register({ scheme: scopeHandle.scheme, pattern: '**/' + scopeHandle.path, hasAccessToAllModels: true }, {
this._register(modes.CompletionProviderRegistry.register({ scheme: scopeHandle.scheme, pattern: '**/' + scopeHandle.path, hasAccessToAllModels: true }, {
triggerCharacters: validatedSuggestProvider.triggerCharacters,
provideCompletionItems: (model: ITextModel, position: Position, _context: modes.CompletionContext) => {
let query = model.getValue();
......@@ -249,11 +248,6 @@ export class SuggestEnabledInput extends Widget implements IThemable {
private selectAll(): void {
this.inputWidget.setSelection(new Range(1, 1, 1, this.getValue().length + 1));
}
dispose(): void {
this.disposables = dispose(this.disposables);
super.dispose();
}
}
// Override styles in selections.ts
......
......@@ -8,7 +8,7 @@ import { localize } from 'vs/nls';
import { timeout, Delayer } from 'vs/base/common/async';
import { isPromiseCanceledError } from 'vs/base/common/errors';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
import { Event as EventOf, Emitter } from 'vs/base/common/event';
import { IAction } from 'vs/base/common/actions';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
......@@ -338,7 +338,6 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
private extensionsBox: HTMLElement;
private primaryActions: IAction[];
private secondaryActions: IAction[] | null;
private disposables: IDisposable[] = [];
private searchViewletState: object;
constructor(
......@@ -373,14 +372,14 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
this.recommendedExtensionsContextKey = RecommendedExtensionsContext.bindTo(contextKeyService);
this.defaultRecommendedExtensionsContextKey = DefaultRecommendedExtensionsContext.bindTo(contextKeyService);
this.defaultRecommendedExtensionsContextKey.set(!this.configurationService.getValue<boolean>(ShowRecommendationsOnlyOnDemandKey));
this.disposables.push(this.viewletService.onDidViewletOpen(this.onViewletOpen, this, this.disposables));
this._register(this.viewletService.onDidViewletOpen(this.onViewletOpen, this));
this.searchViewletState = this.getMemento(StorageScope.WORKSPACE);
this.extensionManagementService.getInstalled(ExtensionType.User).then(result => {
this.hasInstalledExtensionsContextKey.set(result.length > 0);
});
this.configurationService.onDidChangeConfiguration(e => {
this._register(this.configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(AutoUpdateConfigurationKey)) {
this.secondaryActions = null;
this.updateTitleArea();
......@@ -388,7 +387,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
if (e.affectedKeys.indexOf(ShowRecommendationsOnlyOnDemandKey) > -1) {
this.defaultRecommendedExtensionsContextKey.set(!this.configurationService.getValue<boolean>(ShowRecommendationsOnlyOnDemandKey));
}
}, this, this.disposables);
}, this));
}
create(parent: HTMLElement): void {
......@@ -415,18 +414,18 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
this.triggerSearch();
}
this.disposables.push(attachSuggestEnabledInputBoxStyler(this.searchBox, this.themeService));
this._register(attachSuggestEnabledInputBoxStyler(this.searchBox, this.themeService));
this.disposables.push(this.searchBox);
this._register(this.searchBox);
const _searchChange = new Emitter<string>();
this.onSearchChange = _searchChange.event;
this.searchBox.onInputDidChange(() => {
this._register(this.searchBox.onInputDidChange(() => {
this.triggerSearch();
_searchChange.fire(this.searchBox.getValue());
}, this, this.disposables);
}, this));
this.searchBox.onShouldFocusResults(() => this.focusListView(), this, this.disposables);
this._register(this.searchBox.onShouldFocusResults(() => this.focusListView(), this));
this._register(this.onDidChangeVisibility(visible => {
if (visible) {
......@@ -613,24 +612,19 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
this.notificationService.error(err);
}
dispose(): void {
this.disposables = dispose(this.disposables);
super.dispose();
}
}
export class StatusUpdater implements IWorkbenchContribution {
export class StatusUpdater extends Disposable implements IWorkbenchContribution {
private disposables: IDisposable[];
private badgeHandle: IDisposable;
private badgeHandle?: IDisposable;
constructor(
@IActivityService private readonly activityService: IActivityService,
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService
) {
extensionsWorkbenchService.onChange(this.onServiceChange, this, this.disposables);
super();
this._register(extensionsWorkbenchService.onChange(this.onServiceChange, this));
}
private onServiceChange(): void {
......@@ -650,15 +644,13 @@ export class StatusUpdater implements IWorkbenchContribution {
}
dispose(): void {
this.disposables = dispose(this.disposables);
super.dispose();
dispose(this.badgeHandle);
}
}
export class MaliciousExtensionChecker implements IWorkbenchContribution {
private disposables: IDisposable[];
constructor(
@IExtensionManagementService private readonly extensionsManagementService: IExtensionManagementService,
@IWindowService private readonly windowService: IWindowService,
......@@ -703,8 +695,4 @@ export class MaliciousExtensionChecker implements IWorkbenchContribution {
}).then(() => undefined);
}, err => this.logService.error(err));
}
dispose(): void {
this.disposables = dispose(this.disposables);
}
}
......@@ -5,7 +5,7 @@
import { Event, Emitter } from 'vs/base/common/event';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Disposable } from 'vs/base/common/lifecycle';
import { IExplorerService, IEditableData, IFilesConfiguration, SortOrder, SortOrderConfiguration } from 'vs/workbench/contrib/files/common/files';
import { ExplorerItem, ExplorerModel } from 'vs/workbench/contrib/files/common/explorerModel';
import { URI } from 'vs/base/common/uri';
......@@ -26,7 +26,7 @@ function getFileEventsExcludes(configurationService: IConfigurationService, root
return (configuration && configuration.files && configuration.files.exclude) || Object.create(null);
}
export class ExplorerService implements IExplorerService {
export class ExplorerService extends Disposable implements IExplorerService {
_serviceBrand: any;
private static readonly EXPLORER_FILE_CHANGES_REACT_DELAY = 500; // delay in ms to react to file changes to give our internal events a chance to react first
......@@ -36,7 +36,6 @@ export class ExplorerService implements IExplorerService {
private _onDidChangeEditable = new Emitter<ExplorerItem>();
private _onDidSelectResource = new Emitter<{ resource?: URI, reveal?: boolean }>();
private _onDidCopyItems = new Emitter<{ items: ExplorerItem[], cut: boolean, previouslyCutItems: ExplorerItem[] | undefined }>();
private disposables: IDisposable[] = [];
private editable: { stat: ExplorerItem, data: IEditableData } | undefined;
private _sortOrder: SortOrder;
private cutItems: ExplorerItem[] | undefined;
......@@ -50,6 +49,7 @@ export class ExplorerService implements IExplorerService {
@IClipboardService private clipboardService: IClipboardService,
@IEditorService private editorService: IEditorService
) {
super();
this._sortOrder = this.configurationService.getValue('explorer.sortOrder');
}
......@@ -88,18 +88,18 @@ export class ExplorerService implements IExplorerService {
(root?: URI) => getFileEventsExcludes(this.configurationService, root),
(event: IConfigurationChangeEvent) => event.affectsConfiguration(FILES_EXCLUDE_CONFIG)
);
this.disposables.push(fileEventsFilter);
this._register(fileEventsFilter);
return fileEventsFilter;
}
@memoize get model(): ExplorerModel {
const model = new ExplorerModel(this.contextService);
this.disposables.push(model);
this.disposables.push(this.fileService.onAfterOperation(e => this.onFileOperation(e)));
this.disposables.push(this.fileService.onFileChanges(e => this.onFileChanges(e)));
this.disposables.push(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(this.configurationService.getValue<IFilesConfiguration>())));
this.disposables.push(this.fileService.onDidChangeFileSystemProviderRegistrations(e => {
this._register(model);
this._register(this.fileService.onAfterOperation(e => this.onFileOperation(e)));
this._register(this.fileService.onFileChanges(e => this.onFileChanges(e)));
this._register(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(this.configurationService.getValue<IFilesConfiguration>())));
this._register(this.fileService.onDidChangeFileSystemProviderRegistrations(e => {
if (e.added && this.fileSystemProviderSchemes.has(e.scheme)) {
// A file system provider got re-registered, we should update all file stats since they might change (got read-only)
this._onDidChangeItem.fire({ recursive: true });
......@@ -107,7 +107,7 @@ export class ExplorerService implements IExplorerService {
this.fileSystemProviderSchemes.add(e.scheme);
}
}));
this.disposables.push(model.onDidChangeRoots(() => this._onDidChangeRoots.fire()));
this._register(model.onDidChangeRoots(() => this._onDidChangeRoots.fire()));
return model;
}
......@@ -375,8 +375,4 @@ export class ExplorerService implements IExplorerService {
}
}
}
dispose(): void {
dispose(this.disposables);
}
}
......@@ -40,7 +40,6 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { domEvent } from 'vs/base/browser/event';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ResourceLabels } from 'vs/workbench/browser/labels';
import { IMarker } from 'vs/platform/markers/common/markers';
import { withUndefinedAsNull } from 'vs/base/common/types';
......@@ -90,7 +89,6 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
private currentResourceGotAddedToMarkersData: boolean = false;
readonly markersViewModel: MarkersViewModel;
private disposables: IDisposable[] = [];
constructor(
@IInstantiationService private readonly instantiationService: IInstantiationService,
......@@ -110,7 +108,7 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
this.panelFoucusContextKey = Constants.MarkerPanelFocusContextKey.bindTo(contextKeyService);
this.panelState = this.getMemento(StorageScope.WORKSPACE);
this.markersViewModel = instantiationService.createInstance(MarkersViewModel, this.panelState['multiline']);
this.markersViewModel.onDidChange(this.onDidChangeViewState, this, this.disposables);
this._register(this.markersViewModel.onDidChange(this.onDidChangeViewState, this));
this.setCurrentActiveEditor();
}
......@@ -734,6 +732,5 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
super.dispose();
this.tree.dispose();
this.markersViewModel.dispose();
this.disposables = dispose(this.disposables);
}
}
......@@ -18,7 +18,7 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { attachInputBoxStyler, attachStylerCallback, attachCheckboxStyler } from 'vs/platform/theme/common/styler';
import { IMarkersWorkbenchService } from 'vs/workbench/contrib/markers/browser/markers';
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import { toDisposable } from 'vs/base/common/lifecycle';
import { BaseActionViewItem, ActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { badgeBackground, badgeForeground, contrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { localize } from 'vs/nls';
......@@ -296,8 +296,6 @@ export class QuickFixAction extends Action {
private static readonly CLASS: string = 'markers-panel-action-quickfix';
private static readonly AUTO_FIX_CLASS: string = QuickFixAction.CLASS + ' autofixable';
private disposables: IDisposable[] = [];
private readonly _onShowQuickFixes: Emitter<void> = new Emitter<void>();
readonly onShowQuickFixes: Event<void> = this._onShowQuickFixes.event;
......@@ -324,11 +322,6 @@ export class QuickFixAction extends Action {
this._onShowQuickFixes.fire();
return Promise.resolve();
}
dispose(): void {
dispose(this.disposables);
super.dispose();
}
}
export class QuickFixActionViewItem extends ActionViewItem {
......
......@@ -140,10 +140,9 @@ interface RelatedInformationFilterData {
export type FilterData = ResourceMarkersFilterData | MarkerFilterData | RelatedInformationFilterData;
export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, ResourceMarkersFilterData, IResourceMarkersTemplateData> {
export class ResourceMarkersRenderer extends Disposable implements ITreeRenderer<ResourceMarkers, ResourceMarkersFilterData, IResourceMarkersTemplateData> {
private renderedNodes = new Map<ITreeNode<ResourceMarkers, ResourceMarkersFilterData>, IResourceMarkersTemplateData>();
private disposables: IDisposable[] = [];
constructor(
private labels: ResourceLabels,
......@@ -151,7 +150,8 @@ export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, R
@IThemeService private readonly themeService: IThemeService,
@ILabelService private readonly labelService: ILabelService
) {
onDidChangeRenderNodeCount(this.onDidChangeRenderNodeCount, this, this.disposables);
super();
this._register(onDidChangeRenderNodeCount(this.onDidChangeRenderNodeCount, this));
}
templateId = TemplateId.ResourceMarkers;
......@@ -205,10 +205,6 @@ export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, R
private updateCount(node: ITreeNode<ResourceMarkers, ResourceMarkersFilterData>, templateData: IResourceMarkersTemplateData): void {
templateData.count.setCount(node.children.reduce((r, n) => r + (n.visible ? 1 : 0), 0));
}
dispose(): void {
this.disposables = dispose(this.disposables);
}
}
export class FileResourceMarkersRenderer extends ResourceMarkersRenderer {
......
......@@ -12,7 +12,7 @@ import { Action, IAction } from 'vs/base/common/actions';
import { Emitter, Event } from 'vs/base/common/event';
import { MarkdownString } from 'vs/base/common/htmlContent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { Disposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { IMarginData } from 'vs/editor/browser/controller/mouseTarget';
import { ICodeEditor, IEditorMouseEvent, IViewZone, MouseTargetType } from 'vs/editor/browser/editorBrowser';
......@@ -302,8 +302,6 @@ export class FolderSettingsActionViewItem extends BaseActionViewItem {
private detailsElement: HTMLElement;
private dropDownElement: HTMLElement;
private disposables: IDisposable[] = [];
constructor(
action: IAction,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
......@@ -312,7 +310,7 @@ export class FolderSettingsActionViewItem extends BaseActionViewItem {
super(null, action);
const workspace = this.contextService.getWorkspace();
this._folder = workspace.folders.length === 1 ? workspace.folders[0] : null;
this.disposables.push(this.contextService.onDidChangeWorkspaceFolders(() => this.onWorkspaceFoldersChanged()));
this._register(this.contextService.onDidChangeWorkspaceFolders(() => this.onWorkspaceFoldersChanged()));
}
get folder(): IWorkspaceFolder | null {
......@@ -347,8 +345,8 @@ export class FolderSettingsActionViewItem extends BaseActionViewItem {
'tabindex': '0'
}, this.labelElement, this.detailsElement, this.dropDownElement);
this._register(DOM.addDisposableListener(this.anchorElement, DOM.EventType.MOUSE_DOWN, e => DOM.EventHelper.stop(e)));
this.disposables.push(DOM.addDisposableListener(this.anchorElement, DOM.EventType.CLICK, e => this.onClick(e)));
this.disposables.push(DOM.addDisposableListener(this.anchorElement, DOM.EventType.KEY_UP, e => this.onKeyUp(e)));
this._register(DOM.addDisposableListener(this.anchorElement, DOM.EventType.CLICK, e => this.onClick(e)));
this._register(DOM.addDisposableListener(this.anchorElement, DOM.EventType.KEY_UP, e => this.onKeyUp(e)));
DOM.append(this.container, this.anchorElement);
......@@ -460,11 +458,6 @@ export class FolderSettingsActionViewItem extends BaseActionViewItem {
return label;
}
dispose(): void {
dispose(this.disposables);
super.dispose();
}
}
export type SettingsTarget = ConfigurationTarget.USER_LOCAL | ConfigurationTarget.USER_REMOTE | ConfigurationTarget.WORKSPACE | URI;
......
......@@ -8,7 +8,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation';
import * as errors from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { getBaseLabel } from 'vs/base/common/labels';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { Disposable, IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { ResourceMap, TernarySearchTree, values } from 'vs/base/common/map';
import * as objects from 'vs/base/common/objects';
import { lcut } from 'vs/base/common/strings';
......@@ -1044,12 +1044,11 @@ export class RangeHighlightDecorations implements IDisposable {
private _decorationId: string | null = null;
private _model: ITextModel | null = null;
private _modelDisposables: IDisposable[] = [];
private readonly _modelDisposables = new DisposableStore();
constructor(
@IModelService private readonly _modelService: IModelService
) {
}
) { }
removeHighlightRange() {
if (this._model && this._decorationId) {
......@@ -1081,12 +1080,12 @@ export class RangeHighlightDecorations implements IDisposable {
if (this._model !== model) {
this.disposeModelListeners();
this._model = model;
this._modelDisposables.push(this._model.onDidChangeDecorations((e) => {
this._modelDisposables.add(this._model.onDidChangeDecorations((e) => {
this.disposeModelListeners();
this.removeHighlightRange();
this._model = null;
}));
this._modelDisposables.push(this._model.onWillDispose(() => {
this._modelDisposables.add(this._model.onWillDispose(() => {
this.disposeModelListeners();
this.removeHighlightRange();
this._model = null;
......@@ -1095,8 +1094,7 @@ export class RangeHighlightDecorations implements IDisposable {
}
private disposeModelListeners() {
this._modelDisposables.forEach(disposable => disposable.dispose());
this._modelDisposables = [];
this._modelDisposables.clear();
}
dispose() {
......@@ -1105,6 +1103,7 @@ export class RangeHighlightDecorations implements IDisposable {
this.disposeModelListeners();
this._model = null;
}
this._modelDisposables.dispose();
}
private static readonly _RANGE_HIGHLIGHT_DECORATION = ModelDecorationOptions.register({
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册