chore(vscode): update to 1.55.2

This commit is contained in:
Akash Satheesan
2021-04-09 11:32:27 +05:30
1102 changed files with 39988 additions and 23544 deletions

View File

@@ -18,13 +18,31 @@ import { onUnexpectedError } from 'vs/base/common/errors';
import { Platform, platform } from 'vs/base/common/platform';
export class NodeSocket implements ISocket {
public readonly socket: Socket;
private readonly _errorListener: (err: any) => void;
constructor(socket: Socket) {
this.socket = socket;
this._errorListener = (err: any) => {
if (err) {
if (err.code === 'EPIPE') {
// An EPIPE exception at the wrong time can lead to a renderer process crash
// so ignore the error since the socket will fire the close event soon anyways:
// > https://nodejs.org/api/errors.html#errors_common_system_errors
// > EPIPE (Broken pipe): A write on a pipe, socket, or FIFO for which there is no
// > process to read the data. Commonly encountered at the net and http layers,
// > indicative that the remote side of the stream being written to has been closed.
return;
}
onUnexpectedError(err);
}
};
this.socket.on('error', this._errorListener);
}
public dispose(): void {
this.socket.off('error', this._errorListener);
this.socket.destroy();
}
@@ -62,7 +80,20 @@ export class NodeSocket implements ISocket {
// > However, the false return value is only advisory and the writable stream will unconditionally
// > accept and buffer chunk even if it has not been allowed to drain.
try {
this.socket.write(<Buffer>buffer.buffer);
this.socket.write(<Buffer>buffer.buffer, (err: any) => {
if (err) {
if (err.code === 'EPIPE') {
// An EPIPE exception at the wrong time can lead to a renderer process crash
// so ignore the error since the socket will fire the close event soon anyways:
// > https://nodejs.org/api/errors.html#errors_common_system_errors
// > EPIPE (Broken pipe): A write on a pipe, socket, or FIFO for which there is no
// > process to read the data. Commonly encountered at the net and http layers,
// > indicative that the remote side of the stream being written to has been closed.
return;
}
onUnexpectedError(err);
}
});
} catch (err) {
if (err.code === 'EPIPE') {
// An EPIPE exception at the wrong time can lead to a renderer process crash

View File

@@ -6,7 +6,7 @@
import * as assert from 'assert';
import { Client } from 'vs/base/parts/ipc/node/ipc.cp';
import { TestServiceClient } from './testService';
import { getPathFromAmdModule } from 'vs/base/common/amd';
import { getPathFromAmdModule } from 'vs/base/test/node/testUtils';
function createClient(): Client {
return new Client(getPathFromAmdModule(require, 'bootstrap-fork'), {

View File

@@ -7,7 +7,7 @@
position: absolute;
width: 600px;
z-index: 2000;
padding-bottom: 6px;
padding: 0 1px 6px 1px;
left: 50%;
margin-left: -300px;
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/quickInput';
import { IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox, IQuickPickItemButtonEvent, QuickPickInput, IQuickPickSeparator, IKeyMods, IQuickPickAcceptEvent, NO_KEY_MODS, ItemActivation } from 'vs/base/parts/quickinput/common/quickInput';
import { IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox, IQuickPickItemButtonEvent, QuickPickInput, IQuickPickSeparator, IKeyMods, IQuickPickAcceptEvent, NO_KEY_MODS, ItemActivation, QuickInputHideReason, IQuickInputHideEvent } from 'vs/base/parts/quickinput/common/quickInput';
import * as dom from 'vs/base/browser/dom';
import { CancellationToken } from 'vs/base/common/cancellation';
import { QuickInputList, QuickInputListFocus } from './quickInputList';
@@ -31,6 +31,7 @@ import { registerCodicon, Codicon } from 'vs/base/common/codicons';
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
import { escape } from 'vs/base/common/strings';
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
import { isString } from 'vs/base/common/types';
export interface IQuickInputOptions {
idPrefix: string;
@@ -133,6 +134,7 @@ type Visibilities = {
};
class QuickInput extends Disposable implements IQuickInput {
protected static readonly noPromptMessage = localize('inputModeEntry', "Press 'Enter' to confirm your input or 'Escape' to cancel");
private _title: string | undefined;
private _description: string | undefined;
@@ -144,9 +146,14 @@ class QuickInput extends Disposable implements IQuickInput {
private _busy = false;
private _ignoreFocusOut = false;
private _buttons: IQuickInputButton[] = [];
protected noValidationMessage = QuickInput.noPromptMessage;
private _validationMessage: string | undefined;
private _lastValidationMessage: string | undefined;
private _severity: Severity = Severity.Ignore;
private _lastSeverity: Severity | undefined;
private buttonsUpdated = false;
private readonly onDidTriggerButtonEmitter = this._register(new Emitter<IQuickInputButton>());
private readonly onDidHideEmitter = this._register(new Emitter<void>());
private readonly onDidHideEmitter = this._register(new Emitter<IQuickInputHideEvent>());
private readonly onDisposeEmitter = this._register(new Emitter<void>());
protected readonly visibleDisposables = this._register(new DisposableStore());
@@ -241,6 +248,24 @@ class QuickInput extends Disposable implements IQuickInput {
this.update();
}
get validationMessage() {
return this._validationMessage;
}
set validationMessage(validationMessage: string | undefined) {
this._validationMessage = validationMessage;
this.update();
}
get severity() {
return this._severity;
}
set severity(severity: Severity) {
this._severity = severity;
this.update();
}
readonly onDidTriggerButton = this.onDidTriggerButtonEmitter.event;
show(): void {
@@ -266,10 +291,10 @@ class QuickInput extends Disposable implements IQuickInput {
this.ui.hide();
}
didHide(): void {
didHide(reason = QuickInputHideReason.Other): void {
this.visible = false;
this.visibleDisposables.clear();
this.onDidHideEmitter.fire();
this.onDidHideEmitter.fire({ reason });
}
readonly onDidHide = this.onDidHideEmitter.event;
@@ -328,6 +353,16 @@ class QuickInput extends Disposable implements IQuickInput {
this.ui.ignoreFocusOut = this.ignoreFocusOut;
this.ui.setEnabled(this.enabled);
this.ui.setContextKey(this.contextKey);
const validationMessage = this.validationMessage || this.noValidationMessage;
if (this._lastValidationMessage !== validationMessage) {
this._lastValidationMessage = validationMessage;
dom.reset(this.ui.message, ...renderLabelWithIcons(escape(validationMessage)));
}
if (this._lastSeverity !== this.severity) {
this._lastSeverity = this.severity;
this.showMessageDecoration(this.severity);
}
}
private getTitle() {
@@ -359,7 +394,7 @@ class QuickInput extends Disposable implements IQuickInput {
protected showMessageDecoration(severity: Severity) {
this.ui.inputBox.showDecoration(severity);
if (severity === Severity.Error) {
if (severity !== Severity.Ignore) {
const styles = this.ui.inputBox.stylesForType(severity);
this.ui.message.style.color = styles.foreground ? `${styles.foreground}` : '';
this.ui.message.style.backgroundColor = styles.background ? `${styles.background}` : '';
@@ -414,8 +449,6 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
private readonly onDidTriggerItemButtonEmitter = this._register(new Emitter<IQuickPickItemButtonEvent<T>>());
private _valueSelection: Readonly<[number, number]> | undefined;
private valueSelectionUpdated = true;
private _validationMessage: string | undefined;
private _lastValidationMessage: string | undefined;
private _ok: boolean | 'default' = 'default';
private _customButton = false;
private _customButtonLabel: string | undefined;
@@ -587,15 +620,6 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
this.update();
}
get validationMessage() {
return this._validationMessage;
}
set validationMessage(validationMessage: string | undefined) {
this._validationMessage = validationMessage;
this.update();
}
get customButton() {
return this._customButton;
}
@@ -964,12 +988,6 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
this.selectedItemsToConfirm = null;
}
}
const validationMessage = this.validationMessage || '';
if (this._lastValidationMessage !== validationMessage) {
this._lastValidationMessage = validationMessage;
dom.reset(this.ui.message, ...renderLabelWithIcons(escape(validationMessage)));
this.showMessageDecoration(this.validationMessage ? Severity.Error : Severity.Ignore);
}
this.ui.customButton.label = this.customLabel || '';
this.ui.customButton.element.title = this.customHover || '';
this.ui.setComboboxAccessibility(true);
@@ -987,18 +1005,12 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
}
class InputBox extends QuickInput implements IInputBox {
private static readonly noPromptMessage = localize('inputModeEntry', "Press 'Enter' to confirm your input or 'Escape' to cancel");
private _value = '';
private _valueSelection: Readonly<[number, number]> | undefined;
private valueSelectionUpdated = true;
private _placeholder: string | undefined;
private _password = false;
private _prompt: string | undefined;
private noValidationMessage = InputBox.noPromptMessage;
private _validationMessage: string | undefined;
private _lastValidationMessage: string | undefined;
private readonly onDidValueChangeEmitter = this._register(new Emitter<string>());
private readonly onDidAcceptEmitter = this._register(new Emitter<void>());
@@ -1043,16 +1055,7 @@ class InputBox extends QuickInput implements IInputBox {
this._prompt = prompt;
this.noValidationMessage = prompt
? localize('inputModeEntryDescription', "{0} (Press 'Enter' to confirm or 'Escape' to cancel)", prompt)
: InputBox.noPromptMessage;
this.update();
}
get validationMessage() {
return this._validationMessage;
}
set validationMessage(validationMessage: string | undefined) {
this._validationMessage = validationMessage;
: QuickInput.noPromptMessage;
this.update();
}
@@ -1100,12 +1103,7 @@ class InputBox extends QuickInput implements IInputBox {
if (this.ui.inputBox.password !== this.password) {
this.ui.inputBox.password = this.password;
}
const validationMessage = this.validationMessage || this.noValidationMessage;
if (this._lastValidationMessage !== validationMessage) {
this._lastValidationMessage = validationMessage;
dom.reset(this.ui.message, ...renderLabelWithIcons(validationMessage));
this.showMessageDecoration(this.validationMessage ? Severity.Error : Severity.Ignore);
}
}
}
@@ -1222,9 +1220,6 @@ export class QuickInputController extends Disposable {
const message = dom.append(extraContainer, $(`#${this.idPrefix}message.quick-input-message`));
const progressBar = new ProgressBar(container);
progressBar.getContainer().classList.add('quick-input-progress');
const list = this._register(new QuickInputList(container, this.idPrefix + 'list', this.options));
this._register(list.onChangedAllVisibleChecked(checked => {
checkAll.checked = checked;
@@ -1250,6 +1245,9 @@ export class QuickInputController extends Disposable {
}
}));
const progressBar = new ProgressBar(container);
progressBar.getContainer().classList.add('quick-input-progress');
const focusTracker = dom.trackFocus(container);
this._register(focusTracker);
this._register(dom.addDisposableListener(container, dom.EventType.FOCUS, e => {
@@ -1257,7 +1255,7 @@ export class QuickInputController extends Disposable {
}, true));
this._register(focusTracker.onDidBlur(() => {
if (!this.getUI().ignoreFocusOut && !this.options.ignoreFocusOut()) {
this.hide();
this.hide(QuickInputHideReason.Blur);
}
this.previousFocusElement = undefined;
}));
@@ -1273,7 +1271,7 @@ export class QuickInputController extends Disposable {
break;
case KeyCode.Escape:
dom.EventHelper.stop(e, true);
this.hide();
this.hide(QuickInputHideReason.Gesture);
break;
case KeyCode.Tab:
if (!event.altKey && !event.ctrlKey && !event.metaKey) {
@@ -1320,8 +1318,8 @@ export class QuickInputController extends Disposable {
message,
customButtonContainer,
customButton,
progressBar,
list,
progressBar,
onDidAccept: this.onDidAcceptEmitter.event,
onDidCustom: this.onDidCustomEmitter.event,
onDidTriggerButton: this.onDidTriggerButtonEmitter.event,
@@ -1408,6 +1406,7 @@ export class QuickInputController extends Disposable {
resolve(undefined);
}),
];
input.title = options.title;
input.canSelectMany = !!options.canPickMany;
input.placeholder = options.placeHolder;
input.ignoreFocusOut = !!options.ignoreFocusLost;
@@ -1438,6 +1437,22 @@ export class QuickInputController extends Disposable {
});
}
private setValidationOnInput(input: IInputBox, validationResult: string | {
content: string;
severity: Severity;
} | null | undefined) {
if (validationResult && isString(validationResult)) {
input.severity = Severity.Error;
input.validationMessage = validationResult;
} else if (validationResult && !isString(validationResult)) {
input.severity = validationResult.severity;
input.validationMessage = validationResult.content;
} else {
input.severity = Severity.Ignore;
input.validationMessage = undefined;
}
}
input(options: IInputOptions = {}, token: CancellationToken = CancellationToken.None): Promise<string | undefined> {
return new Promise<string | undefined>((resolve) => {
if (token.isCancellationRequested) {
@@ -1458,7 +1473,7 @@ export class QuickInputController extends Disposable {
}
validation.then(result => {
if (value === validationValue) {
input.validationMessage = result || undefined;
this.setValidationOnInput(input, result);
}
});
}),
@@ -1469,11 +1484,11 @@ export class QuickInputController extends Disposable {
validationValue = value;
}
validation.then(result => {
if (!result) {
if (!result || (!isString(result) && result.severity !== Severity.Error)) {
resolve(value);
input.hide();
} else if (value === validationValue) {
input.validationMessage = result;
this.setValidationOnInput(input, result);
}
});
}),
@@ -1485,6 +1500,8 @@ export class QuickInputController extends Disposable {
resolve(undefined);
}),
];
input.title = options.title;
input.value = options.value || '';
input.valueSelection = options.valueSelection;
input.prompt = options.prompt;
@@ -1600,7 +1617,7 @@ export class QuickInputController extends Disposable {
}
}
hide() {
hide(reason?: QuickInputHideReason) {
const controller = this.controller;
if (controller) {
const focusChanged = !this.ui?.container.contains(document.activeElement);
@@ -1615,7 +1632,7 @@ export class QuickInputController extends Disposable {
this.options.returnFocus();
}
}
controller.didHide();
controller.didHide(reason);
}
}

View File

@@ -10,6 +10,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import { IMatch } from 'vs/base/common/filters';
import { IItemAccessor } from 'vs/base/common/fuzzyScorer';
import { Schemas } from 'vs/base/common/network';
import Severity from 'vs/base/common/severity';
export interface IQuickPickItemHighlights {
label?: IMatch[];
@@ -58,6 +59,11 @@ export interface IQuickNavigateConfiguration {
export interface IPickOptions<T extends IQuickPickItem> {
/**
* an optional string to show as the title of the quick input
*/
title?: string;
/**
* an optional string to show as placeholder in the input box to guide the user what she picks on
*/
@@ -115,6 +121,11 @@ export interface IPickOptions<T extends IQuickPickItem> {
export interface IInputOptions {
/**
* an optional string to show as the title of the quick input
*/
title?: string;
/**
* the value to prefill in the input box
*/
@@ -145,12 +156,34 @@ export interface IInputOptions {
/**
* an optional function that is used to validate user input.
*/
validateInput?: (input: string) => Promise<string | null | undefined>;
validateInput?: (input: string) => Promise<string | null | undefined | { content: string, severity: Severity }>;
}
export enum QuickInputHideReason {
/**
* Focus moved away from the quick input.
*/
Blur = 1,
/**
* An explicit user gesture, e.g. pressing Escape key.
*/
Gesture,
/**
* Anything else.
*/
Other
}
export interface IQuickInputHideEvent {
reason: QuickInputHideReason;
}
export interface IQuickInput extends IDisposable {
readonly onDidHide: Event<void>;
readonly onDidHide: Event<IQuickInputHideEvent>;
readonly onDispose: Event<void>;
title: string | undefined;
@@ -301,6 +334,8 @@ export interface IInputBox extends IQuickInput {
prompt: string | undefined;
validationMessage: string | undefined;
severity: Severity;
}
export interface IQuickInputButton {

View File

@@ -22,6 +22,8 @@
/**
* A minimal set of methods exposed from Electron's `ipcRenderer`
* to support communication to main process.
*
* @type {import('../electron-sandbox/electronTypes').IpcRenderer}
*/
ipcRenderer: {
@@ -49,34 +51,46 @@
/**
* @param {string} channel
* @param {(event: import('electron').IpcRendererEvent, ...args: any[]) => void} listener
* @returns {import('../electron-sandbox/electronTypes').IpcRenderer}
*/
on(channel, listener) {
if (validateIPC(channel)) {
ipcRenderer.on(channel, listener);
return this;
}
},
/**
* @param {string} channel
* @param {(event: import('electron').IpcRendererEvent, ...args: any[]) => void} listener
* @returns {import('../electron-sandbox/electronTypes').IpcRenderer}
*/
once(channel, listener) {
if (validateIPC(channel)) {
ipcRenderer.once(channel, listener);
return this;
}
},
/**
* @param {string} channel
* @param {(event: import('electron').IpcRendererEvent, ...args: any[]) => void} listener
* @returns {import('../electron-sandbox/electronTypes').IpcRenderer}
*/
removeListener(channel, listener) {
if (validateIPC(channel)) {
ipcRenderer.removeListener(channel, listener);
return this;
}
}
},
/**
* @type {import('../electron-sandbox/globals').IpcMessagePort}
*/
ipcMessagePort: {
/**
@@ -106,6 +120,8 @@
/**
* Support for subset of methods of Electron's `webFrame` type.
*
* @type {import('../electron-sandbox/electronTypes').WebFrame}
*/
webFrame: {
@@ -121,6 +137,8 @@
/**
* Support for subset of methods of Electron's `crashReporter` type.
*
* @type {import('../electron-sandbox/electronTypes').CrashReporter}
*/
crashReporter: {
@@ -138,6 +156,8 @@
*
* Note: when `sandbox` is enabled, the only properties available
* are https://github.com/electron/electron/blob/master/docs/api/process.md#sandbox
*
* @type {import('../electron-sandbox/globals').ISandboxNodeProcess}
*/
process: {
get platform() { return process.platform; },
@@ -146,6 +166,21 @@
get versions() { return process.versions; },
get type() { return 'renderer'; },
get execPath() { return process.execPath; },
get sandboxed() { return process.sandboxed; },
/**
* @returns {string}
*/
cwd() {
return process.env['VSCODE_CWD'] || process.execPath.substr(0, process.execPath.lastIndexOf(process.platform === 'win32' ? '\\' : '/'));
},
/**
* @returns {Promise<typeof process.env>}
*/
getShellEnv() {
return shellEnv;
},
/**
* @param {{[key: string]: string}} userEnv
@@ -164,20 +199,17 @@
/**
* @param {string} type
* @param {() => void} callback
* @param {Function} callback
* @returns {import('../electron-sandbox/globals').ISandboxNodeProcess}
*/
on(type, callback) {
if (validateProcessEventType(type)) {
// @ts-ignore
process.on(type, callback);
return this;
}
}
},
/**
* Some information about the context we are running in.
*/
context: {
get sandbox() { return process.sandboxed; }
}
};
@@ -226,8 +258,8 @@
return true;
}
/** @type {Promise<void> | undefined} */
let resolvedEnv = undefined;
/** @type {Promise<typeof process.env> | undefined} */
let shellEnv = undefined;
/**
* If VSCode is not run from a terminal, we should resolve additional
@@ -238,28 +270,29 @@
* @param {{[key: string]: string}} userEnv
* @returns {Promise<void>}
*/
function resolveEnv(userEnv) {
if (!resolvedEnv) {
async function resolveEnv(userEnv) {
if (!shellEnv) {
// Apply `userEnv` directly
Object.assign(process.env, userEnv);
// Resolve `shellEnv` from the main side
resolvedEnv = new Promise(function (resolve) {
ipcRenderer.once('vscode:acceptShellEnv', function (event, shellEnv) {
shellEnv = new Promise(function (resolve) {
ipcRenderer.once('vscode:acceptShellEnv', function (event, shellEnvResult) {
if (!process.env['VSCODE_SKIP_PROCESS_ENV_PATCHING'] /* TODO@bpasero for https://github.com/microsoft/vscode/issues/108804 */) {
// Assign all keys of the shell environment to our process environment
// But make sure that the user environment wins in the end over shell environment
Object.assign(process.env, shellEnvResult, userEnv);
}
// Assign all keys of the shell environment to our process environment
// But make sure that the user environment wins in the end
Object.assign(process.env, shellEnv, userEnv);
resolve();
resolve({ ...process.env, ...shellEnvResult, ...userEnv });
});
ipcRenderer.send('vscode:fetchShellEnv');
});
}
return resolvedEnv;
await shellEnv;
}
//#endregion

View File

@@ -3,19 +3,19 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { globals, IProcessEnvironment } from 'vs/base/common/platform';
import { globals, INodeProcess, IProcessEnvironment } from 'vs/base/common/platform';
import { ProcessMemoryInfo, CrashReporter, IpcRenderer, WebFrame } from 'vs/base/parts/sandbox/electron-sandbox/electronTypes';
/**
* In sandboxed renderers we cannot expose all of the `process` global of node.js
*/
export interface IPartialNodeProcess {
export interface ISandboxNodeProcess extends INodeProcess {
/**
* The process.platform property returns a string identifying the operating system platform
* on which the Node.js process is running.
*/
readonly platform: 'win32' | 'linux' | 'darwin';
readonly platform: string;
/**
* The process.arch property returns a string identifying the CPU architecture
@@ -24,9 +24,14 @@ export interface IPartialNodeProcess {
readonly arch: string;
/**
* The type will always be Electron renderer.
* The type will always be `renderer`.
*/
readonly type: 'renderer';
readonly type: string;
/**
* Whether the process is sandboxed or not.
*/
readonly sandboxed: boolean;
/**
* A list of versions for the current node.js/electron configuration.
@@ -48,6 +53,11 @@ export interface IPartialNodeProcess {
*/
on: (type: string, callback: Function) => void;
/**
* The current working directory of the process.
*/
cwd: () => string;
/**
* Resolves with a ProcessMemoryInfo
*
@@ -62,9 +72,6 @@ export interface IPartialNodeProcess {
* process on macOS.
*/
getProcessMemoryInfo: () => Promise<ProcessMemoryInfo>;
}
export interface ISandboxNodeProcess extends IPartialNodeProcess {
/**
* A custom method we add to `process`: Resolve the true process environment to use and
@@ -84,14 +91,12 @@ export interface ISandboxNodeProcess extends IPartialNodeProcess {
* set of environment in `process.env`.
*/
resolveEnv(userEnv: IProcessEnvironment): Promise<void>;
}
export interface ISandboxContext {
/**
* Whether the renderer runs with `sandbox` enabled or not.
* Returns a process environment that includes any shell environment even if the application
* was not started from a shell / terminal / console.
*/
sandbox: boolean;
getShellEnv(): Promise<IProcessEnvironment>;
}
export interface IpcMessagePort {
@@ -114,4 +119,3 @@ export const ipcMessagePort: IpcMessagePort = globals.vscode.ipcMessagePort;
export const webFrame: WebFrame = globals.vscode.webFrame;
export const crashReporter: CrashReporter = globals.vscode.crashReporter;
export const process: ISandboxNodeProcess = globals.vscode.process;
export const context: ISandboxContext = globals.vscode.context;

View File

@@ -8,7 +8,7 @@ import { ipcRenderer, crashReporter, webFrame, process } from 'vs/base/parts/san
suite('Sandbox', () => {
test('globals', () => {
assert.ok(typeof ipcRenderer.invoke === 'function');
assert.ok(typeof ipcRenderer.send === 'function');
assert.ok(typeof crashReporter.addExtraParameter === 'function');
assert.ok(typeof webFrame.setZoomLevel === 'function');
assert.ok(typeof process.platform === 'string');