Fixes #14500: wait for extension points

* Use the extension descriptions available in the UI thread
* Don't wait for handling extension points until extension host is running
* Create the extension host process only after extension points have been handled
* Send the initial configuration as part of the initData to the extension host
This commit is contained in:
Alex Dima
2016-10-26 22:02:47 +02:00
parent d801542057
commit 6dd7a04bbd
11 changed files with 39 additions and 52 deletions

View File

@@ -43,7 +43,7 @@ import * as vscode from 'vscode';
import * as paths from 'vs/base/common/paths';
import { realpathSync } from 'fs';
import { ITelemetryService, ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry';
import { MainContext, ExtHostContext, InstanceCollection } from './extHost.protocol';
import { MainContext, ExtHostContext, InstanceCollection, IInitConfiguration } from './extHost.protocol';
export interface IExtensionApiFactory {
@@ -53,7 +53,7 @@ export interface IExtensionApiFactory {
/**
* This method instantiates and returns the extension API surface
*/
export function createApiFactory(threadService: IThreadService, extensionService: ExtHostExtensionService, contextService: IWorkspaceContextService, telemetryService: ITelemetryService): IExtensionApiFactory {
export function createApiFactory(initDataConfiguration: IInitConfiguration, threadService: IThreadService, extensionService: ExtHostExtensionService, contextService: IWorkspaceContextService, telemetryService: ITelemetryService): IExtensionApiFactory {
@@ -64,7 +64,7 @@ export function createApiFactory(threadService: IThreadService, extensionService
const extHostDocumentSaveParticipant = col.define(ExtHostContext.ExtHostDocumentSaveParticipant).set<ExtHostDocumentSaveParticipant>(new ExtHostDocumentSaveParticipant(extHostDocuments, threadService.get(MainContext.MainThreadWorkspace)));
const extHostEditors = col.define(ExtHostContext.ExtHostEditors).set<ExtHostEditors>(new ExtHostEditors(threadService, extHostDocuments));
const extHostCommands = col.define(ExtHostContext.ExtHostCommands).set<ExtHostCommands>(new ExtHostCommands(threadService, extHostEditors, extHostHeapService));
const extHostConfiguration = col.define(ExtHostContext.ExtHostConfiguration).set<ExtHostConfiguration>(new ExtHostConfiguration(threadService.get(MainContext.MainThreadConfiguration)));
const extHostConfiguration = col.define(ExtHostContext.ExtHostConfiguration).set<ExtHostConfiguration>(new ExtHostConfiguration(threadService.get(MainContext.MainThreadConfiguration), initDataConfiguration));
const extHostDiagnostics = col.define(ExtHostContext.ExtHostDiagnostics).set<ExtHostDiagnostics>(new ExtHostDiagnostics(threadService));
const languageFeatures = col.define(ExtHostContext.ExtHostLanguageFeatures).set<ExtHostLanguageFeatures>(new ExtHostLanguageFeatures(threadService, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics));
const extHostFileSystemEvent = col.define(ExtHostContext.ExtHostFileSystemEventService).set<ExtHostFileSystemEventService>(new ExtHostFileSystemEventService());

View File

@@ -43,6 +43,10 @@ export interface IEnvironment {
extensionTestsPath: string;
}
export interface IInitConfiguration {
_initConfigurationBrand: void;
}
export interface IInitData {
parentPid: number;
environment: IEnvironment;
@@ -50,6 +54,7 @@ export interface IInitData {
workspace: IWorkspace;
};
extensions: IExtensionDescription[];
configuration: IInitConfiguration;
}
export interface InstanceSetter<T> {
@@ -213,7 +218,6 @@ export abstract class MainThreadWorkspaceShape {
}
export abstract class MainProcessExtensionServiceShape {
$onExtensionHostReady(extensionDescriptions: IExtensionDescription[]): TPromise<void> { throw ni(); }
$localShowMessage(severity: Severity, msg: string): void { throw ni(); }
$onExtensionActivated(extensionId: string): void { throw ni(); }
$onExtensionActivationFailed(extensionId: string): void { throw ni(); }

View File

@@ -5,7 +5,6 @@
'use strict';
import { mixin } from 'vs/base/common/objects';
import { illegalState } from 'vs/base/common/errors';
import Event, { Emitter } from 'vs/base/common/event';
import { WorkspaceConfiguration } from 'vscode';
import { ExtHostConfigurationShape, MainThreadConfigurationShape } from './extHost.protocol';
@@ -14,13 +13,13 @@ import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/
export class ExtHostConfiguration extends ExtHostConfigurationShape {
private _proxy: MainThreadConfigurationShape;
private _hasConfig: boolean;
private _config: any;
private _onDidChangeConfiguration = new Emitter<void>();
constructor(proxy: MainThreadConfigurationShape) {
constructor(proxy: MainThreadConfigurationShape, configuration: any) {
super();
this._proxy = proxy;
this._config = configuration;
}
get onDidChangeConfiguration(): Event<void> {
@@ -29,14 +28,10 @@ export class ExtHostConfiguration extends ExtHostConfigurationShape {
public $acceptConfigurationChanged(config: any) {
this._config = config;
this._hasConfig = true;
this._onDidChangeConfiguration.fire(undefined);
}
public getConfiguration(section?: string): WorkspaceConfiguration {
if (!this._hasConfig) {
throw illegalState('missing config');
}
const config = section
? ExtHostConfiguration._lookUp(section, this._config)

View File

@@ -119,7 +119,7 @@ export class ExtHostExtensionService extends AbstractExtensionService<ExtHostExt
* This class is constructed manually because it is a service, so it doesn't use any ctor injection
*/
constructor(availableExtensions: IExtensionDescription[], threadService: IThreadService, telemetryService: ITelemetryService, args: { _serviceBrand: any; workspaceStoragePath: string; }) {
super(false);
super(true);
this._registry.registerExtensions(availableExtensions);
this._threadService = threadService;
this._storage = new ExtHostStorage(threadService);
@@ -186,14 +186,6 @@ export class ExtHostExtensionService extends AbstractExtensionService<ExtHostExt
return result;
}
public registrationDone(): void {
this._proxy.$onExtensionHostReady(this._registry.getAllExtensionDescriptions()).then(() => {
// Wait for the main process to acknowledge its receival of the extensions descriptions
// before allowing extensions to be activated
this._triggerOnReady();
});
}
// -- overwriting AbstractExtensionService
protected _showMessage(severity: Severity, msg: string): void {

View File

@@ -25,7 +25,6 @@ export class MainThreadConfiguration extends MainThreadConfigurationShape {
this._configurationEditingService = configurationEditingService;
const proxy = threadService.get(ExtHostContext.ExtHostConfiguration);
this._toDispose = configurationService.onDidUpdateConfiguration(event => proxy.$acceptConfigurationChanged(event.config));
proxy.$acceptConfigurationChanged(configurationService.getConfiguration());
}
public dispose(): void {

View File

@@ -7,7 +7,7 @@
import Severity from 'vs/base/common/severity';
import { TPromise } from 'vs/base/common/winjs.base';
import { AbstractExtensionService, ActivatedExtension } from 'vs/platform/extensions/common/abstractExtensionService';
import { IMessage, IExtensionDescription, IExtensionsStatus } from 'vs/platform/extensions/common/extensions';
import { IExtensionsRuntimeService, IMessage, IExtensionDescription, IExtensionsStatus } from 'vs/platform/extensions/common/extensions';
import { ExtensionsRegistry, ExtensionPoint, IExtensionPointUser, ExtensionMessageCollector } from 'vs/platform/extensions/common/extensionsRegistry';
import { IMessageService } from 'vs/platform/message/common/message';
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
@@ -53,7 +53,8 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
constructor(
@IThreadService threadService: IThreadService,
@IMessageService messageService: IMessageService,
@IEnvironmentService private environmentService: IEnvironmentService
@IEnvironmentService private environmentService: IEnvironmentService,
@IExtensionsRuntimeService extensionsRuntimeService: IExtensionsRuntimeService
) {
super(false);
this._isDev = !environmentService.isBuilt || !!environmentService.extensionDevelopmentPath;
@@ -62,6 +63,8 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
this._threadService = threadService;
this._proxy = this._threadService.get(ExtHostContext.ExtHostExtensionService);
this._extensionsStatus = {};
extensionsRuntimeService.getExtensions().then((extensionDescriptions) => this._onExtensionDescriptions(extensionDescriptions));
}
private _handleMessage(msg: IMessage) {
@@ -124,7 +127,7 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
// -- called by extension host
public $onExtensionHostReady(extensionDescriptions: IExtensionDescription[]): TPromise<void> {
private _onExtensionDescriptions(extensionDescriptions: IExtensionDescription[]): void {
this._registry.registerExtensions(extensionDescriptions);
let availableExtensions = this._registry.getAllExtensionDescriptions();
@@ -135,7 +138,6 @@ export class MainProcessExtensionService extends AbstractExtensionService<Activa
}
this._triggerOnReady();
return;
}
private _handleExtensionPoint<T>(extensionPoint: ExtensionPoint<T>, availableExtensions: IExtensionDescription[]): void {