Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delay extension host until workspace is completely initialised #67216

Merged
merged 4 commits into from
Feb 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 12 additions & 5 deletions src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ import { ILabelService } from 'vs/platform/label/common/label';
import { IFileMatch, IPatternInfo, ISearchProgressItem, ISearchService } from 'vs/workbench/services/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 { ITextQueryBuilderOptions, QueryBuilder } from 'vs/workbench/contrib/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, IWorkspaceData } from '../node/extHost.protocol';
import { TextSearchComplete } from 'vscode';
import { ExtHostContext, ExtHostWorkspaceShape, IExtHostContext, MainContext, MainThreadWorkspaceShape } from '../node/extHost.protocol';

@extHostNamedCustomer(MainContext.MainThreadWorkspace)
export class MainThreadWorkspace implements MainThreadWorkspaceShape {
Expand All @@ -44,6 +44,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);
}
Expand Down Expand Up @@ -101,13 +102,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 || undefined,
folders: workspace.folders,
id: workspace.id,
name: this._labelService.getWorkspaceLabel(workspace)
} : null);
};
}

// --- search ---
Expand Down
36 changes: 18 additions & 18 deletions src/vs/workbench/api/node/extHost.api.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ 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';
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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -511,34 +511,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;
Expand All @@ -553,10 +553,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);
Expand Down Expand Up @@ -877,11 +877,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>();
Expand All @@ -899,7 +899,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;
Expand All @@ -910,7 +910,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;
};
Expand Down
10 changes: 7 additions & 3 deletions src/vs/workbench/api/node/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
hostExtensions: ExtensionIdentifier[];
extensions: IExtensionDescription[];
Expand Down Expand Up @@ -720,6 +723,7 @@ export interface ExtHostTreeViewsShape {
}

export interface ExtHostWorkspaceShape {
$initializeWorkspace(workspace: IWorkspaceData | null): void;
$acceptWorkspaceData(workspace: IWorkspaceData | null): void;
$handleTextSearchResult(result: IRawFileMatch2, requestId: number): void;
}
Expand Down
12 changes: 7 additions & 5 deletions src/vs/workbench/api/node/extHostConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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 {
Expand All @@ -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);
Expand Down