mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-27 03:54:24 +01:00
Delay extension host until workspace is completely initialized
This commit is contained in:
@@ -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<T>(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<boolean> {
|
||||
return extHostEditors.applyWorkspaceEdit(edit);
|
||||
@@ -868,11 +868,11 @@ class Extension<T> implements vscode.Extension<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export function initializeExtensionApi(extensionService: ExtHostExtensionService, apiFactory: IExtensionApiFactory, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): Promise<void> {
|
||||
return extensionService.getExtensionPathIndex().then(trie => defineAPI(apiFactory, trie, extensionRegistry, configProvider));
|
||||
export function initializeExtensionApi(extensionService: ExtHostExtensionService, apiFactory: IExtensionApiFactory, extensionRegistry: ExtensionDescriptionRegistry, workspaceProvider: ExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider): Promise<void> {
|
||||
return extensionService.getExtensionPathIndex().then(trie => defineAPI(apiFactory, trie, extensionRegistry, workspaceProvider, configProvider));
|
||||
}
|
||||
|
||||
function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchTree<IExtensionDescription>, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): void {
|
||||
function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchTree<IExtensionDescription>, extensionRegistry: ExtensionDescriptionRegistry, workspaceProvider: ExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider): void {
|
||||
|
||||
// each extension is meant to get its own api implementation
|
||||
const extApiImpl = new Map<string, typeof vscode>();
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<vscode.ConfigurationChangeEvent>();
|
||||
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);
|
||||
|
||||
@@ -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<IConfig> {
|
||||
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<void> {
|
||||
public async $startDASession(debugAdapterHandle: number, sessionDto: IDebugSessionDto): Promise<void> {
|
||||
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<vscode.DebugConfiguration[]> {
|
||||
public async $provideDebugConfigurations(configProviderHandle: number, folderUri: UriComponents | undefined): Promise<vscode.DebugConfiguration[]> {
|
||||
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<vscode.DebugConfiguration> {
|
||||
public async $resolveDebugConfiguration(configProviderHandle: number, folderUri: UriComponents | undefined, debugConfiguration: vscode.DebugConfiguration): Promise<vscode.DebugConfiguration> {
|
||||
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<IAdapterDescriptor> {
|
||||
public async $legacyDebugAdapterExecutable(configProviderHandle: number, folderUri: UriComponents | undefined): Promise<IAdapterDescriptor> {
|
||||
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<IAdapterDescriptor> {
|
||||
public async $provideDebugAdapter(adapterProviderHandle: number, sessionDto: IDebugSessionDto): Promise<IAdapterDescriptor> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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();
|
||||
|
||||
@@ -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<string>;
|
||||
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<void> {
|
||||
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<void> {
|
||||
private _handleEagerExtensions(workspaceProvider: ExtHostWorkspaceProvider): Promise<void> {
|
||||
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<void> {
|
||||
private _handleWorkspaceContainsEagerExtensions(workspace: IWorkspace): Promise<void> {
|
||||
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<void> {
|
||||
private _handleWorkspaceContainsEagerExtension(workspace: IWorkspace, desc: IExtensionDescription): Promise<void> {
|
||||
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<void> {
|
||||
private async _activateIfFileName(workspace: IWorkspace, extensionId: ExtensionIdentifier, fileName: string): Promise<void> {
|
||||
|
||||
// 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`);
|
||||
|
||||
@@ -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]);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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<string, TaskExecutionImpl>();
|
||||
}
|
||||
|
||||
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<vscode.Task[]> {
|
||||
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<vscode.TaskExecution> {
|
||||
public async executeTask(extension: IExtensionDescription, task: vscode.Task): Promise<vscode.TaskExecution> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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<ExtHostWorkspaceProvider> {
|
||||
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<vscode.WorkspaceFoldersChangeEvent>();
|
||||
private readonly _proxy: MainThreadWorkspaceShape;
|
||||
|
||||
private _confirmedWorkspace: ExtHostWorkspaceImpl;
|
||||
private _unconfirmedWorkspace: ExtHostWorkspaceImpl;
|
||||
|
||||
private _messageService: MainThreadMessageServiceShape;
|
||||
private readonly _proxy: MainThreadWorkspaceShape;
|
||||
private readonly _messageService: MainThreadMessageServiceShape;
|
||||
|
||||
readonly onDidChangeWorkspace: Event<vscode.WorkspaceFoldersChangeEvent> = this._onDidChangeWorkspace.event;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user