mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-24 18:49:00 +01:00
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:
@@ -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());
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user