diff --git a/src/vs/workbench/api/common/extHostDebugService.ts b/src/vs/workbench/api/common/extHostDebugService.ts index 5050a8dc1df..6c1802ec3e4 100644 --- a/src/vs/workbench/api/common/extHostDebugService.ts +++ b/src/vs/workbench/api/common/extHostDebugService.ts @@ -33,6 +33,7 @@ import * as vscode from 'vscode'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { withNullAsUndefined } from 'vs/base/common/types'; +import { IProcessEnvironment } from 'vs/base/common/platform'; export const IExtHostDebugService = createDecorator('IExtHostDebugService'); @@ -372,10 +373,14 @@ export class ExtHostDebugServiceBase implements IExtHostDebugService, ExtHostDeb return Promise.resolve(undefined); } + protected createVariableResolver(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider): AbstractVariableResolverService { + return new ExtHostVariableResolverService(folders, editorService, configurationService); + } + public async $substituteVariables(folderUri: UriComponents | undefined, config: IConfig): Promise { if (!this._variableResolver) { const [workspaceFolders, configProvider] = await Promise.all([this._workspaceService.getWorkspaceFolders2(), this._configurationService.getConfigProvider()]); - this._variableResolver = new ExtHostVariableResolverService(workspaceFolders || [], this._editorsService, configProvider!); + this._variableResolver = this.createVariableResolver(workspaceFolders || [], this._editorsService, configProvider); } let ws: IWorkspaceFolder | undefined; const folder = await this.getFolder(folderUri); @@ -954,9 +959,9 @@ export class ExtHostDebugConsole implements vscode.DebugConsole { } } -class ExtHostVariableResolverService extends AbstractVariableResolverService { +export class ExtHostVariableResolverService extends AbstractVariableResolverService { - constructor(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider) { + constructor(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider, env?: IProcessEnvironment) { super({ getFolderUri: (folderName: string): URI | undefined => { const found = folders.filter(f => f.name === folderName); @@ -972,7 +977,7 @@ class ExtHostVariableResolverService extends AbstractVariableResolverService { return configurationService.getConfiguration(undefined, folderUri).get(section); }, getExecPath: (): string | undefined => { - return undefined; + return env ? env['VSCODE_EXEC_PATH'] : undefined; }, getFilePath: (): string | undefined => { const activeEditor = editorService.activeEditor(); @@ -998,7 +1003,7 @@ class ExtHostVariableResolverService extends AbstractVariableResolverService { } return undefined; } - }, {} /* process.env as IProcessEnvironment */); + }, env); } } @@ -1056,9 +1061,11 @@ interface IDapTransport { stop(): void; } +/* + * experimental: call directly into a debug adapter implementation + */ class DirectDebugAdapter extends AbstractDebugAdapter implements IDapTransport { - private _sendUp!: (msg: DebugProtocol.ProtocolMessage) => void; constructor(implementation: any) { diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index 3f62931e053..ac05c037e00 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -5,7 +5,6 @@ import * as nls from 'vs/nls'; import * as vscode from 'vscode'; -import * as path from 'vs/base/common/path'; import { DebugAdapterExecutable } from 'vs/workbench/api/common/extHostTypes'; import { ExecutableDebugAdapter, SocketDebugAdapter } from 'vs/workbench/contrib/debug/node/debugAdapter'; import { AbstractDebugAdapter } from 'vs/workbench/contrib/debug/common/abstractDebugAdapter'; @@ -18,14 +17,12 @@ import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; -import { ExtHostDebugServiceBase, ExtHostDebugSession } from 'vs/workbench/api/common/extHostDebugService'; +import { ExtHostDebugServiceBase, ExtHostDebugSession, ExtHostVariableResolverService } from 'vs/workbench/api/common/extHostDebugService'; import { ISignService } from 'vs/platform/sign/common/sign'; import { SignService } from 'vs/platform/sign/node/signService'; import { hasChildProcesses, prepareCommand, runInExternalTerminal } from 'vs/workbench/contrib/debug/node/terminals'; import { IDisposable } from 'vs/base/common/lifecycle'; import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/common/variableResolver'; -import { URI } from 'vs/base/common/uri'; -import { Schemas } from 'vs/base/common/network'; import { IProcessEnvironment } from 'vs/base/common/platform'; @@ -122,52 +119,9 @@ export class ExtHostDebugService extends ExtHostDebugServiceBase { } return super.$runInTerminal(args); } -} -export class ExtHostVariableResolverService extends AbstractVariableResolverService { - - constructor(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider) { - super({ - getFolderUri: (folderName: string): URI | undefined => { - const found = folders.filter(f => f.name === folderName); - if (found && found.length > 0) { - return found[0].uri; - } - return undefined; - }, - getWorkspaceFolderCount: (): number => { - return folders.length; - }, - getConfigurationValue: (folderUri: URI, section: string): string | undefined => { - return configurationService.getConfiguration(undefined, folderUri).get(section); - }, - getExecPath: (): string | undefined => { - return process.env['VSCODE_EXEC_PATH']; - }, - getFilePath: (): string | undefined => { - const activeEditor = editorService.activeEditor(); - if (activeEditor) { - const resource = activeEditor.document.uri; - if (resource.scheme === Schemas.file) { - return path.normalize(resource.fsPath); - } - } - return undefined; - }, - getSelectedText: (): string | undefined => { - const activeEditor = editorService.activeEditor(); - if (activeEditor && !activeEditor.selection.isEmpty) { - return activeEditor.document.getText(activeEditor.selection); - } - return undefined; - }, - getLineNumber: (): string | undefined => { - const activeEditor = editorService.activeEditor(); - if (activeEditor) { - return String(activeEditor.selection.end.line + 1); - } - return undefined; - } - }, process.env as IProcessEnvironment); + protected createVariableResolver(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider): AbstractVariableResolverService { + return new ExtHostVariableResolverService(folders, editorService, configurationService, process.env as IProcessEnvironment); } + } diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 6e1a647067a..d6d9a1ee84c 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -12,7 +12,7 @@ import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import * as vscode from 'vscode'; import * as tasks from '../common/shared/tasks'; import * as Objects from 'vs/base/common/objects'; -import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService'; +import { ExtHostVariableResolverService } from 'vs/workbench/api/common/extHostDebugService'; import { IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -23,6 +23,7 @@ import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitData import { ExtHostTaskBase, TaskHandleDTO, TaskDTO, CustomExecutionDTO, HandlerData } from 'vs/workbench/api/common/extHostTask'; import { Schemas } from 'vs/base/common/network'; import { ILogService } from 'vs/platform/log/common/log'; +import { IProcessEnvironment } from 'vs/base/common/platform'; export class ExtHostTask extends ExtHostTaskBase { private _variableResolver: ExtHostVariableResolverService | undefined; @@ -102,7 +103,7 @@ export class ExtHostTask extends ExtHostTaskBase { private async getVariableResolver(workspaceFolders: vscode.WorkspaceFolder[]): Promise { if (this._variableResolver === undefined) { const configProvider = await this._configurationService.getConfigProvider(); - this._variableResolver = new ExtHostVariableResolverService(workspaceFolders, this._editorService, configProvider); + this._variableResolver = new ExtHostVariableResolverService(workspaceFolders, this._editorService, configProvider, process.env as IProcessEnvironment); } return this._variableResolver; } diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 64d1a0005b7..bac43635693 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -16,7 +16,7 @@ import { IShellLaunchConfig, ITerminalEnvironment } from 'vs/workbench/contrib/t import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess'; import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService'; +import { ExtHostVariableResolverService } from 'vs/workbench/api/common/extHostDebugService'; import { ExtHostDocumentsAndEditors, IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; @@ -120,7 +120,7 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { private async _updateVariableResolver(): Promise { const configProvider = await this._extHostConfiguration.getConfigProvider(); const workspaceFolders = await this._extHostWorkspace.getWorkspaceFolders2(); - this._variableResolver = new ExtHostVariableResolverService(workspaceFolders || [], this._extHostDocumentsAndEditors, configProvider); + this._variableResolver = new ExtHostVariableResolverService(workspaceFolders || [], this._extHostDocumentsAndEditors, configProvider, process.env as platform.IProcessEnvironment); } public async $spawnExtHostProcess(id: number, shellLaunchConfigDto: IShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents | undefined, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise { diff --git a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts index c6f302d1b3c..5947f5e4e96 100644 --- a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts @@ -32,17 +32,24 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe _serviceBrand: undefined; + private _context: IVariableResolveContext; + private _envVariables?: IProcessEnvironment; protected _contributedVariables: Map Promise> = new Map(); - constructor( - private _context: IVariableResolveContext, - private _envVariables: IProcessEnvironment - ) { - if (isWindows && _envVariables) { - this._envVariables = Object.create(null); - Object.keys(_envVariables).forEach(key => { - this._envVariables[key.toLowerCase()] = _envVariables[key]; - }); + + constructor(_context: IVariableResolveContext, _envVariables?: IProcessEnvironment) { + this._context = _context; + if (_envVariables) { + if (isWindows) { + // windows env variables are case insensitive + const ev: IProcessEnvironment = Object.create(null); + this._envVariables = ev; + Object.keys(_envVariables).forEach(key => { + ev[key.toLowerCase()] = _envVariables[key]; + }); + } else { + this._envVariables = _envVariables; + } } } @@ -180,14 +187,13 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe case 'env': if (argument) { - if (isWindows) { - argument = argument.toLowerCase(); + if (this._envVariables) { + const env = this._envVariables[isWindows ? argument.toLowerCase() : argument]; + if (types.isString(env)) { + return env; + } } - const env = this._envVariables[argument]; - if (types.isString(env)) { - return env; - } - // For `env` we should do the same as a normal shell does - evaluates missing envs to an empty string #46436 + // For `env` we should do the same as a normal shell does - evaluates undefined envs to an empty string #46436 return ''; } throw new Error(localize('missingEnvVarName', "'{0}' can not be resolved because no environment variable name is given.", match));