diff --git a/src/vs/editor/common/services/modeServiceImpl.ts b/src/vs/editor/common/services/modeServiceImpl.ts index 0b69fed633b..ffb1424db08 100644 --- a/src/vs/editor/common/services/modeServiceImpl.ts +++ b/src/vs/editor/common/services/modeServiceImpl.ts @@ -12,7 +12,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import mime = require('vs/base/common/mime'); import { IFilesConfiguration } from 'vs/platform/files/common/files'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; -import { IExtensionPoint, IExtensionPointUser, IExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; +import { IExtensionPoint, IExtensionPointUser, ExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import * as modes from 'vs/editor/common/modes'; import { FrankensteinMode } from 'vs/editor/common/modes/abstractMode'; @@ -94,7 +94,7 @@ function isUndefinedOrStringArray(value: string[]): boolean { return value.every(item => typeof item === 'string'); } -function isValidLanguageExtensionPoint(value: ILanguageExtensionPoint, collector: IExtensionMessageCollector): boolean { +function isValidLanguageExtensionPoint(value: ILanguageExtensionPoint, collector: ExtensionMessageCollector): boolean { if (!value) { collector.error(nls.localize('invalid.empty', "Empty value for `contributes.{0}`", languagesExtPoint.name)); return false; diff --git a/src/vs/editor/node/textMate/TMSnippets.ts b/src/vs/editor/node/textMate/TMSnippets.ts index 15b203a575e..40273eca78d 100644 --- a/src/vs/editor/node/textMate/TMSnippets.ts +++ b/src/vs/editor/node/textMate/TMSnippets.ts @@ -9,7 +9,7 @@ import { parse } from 'vs/base/common/json'; import * as paths from 'vs/base/common/paths'; import { TPromise } from 'vs/base/common/winjs.base'; import { readFile } from 'vs/base/node/pfs'; -import { IExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; +import { ExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; import { ISnippetsRegistry, Extensions, ISnippet } from 'vs/editor/common/modes/snippetsRegistry'; import { IModeService } from 'vs/editor/common/services/modeService'; import platform = require('vs/platform/platform'); @@ -56,7 +56,7 @@ export class MainProcessTextMateSnippet { }); } - private _withSnippetContribution(extensionName: string, extensionFolderPath: string, snippet: ISnippetsExtensionPoint, collector: IExtensionMessageCollector): void { + private _withSnippetContribution(extensionName: string, extensionFolderPath: string, snippet: ISnippetsExtensionPoint, collector: ExtensionMessageCollector): void { if (!snippet.language || (typeof snippet.language !== 'string') || !this._modeService.isRegisteredMode(snippet.language)) { collector.error(nls.localize('invalid.language', "Unknown language in `contributes.{0}.language`. Provided value: {1}", snippetsExtensionPoint.name, String(snippet.language))); return; diff --git a/src/vs/editor/node/textMate/TMSyntax.ts b/src/vs/editor/node/textMate/TMSyntax.ts index 188e53df270..3c27507a5b0 100644 --- a/src/vs/editor/node/textMate/TMSyntax.ts +++ b/src/vs/editor/node/textMate/TMSyntax.ts @@ -9,7 +9,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import * as paths from 'vs/base/common/paths'; import * as strings from 'vs/base/common/strings'; import Event, { Emitter } from 'vs/base/common/event'; -import { IExtensionPoint, IExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; +import { IExtensionPoint, ExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; import { ILineTokens, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/modes'; import { TMState } from 'vs/editor/common/modes/TMState'; import { LineTokens } from 'vs/editor/common/modes/supports'; @@ -163,7 +163,7 @@ export class MainProcessTextMateSyntax { }); } - private _handleGrammarExtensionPointUser(extensionFolderPath: string, syntax: ITMSyntaxExtensionPoint, collector: IExtensionMessageCollector): void { + private _handleGrammarExtensionPointUser(extensionFolderPath: string, syntax: ITMSyntaxExtensionPoint, collector: ExtensionMessageCollector): void { if (syntax.language && ((typeof syntax.language !== 'string') || !this._modeService.isRegisteredMode(syntax.language))) { collector.error(nls.localize('invalid.language', "Unknown language in `contributes.{0}.language`. Provided value: {1}", grammarsExtPoint.name, String(syntax.language))); return; diff --git a/src/vs/platform/actions/browser/menusExtensionPoint.ts b/src/vs/platform/actions/browser/menusExtensionPoint.ts index c1526a461e1..9bfc70e8d83 100644 --- a/src/vs/platform/actions/browser/menusExtensionPoint.ts +++ b/src/vs/platform/actions/browser/menusExtensionPoint.ts @@ -11,7 +11,7 @@ import { join } from 'vs/base/common/paths'; import { IdGenerator } from 'vs/base/common/idGenerator'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { forEach } from 'vs/base/common/collections'; -import { IExtensionPointUser, IExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; +import { IExtensionPointUser, ExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; @@ -35,7 +35,7 @@ namespace schema { } } - export function isValidMenuItems(menu: IUserFriendlyMenuItem[], collector: IExtensionMessageCollector): boolean { + export function isValidMenuItems(menu: IUserFriendlyMenuItem[], collector: ExtensionMessageCollector): boolean { if (!Array.isArray(menu)) { collector.error(localize('requirearry', "menu items must be an arry")); return false; @@ -123,7 +123,7 @@ namespace schema { export type IUserFriendlyIcon = string | { light: string; dark: string; }; - export function isValidCommand(command: IUserFriendlyCommand, collector: IExtensionMessageCollector): boolean { + export function isValidCommand(command: IUserFriendlyCommand, collector: ExtensionMessageCollector): boolean { if (!command) { collector.error(localize('nonempty', "expected non-empty value.")); return false; @@ -146,7 +146,7 @@ namespace schema { return true; } - function isValidIcon(icon: IUserFriendlyIcon, collector: IExtensionMessageCollector): boolean { + function isValidIcon(icon: IUserFriendlyIcon, collector: ExtensionMessageCollector): boolean { if (typeof icon === 'undefined') { return true; } diff --git a/src/vs/platform/extensions/common/abstractExtensionService.ts b/src/vs/platform/extensions/common/abstractExtensionService.ts index e881a3b2e23..bb27a525222 100644 --- a/src/vs/platform/extensions/common/abstractExtensionService.ts +++ b/src/vs/platform/extensions/common/abstractExtensionService.ts @@ -8,7 +8,7 @@ import * as nls from 'vs/nls'; import Severity from 'vs/base/common/severity'; import { TPromise } from 'vs/base/common/winjs.base'; import { IExtensionDescription, IExtensionService, IExtensionsStatus, ExtensionPointContribution } from 'vs/platform/extensions/common/extensions'; -import { IExtensionPoint, ExtensionsRegistry, onWillActivate } from 'vs/platform/extensions/common/extensionsRegistry'; +import { IExtensionPoint, onWillActivate } from 'vs/platform/extensions/common/extensionsRegistry'; const hasOwnProperty = Object.hasOwnProperty; @@ -35,6 +35,7 @@ export abstract class AbstractExtensionService imp protected _activatedExtensions: IActivatedExtensionMap; private _onReady: TPromise; private _onReadyC: (v: boolean) => void; + protected _registry: ExtensionDescriptionRegistry; constructor(isReadyByDefault: boolean) { if (isReadyByDefault) { @@ -49,6 +50,7 @@ export abstract class AbstractExtensionService imp } this._activatingExtensions = {}; this._activatedExtensions = {}; + this._registry = new ExtensionDescriptionRegistry(); } protected _triggerOnReady(): void { @@ -61,7 +63,7 @@ export abstract class AbstractExtensionService imp public readExtensionPointContributions(extPoint: IExtensionPoint): TPromise[]> { return this.onReady().then(() => { - let availableExtensions = ExtensionsRegistry.getAllExtensionDescriptions(); + let availableExtensions = this._registry.getAllExtensionDescriptions(); let result: ExtensionPointContribution[] = [], resultLen = 0; for (let i = 0, len = availableExtensions.length; i < len; i++) { @@ -87,14 +89,14 @@ export abstract class AbstractExtensionService imp public activateByEvent(activationEvent: string): TPromise { return this._onReady.then(() => { onWillActivate.fire(activationEvent); - let activateExtensions = ExtensionsRegistry.getExtensionDescriptionsForActivationEvent(activationEvent); + let activateExtensions = this._registry.getExtensionDescriptionsForActivationEvent(activationEvent); return this._activateExtensions(activateExtensions, 0); }); } public activateById(extensionId: string): TPromise { return this._onReady.then(() => { - let desc = ExtensionsRegistry.getExtensionDescription(extensionId); + let desc = this._registry.getExtensionDescription(extensionId); if (!desc) { throw new Error('Extension `' + extensionId + '` is not known'); } @@ -113,7 +115,7 @@ export abstract class AbstractExtensionService imp for (let j = 0, lenJ = depIds.length; j < lenJ; j++) { let depId = depIds[j]; - let depDesc = ExtensionsRegistry.getExtensionDescription(depId); + let depDesc = this._registry.getExtensionDescription(depId); if (!depDesc) { // Error condition 1: unknown dependency @@ -223,3 +225,61 @@ export abstract class AbstractExtensionService imp protected abstract _actualActivateExtension(extensionDescription: IExtensionDescription): TPromise; } + + +interface IExtensionDescriptionMap { + [extensionId: string]: IExtensionDescription; +} + +export class ExtensionDescriptionRegistry { + private _extensionsMap: IExtensionDescriptionMap; + private _extensionsArr: IExtensionDescription[]; + private _activationMap: { [activationEvent: string]: IExtensionDescription[]; }; + + constructor() { + this._extensionsMap = {}; + this._extensionsArr = []; + this._activationMap = {}; + } + + public registerExtensions(extensionDescriptions: IExtensionDescription[]): void { + for (let i = 0, len = extensionDescriptions.length; i < len; i++) { + let extensionDescription = extensionDescriptions[i]; + + if (hasOwnProperty.call(this._extensionsMap, extensionDescription.id)) { + // No overwriting allowed! + console.error('Extension `' + extensionDescription.id + '` is already registered'); + continue; + } + + this._extensionsMap[extensionDescription.id] = extensionDescription; + this._extensionsArr.push(extensionDescription); + + if (Array.isArray(extensionDescription.activationEvents)) { + for (let j = 0, lenJ = extensionDescription.activationEvents.length; j < lenJ; j++) { + let activationEvent = extensionDescription.activationEvents[j]; + this._activationMap[activationEvent] = this._activationMap[activationEvent] || []; + this._activationMap[activationEvent].push(extensionDescription); + } + } + } + } + + public getExtensionDescriptionsForActivationEvent(activationEvent: string): IExtensionDescription[] { + if (!hasOwnProperty.call(this._activationMap, activationEvent)) { + return []; + } + return this._activationMap[activationEvent].slice(0); + } + + public getAllExtensionDescriptions(): IExtensionDescription[] { + return this._extensionsArr.slice(0); + } + + public getExtensionDescription(extensionId: string): IExtensionDescription { + if (!hasOwnProperty.call(this._extensionsMap, extensionId)) { + return null; + } + return this._extensionsMap[extensionId]; + } +} diff --git a/src/vs/platform/extensions/common/extensionsRegistry.ts b/src/vs/platform/extensions/common/extensionsRegistry.ts index 638522732af..a5d19f5bc6a 100644 --- a/src/vs/platform/extensions/common/extensionsRegistry.ts +++ b/src/vs/platform/extensions/common/extensionsRegistry.ts @@ -13,15 +13,12 @@ import { Extensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/c import { Registry } from 'vs/platform/platform'; import { Emitter } from 'vs/base/common/event'; +const hasOwnProperty = Object.hasOwnProperty; +const schemaRegistry = Registry.as(Extensions.JSONContribution); + export const onWillActivate: Emitter = new Emitter(); -export interface IExtensionMessageCollector { - error(message: string): void; - warn(message: string): void; - info(message: string): void; -} - -export class ExtensionMessageCollector implements IExtensionMessageCollector { +export class ExtensionMessageCollector { private _messageHandler: (msg: IMessage) => void; private _source: string; @@ -50,21 +47,12 @@ export class ExtensionMessageCollector implements IExtensionMessageCollector { public info(message: string): void { this._msg(Severity.Info, message); } - } - - -interface IExtensionDescriptionMap { - [extensionId: string]: IExtensionDescription; -} -const hasOwnProperty = Object.hasOwnProperty; -let schemaRegistry = Registry.as(Extensions.JSONContribution); - export interface IExtensionPointUser { description: IExtensionDescription; value: T; - collector: IExtensionMessageCollector; + collector: ExtensionMessageCollector; } export interface IExtensionPointHandler { @@ -76,17 +64,6 @@ export interface IExtensionPoint { setHandler(handler: IExtensionPointHandler): void; } -export interface IExtensionsRegistry { - registerExtensions(extensionDescriptions: IExtensionDescription[]): void; - - getExtensionDescriptionsForActivationEvent(activationEvent: string): IExtensionDescription[]; - getAllExtensionDescriptions(): IExtensionDescription[]; - getExtensionDescription(extensionId: string): IExtensionDescription; - - registerExtensionPoint(extensionPoint: string, deps: IExtensionPoint[], jsonSchema: IJSONSchema): IExtensionPoint; - getExtensionPoints(): ExtensionPoint[]; -} - export class ExtensionPoint implements IExtensionPoint { public readonly name: string; @@ -137,8 +114,6 @@ export class ExtensionPoint implements IExtensionPoint { } } - - const schemaId = 'vscode://schemas/vscode-extensions'; const schema: IJSONSchema = { default: { @@ -257,17 +232,11 @@ const schema: IJSONSchema = { } }; -class ExtensionsRegistryImpl implements IExtensionsRegistry { +export class ExtensionsRegistryImpl { - private _extensionsMap: IExtensionDescriptionMap; - private _extensionsArr: IExtensionDescription[]; - private _activationMap: { [activationEvent: string]: IExtensionDescription[]; }; private _extensionPoints: { [extPoint: string]: ExtensionPoint; }; constructor() { - this._extensionsMap = {}; - this._extensionsArr = []; - this._activationMap = {}; this._extensionPoints = {}; } @@ -287,54 +256,12 @@ class ExtensionsRegistryImpl implements IExtensionsRegistry { public getExtensionPoints(): ExtensionPoint[] { return Object.keys(this._extensionPoints).map(point => this._extensionPoints[point]); } - - public registerExtensions(extensionDescriptions: IExtensionDescription[]): void { - for (let i = 0, len = extensionDescriptions.length; i < len; i++) { - let extensionDescription = extensionDescriptions[i]; - - if (hasOwnProperty.call(this._extensionsMap, extensionDescription.id)) { - // No overwriting allowed! - console.error('Extension `' + extensionDescription.id + '` is already registered'); - continue; - } - - this._extensionsMap[extensionDescription.id] = extensionDescription; - this._extensionsArr.push(extensionDescription); - - if (Array.isArray(extensionDescription.activationEvents)) { - for (let j = 0, lenJ = extensionDescription.activationEvents.length; j < lenJ; j++) { - let activationEvent = extensionDescription.activationEvents[j]; - this._activationMap[activationEvent] = this._activationMap[activationEvent] || []; - this._activationMap[activationEvent].push(extensionDescription); - } - } - } - } - - public getExtensionDescriptionsForActivationEvent(activationEvent: string): IExtensionDescription[] { - if (!hasOwnProperty.call(this._activationMap, activationEvent)) { - return []; - } - return this._activationMap[activationEvent].slice(0); - } - - public getAllExtensionDescriptions(): IExtensionDescription[] { - return this._extensionsArr.slice(0); - } - - public getExtensionDescription(extensionId: string): IExtensionDescription { - if (!hasOwnProperty.call(this._extensionsMap, extensionId)) { - return null; - } - return this._extensionsMap[extensionId]; - } } - const PRExtensions = { ExtensionsRegistry: 'ExtensionsRegistry' }; Registry.add(PRExtensions.ExtensionsRegistry, new ExtensionsRegistryImpl()); -export const ExtensionsRegistry: IExtensionsRegistry = Registry.as(PRExtensions.ExtensionsRegistry); +export const ExtensionsRegistry: ExtensionsRegistryImpl = Registry.as(PRExtensions.ExtensionsRegistry); schemaRegistry.registerSchema(schemaId, schema); \ No newline at end of file diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 060ac66a02f..b3bbfb536be 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -36,7 +36,6 @@ import Severity from 'vs/base/common/severity'; import EditorCommon = require('vs/editor/common/editorCommon'); import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; -import { ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; import { TPromise } from 'vs/base/common/winjs.base'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; @@ -143,13 +142,13 @@ export function createApiFactory(threadService: IThreadService, extensionService // namespace: extensions const extensions: typeof vscode.extensions = { getExtension(extensionId: string): Extension { - let desc = ExtensionsRegistry.getExtensionDescription(extensionId); + let desc = extensionService.getExtensionDescription(extensionId); if (desc) { return new Extension(extensionService, desc); } }, get all(): Extension[] { - return ExtensionsRegistry.getAllExtensionDescriptions().map((desc) => new Extension(extensionService, desc)); + return extensionService.getAllExtensionDescriptions().map((desc) => new Extension(extensionService, desc)); } }; @@ -417,7 +416,7 @@ class Extension implements vscode.Extension { } } -export function defineAPI(factory: IExtensionApiFactory, extensions: IExtensionDescription[]): void { +export function defineAPI(factory: IExtensionApiFactory, extensionService: ExtHostExtensionService): void { // each extension is meant to get its own api implementation const extApiImpl: { [id: string]: typeof vscode } = Object.create(null); @@ -425,6 +424,7 @@ export function defineAPI(factory: IExtensionApiFactory, extensions: IExtensionD // create trie to enable fast 'filename -> extension id' look up const trie = new TrieMap(TrieMap.PathSplitter); + const extensions = extensionService.getAllExtensionDescriptions(); for (const ext of extensions) { if (ext.name) { const path = realpathSync(ext.extensionFolderPath); diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 13781f3a5e4..bc7bf0c2e0a 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -22,6 +22,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions' import { StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/platform/statusbar/common/statusbar'; import { ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry'; import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands'; +import { IWorkspace } from 'vs/platform/workspace/common/workspace'; import * as editorCommon from 'vs/editor/common/editorCommon'; import * as modes from 'vs/editor/common/modes'; @@ -34,6 +35,23 @@ import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; import { IWorkspaceSymbol } from 'vs/workbench/parts/search/common/search'; import { IApplyEditsOptions, TextEditorRevealType, ITextEditorConfigurationUpdate, IResolvedTextEditorConfiguration, ISelectionChangeEvent } from './mainThreadEditorsTracker'; +export interface IEnvironment { + appSettingsHome: string; + disableExtensions: boolean; + userExtensionsHome: string; + extensionDevelopmentPath: string; + extensionTestsPath: string; +} + +export interface IInitData { + parentPid: number; + environment: IEnvironment; + contextService: { + workspace: IWorkspace; + }; + extensions: IExtensionDescription[]; +} + export interface InstanceSetter { set(instance: T): R; } diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index be1ed872a91..8a0f2016c00 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -11,7 +11,6 @@ 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 { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; import { ExtHostStorage } from 'vs/workbench/api/node/extHostStorage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThreadService } from 'vs/workbench/services/thread/common/threadService'; @@ -119,8 +118,9 @@ export class ExtHostExtensionService extends AbstractExtensionService { + 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(); diff --git a/src/vs/workbench/api/node/mainThreadExtensionService.ts b/src/vs/workbench/api/node/mainThreadExtensionService.ts index 03ddce9e31f..eb2f6954a0c 100644 --- a/src/vs/workbench/api/node/mainThreadExtensionService.ts +++ b/src/vs/workbench/api/node/mainThreadExtensionService.ts @@ -125,9 +125,9 @@ export class MainProcessExtensionService extends AbstractExtensionService { - ExtensionsRegistry.registerExtensions(extensionDescriptions); + this._registry.registerExtensions(extensionDescriptions); - let availableExtensions = ExtensionsRegistry.getAllExtensionDescriptions(); + let availableExtensions = this._registry.getAllExtensionDescriptions(); let extensionPoints = ExtensionsRegistry.getExtensionPoints(); for (let i = 0, len = extensionPoints.length; i < len; i++) { diff --git a/src/vs/workbench/node/extensionHostMain.ts b/src/vs/workbench/node/extensionHostMain.ts index eb74c8d62ad..29216aec2f9 100644 --- a/src/vs/workbench/node/extensionHostMain.ts +++ b/src/vs/workbench/node/extensionHostMain.ts @@ -11,34 +11,15 @@ import nls = require('vs/nls'); import pfs = require('vs/base/node/pfs'); import { TPromise } from 'vs/base/common/winjs.base'; import paths = require('vs/base/common/paths'); -import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; import { createApiFactory, defineAPI } from 'vs/workbench/api/node/extHost.api.impl'; import { IMainProcessExtHostIPC } from 'vs/platform/extensions/common/ipcRemoteCom'; import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; import { ExtHostThreadService } from 'vs/workbench/services/thread/common/extHostThreadService'; import { RemoteTelemetryService } from 'vs/workbench/api/node/extHostTelemetry'; import { IWorkspaceContextService, WorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IInitData, IEnvironment } from 'vs/workbench/api/node/extHost.protocol'; import * as errors from 'vs/base/common/errors'; -export interface IEnvironment { - appSettingsHome: string; - disableExtensions: boolean; - userExtensionsHome: string; - extensionDevelopmentPath: string; - extensionTestsPath: string; -} - -export interface IInitData { - environment: IEnvironment; - threadService: any; - contextService: { - workspace: any; - options: any; - }; - extensions: IExtensionDescription[]; -} - const nativeExit = process.exit.bind(process); process.exit = function () { const err = new Error('An extension called process.exit() and this was prevented.'); @@ -58,13 +39,11 @@ export class ExtensionHostMain { private _contextService: IWorkspaceContextService; private _environment: IEnvironment; private _extensionService: ExtHostExtensionService; - private _extensions: IExtensionDescription[]; constructor(remoteCom: IMainProcessExtHostIPC, initData: IInitData) { this._isTerminating = false; this._environment = initData.environment; - this._extensions = initData.extensions; this._contextService = new WorkspaceContextService(initData.contextService.workspace); const workspaceStoragePath = this._getOrCreateWorkspaceStoragePath(); @@ -73,11 +52,11 @@ export class ExtensionHostMain { const telemetryService = new RemoteTelemetryService('pluginHostTelemetry', threadService); - this._extensionService = new ExtHostExtensionService(threadService, telemetryService, { _serviceBrand: 'optionalArgs', workspaceStoragePath }); + this._extensionService = new ExtHostExtensionService(initData.extensions, threadService, telemetryService, { _serviceBrand: 'optionalArgs', workspaceStoragePath }); // Create the ext host API const factory = createApiFactory(threadService, this._extensionService, this._contextService, telemetryService); - defineAPI(factory, this._extensions); + defineAPI(factory, this._extensionService); } private _getOrCreateWorkspaceStoragePath(): string { @@ -144,7 +123,7 @@ export class ExtensionHostMain { let allPromises: TPromise[] = []; try { - let allExtensions = ExtensionsRegistry.getAllExtensionDescriptions(); + let allExtensions = this._extensionService.getAllExtensionDescriptions(); let allExtensionsIds = allExtensions.map(ext => ext.id); let activatedExtensions = allExtensionsIds.filter(id => this._extensionService.isActivated(id)); @@ -164,7 +143,6 @@ export class ExtensionHostMain { } private registerExtensions(): TPromise { - ExtensionsRegistry.registerExtensions(this._extensions); this._extensionService.registrationDone(); return this.handleEagerExtensions().then(() => this.handleExtensionTests()); } @@ -189,7 +167,7 @@ export class ExtensionHostMain { [filename: string]: boolean; } = {}; - ExtensionsRegistry.getAllExtensionDescriptions().forEach((desc) => { + this._extensionService.getAllExtensionDescriptions().forEach((desc) => { let activationEvents = desc.activationEvents; if (!activationEvents) { return; diff --git a/src/vs/workbench/node/extensionHostProcess.ts b/src/vs/workbench/node/extensionHostProcess.ts index e33e1cc82d7..726c7231287 100644 --- a/src/vs/workbench/node/extensionHostProcess.ts +++ b/src/vs/workbench/node/extensionHostProcess.ts @@ -7,10 +7,11 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { TPromise } from 'vs/base/common/winjs.base'; -import { ExtensionHostMain, IInitData, exit } from 'vs/workbench/node/extensionHostMain'; +import { ExtensionHostMain, exit } from 'vs/workbench/node/extensionHostMain'; import { create as createIPC, IMainProcessExtHostIPC } from 'vs/platform/extensions/common/ipcRemoteCom'; import marshalling = require('vs/base/common/marshalling'); import { createQueuedSender } from 'vs/base/node/processes'; +import { IInitData } from 'vs/workbench/api/node/extHost.protocol'; interface IRendererConnection { remoteCom: IMainProcessExtHostIPC; diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 5c560a357b8..3feb264e282 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -26,6 +26,7 @@ import { IExtensionsRuntimeService } from 'vs/platform/extensions/common/extensi import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import Event, { Emitter } from 'vs/base/common/event'; import { createQueuedSender, IQueuedSender } from 'vs/base/node/processes'; +import { IInitData } from 'vs/workbench/api/node/extHost.protocol'; export const EXTENSION_LOG_BROADCAST_CHANNEL = 'vscode:extensionLog'; export const EXTENSION_ATTACH_BROADCAST_CHANNEL = 'vscode:extensionAttach'; @@ -200,7 +201,7 @@ export class ExtensionHostProcessWorker { window.clearTimeout(this.initializeTimer); } this.extensionsRuntimeService.getExtensions().then(extensionDescriptors => { - let initPayload = stringify({ + let initData: IInitData = { parentPid: process.pid, environment: { appSettingsHome: this.environmentService.appSettingsHome, @@ -213,8 +214,8 @@ export class ExtensionHostProcessWorker { workspace: this.contextService.getWorkspace() }, extensions: extensionDescriptors - }); - this.extensionHostProcessQueuedSender.send(initPayload); + }; + this.extensionHostProcessQueuedSender.send(stringify(initData)); }); } diff --git a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts index c23b460f0b5..c64fd9f4d05 100644 --- a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts @@ -10,7 +10,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { Keybinding } from 'vs/base/common/keybinding'; import * as platform from 'vs/base/common/platform'; import { toDisposable } from 'vs/base/common/lifecycle'; -import { IExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; +import { ExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; import { Extensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { KeybindingService } from 'vs/platform/keybinding/browser/keybindingServiceImpl'; import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; @@ -203,7 +203,7 @@ export class WorkbenchKeybindingService extends KeybindingService { return super.getElectronAcceleratorFor(keybinding); } - private _handleKeybindingsExtensionPointUser(isBuiltin: boolean, keybindings: ContributedKeyBinding | ContributedKeyBinding[], collector: IExtensionMessageCollector): boolean { + private _handleKeybindingsExtensionPointUser(isBuiltin: boolean, keybindings: ContributedKeyBinding | ContributedKeyBinding[], collector: ExtensionMessageCollector): boolean { if (isContributedKeyBindingsArray(keybindings)) { let commandAdded = false; for (let i = 0, len = keybindings.length; i < len; i++) { @@ -215,7 +215,7 @@ export class WorkbenchKeybindingService extends KeybindingService { } } - private _handleKeybinding(isBuiltin: boolean, idx: number, keybindings: ContributedKeyBinding, collector: IExtensionMessageCollector): boolean { + private _handleKeybinding(isBuiltin: boolean, idx: number, keybindings: ContributedKeyBinding, collector: ExtensionMessageCollector): boolean { let rejects: string[] = []; let commandAdded = false; diff --git a/src/vs/workbench/services/themes/electron-browser/themeService.ts b/src/vs/workbench/services/themes/electron-browser/themeService.ts index a6e82bcfc1f..604ed663470 100644 --- a/src/vs/workbench/services/themes/electron-browser/themeService.ts +++ b/src/vs/workbench/services/themes/electron-browser/themeService.ts @@ -10,7 +10,7 @@ import Paths = require('vs/base/common/paths'); import Json = require('vs/base/common/json'); import { IThemeExtensionPoint } from 'vs/platform/theme/common/themeExtensionPoint'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; -import { ExtensionsRegistry, IExtensionMessageCollector } from 'vs/platform/extensions/common/extensionsRegistry'; +import { ExtensionsRegistry, ExtensionMessageCollector } from 'vs/platform/extensions/common/extensionsRegistry'; import { IThemeService, IThemeData, IThemeSetting, IThemeDocument } from 'vs/workbench/services/themes/common/themeService'; import { TokenStylesContribution, EditorStylesContribution, SearchViewStylesContribution, TerminalStylesContribution } from 'vs/workbench/services/themes/electron-browser/stylesContributions'; import { getBaseThemeId } from 'vs/platform/theme/common/themes'; @@ -299,7 +299,7 @@ export class ThemeService implements IThemeService { }); } - private onThemes(extensionFolderPath: string, extensionData: ExtensionData, themes: IThemeExtensionPoint[], collector: IExtensionMessageCollector): void { + private onThemes(extensionFolderPath: string, extensionData: ExtensionData, themes: IThemeExtensionPoint[], collector: ExtensionMessageCollector): void { if (!Array.isArray(themes)) { collector.error(nls.localize( 'reqarray', @@ -338,7 +338,7 @@ export class ThemeService implements IThemeService { }); } - private onIconThemes(extensionFolderPath: string, extensionData: ExtensionData, iconThemes: IThemeExtensionPoint[], collector: IExtensionMessageCollector): void { + private onIconThemes(extensionFolderPath: string, extensionData: ExtensionData, iconThemes: IThemeExtensionPoint[], collector: ExtensionMessageCollector): void { if (!Array.isArray(iconThemes)) { collector.error(nls.localize( 'reqarray',