Skip to content

Commit b420c54

Browse files
committed
Remove cyclic dependency between IExtensionService and IThreadService
1 parent 2e5311c commit b420c54

3 files changed

Lines changed: 65 additions & 28 deletions

File tree

src/vs/workbench/api/electron-browser/extensionHost.contribution.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import { MainThreadStorage } from './mainThreadStorage';
3232
import { MainThreadTelemetry } from './mainThreadTelemetry';
3333
import { MainThreadTerminalService } from './mainThreadTerminalService';
3434
import { MainThreadWorkspace } from './mainThreadWorkspace';
35-
import { MainProcessExtensionService } from './mainThreadExtensionService';
35+
import { MainProcessExtensionServiceAPI } from './mainThreadExtensionService';
3636
import { MainThreadFileSystemEventService } from './mainThreadFileSystemEventService';
3737
import { MainThreadTask } from './mainThreadTask';
3838
import { MainThreadSCM } from './mainThreadSCM';
@@ -93,15 +93,13 @@ export class ExtHostContribution implements IWorkbenchContribution {
9393
col.define(MainContext.MainThreadSCM).set(create(MainThreadSCM));
9494
col.define(MainContext.MainThreadTask).set(create(MainThreadTask));
9595
col.define(MainContext.MainThreadCredentials).set(create(MainThreadCredentials));
96-
if (this.extensionService instanceof MainProcessExtensionService) {
97-
col.define(MainContext.MainProcessExtensionService).set(<MainProcessExtensionService>this.extensionService);
98-
}
96+
col.define(MainContext.MainProcessExtensionService).set(create(MainProcessExtensionServiceAPI));
9997
col.finish(true, this.threadService);
10098

10199
// Other interested parties
102-
create(JSONValidationExtensionPoint);
100+
create(JSONValidationExtensionPoint); // TODO@rehost: can survive an ext host restart
103101
create(ColorExtensionPoint);
104-
this.instantiationService.createInstance(LanguageConfigurationFileHandler);
102+
this.instantiationService.createInstance(LanguageConfigurationFileHandler); // TODO@rehost: can survive an ext host restart
105103
create(MainThreadFileSystemEventService);
106104
create(SaveParticipant);
107105
}

