mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-24 10:38:59 +01:00
Initialize configuration data through ExtHostConfiguration
This commit is contained in:
@@ -24,7 +24,7 @@ import { ExtHostApiCommands } from 'vs/workbench/api/node/extHostApiCommands';
|
||||
import { ExtHostClipboard } from 'vs/workbench/api/node/extHostClipboard';
|
||||
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { ExtHostComments } from 'vs/workbench/api/node/extHostComments';
|
||||
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService';
|
||||
import { ExtHostDecorations } from 'vs/workbench/api/node/extHostDecorations';
|
||||
import { ExtHostDiagnostics } from 'vs/workbench/api/node/extHostDiagnostics';
|
||||
@@ -66,7 +66,7 @@ import * as vscode from 'vscode';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
export interface IExtensionApiFactory {
|
||||
(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry): typeof vscode;
|
||||
(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, 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): typeof vscode {
|
||||
return function (extension: IExtensionDescription, extensionRegistry: ExtensionDescriptionRegistry, 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
|
||||
@@ -598,11 +598,11 @@ export function createApiFactory(
|
||||
return extHostDocumentSaveParticipant.getOnWillSaveTextDocumentEvent(extension)(listener, thisArgs, disposables);
|
||||
},
|
||||
onDidChangeConfiguration: (listener: (_: any) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
|
||||
return extHostConfiguration.onDidChangeConfiguration(listener, thisArgs, disposables);
|
||||
return configProvider.onDidChangeConfiguration(listener, thisArgs, disposables);
|
||||
},
|
||||
getConfiguration(section?: string, resource?: vscode.Uri): vscode.WorkspaceConfiguration {
|
||||
resource = arguments.length === 1 ? undefined : resource;
|
||||
return extHostConfiguration.getConfiguration(section, resource, extension.identifier);
|
||||
return configProvider.getConfiguration(section, resource, extension.identifier);
|
||||
},
|
||||
registerTextDocumentContentProvider(scheme: string, provider: vscode.TextDocumentContentProvider) {
|
||||
return extHostDocumentContentProviders.registerTextDocumentContentProvider(scheme, provider);
|
||||
@@ -865,11 +865,11 @@ class Extension<T> implements vscode.Extension<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export function initializeExtensionApi(extensionService: ExtHostExtensionService, apiFactory: IExtensionApiFactory, extensionRegistry: ExtensionDescriptionRegistry): Promise<void> {
|
||||
return extensionService.getExtensionPathIndex().then(trie => defineAPI(apiFactory, trie, extensionRegistry));
|
||||
export function initializeExtensionApi(extensionService: ExtHostExtensionService, apiFactory: IExtensionApiFactory, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): Promise<void> {
|
||||
return extensionService.getExtensionPathIndex().then(trie => defineAPI(apiFactory, trie, extensionRegistry, configProvider));
|
||||
}
|
||||
|
||||
function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchTree<IExtensionDescription>, extensionRegistry: ExtensionDescriptionRegistry): void {
|
||||
function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchTree<IExtensionDescription>, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): void {
|
||||
|
||||
// each extension is meant to get its own api implementation
|
||||
const extApiImpl = new Map<string, typeof vscode>();
|
||||
@@ -887,7 +887,7 @@ function defineAPI(factory: IExtensionApiFactory, extensionPaths: TernarySearchT
|
||||
if (ext) {
|
||||
let apiImpl = extApiImpl.get(ExtensionIdentifier.toKey(ext.identifier));
|
||||
if (!apiImpl) {
|
||||
apiImpl = factory(ext, extensionRegistry);
|
||||
apiImpl = factory(ext, extensionRegistry, configProvider);
|
||||
extApiImpl.set(ExtensionIdentifier.toKey(ext.identifier), apiImpl);
|
||||
}
|
||||
return apiImpl;
|
||||
@@ -898,7 +898,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);
|
||||
defaultApiImpl = factory(nullExtensionDescription, extensionRegistry, configProvider);
|
||||
}
|
||||
return defaultApiImpl;
|
||||
};
|
||||
|
||||
@@ -67,7 +67,6 @@ export interface IInitData {
|
||||
environment: IEnvironment;
|
||||
workspace: IWorkspaceData;
|
||||
extensions: IExtensionDescription[];
|
||||
configuration: IConfigurationInitData;
|
||||
telemetryInfo: ITelemetryInfo;
|
||||
logLevel: LogLevel;
|
||||
logsLocation: URI;
|
||||
@@ -632,7 +631,8 @@ export interface ExtHostCommandsShape {
|
||||
}
|
||||
|
||||
export interface ExtHostConfigurationShape {
|
||||
$acceptConfigurationChanged(data: IConfigurationData, eventData: IWorkspaceConfigurationChangeEventData): void;
|
||||
$initializeConfiguration(data: IConfigurationInitData): void;
|
||||
$acceptConfigurationChanged(data: IConfigurationInitData, eventData: IWorkspaceConfigurationChangeEventData): void;
|
||||
}
|
||||
|
||||
export interface ExtHostDiagnosticsShape {
|
||||
|
||||
@@ -17,6 +17,7 @@ import { ResourceMap } from 'vs/base/common/map';
|
||||
import { ConfigurationScope, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { isObject } from 'vs/base/common/types';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { Barrier } from 'vs/base/common/async';
|
||||
|
||||
function lookUp(tree: any, key: string) {
|
||||
if (key) {
|
||||
@@ -39,6 +40,34 @@ type ConfigurationInspect<T> = {
|
||||
|
||||
export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
|
||||
private readonly _proxy: MainThreadConfigurationShape;
|
||||
private readonly _extHostWorkspace: ExtHostWorkspace;
|
||||
private readonly _barrier: Barrier;
|
||||
private _actual: ExtHostConfigProvider;
|
||||
|
||||
constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace) {
|
||||
this._proxy = proxy;
|
||||
this._extHostWorkspace = extHostWorkspace;
|
||||
this._barrier = new Barrier();
|
||||
this._actual = null;
|
||||
}
|
||||
|
||||
public getConfigProvider(): Promise<ExtHostConfigProvider> {
|
||||
return this._barrier.wait().then(_ => this._actual);
|
||||
}
|
||||
|
||||
$initializeConfiguration(data: IConfigurationInitData): void {
|
||||
this._actual = new ExtHostConfigProvider(this._proxy, this._extHostWorkspace, data);
|
||||
this._barrier.open();
|
||||
}
|
||||
|
||||
$acceptConfigurationChanged(data: IConfigurationInitData, eventData: IWorkspaceConfigurationChangeEventData): void {
|
||||
this._actual.$acceptConfigurationChanged(data, eventData);
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostConfigProvider {
|
||||
|
||||
private readonly _onDidChangeConfiguration = new Emitter<vscode.ConfigurationChangeEvent>();
|
||||
private readonly _proxy: MainThreadConfigurationShape;
|
||||
private readonly _extHostWorkspace: ExtHostWorkspace;
|
||||
@@ -48,7 +77,7 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace, data: IConfigurationInitData) {
|
||||
this._proxy = proxy;
|
||||
this._extHostWorkspace = extHostWorkspace;
|
||||
this._configuration = ExtHostConfiguration.parse(data);
|
||||
this._configuration = ExtHostConfigProvider.parse(data);
|
||||
this._configurationScopes = data.configurationScopes;
|
||||
}
|
||||
|
||||
@@ -56,8 +85,9 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
return this._onDidChangeConfiguration && this._onDidChangeConfiguration.event;
|
||||
}
|
||||
|
||||
$acceptConfigurationChanged(data: IConfigurationData, eventData: IWorkspaceConfigurationChangeEventData) {
|
||||
this._configuration = ExtHostConfiguration.parse(data);
|
||||
$acceptConfigurationChanged(data: IConfigurationInitData, eventData: IWorkspaceConfigurationChangeEventData) {
|
||||
this._configuration = ExtHostConfigProvider.parse(data);
|
||||
this._configurationScopes = data.configurationScopes;
|
||||
this._onDidChangeConfiguration.fire(this._toConfigurationChangeEvent(eventData));
|
||||
}
|
||||
|
||||
@@ -220,11 +250,11 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape {
|
||||
}
|
||||
|
||||
private static parse(data: IConfigurationData): Configuration {
|
||||
const defaultConfiguration = ExtHostConfiguration.parseConfigurationModel(data.defaults);
|
||||
const userConfiguration = ExtHostConfiguration.parseConfigurationModel(data.user);
|
||||
const workspaceConfiguration = ExtHostConfiguration.parseConfigurationModel(data.workspace);
|
||||
const defaultConfiguration = ExtHostConfigProvider.parseConfigurationModel(data.defaults);
|
||||
const userConfiguration = ExtHostConfigProvider.parseConfigurationModel(data.user);
|
||||
const workspaceConfiguration = ExtHostConfigProvider.parseConfigurationModel(data.workspace);
|
||||
const folders: ResourceMap<ConfigurationModel> = Object.keys(data.folders).reduce((result, key) => {
|
||||
result.set(URI.parse(key), ExtHostConfiguration.parseConfigurationModel(data.folders[key]));
|
||||
result.set(URI.parse(key), ExtHostConfigProvider.parseConfigurationModel(data.folders[key]));
|
||||
return result;
|
||||
}, new ResourceMap<ConfigurationModel>());
|
||||
return new Configuration(defaultConfiguration, userConfiguration, workspaceConfiguration, folders, new ConfigurationModel(), new ResourceMap<ConfigurationModel>(), false);
|
||||
|
||||
@@ -23,7 +23,7 @@ import { ITerminalSettings, IDebuggerContribution, IConfig, IDebugAdapter, IDebu
|
||||
import { getTerminalLauncher, hasChildProcesses, prepareCommand } from 'vs/workbench/parts/debug/node/terminals';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/node/variableResolver';
|
||||
import { ExtHostConfiguration } from './extHostConfiguration';
|
||||
import { ExtHostConfiguration, ExtHostConfigProvider } from './extHostConfiguration';
|
||||
import { convertToVSCPaths, convertToDAPaths, stringToUri, uriToString } from 'vs/workbench/parts/debug/common/debugUtils';
|
||||
import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
@@ -359,9 +359,10 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public $substituteVariables(folderUri: UriComponents | undefined, config: IConfig): Promise<IConfig> {
|
||||
public async $substituteVariables(folderUri: UriComponents | undefined, config: IConfig): Promise<IConfig> {
|
||||
const configProvider = await this._configurationService.getConfigProvider();
|
||||
if (!this._variableResolver) {
|
||||
this._variableResolver = new ExtHostVariableResolverService(this._workspaceService, this._editorsService, this._configurationService);
|
||||
this._variableResolver = new ExtHostVariableResolverService(this._workspaceService, this._editorsService, configProvider);
|
||||
}
|
||||
let ws: IWorkspaceFolder;
|
||||
const folder = this.getFolder(folderUri);
|
||||
@@ -375,7 +376,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
|
||||
}
|
||||
};
|
||||
}
|
||||
return Promise.resolve(this._variableResolver.resolveAny(ws, config));
|
||||
return this._variableResolver.resolveAny(ws, config);
|
||||
}
|
||||
|
||||
public $startDASession(debugAdapterHandle: number, sessionDto: IDebugSessionDto): Promise<void> {
|
||||
@@ -852,7 +853,7 @@ export class ExtHostDebugConsole implements vscode.DebugConsole {
|
||||
|
||||
export class ExtHostVariableResolverService extends AbstractVariableResolverService {
|
||||
|
||||
constructor(workspaceService: ExtHostWorkspace, editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfiguration) {
|
||||
constructor(workspaceService: ExtHostWorkspace, editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider) {
|
||||
super({
|
||||
getFolderUri: (folderName: string): URI => {
|
||||
const folders = workspaceService.getWorkspaceFolders();
|
||||
|
||||
@@ -219,18 +219,25 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
|
||||
|
||||
this._started = false;
|
||||
|
||||
initializeExtensionApi(this, this._extensionApiFactory, this._registry).then(() => {
|
||||
// Do this when extension service exists, but extensions are not being activated yet.
|
||||
return connectProxyResolver(this._extHostWorkspace, this._extHostConfiguration, this, this._extHostLogService, this._mainThreadTelemetryProxy);
|
||||
}).then(() => {
|
||||
this._barrier.open();
|
||||
});
|
||||
this._initialize();
|
||||
|
||||
if (this._initData.autoStart) {
|
||||
this._startExtensionHost();
|
||||
}
|
||||
}
|
||||
|
||||
private async _initialize(): Promise<void> {
|
||||
try {
|
||||
const configProvider = await this._extHostConfiguration.getConfigProvider();
|
||||
await initializeExtensionApi(this, this._extensionApiFactory, this._registry, configProvider);
|
||||
// Do this when extension service exists, but extensions are not being activated yet.
|
||||
await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._extHostLogService, this._mainThreadTelemetryProxy);
|
||||
this._barrier.open();
|
||||
} catch (err) {
|
||||
errors.onUnexpectedError(err);
|
||||
}
|
||||
}
|
||||
|
||||
public async deactivateAll(): Promise<void> {
|
||||
let allPromises: Promise<void>[] = [];
|
||||
try {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import * as extfs from 'vs/base/node/extfs';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IFileQuery, IFolderQuery, IRawFileQuery, IRawQuery, IRawTextQuery, ISearchCompleteStats, ITextQuery } from 'vs/platform/search/common/search';
|
||||
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/node/extHostConfiguration';
|
||||
import { FileIndexSearchManager } from 'vs/workbench/api/node/extHostSearch.fileIndex';
|
||||
import { FileSearchManager } from 'vs/workbench/services/search/node/fileSearchManager';
|
||||
import { SearchService } from 'vs/workbench/services/search/node/rawSearchService';
|
||||
@@ -46,7 +46,9 @@ export class ExtHostSearch implements ExtHostSearchShape {
|
||||
this._fileSearchManager = new FileSearchManager();
|
||||
this._fileIndexSearchManager = new FileIndexSearchManager();
|
||||
|
||||
registerEHProviders(this, _logService, configService);
|
||||
configService.getConfigProvider().then((configProvider) => {
|
||||
registerEHProviders(this, _logService, configProvider);
|
||||
});
|
||||
}
|
||||
|
||||
private _transformScheme(scheme: string): string {
|
||||
@@ -176,7 +178,7 @@ export class ExtHostSearch implements ExtHostSearchShape {
|
||||
}
|
||||
}
|
||||
|
||||
function registerEHProviders(extHostSearch: ExtHostSearch, logService: ILogService, configService: ExtHostConfiguration) {
|
||||
function registerEHProviders(extHostSearch: ExtHostSearch, logService: ILogService, configService: ExtHostConfigProvider) {
|
||||
if (configService.getConfiguration('searchRipgrep').enable || configService.getConfiguration('search').runInExtensionHost) {
|
||||
const outputChannel = new OutputChannel(logService);
|
||||
extHostSearch.registerTextSearchProvider('file', new RipgrepSearchProvider(outputChannel));
|
||||
|
||||
@@ -471,14 +471,15 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
});
|
||||
}
|
||||
|
||||
public $resolveVariables(uriComponents: UriComponents, toResolve: { process?: { name: string; cwd?: string; path?: string }, variables: string[] }): Promise<{ process?: string, variables: { [key: string]: string; } }> {
|
||||
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();
|
||||
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, this._configurationService);
|
||||
let resolver = new ExtHostVariableResolverService(this._workspaceService, this._editorService, configProvider);
|
||||
let ws: IWorkspaceFolder = {
|
||||
uri: workspaceFolder.uri,
|
||||
name: workspaceFolder.name,
|
||||
@@ -504,7 +505,7 @@ export class ExtHostTask implements ExtHostTaskShape {
|
||||
paths
|
||||
);
|
||||
}
|
||||
return Promise.resolve(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private nextHandle(): number {
|
||||
|
||||
@@ -374,11 +374,11 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
|
||||
}
|
||||
}
|
||||
|
||||
public $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number): void {
|
||||
public async $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number): Promise<void> {
|
||||
// TODO: This function duplicates a lot of TerminalProcessManager.createProcess, ideally
|
||||
// they would be merged into a single implementation.
|
||||
|
||||
const terminalConfig = this._extHostConfiguration.getConfiguration('terminal.integrated');
|
||||
const configProvider = await this._extHostConfiguration.getConfigProvider();
|
||||
const terminalConfig = configProvider.getConfiguration('terminal.integrated');
|
||||
|
||||
if (!shellLaunchConfig.executable) {
|
||||
// TODO: This duplicates some of TerminalConfigHelper.mergeDefaultShellPathAndArgs and should be merged
|
||||
|
||||
Reference in New Issue
Block a user