Skip to content

Commit 1e47b51

Browse files
committed
Extend extension point handler to collect implicit activation events
1 parent 1d4beed commit 1e47b51

File tree

4 files changed

+66
-7
lines changed

4 files changed

+66
-7
lines changed

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

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

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

404405
export function isApplicationScopedExtension(manifest: IExtensionManifest): boolean {
405406
return isLanguagePackExtension(manifest);

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

Lines changed: 37 additions & 5 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 } from 'vs/workbench/services/extensions/common/extensions';
19-
import { 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, IImplicitActivationEvents } from 'vs/workbench/services/extensions/common/extensions';
19+
import { ExtensionActivationEventsCollector, 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,6 +153,7 @@ 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>>;
156157
private readonly _allRequestedActivateEvents = new Set<string>();
157158
private readonly _proposedApiController: ProposedApiController;
158159
private readonly _isExtensionDevHost: boolean;
@@ -206,6 +207,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
206207
this._installedExtensionsReady = new Barrier();
207208
this._isDev = !this._environmentService.isBuilt || this._environmentService.isExtensionDevelopment;
208209
this._extensionsMessages = new Map<string, IMessage[]>();
210+
this._extensionsImplicitActivationEvents = new Map<string, Set<string>>();
209211
this._proposedApiController = _instantiationService.createInstance(ProposedApiController);
210212

211213
this._extensionHostManagers = [];
@@ -1211,19 +1213,48 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
12111213
}
12121214

12131215
const messageHandler = (msg: IMessage) => this._handleExtensionPointMessage(msg);
1216+
const implicitActivationEventsHandler = (info: IImplicitActivationEvents) => this._handleImplicitExtensionActivationEvents(info);
12141217
const availableExtensions = this._registry.getAllExtensionDescriptions();
12151218
const extensionPoints = ExtensionsRegistry.getExtensionPoints();
12161219
perf.mark('code/willHandleExtensionPoints');
12171220
for (const extensionPoint of extensionPoints) {
12181221
if (affectedExtensionPoints[extensionPoint.name]) {
12191222
perf.mark(`code/willHandleExtensionPoint/${extensionPoint.name}`);
1220-
AbstractExtensionService._handleExtensionPoint(extensionPoint, availableExtensions, messageHandler);
1223+
AbstractExtensionService._handleExtensionPoint(extensionPoint, availableExtensions, messageHandler, implicitActivationEventsHandler);
12211224
perf.mark(`code/didHandleExtensionPoint/${extensionPoint.name}`);
12221225
}
12231226
}
1227+
this._combineImplicitExtensionActivationEvents();
12241228
perf.mark('code/didHandleExtensionPoints');
12251229
}
12261230

1231+
private _combineImplicitExtensionActivationEvents() {
1232+
for (const [extensionKey, implicitActivationEvents] of this._extensionsImplicitActivationEvents.entries()) {
1233+
const extensionDescription = this._registry.getExtensionDescription(extensionKey);
1234+
if (!extensionDescription) {
1235+
continue;
1236+
}
1237+
1238+
for (const activationEvents of (extensionDescription?.activationEvents ?? [])) {
1239+
implicitActivationEvents.add(activationEvents);
1240+
}
1241+
extensionDescription.activationEvents = Array.from(implicitActivationEvents);
1242+
}
1243+
}
1244+
1245+
private _handleImplicitExtensionActivationEvents(extensionActivationEventsInfo: IImplicitActivationEvents) {
1246+
const extensionKey = ExtensionIdentifier.toKey(extensionActivationEventsInfo.extensionId);
1247+
1248+
if (!this._extensionsImplicitActivationEvents.has(extensionKey)) {
1249+
this._extensionsImplicitActivationEvents.set(extensionKey, new Set());
1250+
}
1251+
const implicitActivationEvents = this._extensionsImplicitActivationEvents.get(extensionKey);
1252+
1253+
for (const activationEvent of extensionActivationEventsInfo.implicitActivationEvents) {
1254+
implicitActivationEvents?.add(activationEvent);
1255+
}
1256+
}
1257+
12271258
private _handleExtensionPointMessage(msg: IMessage) {
12281259
const extensionKey = ExtensionIdentifier.toKey(msg.extensionId);
12291260

@@ -1273,14 +1304,15 @@ export abstract class AbstractExtensionService extends Disposable implements IEx
12731304
}
12741305
}
12751306