src/vs/workbench/api/electron-browser/mainThreadExtensionService.ts

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,20 @@ import { localize } from 'vs/nls';
1111
import * as path from 'path';
1212
import URI from 'vs/base/common/uri';
1313
import { AbstractExtensionService, ActivatedExtension } from 'vs/platform/extensions/common/abstractExtensionService';
14-
import { IMessage, IExtensionDescription, IExtensionsStatus } from 'vs/platform/extensions/common/extensions';
14+
import { IMessage, IExtensionDescription, IExtensionsStatus, IExtensionService } from 'vs/platform/extensions/common/extensions';
1515
import { IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
1616
import { areSameExtensions, getGloballyDisabledExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
1717
import { ExtensionsRegistry, ExtensionPoint, IExtensionPointUser, ExtensionMessageCollector } from 'vs/platform/extensions/common/extensionsRegistry';
1818
import { ExtensionScanner, MessagesCollector } from 'vs/workbench/node/extensionPoints';
1919
import { IMessageService } from 'vs/platform/message/common/message';
20-
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
21-
import { ExtHostContext, ExtHostExtensionServiceShape } from '../node/extHost.protocol';
20+
import { IThreadService, ProxyIdentifier } from 'vs/workbench/services/thread/common/threadService';
21+
import { ExtHostContext, ExtHostExtensionServiceShape, MainProcessExtensionServiceShape } from '../node/extHost.protocol';
2222
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
2323
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
2424
import { IStorageService } from 'vs/platform/storage/common/storage';
25+
import { IInstantiationService } from "vs/platform/instantiation/common/instantiation";
26+
import { ExtensionHostProcessWorker } from "vs/workbench/electron-browser/extensionHost";
27+
import { MainThreadService } from "vs/workbench/services/thread/electron-browser/threadService";
2528

2629
const SystemExtensionsRoot = path.normalize(path.join(URI.parse(require.toUrl('')).fsPath, '..', 'extensions'));
2730

@@ -50,17 +53,18 @@ function messageWithSource(msg: IMessage): string {
5053

5154
const hasOwnProperty = Object.hasOwnProperty;
5255

53-
export class MainProcessExtensionService extends AbstractExtensionService<ActivatedExtension> {
56+
export class MainProcessExtensionService extends AbstractExtensionService<ActivatedExtension> implements IThreadService {
5457

5558
private _proxy: ExtHostExtensionServiceShape;
5659
private _isDev: boolean;
5760
private _extensionsStatus: { [id: string]: IExtensionsStatus };
61+
private _threadService: IThreadService;
5862

5963
/**
6064
* This class is constructed manually because it is a service, so it doesn't use any ctor injection
6165
*/
6266
constructor(
63-
@IThreadService private readonly _threadService: IThreadService,
67+
@IInstantiationService private readonly _instantiationService: IInstantiationService,
6468
@IMessageService private readonly _messageService: IMessageService,
6569
@IEnvironmentService private readonly environmentService: IEnvironmentService,
6670
@ITelemetryService private readonly _telemetryService: ITelemetryService,
@@ -70,9 +74,13 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
7074
super(false);
7175
this._isDev = !environmentService.isBuilt || environmentService.isExtensionDevelopment;
7276

73-
this._proxy = this._threadService.get(ExtHostContext.ExtHostExtensionService);
7477
this._extensionsStatus = {};
7578

79+
const extensionHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker);
80+
this._threadService = this._instantiationService.createInstance(MainThreadService, extensionHostProcessWorker.messagingProtocol);
81+
this._proxy = this._threadService.get(ExtHostContext.ExtHostExtensionService);
82+
extensionHostProcessWorker.start(this);
83+
7684
this.scanExtensions().done(extensionDescriptions => {
7785
const disabledExtensions = [
7886
...getGloballyDisabledExtensions(extensionEnablementService, storageService, extensionDescriptions),
@@ -88,14 +96,29 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
8896
});
8997
}
9098

99+
// ---- begin IThreadService
100+
101+
public get<T>(identifier: ProxyIdentifier<T>): T {
102+
return this._threadService.get(identifier);
103+
}
104+
105+
/**
106+
* Register instance.
107+
*/
108+
public set<T>(identifier: ProxyIdentifier<T>, value: T): void {
109+
this._threadService.set(identifier, value);
110+
}
111+
112+
// ---- end IThreadService
113+
91114
private _handleMessage(msg: IMessage) {
92115

93116
if (!this._extensionsStatus[msg.source]) {
94117
this._extensionsStatus[msg.source] = { messages: [] };
95118
}
96119
this._extensionsStatus[msg.source].messages.push(msg);
97120

98-
this.$localShowMessage(
121+
this._localShowMessage(
99122
msg.type, messageWithSource(msg),
100123
this.environmentService.extensionDevelopmentPath === msg.source
101124
);
@@ -108,7 +131,7 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
108131
}
109132
}
110133

111-
public $localShowMessage(severity: Severity, msg: string, useMessageService: boolean = this._isDev): void {
134+
public _localShowMessage(severity: Severity, msg: string, useMessageService: boolean = this._isDev): void {
112135
// Only show nasty intrusive messages if doing extension development
113136
// and print all other messages to the console
114137
if (useMessageService && (severity === Severity.Error || severity === Severity.Warning)) {
@@ -129,7 +152,7 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
129152
}
130153

131154
protected _showMessage(severity: Severity, msg: string): void {
132-
this.$localShowMessage(severity, msg);
155+
this._localShowMessage(severity, msg);
133156
}
134157

135158
protected _createFailedExtension(): ActivatedExtension {
@@ -180,11 +203,11 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
180203
extensionPoint.acceptUsers(users);
181204
}
182205

183-
public $onExtensionActivated(extensionId: string): void {
206+
public _onExtensionActivated(extensionId: string): void {
184207
this._activatedExtensions[extensionId] = new MainProcessSuccessExtension();
185208
}
186209

187-
public $onExtensionActivationFailed(extensionId: string): void {
210+
public _onExtensionActivationFailed(extensionId: string): void {
188211
this._activatedExtensions[extensionId] = new MainProcessFailedExtension();
189212
}
190213

@@ -223,8 +246,31 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
223246
collector.error('', err);
224247
return [];
225248
}).then(extensions => {
226-
collector.getMessages().forEach(entry => this.$localShowMessage(entry.type, this._isDev ? (entry.source ? '[' + entry.source + ']: ' : '') + entry.message : entry.message));
249+
collector.getMessages().forEach(entry => this._localShowMessage(entry.type, this._isDev ? (entry.source ? '[' + entry.source + ']: ' : '') + entry.message : entry.message));
227250
return extensions;
228251
});
229252
}
230253
}
254+
255+
export class MainProcessExtensionServiceAPI extends MainProcessExtensionServiceShape {
256+
257+
private readonly _extensionService: MainProcessExtensionService;
258+
259+
constructor( @IExtensionService extensionService: IExtensionService) {
260+
super();
261+
262+
if (extensionService instanceof MainProcessExtensionService) {
263+
this._extensionService = extensionService;
264+
}
265+
}
266+
267+
$localShowMessage(severity: Severity, msg: string): void {
268+
this._extensionService._localShowMessage(severity, msg);
269+
}
270+
$onExtensionActivated(extensionId: string): void {
271+
this._extensionService._onExtensionActivated(extensionId);
272+
}
273+
$onExtensionActivationFailed(extensionId: string): void {
274+
this._extensionService._onExtensionActivationFailed(extensionId);
275+
}
276+
}

src/vs/workbench/electron-browser/shell.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import { RequestService } from 'vs/platform/request/electron-browser/requestServ
4040
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
4141
import { SearchService } from 'vs/workbench/services/search/node/searchService';
4242
import { LifecycleService } from 'vs/workbench/services/lifecycle/electron-browser/lifecycleService';
43-
import { MainThreadService } from 'vs/workbench/services/thread/electron-browser/threadService';
4443
import { MarkerService } from 'vs/platform/markers/common/markerService';
4544
import { IModelService } from 'vs/editor/common/services/modelService';
4645
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
@@ -78,7 +77,6 @@ import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net';
7877
import { IExtensionManagementChannel, ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc';
7978
import { IExtensionManagementService, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
8079
import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
81-
import { ExtensionHostProcessWorker } from 'vs/workbench/electron-browser/extensionHost';
8280
import { ITimerService } from 'vs/workbench/services/timer/common/timerService';
8381
import { remote, ipcRenderer as ipc } from 'electron';
8482
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
@@ -117,7 +115,6 @@ export class WorkbenchShell {
117115
private messageService: MessageService;
118116
private environmentService: IEnvironmentService;
119117
private contextViewService: ContextViewService;
120-
private threadService: MainThreadService;
121118
private configurationService: IConfigurationService;
122119
private contextService: IWorkspaceContextService;
123120
private telemetryService: ITelemetryService;
@@ -324,15 +321,11 @@ export class WorkbenchShell {
324321
serviceCollection.set(IExtensionEnablementService, extensionEnablementService);
325322
disposables.push(extensionEnablementService);
326323

327-
const extensionHostProcessWorker = instantiationService.createInstance(ExtensionHostProcessWorker);
328-
this.threadService = instantiationService.createInstance(MainThreadService, extensionHostProcessWorker.messagingProtocol);
329-
serviceCollection.set(IThreadService, this.threadService);
330-
331-
this.timerService.beforeExtensionLoad = Date.now();
332-
333324
this.extensionService = instantiationService.createInstance(MainProcessExtensionService);
334325
serviceCollection.set(IExtensionService, this.extensionService);
335-
extensionHostProcessWorker.start(this.extensionService);
326+
serviceCollection.set(IThreadService, this.extensionService);
327+
328+
this.timerService.beforeExtensionLoad = Date.now();
336329
this.extensionService.onReady().done(() => {
337330
this.timerService.afterExtensionLoad = Date.now();
338331
});

0 commit comments

Comments
 (0)