diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index 6a435ed4660..647478faf8b 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -14,13 +14,13 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { IFolderQuery, IPatternInfo, ISearchConfiguration, ISearchProgressItem, ISearchService, QueryType, IFileQuery, IFileMatch } from 'vs/platform/search/common/search'; import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; import { IWindowService } from 'vs/platform/windows/common/windows'; -import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, WorkbenchState, IWorkspace } from 'vs/platform/workspace/common/workspace'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { QueryBuilder, ITextQueryBuilderOptions } from 'vs/workbench/parts/search/common/queryBuilder'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; -import { ExtHostContext, ExtHostWorkspaceShape, IExtHostContext, MainContext, MainThreadWorkspaceShape } from '../node/extHost.protocol'; +import { ExtHostContext, ExtHostWorkspaceShape, IExtHostContext, MainContext, MainThreadWorkspaceShape, IWorkspaceData } from '../node/extHost.protocol'; import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation'; import { TextSearchComplete } from 'vscode'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; @@ -45,6 +45,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { @ILabelService private readonly _labelService: ILabelService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostWorkspace); + this._contextService.getCompleteWorkspace().then(workspace => this._proxy.$initializeWorkspace(this.getWorkspaceData(workspace))); this._contextService.onDidChangeWorkspaceFolders(this._onDidChangeWorkspace, this, this._toDispose); this._contextService.onDidChangeWorkbenchState(this._onDidChangeWorkspace, this, this._toDispose); } @@ -102,13 +103,19 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { } private _onDidChangeWorkspace(): void { - const workspace = this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : this._contextService.getWorkspace(); - this._proxy.$acceptWorkspaceData(workspace ? { + this._proxy.$acceptWorkspaceData(this.getWorkspaceData(this._contextService.getWorkspace())); + } + + private getWorkspaceData(workspace: IWorkspace): IWorkspaceData | null { + if (this._contextService.getWorkbenchState() === WorkbenchState.EMPTY) { + return null; + } + return { configuration: workspace.configuration, folders: workspace.folders, id: workspace.id, name: this._labelService.getWorkspaceLabel(workspace) - } : null); + }; } // --- search --- diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 249c88fa891..9495cc980d5 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -58,7 +58,7 @@ import * as extHostTypes from 'vs/workbench/api/node/extHostTypes'; import { ExtHostUrls } from 'vs/workbench/api/node/extHostUrls'; import { ExtHostWebviews } from 'vs/workbench/api/node/extHostWebview'; import { ExtHostWindow } from 'vs/workbench/api/node/extHostWindow'; -import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; +import { ExtHostWorkspace, ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace'; import { IExtensionDescription, throwProposedApiError, checkProposedApiEnabled, nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/node/extensionDescriptionRegistry'; @@ -66,7 +66,7 @@ import * as vscode from 'vscode'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; export interface IExtensionApiFactory { - (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; + (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, workspaceProvider: ExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider): typeof vscode; } function proposedApiFunction(extension: IExtensionDescription, fn: T): T { @@ -142,7 +142,7 @@ export function createApiFactory( // Register API-ish commands ExtHostApiCommands.register(extHostCommands); - return function (extension: IExtensionDescription, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode { + return function (extension: IExtensionDescription, extensionRegistry: ExtensionDescriptionRegistry, workspaceProvider: ExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider): typeof vscode { // Check document selectors for being overly generic. Technically this isn't a problem but // in practice many extensions say they support `fooLang` but need fs-access to do so. Those @@ -505,34 +505,34 @@ export function createApiFactory( // namespace: workspace const workspace: typeof vscode.workspace = { get rootPath() { - return extHostWorkspace.getPath(); + return workspaceProvider.getPath(); }, set rootPath(value) { throw errors.readonly(); }, getWorkspaceFolder(resource) { - return extHostWorkspace.getWorkspaceFolder(resource); + return workspaceProvider.getWorkspaceFolder(resource); }, get workspaceFolders() { - return extHostWorkspace.getWorkspaceFolders(); + return workspaceProvider.getWorkspaceFolders(); }, get name() { - return extHostWorkspace.name; + return workspaceProvider.name; }, set name(value) { throw errors.readonly(); }, updateWorkspaceFolders: (index, deleteCount, ...workspaceFoldersToAdd) => { - return extHostWorkspace.updateWorkspaceFolders(extension, index, deleteCount || 0, ...workspaceFoldersToAdd); + return workspaceProvider.updateWorkspaceFolders(extension, index, deleteCount || 0, ...workspaceFoldersToAdd); }, onDidChangeWorkspaceFolders: function (listener, thisArgs?, disposables?) { - return extHostWorkspace.onDidChangeWorkspace(listener, thisArgs, disposables); + return workspaceProvider.onDidChangeWorkspace(listener, thisArgs, disposables); }, asRelativePath: (pathOrUri, includeWorkspace) => { - return extHostWorkspace.getRelativePath(pathOrUri, includeWorkspace); + return workspaceProvider.getRelativePath(pathOrUri, includeWorkspace); }, findFiles: (include, exclude, maxResults?, token?) => { - return extHostWorkspace.findFiles(typeConverters.GlobPattern.from(include), typeConverters.GlobPattern.from(exclude), maxResults, extension.identifier, token); + return workspaceProvider.findFiles(typeConverters.GlobPattern.from(include), typeConverters.GlobPattern.from(exclude), maxResults, extension.identifier, token); }, findTextInFiles: (query: vscode.TextSearchQuery, optionsOrCallback, callbackOrToken?, token?: vscode.CancellationToken) => { let options: vscode.FindTextInFilesOptions; @@ -547,10 +547,10 @@ export function createApiFactory( token = callbackOrToken; } - return extHostWorkspace.findTextInFiles(query, options || {}, callback, extension.identifier, token); + return workspaceProvider.findTextInFiles(query, options || {}, callback, extension.identifier, token); }, saveAll: (includeUntitled?) => { - return extHostWorkspace.saveAll(includeUntitled); + return workspaceProvider.saveAll(includeUntitled); }, applyEdit(edit: vscode.WorkspaceEdit): Thenable { return extHostEditors.applyWorkspaceEdit(edit); @@ -868,11 +868,11 @@ class Extension implements vscode.Extension { } } -export function initializeExtensionApi(extensionService: ExtHostExtensionService, apiFactory: IExtensionApiFactory, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): Promise { - return extensionService.getExtensionPathIndex().then(trie => defineAPI(apiFactory, trie, extensionRegistry, configProvider)); +export function initializeExtensionApi(extensionService: ExtHostExtensionService, apiFactory: IExtensionApiFactory, extensionRegistry: ExtensionDescriptionRegistry, workspaceProvider: ExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider): Promise { + return extensionService.getExtensionPathIndex().then(trie => defineAPI(apiFactory, trie, extensionRegistry, workspaceProvider, configProvider)); } -function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchTree, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): void { +function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchTree, extensionRegistry: ExtensionDescriptionRegistry, workspaceProvider: ExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider): void { // each extension is meant to get its own api implementation const extApiImpl = new Map(); @@ -890,7 +890,7 @@ function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchT if (ext) { let apiImpl = extApiImpl.get(ExtensionIdentifier.toKey(ext.identifier)); if (!apiImpl) { - apiImpl = factory(ext, extensionRegistry, configProvider); + apiImpl = factory(ext, extensionRegistry, workspaceProvider, configProvider); extApiImpl.set(ExtensionIdentifier.toKey(ext.identifier), apiImpl); } return apiImpl; @@ -901,7 +901,7 @@ function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchT let extensionPathsPretty = ''; extensionPaths.forEach((value, index) => extensionPathsPretty += `\t${index} -> ${value.identifier.value}\n`); console.warn(`Could not identify extension for 'vscode' require call from ${parent.filename}. These are the extension path mappings: \n${extensionPathsPretty}`); - defaultApiImpl = factory(nullExtensionDescription, extensionRegistry, configProvider); + defaultApiImpl = factory(nullExtensionDescription, extensionRegistry, workspaceProvider, configProvider); } return defaultApiImpl; }; diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 72e15943a45..1cc97e53c33 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -55,18 +55,21 @@ export interface IEnvironment { globalStorageHome: URI; } -export interface IWorkspaceData { +export interface IStaticWorkspaceData { id: string; name: string; - folders: { uri: UriComponents, name: string, index: number }[]; configuration?: UriComponents; } +export interface IWorkspaceData extends IStaticWorkspaceData { + folders: { uri: UriComponents, name: string, index: number }[]; +} + export interface IInitData { commit: string; parentPid: number; environment: IEnvironment; - workspace: IWorkspaceData; + workspace: IStaticWorkspaceData; resolvedExtensions: ExtensionIdentifier[]; extensions: IExtensionDescription[]; telemetryInfo: ITelemetryInfo; @@ -716,6 +719,7 @@ export interface ExtHostTreeViewsShape { } export interface ExtHostWorkspaceShape { + $initializeWorkspace(workspace: IWorkspaceData): void; $acceptWorkspaceData(workspace: IWorkspaceData): void; $handleTextSearchResult(result: IRawFileMatch2, requestId: number): void; } diff --git a/src/vs/workbench/api/node/extHostConfiguration.ts b/src/vs/workbench/api/node/extHostConfiguration.ts index 3e73209ffbb..02b41e0f546 100644 --- a/src/vs/workbench/api/node/extHostConfiguration.ts +++ b/src/vs/workbench/api/node/extHostConfiguration.ts @@ -7,7 +7,7 @@ import { mixin, deepClone } from 'vs/base/common/objects'; import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import * as vscode from 'vscode'; -import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; +import { ExtHostWorkspace, ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace'; import { ExtHostConfigurationShape, MainThreadConfigurationShape, IWorkspaceConfigurationChangeEventData, IConfigurationInitData } from './extHost.protocol'; import { ConfigurationTarget as ExtHostConfigurationTarget } from './extHostTypes'; import { IConfigurationData, ConfigurationTarget, IConfigurationModel } from 'vs/platform/configuration/common/configuration'; @@ -57,8 +57,10 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape { } $initializeConfiguration(data: IConfigurationInitData): void { - this._actual = new ExtHostConfigProvider(this._proxy, this._extHostWorkspace, data); - this._barrier.open(); + this._extHostWorkspace.getWorkspaceProvider().then(workspaceProvider => { + this._actual = new ExtHostConfigProvider(this._proxy, workspaceProvider, data); + this._barrier.open(); + }); } $acceptConfigurationChanged(data: IConfigurationInitData, eventData: IWorkspaceConfigurationChangeEventData): void { @@ -70,11 +72,11 @@ export class ExtHostConfigProvider { private readonly _onDidChangeConfiguration = new Emitter(); private readonly _proxy: MainThreadConfigurationShape; - private readonly _extHostWorkspace: ExtHostWorkspace; + private readonly _extHostWorkspace: ExtHostWorkspaceProvider; private _configurationScopes: { [key: string]: ConfigurationScope }; private _configuration: Configuration; - constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace, data: IConfigurationInitData) { + constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspaceProvider, data: IConfigurationInitData) { this._proxy = proxy; this._extHostWorkspace = extHostWorkspace; this._configuration = ExtHostConfigProvider.parse(data); diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index a4b106f656b..cdf59f777bf 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -16,7 +16,7 @@ import { import * as vscode from 'vscode'; import { Disposable, Position, Location, SourceBreakpoint, FunctionBreakpoint, DebugAdapterServer, DebugAdapterExecutable } from 'vs/workbench/api/node/extHostTypes'; import { ExecutableDebugAdapter, SocketDebugAdapter, AbstractDebugAdapter } from 'vs/workbench/parts/debug/node/debugAdapter'; -import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; +import { ExtHostWorkspace, ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace'; import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors'; import { ITerminalSettings, IDebuggerContribution, IConfig, IDebugAdapter, IDebugAdapterServer, IDebugAdapterExecutable, IAdapterDescriptor } from 'vs/workbench/parts/debug/common/debug'; @@ -360,12 +360,12 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { } public async $substituteVariables(folderUri: UriComponents | undefined, config: IConfig): Promise { - const configProvider = await this._configurationService.getConfigProvider(); + const [workspaceProvider, configProvider] = await Promise.all([this._workspaceService.getWorkspaceProvider(), this._configurationService.getConfigProvider()]); if (!this._variableResolver) { - this._variableResolver = new ExtHostVariableResolverService(this._workspaceService, this._editorsService, configProvider); + this._variableResolver = new ExtHostVariableResolverService(workspaceProvider, this._editorsService, configProvider); } let ws: IWorkspaceFolder; - const folder = this.getFolder(folderUri); + const folder = this.getFolder(folderUri, workspaceProvider); if (folder) { ws = { uri: folder.uri, @@ -379,10 +379,11 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { return this._variableResolver.resolveAny(ws, config); } - public $startDASession(debugAdapterHandle: number, sessionDto: IDebugSessionDto): Promise { + public async $startDASession(debugAdapterHandle: number, sessionDto: IDebugSessionDto): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); const mythis = this; - const session = this.getSession(sessionDto); + const session = this.getSession(sessionDto, workspaceProvider); return this.getAdapterDescriptor(this.getAdapterFactoryByType(session.type), session).then(x => { const adapter = this.convertToDto(x); @@ -546,7 +547,8 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { this.fireBreakpointChanges(a, r, c); } - public $provideDebugConfigurations(configProviderHandle: number, folderUri: UriComponents | undefined): Promise { + public async $provideDebugConfigurations(configProviderHandle: number, folderUri: UriComponents | undefined): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); let provider = this.getConfigProviderByHandle(configProviderHandle); if (!provider) { return Promise.reject(new Error('no handler found')); @@ -554,10 +556,11 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { if (!provider.provideDebugConfigurations) { return Promise.reject(new Error('handler has no method provideDebugConfigurations')); } - return asPromise(() => provider.provideDebugConfigurations(this.getFolder(folderUri), CancellationToken.None)); + return asPromise(() => provider.provideDebugConfigurations(this.getFolder(folderUri, workspaceProvider), CancellationToken.None)); } - public $resolveDebugConfiguration(configProviderHandle: number, folderUri: UriComponents | undefined, debugConfiguration: vscode.DebugConfiguration): Promise { + public async $resolveDebugConfiguration(configProviderHandle: number, folderUri: UriComponents | undefined, debugConfiguration: vscode.DebugConfiguration): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); let provider = this.getConfigProviderByHandle(configProviderHandle); if (!provider) { return Promise.reject(new Error('no handler found')); @@ -565,11 +568,12 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { if (!provider.resolveDebugConfiguration) { return Promise.reject(new Error('handler has no method resolveDebugConfiguration')); } - return asPromise(() => provider.resolveDebugConfiguration(this.getFolder(folderUri), debugConfiguration, CancellationToken.None)); + return asPromise(() => provider.resolveDebugConfiguration(this.getFolder(folderUri, workspaceProvider), debugConfiguration, CancellationToken.None)); } // TODO@AW legacy - public $legacyDebugAdapterExecutable(configProviderHandle: number, folderUri: UriComponents | undefined): Promise { + public async $legacyDebugAdapterExecutable(configProviderHandle: number, folderUri: UriComponents | undefined): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); let provider = this.getConfigProviderByHandle(configProviderHandle); if (!provider) { return Promise.reject(new Error('no handler found')); @@ -577,41 +581,42 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { if (!provider.debugAdapterExecutable) { return Promise.reject(new Error('handler has no method debugAdapterExecutable')); } - return asPromise(() => provider.debugAdapterExecutable(this.getFolder(folderUri), CancellationToken.None)).then(x => this.convertToDto(x)); + return asPromise(() => provider.debugAdapterExecutable(this.getFolder(folderUri, workspaceProvider), CancellationToken.None)).then(x => this.convertToDto(x)); } - public $provideDebugAdapter(adapterProviderHandle: number, sessionDto: IDebugSessionDto): Promise { + public async $provideDebugAdapter(adapterProviderHandle: number, sessionDto: IDebugSessionDto): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); let adapterProvider = this.getAdapterProviderByHandle(adapterProviderHandle); if (!adapterProvider) { return Promise.reject(new Error('no handler found')); } - return this.getAdapterDescriptor(adapterProvider, this.getSession(sessionDto)).then(x => this.convertToDto(x)); + return this.getAdapterDescriptor(adapterProvider, this.getSession(sessionDto, workspaceProvider)).then(x => this.convertToDto(x)); } - public $acceptDebugSessionStarted(sessionDto: IDebugSessionDto): void { - - this._onDidStartDebugSession.fire(this.getSession(sessionDto)); + public async $acceptDebugSessionStarted(sessionDto: IDebugSessionDto): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); + this._onDidStartDebugSession.fire(this.getSession(sessionDto, workspaceProvider)); } - public $acceptDebugSessionTerminated(sessionDto: IDebugSessionDto): void { - - const session = this.getSession(sessionDto); + public async $acceptDebugSessionTerminated(sessionDto: IDebugSessionDto): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); + const session = this.getSession(sessionDto, workspaceProvider); if (session) { this._onDidTerminateDebugSession.fire(session); this._debugSessions.delete(session.id); } } - public $acceptDebugSessionActiveChanged(sessionDto: IDebugSessionDto): void { - - this._activeDebugSession = sessionDto ? this.getSession(sessionDto) : undefined; + public async $acceptDebugSessionActiveChanged(sessionDto: IDebugSessionDto): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); + this._activeDebugSession = sessionDto ? this.getSession(sessionDto, workspaceProvider) : undefined; this._onDidChangeActiveDebugSession.fire(this._activeDebugSession); } - public $acceptDebugSessionCustomEvent(sessionDto: IDebugSessionDto, event: any): void { - + public async $acceptDebugSessionCustomEvent(sessionDto: IDebugSessionDto, event: any): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); const ee: vscode.DebugSessionCustomEvent = { - session: this.getSession(sessionDto), + session: this.getSession(sessionDto, workspaceProvider), event: event.event, body: event.body }; @@ -776,12 +781,12 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { } } - private getSession(dto: IDebugSessionDto): ExtHostDebugSession { + private getSession(dto: IDebugSessionDto, workspaceProvider: ExtHostWorkspaceProvider): ExtHostDebugSession { if (dto) { if (typeof dto === 'string') { return this._debugSessions.get(dto); } else { - const debugSession = new ExtHostDebugSession(this._debugServiceProxy, dto.id, dto.type, dto.name, this.getFolder(dto.folderUri), dto.configuration); + const debugSession = new ExtHostDebugSession(this._debugServiceProxy, dto.id, dto.type, dto.name, this.getFolder(dto.folderUri, workspaceProvider), dto.configuration); this._debugSessions.set(debugSession.id, debugSession); return debugSession; } @@ -789,10 +794,10 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { return undefined; } - private getFolder(_folderUri: UriComponents | undefined): vscode.WorkspaceFolder | undefined { + private getFolder(_folderUri: UriComponents | undefined, workspaceProvider: ExtHostWorkspaceProvider): vscode.WorkspaceFolder | undefined { if (_folderUri) { const folderURI = URI.revive(_folderUri); - return this._workspaceService.resolveWorkspaceFolder(folderURI); + return workspaceProvider.resolveWorkspaceFolder(folderURI); } return undefined; } @@ -853,7 +858,7 @@ export class ExtHostDebugConsole implements vscode.DebugConsole { export class ExtHostVariableResolverService extends AbstractVariableResolverService { - constructor(workspaceService: ExtHostWorkspace, editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider) { + constructor(workspaceService: ExtHostWorkspaceProvider, editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider) { super({ getFolderUri: (folderName: string): URI => { const folders = workspaceService.getWorkspaceFolders(); diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 8edbff284ea..dbe9d99623e 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -13,12 +13,12 @@ import { URI } from 'vs/base/common/uri'; import * as pfs from 'vs/base/node/pfs'; import { ILogService } from 'vs/platform/log/common/log'; import { createApiFactory, initializeExtensionApi, IExtensionApiFactory } from 'vs/workbench/api/node/extHost.api.impl'; -import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, IWorkspaceData, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape } from 'vs/workbench/api/node/extHost.protocol'; +import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IStaticWorkspaceData } from 'vs/workbench/api/node/extHost.protocol'; import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration'; import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionMemento, IExtensionModule } from 'vs/workbench/api/node/extHostExtensionActivator'; import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService'; import { ExtHostStorage } from 'vs/workbench/api/node/extHostStorage'; -import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; +import { ExtHostWorkspace, ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/node/extensionDescriptionRegistry'; import { connectProxyResolver } from 'vs/workbench/services/extensions/node/proxyResolver'; @@ -26,6 +26,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation'; import * as errors from 'vs/base/common/errors'; import { ResolvedAuthority } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { IWorkspace } from 'vs/platform/workspace/common/workspace'; class ExtensionMemento implements IExtensionMemento { @@ -80,13 +81,13 @@ class ExtensionMemento implements IExtensionMemento { class ExtensionStoragePath { - private readonly _workspace: IWorkspaceData; + private readonly _workspace: IStaticWorkspaceData; private readonly _environment: IEnvironment; private readonly _ready: Promise; private _value: string; - constructor(workspace: IWorkspaceData, environment: IEnvironment) { + constructor(workspace: IStaticWorkspaceData, environment: IEnvironment) { this._workspace = workspace; this._environment = environment; this._ready = this._getOrCreateWorkspaceStoragePath().then(value => this._value = value); @@ -229,9 +230,10 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { private async _initialize(): Promise { try { const configProvider = await this._extHostConfiguration.getConfigProvider(); - await initializeExtensionApi(this, this._extensionApiFactory, this._registry, configProvider); + const workspaceProvider = await this._extHostWorkspace.getWorkspaceProvider(); + await initializeExtensionApi(this, this._extensionApiFactory, this._registry, workspaceProvider, configProvider); // Do this when extension service exists, but extensions are not being activated yet. - await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._extHostLogService, this._mainThreadTelemetryProxy); + await connectProxyResolver(workspaceProvider, configProvider, this, this._extHostLogService, this._mainThreadTelemetryProxy); this._barrier.open(); } catch (err) { errors.onUnexpectedError(err); @@ -473,15 +475,15 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { // -- eager activation // Handle "eager" activation extensions - private _handleEagerExtensions(): Promise { + private _handleEagerExtensions(workspaceProvider: ExtHostWorkspaceProvider): Promise { this._activateByEvent('*', true).then(undefined, (err) => { console.error(err); }); - return this._handleWorkspaceContainsEagerExtensions(this._initData.workspace); + return this._handleWorkspaceContainsEagerExtensions(workspaceProvider.workspace); } - private _handleWorkspaceContainsEagerExtensions(workspace: IWorkspaceData): Promise { + private _handleWorkspaceContainsEagerExtensions(workspace: IWorkspace): Promise { if (!workspace || workspace.folders.length === 0) { return Promise.resolve(undefined); } @@ -493,7 +495,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { ).then(() => { }); } - private _handleWorkspaceContainsEagerExtension(workspace: IWorkspaceData, desc: IExtensionDescription): Promise { + private _handleWorkspaceContainsEagerExtension(workspace: IWorkspace, desc: IExtensionDescription): Promise { const activationEvents = desc.activationEvents; if (!activationEvents) { return Promise.resolve(undefined); @@ -523,7 +525,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { return Promise.all([fileNamePromise, globPatternPromise]).then(() => { }); } - private async _activateIfFileName(workspace: IWorkspaceData, extensionId: ExtensionIdentifier, fileName: string): Promise { + private async _activateIfFileName(workspace: IWorkspace, extensionId: ExtensionIdentifier, fileName: string): Promise { // find exact path for (const { uri } of workspace.folders) { @@ -637,7 +639,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { this._started = true; return this._barrier.wait() - .then(() => this._handleEagerExtensions()) + .then(() => this._extHostWorkspace.getWorkspaceProvider()) + .then(workspaceProvider => this._handleEagerExtensions(workspaceProvider)) .then(() => this._handleExtensionTests()) .then(() => { this._extHostLogService.info(`eager extensions activated`); diff --git a/src/vs/workbench/api/node/extHostQuickOpen.ts b/src/vs/workbench/api/node/extHostQuickOpen.ts index c01fbad3ef8..ab869c83dc0 100644 --- a/src/vs/workbench/api/node/extHostQuickOpen.ts +++ b/src/vs/workbench/api/node/extHostQuickOpen.ts @@ -164,7 +164,7 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape { return undefined; } - return this._workspace.getWorkspaceFolders().filter(folder => folder.uri.toString() === selectedFolder.uri.toString())[0]; + return this._workspace.getWorkspaceProvider().then(workspaceProvider => workspaceProvider.getWorkspaceFolders().filter(folder => folder.uri.toString() === selectedFolder.uri.toString())[0]); }); } diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 6bbb0f26c42..e1f4043495c 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -16,7 +16,7 @@ import { IExtensionDescription } from 'vs/workbench/services/extensions/common/e import { MainContext, MainThreadTaskShape, ExtHostTaskShape, IMainContext } from 'vs/workbench/api/node/extHost.protocol'; import * as types from 'vs/workbench/api/node/extHostTypes'; -import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; +import { ExtHostWorkspace, ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace'; import * as vscode from 'vscode'; import { TaskDefinitionDTO, TaskExecutionDTO, TaskPresentationOptionsDTO, ProcessExecutionOptionsDTO, ProcessExecutionDTO, @@ -219,7 +219,7 @@ namespace TaskDTO { }; return result; } - export function to(value: TaskDTO, workspace: ExtHostWorkspace): types.Task { + export function to(value: TaskDTO, workspace: ExtHostWorkspaceProvider): types.Task { if (value === undefined || value === null) { return undefined; } @@ -296,8 +296,8 @@ class TaskExecutionImpl implements vscode.TaskExecution { } namespace TaskExecutionDTO { - export function to(value: TaskExecutionDTO, tasks: ExtHostTask): vscode.TaskExecution { - return new TaskExecutionImpl(tasks, value.id, TaskDTO.to(value.task, tasks.extHostWorkspace)); + export function to(value: TaskExecutionDTO, tasks: ExtHostTask, workspaceProvider: ExtHostWorkspaceProvider): vscode.TaskExecution { + return new TaskExecutionImpl(tasks, value.id, TaskDTO.to(value.task, workspaceProvider)); } export function from(value: vscode.TaskExecution): TaskExecutionDTO { return { @@ -338,10 +338,6 @@ export class ExtHostTask implements ExtHostTaskShape { this._taskExecutions = new Map(); } - public get extHostWorkspace(): ExtHostWorkspace { - return this._workspaceService; - } - public registerTaskProvider(extension: IExtensionDescription, provider: vscode.TaskProvider): vscode.Disposable { if (!provider) { return new types.Disposable(() => { }); @@ -360,10 +356,11 @@ export class ExtHostTask implements ExtHostTaskShape { } public fetchTasks(filter?: vscode.TaskFilter): Promise { - return this._proxy.$fetchTasks(TaskFilterDTO.from(filter)).then((values) => { + return this._proxy.$fetchTasks(TaskFilterDTO.from(filter)).then(async (values) => { let result: vscode.Task[] = []; + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); for (let value of values) { - let task = TaskDTO.to(value, this._workspaceService); + let task = TaskDTO.to(value, workspaceProvider); if (task) { result.push(task); } @@ -372,17 +369,18 @@ export class ExtHostTask implements ExtHostTaskShape { }); } - public executeTask(extension: IExtensionDescription, task: vscode.Task): Promise { + public async executeTask(extension: IExtensionDescription, task: vscode.Task): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); let tTask = (task as types.Task); // We have a preserved ID. So the task didn't change. if (tTask._id !== undefined) { - return this._proxy.$executeTask(TaskHandleDTO.from(tTask)).then(value => this.getTaskExecution(value, task)); + return this._proxy.$executeTask(TaskHandleDTO.from(tTask)).then(value => this.getTaskExecution(value, workspaceProvider, task)); } else { let dto = TaskDTO.from(task, extension); if (dto === undefined) { return Promise.reject(new Error('Task is not valid')); } - return this._proxy.$executeTask(dto).then(value => this.getTaskExecution(value, task)); + return this._proxy.$executeTask(dto).then(value => this.getTaskExecution(value, workspaceProvider, task)); } } @@ -403,9 +401,10 @@ export class ExtHostTask implements ExtHostTaskShape { return this._onDidExecuteTask.event; } - public $onDidStartTask(execution: TaskExecutionDTO): void { + public async $onDidStartTask(execution: TaskExecutionDTO): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); this._onDidExecuteTask.fire({ - execution: this.getTaskExecution(execution) + execution: this.getTaskExecution(execution, workspaceProvider) }); } @@ -413,8 +412,9 @@ export class ExtHostTask implements ExtHostTaskShape { return this._onDidTerminateTask.event; } - public $OnDidEndTask(execution: TaskExecutionDTO): void { - const _execution = this.getTaskExecution(execution); + public async $OnDidEndTask(execution: TaskExecutionDTO): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); + const _execution = this.getTaskExecution(execution, workspaceProvider); this._taskExecutions.delete(execution.id); this._onDidTerminateTask.fire({ execution: _execution @@ -425,8 +425,9 @@ export class ExtHostTask implements ExtHostTaskShape { return this._onDidTaskProcessStarted.event; } - public $onDidStartTaskProcess(value: TaskProcessStartedDTO): void { - const execution = this.getTaskExecution(value.id); + public async $onDidStartTaskProcess(value: TaskProcessStartedDTO): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); + const execution = this.getTaskExecution(value.id, workspaceProvider); if (execution) { this._onDidTaskProcessStarted.fire({ execution: execution, @@ -439,8 +440,9 @@ export class ExtHostTask implements ExtHostTaskShape { return this._onDidTaskProcessEnded.event; } - public $onDidEndTaskProcess(value: TaskProcessEndedDTO): void { - const execution = this.getTaskExecution(value.id); + public async $onDidEndTaskProcess(value: TaskProcessEndedDTO): Promise { + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); + const execution = this.getTaskExecution(value.id, workspaceProvider); if (execution) { this._onDidTaskProcessEnded.fire({ execution: execution, @@ -473,13 +475,14 @@ export class ExtHostTask implements ExtHostTaskShape { public async $resolveVariables(uriComponents: UriComponents, toResolve: { process?: { name: string; cwd?: string; path?: string }, variables: string[] }): Promise<{ process?: string, variables: { [key: string]: string; } }> { const configProvider = await this._configurationService.getConfigProvider(); + const workspaceProvider = await this._workspaceService.getWorkspaceProvider(); let uri: URI = URI.revive(uriComponents); let result = { process: undefined as string, variables: Object.create(null) }; - let workspaceFolder = this._workspaceService.resolveWorkspaceFolder(uri); - let resolver = new ExtHostVariableResolverService(this._workspaceService, this._editorService, configProvider); + let workspaceFolder = workspaceProvider.resolveWorkspaceFolder(uri); + let resolver = new ExtHostVariableResolverService(workspaceProvider, this._editorService, configProvider); let ws: IWorkspaceFolder = { uri: workspaceFolder.uri, name: workspaceFolder.name, @@ -512,7 +515,7 @@ export class ExtHostTask implements ExtHostTaskShape { return this._handleCounter++; } - private getTaskExecution(execution: TaskExecutionDTO | string, task?: vscode.Task): TaskExecutionImpl { + private getTaskExecution(execution: TaskExecutionDTO | string, workspaceProvider: ExtHostWorkspaceProvider, task?: vscode.Task): TaskExecutionImpl { if (typeof execution === 'string') { return this._taskExecutions.get(execution); } @@ -521,7 +524,7 @@ export class ExtHostTask implements ExtHostTaskShape { if (result) { return result; } - result = new TaskExecutionImpl(this, execution.id, task ? task : TaskDTO.to(execution.task, this._workspaceService)); + result = new TaskExecutionImpl(this, execution.id, task ? task : TaskDTO.to(execution.task, workspaceProvider)); this._taskExecutions.set(execution.id, result); return result; } diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index 00fa6ec1cf1..6a4053b9910 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -23,8 +23,9 @@ import { Range, RelativePattern } from 'vs/workbench/api/node/extHostTypes'; import { ITextQueryBuilderOptions } from 'vs/workbench/parts/search/common/queryBuilder'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import * as vscode from 'vscode'; -import { ExtHostWorkspaceShape, IMainContext, IWorkspaceData, MainContext, MainThreadMessageServiceShape, MainThreadWorkspaceShape } from './extHost.protocol'; +import { ExtHostWorkspaceShape, IWorkspaceData, MainThreadMessageServiceShape, MainThreadWorkspaceShape, IMainContext, MainContext } from './extHost.protocol'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { Barrier } from 'vs/base/common/async'; function isFolderEqual(folderA: URI, folderB: URI): boolean { return isEqual(folderA, folderB, !isLinux); @@ -142,13 +143,55 @@ class ExtHostWorkspaceImpl extends Workspace { export class ExtHostWorkspace implements ExtHostWorkspaceShape { + private readonly _mainContext: IMainContext; + private readonly _logService: ILogService; + private readonly _requestIdProvider: Counter; + private readonly _barrier: Barrier; + private _actual: ExtHostWorkspaceProvider; + + constructor( + mainContext: IMainContext, + logService: ILogService, + requestIdProvider: Counter + ) { + this._mainContext = mainContext; + this._logService = logService; + this._requestIdProvider = requestIdProvider; + this._barrier = new Barrier(); + this._actual = null; + } + + public getWorkspaceProvider(): Promise { + return this._barrier.wait().then(_ => this._actual); + } + + $initializeWorkspace(data: IWorkspaceData): void { + this._actual = new ExtHostWorkspaceProvider(this._mainContext, data, this._logService, this._requestIdProvider); + this._barrier.open(); + } + + $acceptWorkspaceData(workspace: IWorkspaceData): void { + if (this._actual) { + this._actual.$acceptWorkspaceData(workspace); + } + } + + $handleTextSearchResult(result: IRawFileMatch2, requestId: number): void { + if (this._actual) { + this._actual.$handleTextSearchResult(result, requestId); + } + } + +} +export class ExtHostWorkspaceProvider { + private readonly _onDidChangeWorkspace = new Emitter(); - private readonly _proxy: MainThreadWorkspaceShape; private _confirmedWorkspace: ExtHostWorkspaceImpl; private _unconfirmedWorkspace: ExtHostWorkspaceImpl; - private _messageService: MainThreadMessageServiceShape; + private readonly _proxy: MainThreadWorkspaceShape; + private readonly _messageService: MainThreadMessageServiceShape; readonly onDidChangeWorkspace: Event = this._onDidChangeWorkspace.event; diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index b54507fb37e..99b3fa2d6f0 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -426,7 +426,6 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { }, workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : { configuration: workspace.configuration, - folders: workspace.folders, id: workspace.id, name: this._labelService.getWorkspaceLabel(workspace) }, diff --git a/src/vs/workbench/services/extensions/node/extensionHostMain.ts b/src/vs/workbench/services/extensions/node/extensionHostMain.ts index ec9cd8be9e4..1a9fa2f0b5f 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostMain.ts @@ -49,7 +49,6 @@ export class ExtensionHostMain { private _isTerminating: boolean; private readonly _environment: IEnvironment; private readonly _extensionService: ExtHostExtensionService; - private readonly _extHostConfiguration: ExtHostConfiguration; private readonly _extHostLogService: ExtHostLogService; private disposables: IDisposable[] = []; @@ -74,13 +73,13 @@ export class ExtensionHostMain { this.disposables.push(this._extHostLogService); this._searchRequestIdProvider = new Counter(); - const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, initData.workspace, this._extHostLogService, this._searchRequestIdProvider); + const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, this._extHostLogService, this._searchRequestIdProvider); this._extHostLogService.info('extension host started'); this._extHostLogService.trace('initData', initData); - this._extHostConfiguration = new ExtHostConfiguration(rpcProtocol.getProxy(MainContext.MainThreadConfiguration), extHostWorkspace); - this._extensionService = new ExtHostExtensionService(nativeExit, initData, rpcProtocol, extHostWorkspace, this._extHostConfiguration, this._extHostLogService); + const extHostConfiguraiton = new ExtHostConfiguration(rpcProtocol.getProxy(MainContext.MainThreadConfiguration), extHostWorkspace); + this._extensionService = new ExtHostExtensionService(nativeExit, initData, rpcProtocol, extHostWorkspace, extHostConfiguraiton, this._extHostLogService); // error forwarding and stack trace scanning Error.stackTraceLimit = 100; // increase number of stack frames (from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) diff --git a/src/vs/workbench/services/extensions/node/proxyResolver.ts b/src/vs/workbench/services/extensions/node/proxyResolver.ts index c330eb973a2..bd4ab8800d6 100644 --- a/src/vs/workbench/services/extensions/node/proxyResolver.ts +++ b/src/vs/workbench/services/extensions/node/proxyResolver.ts @@ -8,7 +8,7 @@ import * as https from 'https'; import * as nodeurl from 'url'; import { assign } from 'vs/base/common/objects'; -import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; +import { ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace'; import { ExtHostConfigProvider } from 'vs/workbench/api/node/extHostConfiguration'; import { ProxyAgent } from 'vscode-proxy-agent'; import { MainThreadTelemetryShape } from 'vs/workbench/api/node/extHost.protocol'; @@ -18,7 +18,7 @@ import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionS import { URI } from 'vs/base/common/uri'; export function connectProxyResolver( - extHostWorkspace: ExtHostWorkspace, + extHostWorkspace: ExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider, extensionService: ExtHostExtensionService, extHostLogService: ExtHostLogService, @@ -32,7 +32,7 @@ export function connectProxyResolver( const maxCacheEntries = 5000; // Cache can grow twice that much due to 'oldCache'. function createProxyAgent( - extHostWorkspace: ExtHostWorkspace, + extHostWorkspace: ExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider, extHostLogService: ExtHostLogService, mainThreadTelemetry: MainThreadTelemetryShape diff --git a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts index 995f762f4b4..b58db1f2440 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import { URI } from 'vs/base/common/uri'; -import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; +import { ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace'; import { ExtHostConfigProvider } from 'vs/workbench/api/node/extHostConfiguration'; import { MainThreadConfigurationShape, IConfigurationInitData } from 'vs/workbench/api/node/extHost.protocol'; import { ConfigurationModel } from 'vs/platform/configuration/common/configurationModels'; @@ -31,7 +31,7 @@ suite('ExtHostConfiguration', function () { if (!shape) { shape = new class extends mock() { }; } - return new ExtHostConfigProvider(shape, new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService(), new Counter()), createConfigurationData(contents)); + return new ExtHostConfigProvider(shape, new ExtHostWorkspaceProvider(new TestRPCProtocol(), null, new NullLogService(), new Counter()), createConfigurationData(contents)); } function createConfigurationData(contents: any): IConfigurationInitData { @@ -265,7 +265,7 @@ suite('ExtHostConfiguration', function () { test('inspect in no workspace context', function () { const testObject = new ExtHostConfigProvider( new class extends mock() { }, - new ExtHostWorkspace(new TestRPCProtocol(), null, new NullLogService(), new Counter()), + new ExtHostWorkspaceProvider(new TestRPCProtocol(), null, new NullLogService(), new Counter()), { defaults: new ConfigurationModel({ 'editor': { @@ -308,7 +308,7 @@ suite('ExtHostConfiguration', function () { folders[workspaceUri.toString()] = workspace; const testObject = new ExtHostConfigProvider( new class extends mock() { }, - new ExtHostWorkspace(new TestRPCProtocol(), { + new ExtHostWorkspaceProvider(new TestRPCProtocol(), { 'id': 'foo', 'folders': [aWorkspaceFolder(URI.file('foo'), 0)], 'name': 'foo' @@ -382,7 +382,7 @@ suite('ExtHostConfiguration', function () { const testObject = new ExtHostConfigProvider( new class extends mock() { }, - new ExtHostWorkspace(new TestRPCProtocol(), { + new ExtHostWorkspaceProvider(new TestRPCProtocol(), { 'id': 'foo', 'folders': [aWorkspaceFolder(firstRoot, 0), aWorkspaceFolder(secondRoot, 1)], 'name': 'foo' @@ -591,7 +591,7 @@ suite('ExtHostConfiguration', function () { const workspaceFolder = aWorkspaceFolder(URI.file('folder1'), 0); const testObject = new ExtHostConfigProvider( new class extends mock() { }, - new ExtHostWorkspace(new TestRPCProtocol(), { + new ExtHostWorkspaceProvider(new TestRPCProtocol(), { 'id': 'foo', 'folders': [workspaceFolder], 'name': 'foo' diff --git a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts index 45f61e09759..de017d9d841 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { URI } from 'vs/base/common/uri'; import { basename } from 'path'; -import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; +import { ExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace'; import { TestRPCProtocol } from './testRPCProtocol'; import { normalize } from 'vs/base/common/paths'; import { IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace'; @@ -30,7 +30,7 @@ suite('ExtHostWorkspace', function () { version: undefined! }; - function assertAsRelativePath(workspace: ExtHostWorkspace, input: string, expected: string, includeWorkspace?: boolean) { + function assertAsRelativePath(workspace: ExtHostWorkspaceProvider, input: string, expected: string, includeWorkspace?: boolean) { const actual = workspace.getRelativePath(input, includeWorkspace); if (actual === expected) { assert.ok(true); @@ -41,7 +41,7 @@ suite('ExtHostWorkspace', function () { test('asRelativePath', () => { - const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/Applications/NewsWoWBot'), 0)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/Applications/NewsWoWBot'), 0)], name: 'Test' }, new NullLogService(), new Counter()); assertAsRelativePath(ws, '/Coding/Applications/NewsWoWBot/bernd/das/brot', 'bernd/das/brot'); assertAsRelativePath(ws, '/Apps/DartPubCache/hosted/pub.dartlang.org/convert-2.0.1/lib/src/hex.dart', @@ -55,7 +55,7 @@ suite('ExtHostWorkspace', function () { test('asRelativePath, same paths, #11402', function () { const root = '/home/aeschli/workspaces/samples/docker'; const input = '/home/aeschli/workspaces/samples/docker'; - const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); assertAsRelativePath(ws, (input), input); @@ -64,20 +64,20 @@ suite('ExtHostWorkspace', function () { }); test('asRelativePath, no workspace', function () { - const ws = new ExtHostWorkspace(new TestRPCProtocol(), null!, new NullLogService(), new Counter()); + const ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), null!, new NullLogService(), new Counter()); assertAsRelativePath(ws, (''), ''); assertAsRelativePath(ws, ('/foo/bar'), '/foo/bar'); }); test('asRelativePath, multiple folders', function () { - const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter()); assertAsRelativePath(ws, '/Coding/One/file.txt', 'One/file.txt'); assertAsRelativePath(ws, '/Coding/Two/files/out.txt', 'Two/files/out.txt'); assertAsRelativePath(ws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt'); }); test('slightly inconsistent behaviour of asRelativePath and getWorkspaceFolder, #31553', function () { - const mrws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter()); + const mrws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter()); assertAsRelativePath(mrws, '/Coding/One/file.txt', 'One/file.txt'); assertAsRelativePath(mrws, '/Coding/One/file.txt', 'One/file.txt', true); @@ -89,7 +89,7 @@ suite('ExtHostWorkspace', function () { assertAsRelativePath(mrws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt', true); assertAsRelativePath(mrws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt', false); - const srws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0)], name: 'Test' }, new NullLogService(), new Counter()); + const srws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0)], name: 'Test' }, new NullLogService(), new Counter()); assertAsRelativePath(srws, '/Coding/One/file.txt', 'file.txt'); assertAsRelativePath(srws, '/Coding/One/file.txt', 'file.txt', false); assertAsRelativePath(srws, '/Coding/One/file.txt', 'One/file.txt', true); @@ -99,24 +99,24 @@ suite('ExtHostWorkspace', function () { }); test('getPath, legacy', function () { - let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); + let ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); assert.equal(ws.getPath(), undefined); - ws = new ExtHostWorkspace(new TestRPCProtocol(), null!, new NullLogService(), new Counter()); + ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), null!, new NullLogService(), new Counter()); assert.equal(ws.getPath(), undefined); - ws = new ExtHostWorkspace(new TestRPCProtocol(), undefined!, new NullLogService(), new Counter()); + ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), undefined!, new NullLogService(), new Counter()); assert.equal(ws.getPath(), undefined); - ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('Folder'), 0), aWorkspaceFolderData(URI.file('Another/Folder'), 1)] }, new NullLogService(), new Counter()); + ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('Folder'), 0), aWorkspaceFolderData(URI.file('Another/Folder'), 1)] }, new NullLogService(), new Counter()); assert.equal(ws.getPath().replace(/\\/g, '/'), '/Folder'); - ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('/Folder'), 0)] }, new NullLogService(), new Counter()); + ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('/Folder'), 0)] }, new NullLogService(), new Counter()); assert.equal(ws.getPath().replace(/\\/g, '/'), '/Folder'); }); test('WorkspaceFolder has name and index', function () { - const ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter()); const [one, two] = ws.getWorkspaceFolders(); @@ -127,7 +127,7 @@ suite('ExtHostWorkspace', function () { }); test('getContainingWorkspaceFolder', () => { - const ws = new ExtHostWorkspace(new TestRPCProtocol(), { + const ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [ @@ -175,7 +175,7 @@ suite('ExtHostWorkspace', function () { }); test('Multiroot change event should have a delta, #29641', function (done) { - let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); + let ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); let finished = false; const finish = (error?: any) => { @@ -238,7 +238,7 @@ suite('ExtHostWorkspace', function () { }); test('Multiroot change keeps existing workspaces live', function () { - let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService(), new Counter()); + let ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService(), new Counter()); let firstFolder = ws.getWorkspaceFolders()[0]; ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar2'), 0), aWorkspaceFolderData(URI.parse('foo:bar'), 1, 'renamed')] }); @@ -258,7 +258,7 @@ suite('ExtHostWorkspace', function () { }); test('updateWorkspaceFolders - invalid arguments', function () { - let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); + let ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, null!, null!)); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 0, 0)); @@ -267,7 +267,7 @@ suite('ExtHostWorkspace', function () { assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, -1, 0)); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, -1, -1)); - ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService(), new Counter()); + ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService(), new Counter()); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 1, 1)); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 0, 2)); @@ -289,7 +289,7 @@ suite('ExtHostWorkspace', function () { assertRegistered: undefined! }; - const ws = new ExtHostWorkspace(protocol, { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); + const ws = new ExtHostWorkspaceProvider(protocol, { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); // // Add one folder @@ -522,7 +522,7 @@ suite('ExtHostWorkspace', function () { } }; - let ws = new ExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); + let ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); let sub = ws.onDidChangeWorkspace(e => { try { assert.throws(() => { @@ -541,7 +541,7 @@ suite('ExtHostWorkspace', function () { }); test('`vscode.workspace.getWorkspaceFolder(file)` don\'t return workspace folder when file open from command line. #36221', function () { - let ws = new ExtHostWorkspace(new TestRPCProtocol(), { + let ws = new ExtHostWorkspaceProvider(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [ aWorkspaceFolderData(URI.file('c:/Users/marek/Desktop/vsc_test/'), 0) ]