Skip to content

Commit f80816a

Browse files
authored
fix leaking disposables (#237586)
* chore - mark disposables from registry#register functions as disposables so that they don't appear as leaking * fix various leaking disposables
1 parent 8e81ea6 commit f80816a

File tree

12 files changed

+57
-40
lines changed

12 files changed

+57
-40
lines changed

src/vs/editor/common/languages.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2107,7 +2107,7 @@ export interface CodeLens {
21072107

21082108
export interface CodeLensList {
21092109
lenses: CodeLens[];
2110-
dispose(): void;
2110+
dispose?(): void;
21112111
}
21122112

21132113
export interface CodeLensProvider {

src/vs/editor/common/languages/languageConfigurationRegistry.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { Emitter, Event } from '../../../base/common/event.js';
7-
import { Disposable, IDisposable, toDisposable } from '../../../base/common/lifecycle.js';
7+
import { Disposable, IDisposable, markAsSingleton, toDisposable } from '../../../base/common/lifecycle.js';
88
import * as strings from '../../../base/common/strings.js';
99
import { ITextModel } from '../model.js';
1010
import { DEFAULT_WORD_REGEXP, ensureValidWordDefinition } from '../core/wordHelper.js';
@@ -202,15 +202,15 @@ class ComposedLanguageConfiguration {
202202
);
203203
this._entries.push(entry);
204204
this._resolved = null;
205-
return toDisposable(() => {
205+
return markAsSingleton(toDisposable(() => {
206206
for (let i = 0; i < this._entries.length; i++) {
207207
if (this._entries[i] === entry) {
208208
this._entries.splice(i, 1);
209209
this._resolved = null;
210210
break;
211211
}
212212
}
213-
});
213+
}));
214214
}
215215

216216
public getResolvedConfiguration(): ResolvedLanguageConfiguration | null {
@@ -332,10 +332,10 @@ export class LanguageConfigurationRegistry extends Disposable {
332332
const disposable = entries.register(configuration, priority);
333333
this._onDidChange.fire(new LanguageConfigurationChangeEvent(languageId));
334334

335-
return toDisposable(() => {
335+
return markAsSingleton(toDisposable(() => {
336336
disposable.dispose();
337337
this._onDidChange.fire(new LanguageConfigurationChangeEvent(languageId));
338-
});
338+
}));
339339
}
340340

341341
public getLanguageConfiguration(languageId: string): ResolvedLanguageConfiguration | null {

src/vs/editor/contrib/codelens/browser/codeLensCache.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export class CodeLensCache implements ICodeLensCache {
7777
};
7878
});
7979
const copyModel = new CodeLensModel();
80-
copyModel.add({ lenses: copyItems, dispose: () => { } }, this._fakeProvider);
80+
copyModel.add({ lenses: copyItems }, this._fakeProvider);
8181

8282
const item = new CacheItem(model.getLineCount(), copyModel);
8383
this._cache.set(model.uri.toString(), item);

src/vs/editor/contrib/codelens/browser/codelens.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { CancellationToken } from '../../../../base/common/cancellation.js';
77
import { illegalArgument, onUnexpectedExternalError } from '../../../../base/common/errors.js';
8-
import { DisposableStore } from '../../../../base/common/lifecycle.js';
8+
import { DisposableStore, isDisposable } from '../../../../base/common/lifecycle.js';
99
import { assertType } from '../../../../base/common/types.js';
1010
import { URI } from '../../../../base/common/uri.js';
1111
import { ITextModel } from '../../../common/model.js';
@@ -24,18 +24,21 @@ export class CodeLensModel {
2424

2525
lenses: CodeLensItem[] = [];
2626

27-
private readonly _disposables = new DisposableStore();
27+
private _store: DisposableStore | undefined;
2828

2929
dispose(): void {
30-
this._disposables.dispose();
30+
this._store?.dispose();
3131
}
3232

3333
get isDisposed(): boolean {
34-
return this._disposables.isDisposed;
34+
return this._store?.isDisposed ?? false;
3535
}
3636

3737
add(list: CodeLensList, provider: CodeLensProvider): void {
38-
this._disposables.add(list);
38+
if (isDisposable(list)) {
39+
this._store ??= new DisposableStore();
40+
this._store.add(list);
41+
}
3942
for (const symbol of list.lenses) {
4043
this.lenses.push({ symbol, provider });
4144
}

src/vs/editor/contrib/hover/browser/contentHoverRendered.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ class RenderedContentHoverParts extends Disposable {
273273
...hoverContext
274274
};
275275
const disposables = new DisposableStore();
276+
disposables.add(statusBar);
276277
for (const participant of participants) {
277278
const renderedHoverParts = this._renderHoverPartsForParticipant(hoverParts, participant, hoverRenderingContext);
278279
disposables.add(renderedHoverParts);
@@ -294,7 +295,7 @@ class RenderedContentHoverParts extends Disposable {
294295
actions: renderedStatusBar.actions,
295296
});
296297
}
297-
return toDisposable(() => { disposables.dispose(); });
298+
return disposables;
298299
}
299300

300301
private _renderHoverPartsForParticipant(hoverParts: IHoverPart[], participant: IEditorHoverParticipant<IHoverPart>, hoverRenderingContext: IEditorHoverRenderContext): IRenderedHoverParts<IHoverPart> {

src/vs/editor/contrib/links/browser/getLinks.ts

+19-13
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ export class Link implements ILink {
7070

7171
export class LinksList {
7272

73+
static readonly Empty = new LinksList([]);
74+
7375
readonly links: Link[];
7476

7577
private readonly _disposables = new DisposableStore();
@@ -137,27 +139,31 @@ export class LinksList {
137139

138140
}
139141

140-
export function getLinks(providers: LanguageFeatureRegistry<LinkProvider>, model: ITextModel, token: CancellationToken): Promise<LinksList> {
141-
142+
export async function getLinks(providers: LanguageFeatureRegistry<LinkProvider>, model: ITextModel, token: CancellationToken): Promise<LinksList> {
142143
const lists: [ILinksList, LinkProvider][] = [];
143144

144145
// ask all providers for links in parallel
145-
const promises = providers.ordered(model).reverse().map((provider, i) => {
146-
return Promise.resolve(provider.provideLinks(model, token)).then(result => {
146+
const promises = providers.ordered(model).reverse().map(async (provider, i) => {
147+
try {
148+
const result = await provider.provideLinks(model, token);
147149
if (result) {
148150
lists[i] = [result, provider];
149151
}
150-
}, onUnexpectedExternalError);
151-
});
152-
153-
return Promise.all(promises).then(() => {
154-
const result = new LinksList(coalesce(lists));
155-
if (!token.isCancellationRequested) {
156-
return result;
152+
} catch (err) {
153+
onUnexpectedExternalError(err);
157154
}
158-
result.dispose();
159-
return new LinksList([]);
160155
});
156+
157+
await Promise.all(promises);
158+
159+
let res = new LinksList(coalesce(lists));
160+
161+
if (token.isCancellationRequested) {
162+
res.dispose();
163+
res = LinksList.Empty;
164+
}
165+
166+
return res;
161167
}
162168

163169

src/vs/monaco.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8060,7 +8060,7 @@ declare namespace monaco.languages {
80608060

80618061
export interface CodeLensList {
80628062
lenses: CodeLens[];
8063-
dispose(): void;
8063+
dispose?(): void;
80648064
}
80658065

80668066
export interface CodeLensProvider {

src/vs/platform/actions/common/actions.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { IAction, SubmenuAction } from '../../../base/common/actions.js';
77
import { Event, MicrotaskEmitter } from '../../../base/common/event.js';
8-
import { DisposableStore, dispose, IDisposable, toDisposable } from '../../../base/common/lifecycle.js';
8+
import { DisposableStore, dispose, IDisposable, markAsSingleton, toDisposable } from '../../../base/common/lifecycle.js';
99
import { LinkedList } from '../../../base/common/linkedList.js';
1010
import { ThemeIcon } from '../../../base/common/themables.js';
1111
import { ICommandAction, ICommandActionTitle, Icon, ILocalizedString } from '../../action/common/action.js';
@@ -397,11 +397,11 @@ export const MenuRegistry: IMenuRegistry = new class implements IMenuRegistry {
397397
this._commands.set(command.id, command);
398398
this._onDidChangeMenu.fire(MenuRegistryChangeEvent.for(MenuId.CommandPalette));
399399

400-
return toDisposable(() => {
400+
return markAsSingleton(toDisposable(() => {
401401
if (this._commands.delete(command.id)) {
402402
this._onDidChangeMenu.fire(MenuRegistryChangeEvent.for(MenuId.CommandPalette));
403403
}
404-
});
404+
}));
405405
}
406406

407407
getCommand(id: string): ICommandAction | undefined {
@@ -422,10 +422,10 @@ export const MenuRegistry: IMenuRegistry = new class implements IMenuRegistry {
422422
}
423423
const rm = list.push(item);
424424
this._onDidChangeMenu.fire(MenuRegistryChangeEvent.for(id));
425-
return toDisposable(() => {
425+
return markAsSingleton(toDisposable(() => {
426426
rm();
427427
this._onDidChangeMenu.fire(MenuRegistryChangeEvent.for(id));
428-
});
428+
}));
429429
}
430430

431431
appendMenuItems(items: Iterable<{ id: MenuId; item: IMenuItem | ISubmenuItem }>): IDisposable {

src/vs/platform/commands/common/commands.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { Emitter, Event } from '../../../base/common/event.js';
77
import { Iterable } from '../../../base/common/iterator.js';
88
import { IJSONSchema } from '../../../base/common/jsonSchema.js';
9-
import { IDisposable, toDisposable } from '../../../base/common/lifecycle.js';
9+
import { IDisposable, markAsSingleton, toDisposable } from '../../../base/common/lifecycle.js';
1010
import { LinkedList } from '../../../base/common/linkedList.js';
1111
import { TypeConstraint, validateConstraints } from '../../../base/common/types.js';
1212
import { ILocalizedString } from '../../action/common/action.js';
@@ -121,7 +121,7 @@ export const CommandsRegistry: ICommandRegistry = new class implements ICommandR
121121
// tell the world about this command
122122
this._onDidRegisterCommand.fire(id);
123123

124-
return ret;
124+
return markAsSingleton(ret);
125125
}
126126

127127
registerCommandAlias(oldId: string, newId: string): IDisposable {

src/vs/workbench/contrib/extensions/browser/extensionsList.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
114114
focusOnlyEnabledItems: true
115115
});
116116
actionbar.setFocusable(false);
117-
actionbar.onDidRun(({ error }) => error && this.notificationService.error(error));
117+
const actionBarListener = actionbar.onDidRun(({ error }) => error && this.notificationService.error(error));
118118

119119
const extensionStatusIconAction = this.instantiationService.createInstance(ExtensionStatusAction);
120120
const actions = [
@@ -150,7 +150,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
150150
const extensionContainers: ExtensionContainers = this.instantiationService.createInstance(ExtensionContainers, [...actions, ...widgets]);
151151

152152
actionbar.push(actions, { icon: true, label: true });
153-
const disposable = combinedDisposable(...actions, ...widgets, actionbar, extensionContainers);
153+
const disposable = combinedDisposable(...actions, ...widgets, actionbar, actionBarListener, extensionContainers);
154154

155155
return {
156156
root, element, icon, name, installCount, ratings, description, publisherDisplayName, disposables: [disposable], actionbar,

src/vs/workbench/contrib/scm/browser/scmViewPane.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { IContextKeyService, IContextKey, ContextKeyExpr, RawContextKey } from '
2121
import { ICommandService } from '../../../../platform/commands/common/commands.js';
2222
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';
2323
import { MenuItemAction, IMenuService, registerAction2, MenuId, IAction2Options, MenuRegistry, Action2, IMenu } from '../../../../platform/actions/common/actions.js';
24-
import { IAction, ActionRunner, Action, Separator, IActionRunner } from '../../../../base/common/actions.js';
24+
import { IAction, ActionRunner, Action, Separator, IActionRunner, toAction } from '../../../../base/common/actions.js';
2525
import { ActionBar, IActionViewItemProvider } from '../../../../base/browser/ui/actionbar/actionbar.js';
2626
import { IThemeService, IFileIconTheme } from '../../../../platform/theme/common/themeService.js';
2727
import { isSCMResource, isSCMResourceGroup, isSCMRepository, isSCMInput, collectContextMenuActions, getActionViewItemProvider, isSCMActionButton, isSCMViewService, isSCMResourceNode, connectPrimaryMenu } from './util.js';
@@ -2988,7 +2988,14 @@ export class SCMActionButton implements IDisposable {
29882988
for (let index = 0; index < button.secondaryCommands.length; index++) {
29892989
const commands = button.secondaryCommands[index];
29902990
for (const command of commands) {
2991-
actions.push(new Action(command.id, command.title, undefined, true, async () => await this.executeCommand(command.id, ...(command.arguments || []))));
2991+
actions.push(toAction({
2992+
id: command.id,
2993+
label: command.title,
2994+
enabled: true,
2995+
run: async () => {
2996+
await this.executeCommand(command.id, ...(command.arguments || []));
2997+
}
2998+
}));
29922999
}
29933000
if (commands.length) {
29943001
actions.push(new Separator());

src/vs/workbench/services/authentication/browser/authenticationUsageService.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ export class AuthenticationUsageService extends Disposable implements IAuthentic
8181
}
8282
}
8383

84-
this._authenticationService.onDidRegisterAuthenticationProvider(
84+
this._register(this._authenticationService.onDidRegisterAuthenticationProvider(
8585
provider => this._queue.queue(
8686
() => this._addExtensionsToCache(provider.id)
8787
)
88-
);
88+
));
8989
}
9090

9191
async initializeExtensionUsageCache(): Promise<void> {

0 commit comments

Comments
 (0)