Update to VS Code 1.52.1

This commit is contained in:
Asher
2021-02-09 16:08:37 +00:00
1351 changed files with 56560 additions and 38990 deletions

View File

@@ -17,7 +17,7 @@ import { tmpdir } from 'os';
export interface OpenCommandPipeArgs {
type: 'open';
fileURIs?: string[];
folderURIs: string[];
folderURIs?: string[];
forceNewWindow?: boolean;
diffMode?: boolean;
addMode?: boolean;
@@ -26,6 +26,11 @@ export interface OpenCommandPipeArgs {
waitMarkerFilePath?: string;
}
export interface OpenExternalCommandPipeArgs {
type: 'openExternal';
uris: string[];
}
export interface StatusPipeArgs {
type: 'status';
}
@@ -36,6 +41,8 @@ export interface RunCommandPipeArgs {
args: any[];
}
export type PipeCommand = OpenCommandPipeArgs | StatusPipeArgs | RunCommandPipeArgs | OpenExternalCommandPipeArgs;
export interface ICommandsExecuter {
executeCommand<T>(id: string, ...args: any[]): Promise<T>;
}
@@ -80,11 +87,14 @@ export class CLIServerBase {
req.setEncoding('utf8');
req.on('data', (d: string) => chunks.push(d));
req.on('end', () => {
const data: OpenCommandPipeArgs | StatusPipeArgs | RunCommandPipeArgs | any = JSON.parse(chunks.join(''));
const data: PipeCommand | any = JSON.parse(chunks.join(''));
switch (data.type) {
case 'open':
this.open(data, res);
break;
case 'openExternal':
this.openExternal(data, res);
break;
case 'status':
this.getStatus(data, res);
break;
@@ -140,6 +150,14 @@ export class CLIServerBase {
res.end();
}
private openExternal(data: OpenExternalCommandPipeArgs, res: http.ServerResponse) {
for (const uri of data.uris) {
this._commands.executeCommand('_workbench.openExternal', URI.parse(uri), { allowTunneling: true });
}
res.writeHead(200);
res.end();
}
private async getStatus(data: StatusPipeArgs, res: http.ServerResponse) {
try {
const status = await this._commands.executeCommand('_issues.getSystemStatus');

View File

@@ -14,7 +14,6 @@ import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensi
import { IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { IAdapterDescriptor } from 'vs/workbench/contrib/debug/common/debug';
import { IExtHostConfiguration, ExtHostConfigProvider } from '../common/extHostConfiguration';
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';
@@ -24,13 +23,14 @@ 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 { createCancelablePromise, firstParallel } from 'vs/base/common/async';
export class ExtHostDebugService extends ExtHostDebugServiceBase {
readonly _serviceBrand: undefined;
private _integratedTerminalInstance?: vscode.Terminal;
private _integratedTerminalInstances = new DebugTerminalCollection();
private _terminalDisposedListener: IDisposable | undefined;
constructor(
@@ -39,10 +39,9 @@ export class ExtHostDebugService extends ExtHostDebugServiceBase {
@IExtHostExtensionService extensionService: IExtHostExtensionService,
@IExtHostDocumentsAndEditors editorsService: IExtHostDocumentsAndEditors,
@IExtHostConfiguration configurationService: IExtHostConfiguration,
@IExtHostTerminalService private _terminalService: IExtHostTerminalService,
@IExtHostCommands commandService: IExtHostCommands
@IExtHostTerminalService private _terminalService: IExtHostTerminalService
) {
super(extHostRpcService, workspaceService, extensionService, editorsService, configurationService, commandService);
super(extHostRpcService, workspaceService, extensionService, editorsService, configurationService);
}
protected createDebugAdapter(adapter: IAdapterDescriptor, session: ExtHostDebugSession): AbstractDebugAdapter | undefined {
@@ -76,40 +75,44 @@ export class ExtHostDebugService extends ExtHostDebugServiceBase {
if (!this._terminalDisposedListener) {
// React on terminal disposed and check if that is the debug terminal #12956
this._terminalDisposedListener = this._terminalService.onDidCloseTerminal(terminal => {
if (this._integratedTerminalInstance && this._integratedTerminalInstance === terminal) {
this._integratedTerminalInstance = undefined;
}
this._integratedTerminalInstances.onTerminalClosed(terminal);
});
}
let needNewTerminal = true; // be pessimistic
if (this._integratedTerminalInstance) {
const pid = await this._integratedTerminalInstance.processId;
needNewTerminal = await hasChildProcesses(pid); // if no processes running in terminal reuse terminal
}
const configProvider = await this._configurationService.getConfigProvider();
const shell = this._terminalService.getDefaultShell(true, configProvider);
const shellArgs = this._terminalService.getDefaultShellArgs(true, configProvider);
const shellConfig = JSON.stringify({ shell, shellArgs });
let terminal = await this._integratedTerminalInstances.checkout(shellConfig);
let cwdForPrepareCommand: string | undefined;
let giveShellTimeToInitialize = false;
if (needNewTerminal || !this._integratedTerminalInstance) {
if (!terminal) {
const options: vscode.TerminalOptions = {
shellPath: shell,
// shellArgs: this._terminalService._getDefaultShellArgs(configProvider),
shellArgs: shellArgs,
cwd: args.cwd,
name: args.title || nls.localize('debug.terminal.title', "debuggee"),
};
this._integratedTerminalInstance = this._terminalService.createTerminalFromOptions(options, true);
giveShellTimeToInitialize = true;
terminal = this._terminalService.createTerminalFromOptions(options, true);
this._integratedTerminalInstances.insert(terminal, shellConfig);
} else {
cwdForPrepareCommand = args.cwd;
}
const terminal = this._integratedTerminalInstance;
terminal.show();
const shellProcessId = await this._integratedTerminalInstance.processId;
const shellProcessId = await terminal.processId;
if (giveShellTimeToInitialize) {
// give a new terminal some time to initialize the shell
await new Promise(resolve => setTimeout(resolve, 1000));
}
const command = prepareCommand(shell, args.args, cwdForPrepareCommand, args.env);
terminal.sendText(command, true);
@@ -123,6 +126,49 @@ export class ExtHostDebugService extends ExtHostDebugServiceBase {
}
protected createVariableResolver(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider): AbstractVariableResolverService {
return new ExtHostVariableResolverService(folders, editorService, configurationService, process.env as env.IProcessEnvironment);
return new ExtHostVariableResolverService(folders, editorService, configurationService, process.env as env.IProcessEnvironment, this._workspaceService);
}
}
class DebugTerminalCollection {
/**
* Delay before a new terminal is a candidate for reuse. See #71850
*/
private static minUseDelay = 1000;
private _terminalInstances = new Map<vscode.Terminal, { lastUsedAt: number, config: string }>();
public async checkout(config: string) {
const entries = [...this._terminalInstances.keys()];
const promises = entries.map((terminal) => createCancelablePromise(async ct => {
const pid = await terminal.processId;
if (await hasChildProcesses(pid)) {
return null;
}
// important: date check and map operations must be synchronous
const now = Date.now();
const termInfo = this._terminalInstances.get(terminal);
if (!termInfo || termInfo.lastUsedAt + DebugTerminalCollection.minUseDelay > now || ct.isCancellationRequested) {
return null;
}
if (termInfo.config !== config) {
return null;
}
termInfo.lastUsedAt = now;
return terminal;
}));
return await firstParallel(promises, (t): t is vscode.Terminal => !!t);
}
public insert(terminal: vscode.Terminal, termConfig: string) {
this._terminalInstances.set(terminal, { lastUsedAt: Date.now(), config: termConfig });
}
public onTerminalClosed(terminal: vscode.Terminal) {
this._terminalInstances.delete(terminal);
}
}

View File

@@ -50,6 +50,10 @@ export class ExtHostTask extends ExtHostTaskBase {
}
public async executeTask(extension: IExtensionDescription, task: vscode.Task): Promise<vscode.TaskExecution> {
if (!task.execution) {
throw new Error('Tasks to execute must include an execution');
}
const tTask = (task as types.Task);
// We have a preserved ID. So the task didn't change.
if (tTask._id !== undefined) {

View File

@@ -23,6 +23,7 @@ import { BaseExtHostTerminalService, ExtHostTerminal } from 'vs/workbench/api/co
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { MergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableCollection';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { withNullAsUndefined } from 'vs/base/common/types';
export class ExtHostTerminalService extends BaseExtHostTerminalService {
@@ -56,7 +57,15 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
public createTerminalFromOptions(options: vscode.TerminalOptions, isFeatureTerminal?: boolean): vscode.Terminal {
const terminal = new ExtHostTerminal(this._proxy, options, options.name);
this._terminals.push(terminal);
terminal.create(options.shellPath, options.shellArgs, options.cwd, options.env, /*options.waitOnExit*/ undefined, options.strictEnv, options.hideFromUser, isFeatureTerminal);
terminal.create(
withNullAsUndefined(options.shellPath),
withNullAsUndefined(options.shellArgs),
withNullAsUndefined(options.cwd),
withNullAsUndefined(options.env),
/*options.waitOnExit*/ undefined,
withNullAsUndefined(options.strictEnv),
withNullAsUndefined(options.hideFromUser),
withNullAsUndefined(isFeatureTerminal));
return terminal;
}

View File

@@ -16,7 +16,8 @@ import { isLinux } from 'vs/base/common/platform';
import { IExtHostTunnelService, TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
import { asPromise } from 'vs/base/common/async';
import { Event, Emitter } from 'vs/base/common/event';
import { TunnelOptions } from 'vs/platform/remote/common/tunnel';
import { TunnelOptions, TunnelCreationOptions } from 'vs/platform/remote/common/tunnel';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
class ExtensionTunnel implements vscode.Tunnel {
private _onDispose: Emitter<void> = new Emitter();
@@ -36,9 +37,9 @@ class ExtensionTunnel implements vscode.Tunnel {
export class ExtHostTunnelService extends Disposable implements IExtHostTunnelService {
readonly _serviceBrand: undefined;
private readonly _proxy: MainThreadTunnelServiceShape;
private _forwardPortProvider: ((tunnelOptions: TunnelOptions) => Thenable<vscode.Tunnel> | undefined) | undefined;
private _forwardPortProvider: ((tunnelOptions: TunnelOptions, tunnelCreationOptions: TunnelCreationOptions) => Thenable<vscode.Tunnel> | undefined) | undefined;
private _showCandidatePort: (host: string, port: number, detail: string) => Thenable<boolean> = () => { return Promise.resolve(true); };
private _extensionTunnels: Map<string, Map<number, vscode.Tunnel>> = new Map();
private _extensionTunnels: Map<string, Map<number, { tunnel: vscode.Tunnel, disposeListener: IDisposable }>> = new Map();
private _onDidChangeTunnels: Emitter<void> = new Emitter<void>();
onDidChangeTunnels: vscode.Event<void> = this._onDidChangeTunnels.event;
@@ -53,8 +54,8 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
}
}
async openTunnel(forward: TunnelOptions): Promise<vscode.Tunnel | undefined> {
const tunnel = await this._proxy.$openTunnel(forward);
async openTunnel(extension: IExtensionDescription, forward: TunnelOptions): Promise<vscode.Tunnel | undefined> {
const tunnel = await this._proxy.$openTunnel(forward, extension.displayName);
if (tunnel) {
const disposableTunnel: vscode.Tunnel = new ExtensionTunnel(tunnel.remoteAddress, tunnel.localAddress, () => {
return this._proxy.$closeTunnel(tunnel.remoteAddress);
@@ -69,21 +70,25 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
return this._proxy.$getTunnels();
}
registerCandidateFinder(): Promise<void> {
return this._proxy.$registerCandidateFinder();
}
$filterCandidates(candidates: { host: string, port: number, detail: string }[]): Promise<boolean[]> {
return Promise.all(candidates.map(candidate => {
return this._showCandidatePort(candidate.host, candidate.port, candidate.detail);
}));
registerCandidateFinder(): void {
// Every two seconds, scan to see if the candidate ports have changed;
if (isLinux) {
let oldPorts: { host: string, port: number, detail: string }[] | undefined = undefined;
setInterval(async () => {
const newPorts = await this.findCandidatePorts();
if (!oldPorts || (JSON.stringify(oldPorts) !== JSON.stringify(newPorts))) {
oldPorts = newPorts;
this._proxy.$onFoundNewCandidates(oldPorts.filter(async (candidate) => await this._showCandidatePort(candidate.host, candidate.port, candidate.detail)));
return;
}
}, 2000);
}
}
async setTunnelExtensionFunctions(provider: vscode.RemoteAuthorityResolver | undefined): Promise<IDisposable> {
if (provider) {
if (provider.showCandidatePort) {
this._showCandidatePort = provider.showCandidatePort;
await this._proxy.$setCandidateFilter();
}
if (provider.tunnelFactory) {
this._forwardPortProvider = provider.tunnelFactory;
@@ -98,11 +103,14 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
});
}
async $closeTunnel(remote: { host: string, port: number }): Promise<void> {
async $closeTunnel(remote: { host: string, port: number }, silent?: boolean): Promise<void> {
if (this._extensionTunnels.has(remote.host)) {
const hostMap = this._extensionTunnels.get(remote.host)!;
if (hostMap.has(remote.port)) {
hostMap.get(remote.port)!.dispose();
if (silent) {
hostMap.get(remote.port)!.disposeListener.dispose();
}
hostMap.get(remote.port)!.tunnel.dispose();
hostMap.delete(remote.port);
}
}
@@ -112,16 +120,16 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
this._onDidChangeTunnels.fire();
}
$forwardPort(tunnelOptions: TunnelOptions): Promise<TunnelDto> | undefined {
$forwardPort(tunnelOptions: TunnelOptions, tunnelCreationOptions: TunnelCreationOptions): Promise<TunnelDto> | undefined {
if (this._forwardPortProvider) {
const providedPort = this._forwardPortProvider!(tunnelOptions);
const providedPort = this._forwardPortProvider(tunnelOptions, tunnelCreationOptions);
if (providedPort !== undefined) {
return asPromise(() => providedPort).then(tunnel => {
if (!this._extensionTunnels.has(tunnelOptions.remoteAddress.host)) {
this._extensionTunnels.set(tunnelOptions.remoteAddress.host, new Map());
}
this._extensionTunnels.get(tunnelOptions.remoteAddress.host)!.set(tunnelOptions.remoteAddress.port, tunnel);
this._register(tunnel.onDidDispose(() => this._proxy.$closeTunnel(tunnel.remoteAddress)));
const disposeListener = this._register(tunnel.onDidDispose(() => this._proxy.$closeTunnel(tunnel.remoteAddress)));
this._extensionTunnels.get(tunnelOptions.remoteAddress.host)!.set(tunnelOptions.remoteAddress.port, { tunnel, disposeListener });
return Promise.resolve(TunnelDto.fromApiTunnel(tunnel));
});
}
@@ -130,11 +138,7 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
}
async $findCandidatePorts(): Promise<{ host: string, port: number, detail: string }[]> {
if (!isLinux) {
return [];
}
async findCandidatePorts(): Promise<{ host: string, port: number, detail: string }[]> {
const ports: { host: string, port: number, detail: string }[] = [];
let tcp: string = '';
let tcp6: string = '';
@@ -189,15 +193,19 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
return ports;
}
private getSockets(stdout: string) {
private getSockets(stdout: string): { pid: number, socket: number }[] {
const lines = stdout.trim().split('\n');
return lines.map(line => {
const mapped: { pid: number, socket: number }[] = [];
lines.forEach(line => {
const match = /\/proc\/(\d+)\/fd\/\d+ -> socket:\[(\d+)\]/.exec(line)!;
return {
pid: parseInt(match[1], 10),
socket: parseInt(match[2], 10)
};
if (match && match.length >= 3) {
mapped.push({
pid: parseInt(match[1], 10),
socket: parseInt(match[2], 10)
});
}
});
return mapped;
}
private loadListeningPorts(...stdouts: string[]): { socket: number, ip: string, port: number }[] {