1276-
private static _handleExtensionPoint<T extends IExtensionContributions[keyof IExtensionContributions]>(extensionPoint: ExtensionPoint<T>, availableExtensions: IExtensionDescription[], messageHandler: (msg: IMessage) => void): void {
1307+
private static _handleExtensionPoint<T extends IExtensionContributions[keyof IExtensionContributions]>(extensionPoint: ExtensionPoint<T>, availableExtensions: IExtensionDescription[], messageHandler: (msg: IMessage) => void, implicitActivationEventsHandler: (info: IImplicitActivationEvents) => void): void {
12771308
const users: IExtensionPointUser<T>[] = [];
12781309
for (const desc of availableExtensions) {
12791310
if (desc.contributes && hasOwnProperty.call(desc.contributes, extensionPoint.name)) {
12801311
users.push({
12811312
description: desc,
12821313
value: desc.contributes[extensionPoint.name as keyof typeof desc.contributes] as T,
1283-
collector: new ExtensionMessageCollector(messageHandler, desc, extensionPoint.name)
1314+
collector: new ExtensionMessageCollector(messageHandler, desc, extensionPoint.name),
1315+
implicitActivationEventsCollector: new ExtensionActivationEventsCollector(implicitActivationEventsHandler, desc),
12841316
});
12851317
}
12861318
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ export interface IMessage {
4040
extensionPointId: string;
4141
}
4242

43+
export interface IImplicitActivationEvents {
44+
implicitActivationEvents: string[];
45+
extensionId: ExtensionIdentifier;
46+
}
47+
4348
export class LocalProcessRunningLocation {
4449
public readonly kind = ExtensionHostKind.LocalProcess;
4550
constructor(

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Severity from 'vs/base/common/severity';
1010
import { EXTENSION_IDENTIFIER_PATTERN } from 'vs/platform/extensionManagement/common/extensionManagement';
1111
import { Extensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
1212
import { Registry } from 'vs/platform/registry/common/platform';
13-
import { IMessage } from 'vs/workbench/services/extensions/common/extensions';
13+
import { IImplicitActivationEvents, IMessage } from 'vs/workbench/services/extensions/common/extensions';
1414
import { ExtensionIdentifier, IExtensionDescription, EXTENSION_CATEGORIES } from 'vs/platform/extensions/common/extensions';
1515
import { ExtensionKind } from 'vs/platform/environment/common/environment';
1616
import { allApiProposals } from 'vs/workbench/services/extensions/common/extensionsApiProposals';
@@ -56,10 +56,31 @@ export class ExtensionMessageCollector {
5656
}
5757
}
5858

59+
export class ExtensionActivationEventsCollector {
60+
private readonly _implicitActivationEventsHandler: (info: IImplicitActivationEvents) => void;
61+
private readonly _extension: IExtensionDescription;
62+
63+
constructor(
64+
implicitActivationEventsHandler: (info: IImplicitActivationEvents) => void,
65+
extension: IExtensionDescription
66+
) {
67+
this._implicitActivationEventsHandler = implicitActivationEventsHandler;
68+
this._extension = extension;
69+
}
70+
71+
public addImplicitActivationEvents(events: string[]) {
72+
this._implicitActivationEventsHandler({
73+
implicitActivationEvents: events,
74+
extensionId: this._extension.identifier,
75+
});
76+
}
77+
}
78+
5979
export interface IExtensionPointUser<T> {
6080
description: IExtensionDescription;
6181
value: T;
6282
collector: ExtensionMessageCollector;
83+
implicitActivationEventsCollector: ExtensionActivationEventsCollector;
6384
}
6485

6586
export type IExtensionPointHandler<T> = (extensions: readonly IExtensionPointUser<T>[], delta: ExtensionPointUserDelta<T>) => void;

0 commit comments

Comments
 (0)