mirror of https://github.com/microsoft/vscode.git
Fix leaked Emitters (#246125)
* Fix leaked Emitter * dispose RangesLimitReporter * fix tests
This commit is contained in:
parent
febbcf78c8
commit
48cb4f823e
|
@ -7,7 +7,7 @@ import * as nls from '../../../nls.js';
|
|||
import { Emitter, Event } from '../../../base/common/event.js';
|
||||
import { ILanguageExtensionPoint } from './language.js';
|
||||
import { Registry } from '../../../platform/registry/common/platform.js';
|
||||
import { IDisposable } from '../../../base/common/lifecycle.js';
|
||||
import { Disposable, IDisposable } from '../../../base/common/lifecycle.js';
|
||||
import { Mimes } from '../../../base/common/mime.js';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from '../../../platform/configuration/common/configurationRegistry.js';
|
||||
|
||||
|
@ -16,14 +16,15 @@ export const Extensions = {
|
|||
ModesRegistry: 'editor.modesRegistry'
|
||||
};
|
||||
|
||||
export class EditorModesRegistry {
|
||||
export class EditorModesRegistry extends Disposable {
|
||||
|
||||
private readonly _languages: ILanguageExtensionPoint[];
|
||||
|
||||
private readonly _onDidChangeLanguages = new Emitter<void>();
|
||||
private readonly _onDidChangeLanguages = this._register(new Emitter<void>());
|
||||
public readonly onDidChangeLanguages: Event<void> = this._onDidChangeLanguages.event;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._languages = [];
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ export class ColorDetector extends Disposable implements IEditorContribution {
|
|||
|
||||
private readonly _ruleFactory: DynamicCssRules;
|
||||
|
||||
private readonly _decoratorLimitReporter = new DecoratorLimitReporter();
|
||||
private readonly _decoratorLimitReporter = this._register(new DecoratorLimitReporter());
|
||||
|
||||
constructor(
|
||||
private readonly _editor: ICodeEditor,
|
||||
|
@ -269,8 +269,8 @@ export class ColorDetector extends Disposable implements IEditorContribution {
|
|||
}
|
||||
}
|
||||
|
||||
export class DecoratorLimitReporter {
|
||||
private _onDidChange = new Emitter<void>();
|
||||
export class DecoratorLimitReporter extends Disposable {
|
||||
private _onDidChange = this._register(new Emitter<void>());
|
||||
public readonly onDidChange: Event<void> = this._onDidChange.event;
|
||||
|
||||
private _computed: number = 0;
|
||||
|
|
|
@ -124,7 +124,7 @@ export class FoldingController extends Disposable implements IEditorContribution
|
|||
super();
|
||||
this.editor = editor;
|
||||
|
||||
this._foldingLimitReporter = new RangesLimitReporter(editor);
|
||||
this._foldingLimitReporter = this._register(new RangesLimitReporter(editor));
|
||||
|
||||
const options = this.editor.getOptions();
|
||||
this._isEnabled = options.get(EditorOption.folding);
|
||||
|
@ -513,15 +513,16 @@ export class FoldingController extends Disposable implements IEditorContribution
|
|||
}
|
||||
}
|
||||
|
||||
export class RangesLimitReporter implements FoldingLimitReporter {
|
||||
export class RangesLimitReporter extends Disposable implements FoldingLimitReporter {
|
||||
constructor(private readonly editor: ICodeEditor) {
|
||||
super();
|
||||
}
|
||||
|
||||
public get limit() {
|
||||
return this.editor.getOptions().get(EditorOption.foldingMaximumRegions);
|
||||
}
|
||||
|
||||
private _onDidChange = new Emitter<void>();
|
||||
private _onDidChange = this._register(new Emitter<void>());
|
||||
public readonly onDidChange: Event<void> = this._onDidChange.event;
|
||||
|
||||
private _computed: number = 0;
|
||||
|
|
|
@ -316,7 +316,7 @@ abstract class StickyModelFromCandidateFoldingProvider extends StickyModelCandid
|
|||
|
||||
constructor(editor: IActiveCodeEditor) {
|
||||
super(editor);
|
||||
this._foldingLimitReporter = new RangesLimitReporter(editor);
|
||||
this._foldingLimitReporter = this._register(new RangesLimitReporter(editor));
|
||||
}
|
||||
|
||||
protected createStickyModel(token: CancellationToken, model: FoldingRegions): StickyModel {
|
||||
|
|
|
@ -13,6 +13,7 @@ import { getLanguageTagSettingPlainKey } from './configuration.js';
|
|||
import { Extensions as JSONExtensions, IJSONContributionRegistry } from '../../jsonschemas/common/jsonContributionRegistry.js';
|
||||
import { Registry } from '../../registry/common/platform.js';
|
||||
import { IPolicy, PolicyName } from '../../../base/common/policy.js';
|
||||
import { Disposable } from '../../../base/common/lifecycle.js';
|
||||
|
||||
export enum EditPresentationTypes {
|
||||
Multiline = 'multilineText',
|
||||
|
@ -272,7 +273,7 @@ export const configurationDefaultsSchemaId = 'vscode://schemas/settings/configur
|
|||
|
||||
const contributionRegistry = Registry.as<IJSONContributionRegistry>(JSONExtensions.JSONContribution);
|
||||
|
||||
class ConfigurationRegistry implements IConfigurationRegistry {
|
||||
class ConfigurationRegistry extends Disposable implements IConfigurationRegistry {
|
||||
|
||||
private readonly registeredConfigurationDefaults: IConfigurationDefaults[] = [];
|
||||
private readonly configurationDefaultsOverrides: Map<string, { configurationDefaultOverrides: IConfigurationDefaultOverride[]; configurationDefaultOverrideValue?: IConfigurationDefaultOverrideValue }>;
|
||||
|
@ -284,13 +285,14 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
private readonly resourceLanguageSettingsSchema: IJSONSchema;
|
||||
private readonly overrideIdentifiers = new Set<string>();
|
||||
|
||||
private readonly _onDidSchemaChange = new Emitter<void>();
|
||||
private readonly _onDidSchemaChange = this._register(new Emitter<void>());
|
||||
readonly onDidSchemaChange: Event<void> = this._onDidSchemaChange.event;
|
||||
|
||||
private readonly _onDidUpdateConfiguration = new Emitter<{ properties: ReadonlySet<string>; defaultsOverrides?: boolean }>();
|
||||
private readonly _onDidUpdateConfiguration = this._register(new Emitter<{ properties: ReadonlySet<string>; defaultsOverrides?: boolean }>());
|
||||
readonly onDidUpdateConfiguration = this._onDidUpdateConfiguration.event;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.configurationDefaultsOverrides = new Map();
|
||||
this.defaultLanguageConfigurationOverridesNode = {
|
||||
id: 'defaultOverrides',
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { Emitter, Event } from '../../../base/common/event.js';
|
||||
import { getCompressedContent, IJSONSchema } from '../../../base/common/jsonSchema.js';
|
||||
import { DisposableStore, IDisposable, toDisposable } from '../../../base/common/lifecycle.js';
|
||||
import { Disposable, DisposableStore, IDisposable, toDisposable } from '../../../base/common/lifecycle.js';
|
||||
import * as platform from '../../registry/common/platform.js';
|
||||
|
||||
export const Extensions = {
|
||||
|
@ -65,15 +65,15 @@ function normalizeId(id: string) {
|
|||
|
||||
|
||||
|
||||
class JSONContributionRegistry implements IJSONContributionRegistry {
|
||||
class JSONContributionRegistry extends Disposable implements IJSONContributionRegistry {
|
||||
|
||||
private readonly schemasById: { [id: string]: IJSONSchema } = {};
|
||||
private readonly schemaAssociations: { [uri: string]: string[] } = {};
|
||||
|
||||
private readonly _onDidChangeSchema = new Emitter<string>();
|
||||
private readonly _onDidChangeSchema = this._register(new Emitter<string>());
|
||||
readonly onDidChangeSchema: Event<string> = this._onDidChangeSchema.event;
|
||||
|
||||
private readonly _onDidChangeSchemaAssociations = new Emitter<void>();
|
||||
private readonly _onDidChangeSchemaAssociations = this._register(new Emitter<void>());
|
||||
readonly onDidChangeSchemaAssociations: Event<void> = this._onDidChangeSchemaAssociations.event;
|
||||
|
||||
public registerSchema(uri: string, unresolvedSchemaContent: IJSONSchema, store?: DisposableStore): void {
|
||||
|
|
|
@ -48,6 +48,16 @@ class RegistryImpl implements IRegistry {
|
|||
public as(id: string): any {
|
||||
return this.data.get(id) || null;
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
this.data.forEach((value) => {
|
||||
if (Types.isFunction(value.dispose)) {
|
||||
value.dispose();
|
||||
}
|
||||
});
|
||||
this.data.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const Registry: IRegistry = new RegistryImpl();
|
||||
|
|
|
@ -12,6 +12,7 @@ import { IJSONContributionRegistry, Extensions as JSONExtensions } from '../../j
|
|||
import * as platform from '../../registry/common/platform.js';
|
||||
import { IColorTheme } from './themeService.js';
|
||||
import * as nls from '../../../nls.js';
|
||||
import { Disposable } from '../../../base/common/lifecycle.js';
|
||||
|
||||
// ------ API types
|
||||
|
||||
|
@ -133,9 +134,9 @@ export interface IColorRegistry {
|
|||
type IJSONSchemaForColors = IJSONSchema & { properties: { [name: string]: { oneOf: [IJSONSchemaWithSnippets, IJSONSchema] } } };
|
||||
type IJSONSchemaWithSnippets = IJSONSchema & { defaultSnippets: IJSONSchemaSnippet[] };
|
||||
|
||||
class ColorRegistry implements IColorRegistry {
|
||||
class ColorRegistry extends Disposable implements IColorRegistry {
|
||||
|
||||
private readonly _onDidChangeSchema = new Emitter<void>();
|
||||
private readonly _onDidChangeSchema = this._register(new Emitter<void>());
|
||||
readonly onDidChangeSchema: Event<void> = this._onDidChangeSchema.event;
|
||||
|
||||
private colorsById: { [key: string]: ColorContribution };
|
||||
|
@ -143,6 +144,7 @@ class ColorRegistry implements IColorRegistry {
|
|||
private colorReferenceSchema: IJSONSchema & { enum: string[]; enumDescriptions: string[] } = { type: 'string', enum: [], enumDescriptions: [] };
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.colorsById = {};
|
||||
}
|
||||
|
||||
|
@ -214,7 +216,7 @@ class ColorRegistry implements IColorRegistry {
|
|||
return this.colorReferenceSchema;
|
||||
}
|
||||
|
||||
public toString() {
|
||||
public override toString() {
|
||||
const sorter = (a: string, b: string) => {
|
||||
const cat1 = a.indexOf('.') === -1 ? 0 : 1;
|
||||
const cat2 = b.indexOf('.') === -1 ? 0 : 1;
|
||||
|
|
|
@ -14,6 +14,7 @@ import { URI } from '../../../base/common/uri.js';
|
|||
import { localize } from '../../../nls.js';
|
||||
import { Extensions as JSONExtensions, IJSONContributionRegistry } from '../../jsonschemas/common/jsonContributionRegistry.js';
|
||||
import * as platform from '../../registry/common/platform.js';
|
||||
import { Disposable } from '../../../base/common/lifecycle.js';
|
||||
|
||||
// ------ API types
|
||||
|
||||
|
@ -156,9 +157,9 @@ export const fontColorRegex = /^#[0-9a-fA-F]{0,6}$/;
|
|||
|
||||
export const fontIdErrorMessage = localize('schema.fontId.formatError', 'The font ID must only contain letters, numbers, underscores and dashes.');
|
||||
|
||||
class IconRegistry implements IIconRegistry {
|
||||
class IconRegistry extends Disposable implements IIconRegistry {
|
||||
|
||||
private readonly _onDidChange = new Emitter<void>();
|
||||
private readonly _onDidChange = this._register(new Emitter<void>());
|
||||
readonly onDidChange: Event<void> = this._onDidChange.event;
|
||||
|
||||
private iconsById: { [key: string]: IconContribution };
|
||||
|
@ -182,6 +183,7 @@ class IconRegistry implements IIconRegistry {
|
|||
private iconFontsById: { [key: string]: IconFontDefinition };
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.iconsById = {};
|
||||
this.iconFontsById = {};
|
||||
}
|
||||
|
@ -263,7 +265,7 @@ class IconRegistry implements IIconRegistry {
|
|||
return this.iconFontsById[id];
|
||||
}
|
||||
|
||||
public toString() {
|
||||
public override toString() {
|
||||
const sorter = (i1: IconContribution, i2: IconContribution) => {
|
||||
return i1.id.localeCompare(i2.id);
|
||||
};
|
||||
|
|
|
@ -134,13 +134,14 @@ export interface IThemingRegistry {
|
|||
readonly onThemingParticipantAdded: Event<IThemingParticipant>;
|
||||
}
|
||||
|
||||
class ThemingRegistry implements IThemingRegistry {
|
||||
class ThemingRegistry extends Disposable implements IThemingRegistry {
|
||||
private themingParticipants: IThemingParticipant[] = [];
|
||||
private readonly onThemingParticipantAddedEmitter: Emitter<IThemingParticipant>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.themingParticipants = [];
|
||||
this.onThemingParticipantAddedEmitter = new Emitter<IThemingParticipant>();
|
||||
this.onThemingParticipantAddedEmitter = this._register(new Emitter<IThemingParticipant>());
|
||||
}
|
||||
|
||||
public onColorThemeChange(participant: IThemingParticipant): IDisposable {
|
||||
|
|
|
@ -7,6 +7,7 @@ import { RunOnceScheduler } from '../../../base/common/async.js';
|
|||
import { Color } from '../../../base/common/color.js';
|
||||
import { Emitter, Event } from '../../../base/common/event.js';
|
||||
import { IJSONSchema, IJSONSchemaMap } from '../../../base/common/jsonSchema.js';
|
||||
import { Disposable } from '../../../base/common/lifecycle.js';
|
||||
import * as nls from '../../../nls.js';
|
||||
import { Extensions as JSONExtensions, IJSONContributionRegistry } from '../../jsonschemas/common/jsonContributionRegistry.js';
|
||||
import * as platform from '../../registry/common/platform.js';
|
||||
|
@ -261,9 +262,9 @@ export interface ITokenClassificationRegistry {
|
|||
getTokenStylingSchema(): IJSONSchema;
|
||||
}
|
||||
|
||||
class TokenClassificationRegistry implements ITokenClassificationRegistry {
|
||||
class TokenClassificationRegistry extends Disposable implements ITokenClassificationRegistry {
|
||||
|
||||
private readonly _onDidChangeSchema = new Emitter<void>();
|
||||
private readonly _onDidChangeSchema = this._register(new Emitter<void>());
|
||||
readonly onDidChangeSchema: Event<void> = this._onDidChangeSchema.event;
|
||||
|
||||
private currentTypeNumber = 0;
|
||||
|
@ -347,6 +348,7 @@ class TokenClassificationRegistry implements ITokenClassificationRegistry {
|
|||
};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.tokenTypeById = Object.create(null);
|
||||
this.tokenModifierById = Object.create(null);
|
||||
this.typeHierarchy = Object.create(null);
|
||||
|
@ -471,7 +473,7 @@ class TokenClassificationRegistry implements ITokenClassificationRegistry {
|
|||
}
|
||||
|
||||
|
||||
public toString() {
|
||||
public override toString() {
|
||||
const sorter = (a: string, b: string) => {
|
||||
const cat1 = a.indexOf('.') === -1 ? 0 : 1;
|
||||
const cat2 = b.indexOf('.') === -1 ? 0 : 1;
|
||||
|
|
|
@ -13,6 +13,7 @@ import { NullLogService } from '../../../../platform/log/common/log.js';
|
|||
import { ActivatedExtension, EmptyExtension, ExtensionActivationTimes, ExtensionsActivator, IExtensionsActivatorHost } from '../../common/extHostExtensionActivator.js';
|
||||
import { ExtensionDescriptionRegistry, IActivationEventsReader } from '../../../services/extensions/common/extensionDescriptionRegistry.js';
|
||||
import { ExtensionActivationReason, MissingExtensionDependency } from '../../../services/extensions/common/extensions.js';
|
||||
import { DisposableStore } from '../../../../base/common/lifecycle.js';
|
||||
|
||||
suite('ExtensionsActivator', () => {
|
||||
|
||||
|
@ -23,26 +24,30 @@ suite('ExtensionsActivator', () => {
|
|||
const idC = new ExtensionIdentifier(`c`);
|
||||
|
||||
test('calls activate only once with sequential activations', async () => {
|
||||
const disposables = new DisposableStore();
|
||||
const host = new SimpleExtensionsActivatorHost();
|
||||
const activator = createActivator(host, [
|
||||
desc(idA)
|
||||
]);
|
||||
], [], disposables);
|
||||
|
||||
await activator.activateByEvent('*', false);
|
||||
assert.deepStrictEqual(host.activateCalls, [idA]);
|
||||
|
||||
await activator.activateByEvent('*', false);
|
||||
assert.deepStrictEqual(host.activateCalls, [idA]);
|
||||
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
test('calls activate only once with parallel activations', async () => {
|
||||
const disposables = new DisposableStore();
|
||||
const extActivation = new ExtensionActivationPromiseSource();
|
||||
const host = new PromiseExtensionsActivatorHost([
|
||||
[idA, extActivation]
|
||||
]);
|
||||
const activator = createActivator(host, [
|
||||
desc(idA, [], ['evt1', 'evt2'])
|
||||
]);
|
||||
], [], disposables);
|
||||
|
||||
const activate1 = activator.activateByEvent('evt1', false);
|
||||
const activate2 = activator.activateByEvent('evt2', false);
|
||||
|
@ -53,9 +58,12 @@ suite('ExtensionsActivator', () => {
|
|||
await activate2;
|
||||
|
||||
assert.deepStrictEqual(host.activateCalls, [idA]);
|
||||
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
test('activates dependencies first', async () => {
|
||||
const disposables = new DisposableStore();
|
||||
const extActivationA = new ExtensionActivationPromiseSource();
|
||||
const extActivationB = new ExtensionActivationPromiseSource();
|
||||
const host = new PromiseExtensionsActivatorHost([
|
||||
|
@ -65,7 +73,7 @@ suite('ExtensionsActivator', () => {
|
|||
const activator = createActivator(host, [
|
||||
desc(idA, [idB], ['evt1']),
|
||||
desc(idB, [], ['evt1']),
|
||||
]);
|
||||
], [], disposables);
|
||||
|
||||
const activate = activator.activateByEvent('evt1', false);
|
||||
|
||||
|
@ -81,22 +89,28 @@ suite('ExtensionsActivator', () => {
|
|||
await activate;
|
||||
|
||||
assert.deepStrictEqual(host.activateCalls, [idB, idA]);
|
||||
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
test('Supports having resolved extensions', async () => {
|
||||
const disposables = new DisposableStore();
|
||||
const host = new SimpleExtensionsActivatorHost();
|
||||
const bExt = desc(idB);
|
||||
delete (<Mutable<IExtensionDescription>>bExt).main;
|
||||
delete (<Mutable<IExtensionDescription>>bExt).browser;
|
||||
const activator = createActivator(host, [
|
||||
desc(idA, [idB])
|
||||
], [bExt]);
|
||||
], [bExt], disposables);
|
||||
|
||||
await activator.activateByEvent('*', false);
|
||||
assert.deepStrictEqual(host.activateCalls, [idA]);
|
||||
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
test('Supports having external extensions', async () => {
|
||||
const disposables = new DisposableStore();
|
||||
const extActivationA = new ExtensionActivationPromiseSource();
|
||||
const extActivationB = new ExtensionActivationPromiseSource();
|
||||
const host = new PromiseExtensionsActivatorHost([
|
||||
|
@ -107,7 +121,7 @@ suite('ExtensionsActivator', () => {
|
|||
(<Mutable<IExtensionDescription>>bExt).api = 'none';
|
||||
const activator = createActivator(host, [
|
||||
desc(idA, [idB])
|
||||
], [bExt]);
|
||||
], [bExt], disposables);
|
||||
|
||||
const activate = activator.activateByEvent('*', false);
|
||||
|
||||
|
@ -121,14 +135,17 @@ suite('ExtensionsActivator', () => {
|
|||
|
||||
await activate;
|
||||
assert.deepStrictEqual(host.activateCalls, [idB, idA]);
|
||||
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
test('Error: activateById with missing extension', async () => {
|
||||
const disposables = new DisposableStore();
|
||||
const host = new SimpleExtensionsActivatorHost();
|
||||
const activator = createActivator(host, [
|
||||
desc(idA),
|
||||
desc(idB),
|
||||
]);
|
||||
], [], disposables);
|
||||
|
||||
let error: Error | undefined = undefined;
|
||||
try {
|
||||
|
@ -138,21 +155,27 @@ suite('ExtensionsActivator', () => {
|
|||
}
|
||||
|
||||
assert.strictEqual(typeof error === 'undefined', false);
|
||||
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
test('Error: dependency missing', async () => {
|
||||
const disposables = new DisposableStore();
|
||||
const host = new SimpleExtensionsActivatorHost();
|
||||
const activator = createActivator(host, [
|
||||
desc(idA, [idB]),
|
||||
]);
|
||||
], [], disposables);
|
||||
|
||||
await activator.activateByEvent('*', false);
|
||||
|
||||
assert.deepStrictEqual(host.errors.length, 1);
|
||||
assert.deepStrictEqual(host.errors[0][0], idA);
|
||||
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
test('Error: dependency activation failed', async () => {
|
||||
const disposables = new DisposableStore();
|
||||
const extActivationA = new ExtensionActivationPromiseSource();
|
||||
const extActivationB = new ExtensionActivationPromiseSource();
|
||||
const host = new PromiseExtensionsActivatorHost([
|
||||
|
@ -162,7 +185,7 @@ suite('ExtensionsActivator', () => {
|
|||
const activator = createActivator(host, [
|
||||
desc(idA, [idB]),
|
||||
desc(idB)
|
||||
]);
|
||||
], [], disposables);
|
||||
|
||||
const activate = activator.activateByEvent('*', false);
|
||||
extActivationB.reject(new Error(`b fails!`));
|
||||
|
@ -171,9 +194,12 @@ suite('ExtensionsActivator', () => {
|
|||
assert.deepStrictEqual(host.errors.length, 2);
|
||||
assert.deepStrictEqual(host.errors[0][0], idB);
|
||||
assert.deepStrictEqual(host.errors[1][0], idA);
|
||||
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
test('issue #144518: Problem with git extension and vscode-icons', async () => {
|
||||
const disposables = new DisposableStore();
|
||||
const extActivationA = new ExtensionActivationPromiseSource();
|
||||
const extActivationB = new ExtensionActivationPromiseSource();
|
||||
const extActivationC = new ExtensionActivationPromiseSource();
|
||||
|
@ -186,7 +212,7 @@ suite('ExtensionsActivator', () => {
|
|||
desc(idA, [idB]),
|
||||
desc(idB),
|
||||
desc(idC),
|
||||
]);
|
||||
], [], disposables);
|
||||
|
||||
activator.activateByEvent('*', false);
|
||||
assert.deepStrictEqual(host.activateCalls, [idB, idC]);
|
||||
|
@ -196,6 +222,8 @@ suite('ExtensionsActivator', () => {
|
|||
|
||||
assert.deepStrictEqual(host.activateCalls, [idB, idC, idA]);
|
||||
extActivationA.resolve();
|
||||
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
class SimpleExtensionsActivatorHost implements IExtensionsActivatorHost {
|
||||
|
@ -255,10 +283,10 @@ suite('ExtensionsActivator', () => {
|
|||
}
|
||||
};
|
||||
|
||||
function createActivator(host: IExtensionsActivatorHost, extensionDescriptions: IExtensionDescription[], otherHostExtensionDescriptions: IExtensionDescription[] = []): ExtensionsActivator {
|
||||
const registry = new ExtensionDescriptionRegistry(basicActivationEventsReader, extensionDescriptions);
|
||||
const globalRegistry = new ExtensionDescriptionRegistry(basicActivationEventsReader, extensionDescriptions.concat(otherHostExtensionDescriptions));
|
||||
return new ExtensionsActivator(registry, globalRegistry, host, new NullLogService());
|
||||
function createActivator(host: IExtensionsActivatorHost, extensionDescriptions: IExtensionDescription[], otherHostExtensionDescriptions: IExtensionDescription[] = [], disposables: DisposableStore): ExtensionsActivator {
|
||||
const registry = disposables.add(new ExtensionDescriptionRegistry(basicActivationEventsReader, extensionDescriptions));
|
||||
const globalRegistry = disposables.add(new ExtensionDescriptionRegistry(basicActivationEventsReader, extensionDescriptions.concat(otherHostExtensionDescriptions)));
|
||||
return disposables.add(new ExtensionsActivator(registry, globalRegistry, host, new NullLogService()));
|
||||
}
|
||||
|
||||
function desc(id: ExtensionIdentifier, deps: ExtensionIdentifier[] = [], activationEvents: string[] = ['*']): IExtensionDescription {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { Emitter, Event } from '../../../../../base/common/event.js';
|
||||
import { IMarkdownString } from '../../../../../base/common/htmlContent.js';
|
||||
import { DisposableStore } from '../../../../../base/common/lifecycle.js';
|
||||
import { Disposable, DisposableStore } from '../../../../../base/common/lifecycle.js';
|
||||
import { ThemeIcon } from '../../../../../base/common/themables.js';
|
||||
import { ContextKeyExpression } from '../../../../../platform/contextkey/common/contextkey.js';
|
||||
import { Registry } from '../../../../../platform/registry/common/platform.js';
|
||||
|
@ -27,9 +27,9 @@ export interface IChatViewsWelcomeContributionRegistry {
|
|||
register(descriptor: IChatViewsWelcomeDescriptor): void;
|
||||
}
|
||||
|
||||
class ChatViewsWelcomeContributionRegistry implements IChatViewsWelcomeContributionRegistry {
|
||||
class ChatViewsWelcomeContributionRegistry extends Disposable implements IChatViewsWelcomeContributionRegistry {
|
||||
private readonly descriptors: IChatViewsWelcomeDescriptor[] = [];
|
||||
private readonly _onDidChange = new Emitter<void>();
|
||||
private readonly _onDidChange = this._register(new Emitter<void>());
|
||||
public readonly onDidChange: Event<void> = this._onDidChange.event;
|
||||
|
||||
public register(descriptor: IChatViewsWelcomeDescriptor): void {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter } from '../../../../base/common/event.js';
|
||||
import { DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js';
|
||||
import { Disposable, DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { Registry } from '../../../../platform/registry/common/platform.js';
|
||||
|
@ -36,8 +36,8 @@ export interface IExplorerFileContributionRegistry {
|
|||
register(descriptor: IExplorerFileContributionDescriptor): void;
|
||||
}
|
||||
|
||||
class ExplorerFileContributionRegistry implements IExplorerFileContributionRegistry {
|
||||
private readonly _onDidRegisterDescriptor = new Emitter<IExplorerFileContributionDescriptor>();
|
||||
class ExplorerFileContributionRegistry extends Disposable implements IExplorerFileContributionRegistry {
|
||||
private readonly _onDidRegisterDescriptor = this._register(new Emitter<IExplorerFileContributionDescriptor>());
|
||||
public readonly onDidRegisterDescriptor = this._onDidRegisterDescriptor.event;
|
||||
|
||||
private readonly descriptors: IExplorerFileContributionDescriptor[] = [];
|
||||
|
|
|
@ -41,7 +41,7 @@ import { mainWindow } from '../../../../base/browser/window.js';
|
|||
import { IPreferencesService } from '../../../services/preferences/common/preferences.js';
|
||||
import { Toggle } from '../../../../base/browser/ui/toggle/toggle.js';
|
||||
import { defaultToggleStyles } from '../../../../platform/theme/browser/defaultStyles.js';
|
||||
import { DisposableStore } from '../../../../base/common/lifecycle.js';
|
||||
import { DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js';
|
||||
|
||||
export const manageExtensionIcon = registerIcon('theme-selection-manage-extension', Codicon.gear, localize('manageExtensionIcon', 'Icon for the \'Manage\' action in the theme selection quick pick.'));
|
||||
|
||||
|
@ -53,7 +53,7 @@ enum ConfigureItem {
|
|||
CUSTOM_TOP_ENTRY = 'customTopEntry'
|
||||
}
|
||||
|
||||
class MarketplaceThemesPicker {
|
||||
class MarketplaceThemesPicker implements IDisposable {
|
||||
private readonly _installedExtensions: Promise<Set<string>>;
|
||||
private readonly _marketplaceExtensions: Set<string> = new Set();
|
||||
private readonly _marketplaceThemes: ThemeItem[] = [];
|
||||
|
@ -275,6 +275,7 @@ class MarketplaceThemesPicker {
|
|||
this._queryDelayer.dispose();
|
||||
this._marketplaceExtensions.clear();
|
||||
this._marketplaceThemes.length = 0;
|
||||
this._onDidChange.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ export interface IReadOnlyExtensionDescriptionRegistry {
|
|||
getExtensionDescriptionByIdOrUUID(extensionId: ExtensionIdentifier | string, uuid: string | undefined): IExtensionDescription | undefined;
|
||||
}
|
||||
|
||||
export class ExtensionDescriptionRegistry implements IReadOnlyExtensionDescriptionRegistry {
|
||||
export class ExtensionDescriptionRegistry extends Disposable implements IReadOnlyExtensionDescriptionRegistry {
|
||||
|
||||
public static isHostExtension(extensionId: ExtensionIdentifier | string, myRegistry: ExtensionDescriptionRegistry, globalRegistry: ExtensionDescriptionRegistry): boolean {
|
||||
if (myRegistry.getExtensionDescription(extensionId)) {
|
||||
|
@ -44,7 +44,7 @@ export class ExtensionDescriptionRegistry implements IReadOnlyExtensionDescripti
|
|||
return false;
|
||||
}
|
||||
|
||||
private readonly _onDidChange = new Emitter<void>();
|
||||
private readonly _onDidChange = this._register(new Emitter<void>());
|
||||
public readonly onDidChange = this._onDidChange.event;
|
||||
|
||||
private _versionId: number = 0;
|
||||
|
@ -57,6 +57,7 @@ export class ExtensionDescriptionRegistry implements IReadOnlyExtensionDescripti
|
|||
private readonly _activationEventsReader: IActivationEventsReader,
|
||||
extensionDescriptions: IExtensionDescription[]
|
||||
) {
|
||||
super();
|
||||
this._extensionDescriptions = extensionDescriptions;
|
||||
this._initialize();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ suite('ExtensionDescriptionRegistry', () => {
|
|||
registry.deltaExtensions([extensionA2], [idA]);
|
||||
|
||||
assert.deepStrictEqual(registry.getAllExtensionDescriptions(), [extensionA2]);
|
||||
|
||||
registry.dispose();
|
||||
});
|
||||
|
||||
function desc(id: ExtensionIdentifier, version: string, activationEvents: string[] = ['*']): IExtensionDescription {
|
||||
|
|
|
@ -10,6 +10,7 @@ import { RawContextKey } from '../../../../platform/contextkey/common/contextkey
|
|||
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { LogLevel } from '../../../../platform/log/common/log.js';
|
||||
import { Range } from '../../../../editor/common/core/range.js';
|
||||
import { Disposable } from '../../../../base/common/lifecycle.js';
|
||||
|
||||
/**
|
||||
* Mime type used by the output editor.
|
||||
|
@ -271,16 +272,16 @@ export interface IOutputChannelRegistry {
|
|||
removeChannel(id: string): void;
|
||||
}
|
||||
|
||||
class OutputChannelRegistry implements IOutputChannelRegistry {
|
||||
class OutputChannelRegistry extends Disposable implements IOutputChannelRegistry {
|
||||
private channels = new Map<string, IOutputChannelDescriptor>();
|
||||
|
||||
private readonly _onDidRegisterChannel = new Emitter<string>();
|
||||
private readonly _onDidRegisterChannel = this._register(new Emitter<string>());
|
||||
readonly onDidRegisterChannel = this._onDidRegisterChannel.event;
|
||||
|
||||
private readonly _onDidRemoveChannel = new Emitter<IOutputChannelDescriptor>();
|
||||
private readonly _onDidRemoveChannel = this._register(new Emitter<IOutputChannelDescriptor>());
|
||||
readonly onDidRemoveChannel = this._onDidRemoveChannel.event;
|
||||
|
||||
private readonly _onDidUpdateChannelFiles = new Emitter<IMultiSourceOutputChannelDescriptor>();
|
||||
private readonly _onDidUpdateChannelFiles = this._register(new Emitter<IMultiSourceOutputChannelDescriptor>());
|
||||
readonly onDidUpdateChannelSources = this._onDidUpdateChannelFiles.event;
|
||||
|
||||
public registerChannel(descriptor: IOutputChannelDescriptor): void {
|
||||
|
|
Loading…
Reference in New Issue