Skip to content

Commit c783d52

Browse files
committed
Add implicit activation events when scanning extensions
1 parent 9503cc6 commit c783d52

File tree

12 files changed

+91
-88
lines changed

12 files changed

+91
-88
lines changed

src/vs/platform/extensionManagement/common/extensionsScannerService.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import { IExtensionsProfileScannerService, IScannedProfileExtension } from 'vs/p
3636
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
3737
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
3838
import { localizeManifest } from 'vs/platform/extensionManagement/common/extensionNls';
39+
import { ImplicitActivationEvents } from 'vs/platform/extensionManagement/common/implicitActivationEvents';
3940

4041
export type IScannedExtensionManifest = IRelaxedExtensionManifest & { __metadata?: Metadata };
4142

@@ -577,6 +578,7 @@ class ExtensionsScanner extends Disposable {
577578
const identifier = metadata?.id ? { id, uuid: metadata.id } : { id };
578579
const type = metadata?.isSystem ? ExtensionType.System : input.type;
579580
const isBuiltin = type === ExtensionType.System || !!metadata?.isBuiltin;
581+
ImplicitActivationEvents.updateManifest(manifest);
580582
manifest = await this.translateManifest(input.location, manifest, ExtensionScannerInput.createNlsConfiguration(input));
581583
const extension = {
582584
type,
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { onUnexpectedError } from 'vs/base/common/errors';
7+
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
8+
9+
export interface IActivationEventsGenerator<T> {
10+
(contribution: T, result: { push(item: string): void }): void;
11+
}
12+
13+
export class ImplicitActivationEventsImpl {
14+
15+
private readonly _generators = new Map<string, IActivationEventsGenerator<any>>();
16+
17+
public register<T>(extensionPointName: string, generator: IActivationEventsGenerator<T>): void {
18+
this._generators.set(extensionPointName, generator);
19+
}
20+
21+
public updateManifest(manifest: IExtensionManifest) {
22+
if (!Array.isArray(manifest.activationEvents) || !manifest.contributes) {
23+
return;
24+
}
25+
if (typeof manifest.main === 'undefined' && typeof manifest.browser === 'undefined') {
26+
return;
27+
}
28+
29+
for (const extPointName in manifest.contributes) {
30+
const generator = this._generators.get(extPointName);
31+
if (!generator) {
32+
// There's no generator for this extension point
33+
continue;
34+
}
35+
const contrib = (manifest.contributes as any)[extPointName];
36+
const contribArr = Array.isArray(contrib) ? contrib : [contrib];
37+
try {
38+
generator(contribArr, manifest.activationEvents);
39+
} catch (err) {
40+
onUnexpectedError(err);
41+
}
42+
}
43+
}
44+
}
45+
46+
export const ImplicitActivationEvents: ImplicitActivationEventsImpl = new ImplicitActivationEventsImpl();

src/vs/platform/extensions/common/extensions.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,7 @@ export interface IRelaxedExtensionDescription extends IRelaxedExtensionManifest
399399
browserNlsBundleUris?: { [language: string]: URI };
400400
}
401401

402-
type MutableByKey<T extends {}, K extends keyof T> = Pick<T, K> & Readonly<Omit<T, K>>;
403-
export type IExtensionDescription = MutableByKey<IRelaxedExtensionDescription, 'activationEvents'>;
402+
export type IExtensionDescription = Readonly<IRelaxedExtensionDescription>;
404403

405404
export function isApplicationScopedExtension(manifest: IExtensionManifest): boolean {
406405
return isLanguagePackExtension(manifest);

src/vs/workbench/contrib/notebook/browser/notebookExtensionPoint.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,14 @@ const notebookPreloadContribution: IJSONSchema = {
232232

233233
export const notebooksExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookEditorContribution[]>({
234234
extensionPoint: 'notebooks',
235-
jsonSchema: notebookProviderContribution
235+
jsonSchema: notebookProviderContribution,
236+
activationEventsGenerator: (contribs: INotebookEditorContribution[], result: { push(item: string): void }) => {
237+
for (const contrib of contribs) {
238+
if (contrib.type) {
239+
result.push(`onNotebookSerializer:${contrib.type}`);
240+
}
241+
}
242+
}
236243
});
237244

238245
export const notebookRendererExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookRendererContribution[]>({

src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,7 @@ export class NotebookProviderInfoStore extends Disposable {
100100
builtinProvidersFromCache.set(builtin.id, this.add(builtin));
101101
});
102102

103-
104103
for (const extension of extensions) {
105-
const implicitActivationEvents: string[] = [];
106104
for (const notebookContribution of extension.value) {
107105

108106
if (!notebookContribution.type) {
@@ -122,8 +120,6 @@ export class NotebookProviderInfoStore extends Disposable {
122120
}
123121
}
124122

125-
implicitActivationEvents.push(`onNotebookSerializer:${notebookContribution.type}`);
126-
127123
this.add(new NotebookProviderInfo({
128124
extension: extension.description.identifier,
129125
id: notebookContribution.type,
@@ -133,9 +129,7 @@ export class NotebookProviderInfoStore extends Disposable {
133129
providerDisplayName: extension.description.displayName ?? extension.description.identifier.value,
134130
exclusive: false
135131
}));
136-
137132
}
138-
extension.implicitActivationEventsCollector.addImplicitActivationEvents(implicitActivationEvents);
139133
}
140134

141135
const mementoObject = this._memento.getMemento(StorageScope.PROFILE, StorageTarget.MACHINE);

src/vs/workbench/contrib/terminal/common/terminal.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Event } from 'vs/base/common/event';
88
import { IDisposable } from 'vs/base/common/lifecycle';
99
import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
1010
import { IExtensionPointDescriptor } from 'vs/workbench/services/extensions/common/extensionsRegistry';
11-
import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, TerminalLocationString, IProcessProperty, TitleEventSource, ProcessPropertyType, IFixedTerminalDimensions, IExtensionTerminalProfile, ICreateContributedTerminalProfileOptions, IProcessPropertyMap, ITerminalEnvironment, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal';
11+
import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalChildProcess, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, TerminalLocationString, IProcessProperty, TitleEventSource, ProcessPropertyType, IFixedTerminalDimensions, IExtensionTerminalProfile, ICreateContributedTerminalProfileOptions, IProcessPropertyMap, ITerminalEnvironment, ITerminalProcessOptions, ITerminalContributions } from 'vs/platform/terminal/common/terminal';
1212
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
1313
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
1414
import { URI } from 'vs/base/common/uri';
@@ -710,7 +710,7 @@ export const DEFAULT_COMMANDS_TO_SKIP_SHELL: string[] = [
710710
'workbench.action.toggleMaximizedPanel'
711711
];
712712

713-
export const terminalContributionsDescriptor: IExtensionPointDescriptor = {
713+
export const terminalContributionsDescriptor: IExtensionPointDescriptor<ITerminalContributions> = {
714714
extensionPoint: 'terminal',
715715
defaultExtensionKind: ['workspace'],
716716
jsonSchema: {

src/vs/workbench/services/actions/common/menusExtensionPoint.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,14 @@ const _commandRegistrations = new DisposableStore();
623623

624624
export const commandsExtensionPoint = ExtensionsRegistry.registerExtensionPoint<schema.IUserFriendlyCommand | schema.IUserFriendlyCommand[]>({
625625
extensionPoint: 'commands',
626-
jsonSchema: schema.commandsContribution
626+
jsonSchema: schema.commandsContribution,
627+
activationEventsGenerator: (contribs: schema.IUserFriendlyCommand[], result: { push(item: string): void }) => {
628+
for (const contrib of contribs) {
629+
if (contrib.command) {
630+
result.push(`onCommand:${contrib.command}`);
631+
}
632+
}
633+
}
627634
});
628635

629636
commandsExtensionPoint.setHandler(extensions => {
@@ -662,8 +669,6 @@ commandsExtensionPoint.setHandler(extensions => {
662669
precondition: ContextKeyExpr.deserialize(enablement),
663670
icon: absoluteIcon
664671
}));
665-
666-
extension.implicitActivationEventsCollector.addImplicitActivationEvents([`onCommand:${command}`]);
667672
}
668673

669674
// remove all previous command registrations

src/vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { IExtensionResourceLoaderService } from 'vs/platform/extensionResourceLo
1515
import { IProductService } from 'vs/platform/product/common/productService';
1616
import { ITranslations, localizeManifest } from 'vs/platform/extensionManagement/common/extensionNls';
1717
import { ILogService } from 'vs/platform/log/common/log';
18+
import { ImplicitActivationEvents } from 'vs/platform/extensionManagement/common/implicitActivationEvents';
1819

1920
interface IBundledExtension {
2021
extensionPath: string;
@@ -74,6 +75,7 @@ export class BuiltinExtensionsScannerService implements IBuiltinExtensionsScanne
7475
}
7576
browserNlsBundleUris.en = uriIdentityService.extUri.resolvePath(builtinExtensionsServiceUrl!, e.browserNlsMetadataPath);
7677
}
78+
ImplicitActivationEvents.updateManifest(e.packageJSON);
7779
return {
7880
identifier: { id },
7981
location: uriIdentityService.extUri.joinPath(builtinExtensionsServiceUrl!, e.extensionPath),

src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import { IStringDictionary } from 'vs/base/common/collections';
4343
import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
4444
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
4545
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
46+
import { ImplicitActivationEvents } from 'vs/platform/extensionManagement/common/implicitActivationEvents';
4647

4748
type GalleryExtensionInfo = { readonly id: string; preRelease?: boolean; migrateStorageFrom?: string };
4849
type ExtensionInfo = { readonly id: string; preRelease: boolean };
@@ -679,6 +680,8 @@ export class WebExtensionsScannerService extends Disposable implements IWebExten
679680
};
680681
}
681682

683+
ImplicitActivationEvents.updateManifest(manifest);
684+
682685
const packageNLSUri = webExtension.packageNLSUris?.get(Language.value().toLowerCase());
683686
if (packageNLSUri || webExtension.fallbackPackageNLSUri) {
684687
manifest = packageNLSUri

src/vs/workbench/services/extensions/common/abstractExtensionService.ts

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import { IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementServ
1515
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
1616
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
1717
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
18-
import { ActivationTimes, ExtensionPointContribution, IExtensionService, IExtensionsStatus, IMessage, IWillActivateEvent, IResponsiveStateChangeEvent, toExtension, IExtensionHost, ActivationKind, ExtensionHostKind, ExtensionRunningLocation, extensionHostKindToString, ExtensionActivationReason, IInternalExtensionService, RemoteRunningLocation, LocalProcessRunningLocation, LocalWebWorkerRunningLocation, IImplicitActivationEvents } from 'vs/workbench/services/extensions/common/extensions';
19-
import { ExtensionActivationEventsCollector, ExtensionMessageCollector, ExtensionPoint, ExtensionsRegistry, IExtensionPoint, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry';
18+
import { ActivationTimes, ExtensionPointContribution, IExtensionService, IExtensionsStatus, IMessage, IWillActivateEvent, IResponsiveStateChangeEvent, toExtension, IExtensionHost, ActivationKind, ExtensionHostKind, ExtensionRunningLocation, extensionHostKindToString, ExtensionActivationReason, IInternalExtensionService, RemoteRunningLocation, LocalProcessRunningLocation, LocalWebWorkerRunningLocation } from 'vs/workbench/services/extensions/common/extensions';
19+
import { ExtensionMessageCollector, ExtensionPoint, ExtensionsRegistry, IExtensionPoint, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry';
2020
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
2121
import { ResponsiveState } from 'vs/workbench/services/extensions/common/rpcProtocol';
2222
import { createExtensionHostManager, IExtensionHostManager } from 'vs/workbench/services/extensions/common/extensionHostManager';
@@ -153,7 +153,6 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
153153
private readonly _installedExtensionsReady: Barrier;
154154
private readonly _isDev: boolean;
155155
private readonly _extensionsMessages: Map<string, IMessage[]>;
156-
private readonly _extensionsImplicitActivationEvents: Map<string, Set<string>>;
157156
private readonly _allRequestedActivateEvents = new Set<string>();
158157
private readonly _proposedApiController: ProposedApiController;
159158
private readonly _isExtensionDevHost: boolean;
@@ -207,7 +206,6 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
207206
this._installedExtensionsReady = new Barrier();
208207
this._isDev = !this._environmentService.isBuilt || this._environmentService.isExtensionDevelopment;
209208
this._extensionsMessages = new Map<string, IMessage[]>();
210-
this._extensionsImplicitActivationEvents = new Map<string, Set<string>>();
211209
this._proposedApiController = _instantiationService.createInstance(ProposedApiController);
212210

213211
this._extensionHostManagers = [];
@@ -1213,47 +1211,17 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
12131211
}
12141212

12151213
const messageHandler = (msg: IMessage) => this._handleExtensionPointMessage(msg);
1216-
const implicitActivationEventsHandler = (info: IImplicitActivationEvents) => this._handleImplicitExtensionActivationEvents(info);
12171214
const availableExtensions = this._registry.getAllExtensionDescriptions();
12181215
const extensionPoints = ExtensionsRegistry.getExtensionPoints();
12191216
perf.mark('code/willHandleExtensionPoints');
12201217
for (const extensionPoint of extensionPoints) {
12211218
if (affectedExtensionPoints[extensionPoint.name]) {
12221219
perf.mark(`code/willHandleExtensionPoint/${extensionPoint.name}`);
1223-
AbstractExtensionService._handleExtensionPoint(extensionPoint, availableExtensions, messageHandler, implicitActivationEventsHandler);
1220+
AbstractExtensionService._handleExtensionPoint(extensionPoint, availableExtensions, messageHandler);
12241221
perf.mark(`code/didHandleExtensionPoint/${extensionPoint.name}`);
12251222
}
12261223
}
1227-
this._combineImplicitExtensionActivationEvents();
12281224
perf.mark('code/didHandleExtensionPoints');
1229-
this._registry.set(availableExtensions);
1230-
}
1231-
1232-
private _combineImplicitExtensionActivationEvents() {
1233-
for (const [extensionKey, implicitActivationEvents] of this._extensionsImplicitActivationEvents.entries()) {
1234-
const extensionDescription = this._registry.getExtensionDescription(extensionKey);
1235-
if (!extensionDescription) {
1236-
continue;
1237-
}
1238-
1239-
for (const activationEvents of (extensionDescription?.activationEvents ?? [])) {
1240-
implicitActivationEvents.add(activationEvents);
1241-
}
1242-
extensionDescription.activationEvents = Array.from(implicitActivationEvents);
1243-
}
1244-
}
1245-
1246-
private _handleImplicitExtensionActivationEvents(extensionActivationEventsInfo: IImplicitActivationEvents) {
1247-
const extensionKey = ExtensionIdentifier.toKey(extensionActivationEventsInfo.extensionId);
1248-
1249-
if (!this._extensionsImplicitActivationEvents.has(extensionKey)) {
1250-
this._extensionsImplicitActivationEvents.set(extensionKey, new Set());
1251-
}
1252-
const implicitActivationEvents = this._extensionsImplicitActivationEvents.get(extensionKey);
1253-
1254-
for (const activationEvent of extensionActivationEventsInfo.implicitActivationEvents) {
1255-
implicitActivationEvents?.add(activationEvent);
1256-
}
12571225
}
12581226

12591227
private _handleExtensionPointMessage(msg: IMessage) {
@@ -1305,15 +1273,14 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
13051273
}
13061274
}
13071275

1308-
private static _handleExtensionPoint<T extends IExtensionContributions[keyof IExtensionContributions]>(extensionPoint: ExtensionPoint<T>, availableExtensions: IExtensionDescription[], messageHandler: (msg: IMessage) => void, implicitActivationEventsHandler: (info: IImplicitActivationEvents) => void): void {
1276+
private static _handleExtensionPoint<T extends IExtensionContributions[keyof IExtensionContributions]>(extensionPoint: ExtensionPoint<T>, availableExtensions: IExtensionDescription[], messageHandler: (msg: IMessage) => void): void {
13091277
const users: IExtensionPointUser<T>[] = [];
13101278
for (const desc of availableExtensions) {
13111279
if (desc.contributes && hasOwnProperty.call(desc.contributes, extensionPoint.name)) {
13121280
users.push({
13131281
description: desc,
13141282
value: desc.contributes[extensionPoint.name as keyof typeof desc.contributes] as T,
1315-
collector: new ExtensionMessageCollector(messageHandler, desc, extensionPoint.name),
1316-
implicitActivationEventsCollector: new ExtensionActivationEventsCollector(implicitActivationEventsHandler, desc),
1283+
collector: new ExtensionMessageCollector(messageHandler, desc, extensionPoint.name)
13171284
});
13181285
}
13191286
}

0 commit comments

Comments
 (0)