Merge from vscode 7eaf220cafb9d9e901370ffce02229171cbf3ea6

This commit is contained in:
ADS Merger
2020-09-03 02:34:56 +00:00
committed by Anthony Dresser
parent 39d9eed585
commit a63578e6f7
519 changed files with 14338 additions and 6670 deletions

View File

@@ -17,6 +17,9 @@
<!-- Builtin Extensions (running out of sources) -->
<meta id="vscode-workbench-builtin-extensions" data-settings="{{WORKBENCH_BUILTIN_EXTENSIONS}}">
<!-- Workbench Credentials (running out of sources) -->
<meta id="vscode-workbench-credentials" data-settings="{{WORKBENCH_CREDENTIALS}}">
<!-- Workarounds/Hacks (remote user data uri) -->
<meta id="vscode-remote-user-data-uri" data-settings="{{REMOTE_USER_DATA_URI}}">

View File

@@ -3,8 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IWorkbenchConstructionOptions, create, ICredentialsProvider, IURLCallbackProvider, IWorkspaceProvider, IWorkspace, IWindowIndicator, ICommand, IHomeIndicator, IProductQualityChangeHandler } from 'vs/workbench/workbench.web.api';
import product from 'vs/platform/product/common/product';
import { IWorkbenchConstructionOptions, create, ICredentialsProvider, IURLCallbackProvider, IWorkspaceProvider, IWorkspace, IWindowIndicator, IHomeIndicator, IProductQualityChangeHandler } from 'vs/workbench/workbench.web.api';
import { URI, UriComponents } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { generateUuid } from 'vs/base/common/uuid';
@@ -16,6 +15,7 @@ import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/windows/common/wi
import { isEqual } from 'vs/base/common/resources';
import { isStandalone } from 'vs/base/browser/browser';
import { localize } from 'vs/nls';
import { Schemas } from 'vs/base/common/network';
interface ICredential {
service: string;
@@ -27,6 +27,13 @@ class LocalStorageCredentialsProvider implements ICredentialsProvider {
static readonly CREDENTIALS_OPENED_KEY = 'credentials.provider';
constructor(credentials: ICredential[]) {
this._credentials = credentials;
for (const { service, account, password } of this._credentials) {
this.setPassword(service, account, password);
}
}
private _credentials: ICredential[] | undefined;
private get credentials(): ICredential[] {
if (!this._credentials) {
@@ -277,6 +284,20 @@ class WorkspaceProvider implements IWorkspaceProvider {
return false;
}
hasRemote(): boolean {
if (this.workspace) {
if (isFolderToOpen(this.workspace)) {
return this.workspace.folderUri.scheme === Schemas.vscodeRemote;
}
if (isWorkspaceToOpen(this.workspace)) {
return this.workspace.workspaceUri.scheme === Schemas.vscodeRemote;
}
}
return true;
}
}
class WindowIndicator implements IWindowIndicator {
@@ -287,8 +308,6 @@ class WindowIndicator implements IWindowIndicator {
readonly tooltip: string;
readonly command: string | undefined;
readonly commandImpl: ICommand | undefined = undefined;
constructor(workspace: IWorkspace) {
let repositoryOwner: string | undefined = undefined;
let repositoryName: string | undefined = undefined;
@@ -306,20 +325,16 @@ class WindowIndicator implements IWindowIndicator {
}
}
// Repo
if (repositoryName && repositoryOwner) {
this.label = localize('openInDesktopLabel', "$(remote) Open in Desktop");
this.tooltip = localize('openInDesktopTooltip', "Open in Desktop");
this.command = '_web.openInDesktop';
this.commandImpl = {
id: this.command,
handler: () => {
const protocol = product.quality === 'stable' ? 'vscode' : 'vscode-insiders';
window.open(`${protocol}://vscode.git/clone?url=${encodeURIComponent(`https://github.com/${repositoryOwner}/${repositoryName}.git`)}`);
}
};
} else {
this.label = localize('playgroundLabel', "Web Playground");
this.tooltip = this.label;
this.label = localize('playgroundLabelRepository', "$(remote) VS Code Web Playground: {0}/{1}", repositoryOwner, repositoryName);
this.tooltip = localize('playgroundRepositoryTooltip', "VS Code Web Playground: {0}/{1}", repositoryOwner, repositoryName);
}
// No Repo
else {
this.label = localize('playgroundLabel', "$(remote) VS Code Web Playground");
this.tooltip = localize('playgroundTooltip', "VS Code Web Playground");
}
}
}
@@ -391,6 +406,9 @@ class WindowIndicator implements IWindowIndicator {
}
}
// Workspace Provider
const workspaceProvider = new WorkspaceProvider(workspace, payload);
// Home Indicator
const homeIndicator: IHomeIndicator = {
href: 'https://github.com/Microsoft/vscode',
@@ -398,13 +416,10 @@ class WindowIndicator implements IWindowIndicator {
title: localize('home', "Home")
};
// Commands
const commands: ICommand[] = [];
// Window indicator
const windowIndicator = new WindowIndicator(workspace);
if (windowIndicator.commandImpl) {
commands.push(windowIndicator.commandImpl);
// Window indicator (unless connected to a remote)
let windowIndicator: WindowIndicator | undefined = undefined;
if (!workspaceProvider.hasRemote()) {
windowIndicator = new WindowIndicator(workspace);
}
// Product Quality Change Handler
@@ -422,15 +437,19 @@ class WindowIndicator implements IWindowIndicator {
window.location.href = `${window.location.origin}?${queryString}`;
};
// Find credentials from DOM
const credentialsElement = document.getElementById('vscode-workbench-credentials');
const credentialsElementAttribute = credentialsElement ? credentialsElement.getAttribute('data-settings') : undefined;
const credentialsProvider = new LocalStorageCredentialsProvider(credentialsElementAttribute ? JSON.parse(credentialsElementAttribute) : []);
// Finally create workbench
create(document.body, {
...config,
homeIndicator,
commands,
windowIndicator,
productQualityChangeHandler,
workspaceProvider: new WorkspaceProvider(workspace, payload),
workspaceProvider,
urlCallbackProvider: new PollingURLCallbackProvider(),
credentialsProvider: new LocalStorageCredentialsProvider()
credentialsProvider
});
})();

View File

@@ -33,8 +33,8 @@ const bootstrapWindow = (() => {
return window.MonacoBootstrapWindow;
})();
// Setup shell environment
process['lazyEnv'] = getLazyEnv();
// Load environment in parallel to workbench loading to avoid waterfall
const whenEnvResolved = bootstrapWindow.globals().process.whenEnvResolved;
// Load workbench main JS, CSS and NLS all in parallel. This is an
// optimization to prevent a waterfall of loading to happen, because
@@ -46,18 +46,19 @@ bootstrapWindow.load([
'vs/nls!vs/workbench/workbench.desktop.main',
'vs/css!vs/workbench/workbench.desktop.main'
],
function (workbench, configuration) {
async function (workbench, configuration) {
// Mark start of workbench
perf.mark('didLoadWorkbenchMain');
performance.mark('workbench-start');
return process['lazyEnv'].then(function () {
perf.mark('main/startup');
// Wait for process environment being fully resolved
await whenEnvResolved;
// @ts-ignore
return require('vs/workbench/electron-browser/desktop.main').main(configuration);
});
perf.mark('main/startup');
// @ts-ignore
return require('vs/workbench/electron-browser/desktop.main').main(configuration);
},
{
removeDeveloperKeybindingsAfterLoad: true,
@@ -77,7 +78,7 @@ bootstrapWindow.load([
* @param {{
* partsSplashPath?: string,
* highContrast?: boolean,
* defaultThemeType?: string,
* autoDetectHighContrast?: boolean,
* extensionDevelopmentPath?: string[],
* folderUri?: object,
* workspace?: object
@@ -96,7 +97,8 @@ function showPartsSplash(configuration) {
}
// high contrast mode has been turned on from the outside, e.g. OS -> ignore stored colors and layouts
if (data && configuration.highContrast && data.baseTheme !== 'hc-black') {
const isHighContrast = configuration.highContrast && configuration.autoDetectHighContrast;
if (data && isHighContrast && data.baseTheme !== 'hc-black') {
data = undefined;
}
@@ -111,14 +113,10 @@ function showPartsSplash(configuration) {
baseTheme = data.baseTheme;
shellBackground = data.colorInfo.editorBackground;
shellForeground = data.colorInfo.foreground;
} else if (configuration.highContrast || configuration.defaultThemeType === 'hc') {
} else if (isHighContrast) {
baseTheme = 'hc-black';
shellBackground = '#000000';
shellForeground = '#FFFFFF';
} else if (configuration.defaultThemeType === 'vs') {
baseTheme = 'vs';
shellBackground = '#FFFFFF';
shellForeground = '#000000';
} else {
baseTheme = 'vs-dark';
shellBackground = '#1E1E1E';
@@ -172,26 +170,3 @@ function showPartsSplash(configuration) {
perf.mark('didShowPartsSplash');
}
/**
* @returns {Promise<void>}
*/
function getLazyEnv() {
const ipcRenderer = bootstrapWindow.globals().ipcRenderer;
return new Promise(function (resolve) {
const handle = setTimeout(function () {
resolve();
console.warn('renderer did not receive lazyEnv in time');
}, 10000);
ipcRenderer.once('vscode:acceptShellEnv', function (event, shellEnv) {
clearTimeout(handle);
Object.assign(process.env, shellEnv);
// @ts-ignore
resolve(process.env);
});
ipcRenderer.send('vscode:fetchShellEnv');
});
}

View File

@@ -50,7 +50,7 @@ import { setUnexpectedErrorHandler, onUnexpectedError } from 'vs/base/common/err
import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener';
import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver';
import { IMenubarMainService, MenubarMainService } from 'vs/platform/menubar/electron-main/menubarMainService';
import { RunOnceScheduler } from 'vs/base/common/async';
import { RunOnceScheduler, timeout } from 'vs/base/common/async';
import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu';
import { homedir } from 'os';
import { join, sep, posix } from 'vs/base/common/path';
@@ -68,11 +68,11 @@ import { statSync } from 'fs';
import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc';
import { IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService';
import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc';
import { ElectronExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/electron-main/extensionHostDebugIpc';
import { IElectronMainService, ElectronMainService } from 'vs/platform/electron/electron-main/electronMainService';
import { ISharedProcessMainService, SharedProcessMainService } from 'vs/platform/ipc/electron-main/sharedProcessMainService';
import { IDialogMainService, DialogMainService } from 'vs/platform/dialogs/electron-main/dialogs';
import { withNullAsUndefined } from 'vs/base/common/types';
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
import { coalesce } from 'vs/base/common/arrays';
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
import { StorageKeysSyncRegistryChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc';
@@ -80,8 +80,6 @@ import { INativeEnvironmentService } from 'vs/platform/environment/node/environm
import { mnemonicButtonLabel, getPathLabel } from 'vs/base/common/labels';
import { WebviewMainService } from 'vs/platform/webview/electron-main/webviewMainService';
import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService';
import { createServer, AddressInfo } from 'net';
import { IOpenExtensionWindowResult } from 'vs/platform/debug/common/extensionHostDebug';
import { IFileService } from 'vs/platform/files/common/files';
import { stripComments } from 'vs/base/common/json';
import { generateUuid } from 'vs/base/common/uuid';
@@ -272,6 +270,12 @@ export class CodeApplication extends Disposable {
try {
const shellEnv = await getShellEnvironment(this.logService, this.environmentService);
// TODO@sandbox workaround for https://github.com/electron/electron/issues/25119
if (this.environmentService.sandbox) {
await timeout(100);
}
if (!webContents.isDestroyed()) {
webContents.send('vscode:acceptShellEnv', shellEnv);
}
@@ -297,7 +301,7 @@ export class CodeApplication extends Disposable {
const nativeKeymap = await import('native-keymap');
nativeKeymap.onDidChangeKeyboardLayout(() => {
if (this.windowsMainService) {
this.windowsMainService.sendToAll('vscode:keyboardLayoutChanged', false);
this.windowsMainService.sendToAll('vscode:keyboardLayoutChanged');
}
});
})();
@@ -364,17 +368,17 @@ export class CodeApplication extends Disposable {
const sharedProcess = this.instantiationService.createInstance(SharedProcess, machineId, this.userEnv);
const sharedProcessClient = sharedProcess.whenIpcReady().then(() => {
this.logService.trace('Shared process: IPC ready');
return connect(this.environmentService.sharedIPCHandle, 'main');
});
const sharedProcessReady = sharedProcess.whenReady().then(() => {
this.logService.trace('Shared process: init ready');
return sharedProcessClient;
});
this.lifecycleMainService.when(LifecycleMainPhase.AfterWindowOpen).then(() => {
this._register(new RunOnceScheduler(async () => {
const userEnv = await getShellEnvironment(this.logService, this.environmentService);
sharedProcess.spawn(userEnv);
sharedProcess.spawn(await getShellEnvironment(this.logService, this.environmentService));
}, 3000)).schedule();
});
@@ -847,6 +851,9 @@ export class CodeApplication extends Disposable {
} catch (error) {
this.logService.error(error);
}
// Start to fetch shell environment after window has opened
getShellEnvironment(this.logService, this.environmentService);
}
private handleRemoteAuthorities(): void {
@@ -858,100 +865,3 @@ export class CodeApplication extends Disposable {
});
}
}
class ElectronExtensionHostDebugBroadcastChannel<TContext> extends ExtensionHostDebugBroadcastChannel<TContext> {
constructor(private windowsMainService: IWindowsMainService) {
super();
}
call(ctx: TContext, command: string, arg?: any): Promise<any> {
if (command === 'openExtensionDevelopmentHostWindow') {
return this.openExtensionDevelopmentHostWindow(arg[0], arg[1], arg[2]);
} else {
return super.call(ctx, command, arg);
}
}
private async openExtensionDevelopmentHostWindow(args: string[], env: IProcessEnvironment, debugRenderer: boolean): Promise<IOpenExtensionWindowResult> {
const pargs = parseArgs(args, OPTIONS);
const extDevPaths = pargs.extensionDevelopmentPath;
if (!extDevPaths) {
return {};
}
const [codeWindow] = this.windowsMainService.openExtensionDevelopmentHostWindow(extDevPaths, {
context: OpenContext.API,
cli: pargs,
userEnv: Object.keys(env).length > 0 ? env : undefined
});
if (!debugRenderer) {
return {};
}
const debug = codeWindow.win.webContents.debugger;
let listeners = debug.isAttached() ? Infinity : 0;
const server = createServer(listener => {
if (listeners++ === 0) {
debug.attach();
}
let closed = false;
const writeMessage = (message: object) => {
if (!closed) { // in case sendCommand promises settle after closed
listener.write(JSON.stringify(message) + '\0'); // null-delimited, CDP-compatible
}
};
const onMessage = (_event: Event, method: string, params: unknown, sessionId?: string) =>
writeMessage(({ method, params, sessionId }));
codeWindow.win.on('close', () => {
debug.removeListener('message', onMessage);
listener.end();
closed = true;
});
debug.addListener('message', onMessage);
let buf = Buffer.alloc(0);
listener.on('data', data => {
buf = Buffer.concat([buf, data]);
for (let delimiter = buf.indexOf(0); delimiter !== -1; delimiter = buf.indexOf(0)) {
let data: { id: number; sessionId: string; params: {} };
try {
const contents = buf.slice(0, delimiter).toString('utf8');
buf = buf.slice(delimiter + 1);
data = JSON.parse(contents);
} catch (e) {
console.error('error reading cdp line', e);
}
// depends on a new API for which electron.d.ts has not been updated:
// @ts-ignore
debug.sendCommand(data.method, data.params, data.sessionId)
.then((result: object) => writeMessage({ id: data.id, sessionId: data.sessionId, result }))
.catch((error: Error) => writeMessage({ id: data.id, sessionId: data.sessionId, error: { code: 0, message: error.message } }));
}
});
listener.on('error', err => {
console.error('error on cdp pipe:', err);
});
listener.on('close', () => {
closed = true;
if (--listeners === 0) {
debug.detach();
}
});
});
await new Promise(r => server.listen(0, r));
codeWindow.win.on('close', () => server.close());
return { rendererDebugPort: (server.address() as AddressInfo).port };
}
}

View File

@@ -8,7 +8,7 @@ import * as objects from 'vs/base/common/objects';
import * as nls from 'vs/nls';
import { Emitter } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment, nativeTheme, Event } from 'electron';
import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment, nativeTheme, Event, Details } from 'electron';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
import { ILogService } from 'vs/platform/log/common/log';
@@ -167,12 +167,23 @@ export class CodeWindow extends Disposable implements ICodeWindow {
title: product.nameLong,
webPreferences: {
preload: URI.parse(this.doGetPreloadUrl()).fsPath,
nodeIntegration: true,
enableWebSQL: false,
enableRemoteModule: false,
nativeWindowOpen: true,
webviewTag: true,
zoomFactor: zoomLevelToZoomFactor(windowConfig?.zoomLevel)
zoomFactor: zoomLevelToZoomFactor(windowConfig?.zoomLevel),
...this.environmentService.sandbox ?
// Sandbox
{
sandbox: true,
contextIsolation: true
} :
// No Sandbox
{
nodeIntegration: true
}
}
};
@@ -325,7 +336,18 @@ export class CodeWindow extends Disposable implements ICodeWindow {
return !!this.documentEdited;
}
focus(): void {
focus(options?: { force: boolean }): void {
// macOS: Electron >6.x changed its behaviour to not
// bring the application to the foreground when a window
// is focused programmatically. Only via `app.focus` and
// the option `steal: true` can you get the previous
// behaviour back. The only reason to use this option is
// when a window is getting focused while the application
// is not in the foreground.
if (isMacintosh && options?.force) {
app.focus({ steal: true });
}
if (!this._win) {
return;
}
@@ -392,7 +414,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
private registerListeners(): void {
// Crashes & Unrsponsive
this._win.webContents.on('crashed', () => this.onWindowError(WindowError.CRASHED));
this._win.webContents.on('render-process-gone', (event, details) => this.onWindowError(WindowError.CRASHED, details));
this._win.on('unresponsive', () => this.onWindowError(WindowError.UNRESPONSIVE));
// Window close
@@ -524,8 +546,10 @@ export class CodeWindow extends Disposable implements ICodeWindow {
this.marketplaceHeadersPromise.then(headers => cb({ cancel: false, requestHeaders: Object.assign(details.requestHeaders, headers) })));
}
private onWindowError(error: WindowError): void {
this.logService.error(error === WindowError.CRASHED ? '[VS Code]: renderer process crashed!' : '[VS Code]: detected unresponsive');
private onWindowError(error: WindowError.UNRESPONSIVE): void;
private onWindowError(error: WindowError.CRASHED, details: Details): void;
private onWindowError(error: WindowError, details?: Details): void {
this.logService.error(error === WindowError.CRASHED ? `[VS Code]: renderer process crashed (detail: ${details?.reason})` : '[VS Code]: detected unresponsive');
// If we run extension tests from CLI, showing a dialog is not
// very helpful in this case. Rather, we bring down the test run
@@ -579,11 +603,18 @@ export class CodeWindow extends Disposable implements ICodeWindow {
// Crashed
else {
let message: string;
if (details && details.reason !== 'crashed') {
message = nls.localize('appCrashedDetails', "The window has crashed (reason: '{0}')", details?.reason);
} else {
message = nls.localize('appCrashed', "The window has crashed", details?.reason);
}
this.dialogMainService.showMessageBox({
title: product.nameLong,
type: 'warning',
buttons: [mnemonicButtonLabel(nls.localize({ key: 'reopen', comment: ['&& denotes a mnemonic'] }, "&&Reopen")), mnemonicButtonLabel(nls.localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))],
message: nls.localize('appCrashed', "The window has crashed"),
message,
detail: nls.localize('appCrashedDetail', "We are sorry for the inconvenience! You can reopen the window to continue where you left off."),
noLink: true
}, this._win).then(result => {
@@ -699,7 +730,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
this.showTimeoutHandle = setTimeout(() => {
if (this._win && !this._win.isVisible() && !this._win.isMinimized()) {
this._win.show();
this._win.focus();
this.focus({ force: true });
this._win.webContents.openDevTools();
}
}, 10000);
@@ -754,11 +785,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
windowConfiguration.fullscreen = this.isFullScreen;
// Set Accessibility Config
let autoDetectHighContrast = true;
if (windowConfig?.autoDetectHighContrast === false) {
autoDetectHighContrast = false;
}
windowConfiguration.highContrast = isWindows && autoDetectHighContrast && nativeTheme.shouldUseInvertedColorScheme;
windowConfiguration.highContrast = nativeTheme.shouldUseInvertedColorScheme || nativeTheme.shouldUseHighContrastColors;
windowConfiguration.autoDetectHighContrast = windowConfig?.autoDetectHighContrast ?? true;
windowConfiguration.accessibilitySupport = app.accessibilitySupportEnabled;
// Title style related
@@ -799,7 +827,14 @@ export class CodeWindow extends Disposable implements ICodeWindow {
}
private doGetUrl(config: object): string {
return `${require.toUrl('vs/code/electron-browser/workbench/workbench.html')}?config=${encodeURIComponent(JSON.stringify(config))}`;
let workbench: string;
if (this.environmentService.sandbox) {
workbench = 'vs/code/electron-sandbox/workbench/workbench.html';
} else {
workbench = 'vs/code/electron-browser/workbench/workbench.html';
}
return `${require.toUrl(workbench)}?config=${encodeURIComponent(JSON.stringify(config))}`;
}
private doGetPreloadUrl(): string {

View File

@@ -8,7 +8,7 @@ import 'vs/base/browser/ui/codicons/codiconStyles'; // make sure codicon css is
import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
import { ipcRenderer, process } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { applyZoom, zoomIn, zoomOut } from 'vs/platform/windows/electron-sandbox/window';
import { $, windowOpenNoOpener, addClass } from 'vs/base/browser/dom';
import { $, reset, windowOpenNoOpener, addClass } from 'vs/base/browser/dom';
import { Button } from 'vs/base/browser/ui/button/button';
import { CodiconLabel } from 'vs/base/browser/ui/codicons/codiconLabel';
import * as collections from 'vs/base/common/collections';
@@ -277,33 +277,25 @@ export class IssueReporter extends Disposable {
}
private updateSettingsSearchDetails(data: ISettingsSearchIssueReporterData): void {
const target = document.querySelector('.block-settingsSearchResults .block-info');
const target = document.querySelector<HTMLElement>('.block-settingsSearchResults .block-info');
if (target) {
const details = `
<div class='block-settingsSearchResults-details'>
<div>Query: "${data.query}"</div>
<div>Literal match count: ${data.filterResultCount}</div>
</div>
`;
const queryDiv = $<HTMLDivElement>('div', undefined, `Query: "${data.query}"` as string);
const countDiv = $<HTMLElement>('div', undefined, `Literal match count: ${data.filterResultCount}` as string);
const detailsDiv = $<HTMLDivElement>('.block-settingsSearchResults-details', undefined, queryDiv, countDiv);
let table = `
<tr>
<th>Setting</th>
<th>Extension</th>
<th>Score</th>
</tr>`;
data.actualSearchResults
.forEach(setting => {
table += `
<tr>
<td>${setting.key}</td>
<td>${setting.extensionId}</td>
<td>${String(setting.score).slice(0, 5)}</td>
</tr>`;
});
target.innerHTML = `${details}<table>${table}</table>`;
const table = $('table', undefined,
$('tr', undefined,
$('th', undefined, 'Setting'),
$('th', undefined, 'Extension'),
$('th', undefined, 'Score'),
),
...data.actualSearchResults.map(setting => $('tr', undefined,
$('td', undefined, setting.key),
$('td', undefined, setting.extensionId),
$('td', undefined, String(setting.score).slice(0, 5)),
))
);
reset(target, detailsDiv, table);
}
}
@@ -654,9 +646,9 @@ export class IssueReporter extends Disposable {
issueState.appendChild(issueIcon);
issueState.appendChild(issueStateLabel);
item = $('div.issue', {}, issueState, link);
item = $('div.issue', undefined, issueState, link);
} else {
item = $('div.issue', {}, link);
item = $('div.issue', undefined, link);
}
issues.appendChild(item);
@@ -672,19 +664,19 @@ export class IssueReporter extends Disposable {
}
private setUpTypes(): void {
const makeOption = (issueType: IssueType, description: string) => `<option value="${issueType.valueOf()}">${escape(description)}</option>`;
const makeOption = (issueType: IssueType, description: string) => $('option', { 'value': issueType.valueOf() }, escape(description));
const typeSelect = this.getElementById('issue-type')! as HTMLSelectElement;
const { issueType } = this.issueReporterModel.getData();
if (issueType === IssueType.SettingsSearchIssue) {
typeSelect.innerHTML = makeOption(IssueType.SettingsSearchIssue, localize('settingsSearchIssue', "Settings Search Issue"));
reset(typeSelect, makeOption(IssueType.SettingsSearchIssue, localize('settingsSearchIssue', "Settings Search Issue")));
typeSelect.disabled = true;
} else {
typeSelect.innerHTML = [
reset(typeSelect,
makeOption(IssueType.Bug, localize('bugReporter', "Bug Report")),
makeOption(IssueType.FeatureRequest, localize('featureRequest', "Feature Request")),
makeOption(IssueType.PerformanceIssue, localize('performanceIssue', "Performance Issue"))
].join('\n');
);
}
typeSelect.value = issueType.toString();
@@ -774,9 +766,8 @@ export class IssueReporter extends Disposable {
} else {
show(extensionsBlock);
}
descriptionTitle.innerHTML = `${localize('stepsToReproduce', "Steps to Reproduce")} <span class="required-input">*</span>`;
descriptionSubtitle.innerHTML = localize('bugDescription', "Share the steps needed to reliably reproduce the problem. Please include actual and expected results. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.");
reset(descriptionTitle, localize('stepsToReproduce', "Steps to Reproduce"), $('span.required-input', undefined, '*'));
reset(descriptionSubtitle, localize('bugDescription', "Share the steps needed to reliably reproduce the problem. Please include actual and expected results. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
} else if (issueType === IssueType.PerformanceIssue) {
show(blockContainer);
show(systemBlock);
@@ -790,11 +781,11 @@ export class IssueReporter extends Disposable {
show(extensionsBlock);
}
descriptionTitle.innerHTML = `${localize('stepsToReproduce', "Steps to Reproduce")} <span class="required-input">*</span>`;
descriptionSubtitle.innerHTML = localize('performanceIssueDesciption', "When did this performance issue happen? Does it occur on startup or after a specific series of actions? We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.");
reset(descriptionTitle, localize('stepsToReproduce', "Steps to Reproduce"), $('span.required-input', undefined, '*'));
reset(descriptionSubtitle, localize('performanceIssueDesciption', "When did this performance issue happen? Does it occur on startup or after a specific series of actions? We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
} else if (issueType === IssueType.FeatureRequest) {
descriptionTitle.innerHTML = `${localize('description', "Description")} <span class="required-input">*</span>`;
descriptionSubtitle.innerHTML = localize('featureRequestDescription', "Please describe the feature you would like to see. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.");
reset(descriptionTitle, localize('description', "Description"), $('span.required-input', undefined, '*'));
reset(descriptionSubtitle, localize('featureRequestDescription', "Please describe the feature you would like to see. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
show(problemSource);
if (fileOnExtension) {
@@ -805,8 +796,8 @@ export class IssueReporter extends Disposable {
show(searchedExtensionsBlock);
show(settingsSearchResultsBlock);
descriptionTitle.innerHTML = `${localize('expectedResults', "Expected Results")} <span class="required-input">*</span>`;
descriptionSubtitle.innerHTML = localize('settingsSearchResultsDescription', "Please list the results that you were expecting to see when you searched with this query. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.");
reset(descriptionTitle, localize('expectedResults', "Expected Results"), $('span.required-input', undefined, '*'));
reset(descriptionSubtitle, localize('settingsSearchResultsDescription', "Please list the results that you were expecting to see when you searched with this query. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
}
}
@@ -928,42 +919,82 @@ export class IssueReporter extends Disposable {
}
private updateSystemInfo(state: IssueReporterModelData) {
const target = document.querySelector('.block-system .block-info');
const target = document.querySelector<HTMLElement>('.block-system .block-info');
if (target) {
const systemInfo = state.systemInfo!;
let renderedData = `
<table>
<tr><td>CPUs</td><td>${systemInfo.cpus}</td></tr>
<tr><td>GPU Status</td><td>${Object.keys(systemInfo.gpuStatus).map(key => `${key}: ${systemInfo.gpuStatus[key]}`).join('<br>')}</td></tr>
<tr><td>Load (avg)</td><td>${systemInfo.load}</td></tr>
<tr><td>Memory (System)</td><td>${systemInfo.memory}</td></tr>
<tr><td>Process Argv</td><td>${systemInfo.processArgs}</td></tr>
<tr><td>Screen Reader</td><td>${systemInfo.screenReader}</td></tr>
<tr><td>VM</td><td>${systemInfo.vmHint}</td></tr>
</table>`;
const renderedDataTable = $('table', undefined,
$('tr', undefined,
$('td', undefined, 'CPUs'),
$('td', undefined, systemInfo.cpus || ''),
),
$('tr', undefined,
$('td', undefined, 'GPU Status' as string),
$('td', undefined, Object.keys(systemInfo.gpuStatus).map(key => `${key}: ${systemInfo.gpuStatus[key]}`).join('\n')),
),
$('tr', undefined,
$('td', undefined, 'Load (avg)' as string),
$('td', undefined, systemInfo.load || ''),
),
$('tr', undefined,
$('td', undefined, 'Memory (System)' as string),
$('td', undefined, systemInfo.memory),
),
$('tr', undefined,
$('td', undefined, 'Process Argv' as string),
$('td', undefined, systemInfo.processArgs),
),
$('tr', undefined,
$('td', undefined, 'Screen Reader' as string),
$('td', undefined, systemInfo.screenReader),
),
$('tr', undefined,
$('td', undefined, 'VM'),
$('td', undefined, systemInfo.vmHint),
),
);
reset(target, renderedDataTable);
systemInfo.remoteData.forEach(remote => {
target.appendChild($<HTMLHRElement>('hr'));
if (isRemoteDiagnosticError(remote)) {
renderedData += `
<hr>
<table>
<tr><td>Remote</td><td>${remote.hostName}</td></tr>
<tr><td></td><td>${remote.errorMessage}</td></tr>
</table>`;
const remoteDataTable = $('table', undefined,
$('tr', undefined,
$('td', undefined, 'Remote'),
$('td', undefined, remote.hostName)
),
$('tr', undefined,
$('td', undefined, ''),
$('td', undefined, remote.errorMessage)
)
);
target.appendChild(remoteDataTable);
} else {
renderedData += `
<hr>
<table>
<tr><td>Remote</td><td>${remote.hostName}</td></tr>
<tr><td>OS</td><td>${remote.machineInfo.os}</td></tr>
<tr><td>CPUs</td><td>${remote.machineInfo.cpus}</td></tr>
<tr><td>Memory (System)</td><td>${remote.machineInfo.memory}</td></tr>
<tr><td>VM</td><td>${remote.machineInfo.vmHint}</td></tr>
</table>`;
const remoteDataTable = $('table', undefined,
$('tr', undefined,
$('td', undefined, 'Remote'),
$('td', undefined, remote.hostName)
),
$('tr', undefined,
$('td', undefined, 'OS'),
$('td', undefined, remote.machineInfo.os)
),
$('tr', undefined,
$('td', undefined, 'CPUs'),
$('td', undefined, remote.machineInfo.cpus || '')
),
$('tr', undefined,
$('td', undefined, 'Memory (System)' as string),
$('td', undefined, remote.machineInfo.memory)
),
$('tr', undefined,
$('td', undefined, 'VM'),
$('td', undefined, remote.machineInfo.vmHint)
),
);
target.appendChild(remoteDataTable);
}
});
target.innerHTML = renderedData;
}
}
@@ -995,15 +1026,18 @@ export class IssueReporter extends Disposable {
return 0;
});
const makeOption = (extension: IOption, selectedExtension?: IssueReporterExtensionData) => {
const makeOption = (extension: IOption, selectedExtension?: IssueReporterExtensionData): HTMLOptionElement => {
const selected = selectedExtension && extension.id === selectedExtension.id;
return `<option value="${extension.id}" ${selected ? 'selected' : ''}>${escape(extension.name)}</option>`;
return $<HTMLOptionElement>('option', {
'value': extension.id,
'selected': selected || ''
}, extension.name);
};
const extensionsSelector = this.getElementById('extension-selector');
if (extensionsSelector) {
const { selectedExtension } = this.issueReporterModel.getData();
extensionsSelector.innerHTML = '<option></option>' + extensionOptions.map(extension => makeOption(extension, selectedExtension)).join('\n');
reset(extensionsSelector, $<HTMLOptionElement>('option'), ...extensionOptions.map(extension => makeOption(extension, selectedExtension)));
this.addEventListener('extension-selector', 'change', (e: Event) => {
const selectedExtensionId = (<HTMLInputElement>e.target).value;
@@ -1071,9 +1105,9 @@ export class IssueReporter extends Disposable {
}
private updateProcessInfo(state: IssueReporterModelData) {
const target = document.querySelector('.block-process .block-info');
const target = document.querySelector('.block-process .block-info') as HTMLElement;
if (target) {
target.innerHTML = `<code>${state.processInfo}</code>`;
reset(target, $('code', undefined, state.processInfo));
}
}
@@ -1085,7 +1119,7 @@ export class IssueReporter extends Disposable {
const target = document.querySelector<HTMLElement>('.block-extensions .block-info');
if (target) {
if (this.configuration.disableExtensions) {
target.innerHTML = localize('disabledExtensions', "Extensions are disabled");
reset(target, localize('disabledExtensions', "Extensions are disabled"));
return;
}
@@ -1097,8 +1131,7 @@ export class IssueReporter extends Disposable {
return;
}
const table = this.getExtensionTableHtml(extensions);
target.innerHTML = `<table>${table}</table>${themeExclusionStr}`;
reset(target, this.getExtensionTableHtml(extensions), document.createTextNode(themeExclusionStr));
}
}
@@ -1111,28 +1144,24 @@ export class IssueReporter extends Disposable {
}
const table = this.getExtensionTableHtml(extensions);
target.innerHTML = `<table>${table}</table>`;
target.innerText = '';
target.appendChild(table);
}
}
private getExtensionTableHtml(extensions: IssueReporterExtensionData[]): string {
let table = `
<tr>
<th>Extension</th>
<th>Author (truncated)</th>
<th>Version</th>
</tr>`;
table += extensions.map(extension => {
return `
<tr>
<td>${extension.name}</td>
<td>${extension.publisher.substr(0, 3)}</td>
<td>${extension.version}</td>
</tr>`;
}).join('');
return table;
private getExtensionTableHtml(extensions: IssueReporterExtensionData[]): HTMLTableElement {
return $('table', undefined,
$('tr', undefined,
$('th', undefined, 'Extension'),
$('th', undefined, 'Author (truncated)' as string),
$('th', undefined, 'Version'),
),
...extensions.map(extension => $('tr', undefined,
$('td', undefined, extension.name),
$('td', undefined, extension.publisher.substr(0, 3)),
$('td', undefined, extension.version),
))
);
}
private openLink(event: MouseEvent): void {

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#646465" d="M6 4v8l4-4-4-4zm1 2.414L8.586 8 7 9.586V6.414z"/></svg>

Before

Width:  |  Height:  |  Size: 139 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#646465" d="M11 10H5.344L11 4.414V10z"/></svg>

Before

Width:  |  Height:  |  Size: 118 B

View File

@@ -58,6 +58,7 @@ table {
width: 100%;
table-layout: fixed;
}
th[scope='col'] {
vertical-align: bottom;
border-bottom: 1px solid #cccccc;
@@ -65,6 +66,7 @@ th[scope='col'] {
border-top: 1px solid #cccccc;
cursor: default;
}
td {
padding: .25rem;
vertical-align: top;
@@ -100,7 +102,6 @@ tbody > tr:hover {
display: none;
}
img {
width: 16px;
margin-right: 4px;
.header {
display: flex;
}

View File

@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/processExplorer';
import 'vs/base/browser/ui/codicons/codiconStyles'; // make sure codicon css is loaded
import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { localize } from 'vs/nls';
@@ -16,6 +17,7 @@ import { addDisposableListener, addClass } from 'vs/base/browser/dom';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { isRemoteDiagnosticError, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics';
import { MainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService';
import { CodiconLabel } from 'vs/base/browser/ui/codicons/codiconLabel';
const DEBUG_FLAGS_PATTERN = /\s--(inspect|debug)(-brk|port)?=(\d+)?/;
const DEBUG_PORT_PATTERN = /\s--(inspect|debug)-port=(\d+)/;
@@ -156,15 +158,15 @@ class ProcessExplorer {
return maxProcessId;
}
private updateSectionCollapsedState(shouldExpand: boolean, body: HTMLElement, twistie: HTMLImageElement, sectionName: string) {
private updateSectionCollapsedState(shouldExpand: boolean, body: HTMLElement, twistie: CodiconLabel, sectionName: string) {
if (shouldExpand) {
body.classList.remove('hidden');
this.collapsedStateCache.set(sectionName, false);
twistie.src = './media/expanded.svg';
twistie.text = '$(chevron-down)';
} else {
body.classList.add('hidden');
this.collapsedStateCache.set(sectionName, true);
twistie.src = './media/collapsed.svg';
twistie.text = '$(chevron-right)';
}
}
@@ -191,18 +193,27 @@ class ProcessExplorer {
private renderProcessGroupHeader(sectionName: string, body: HTMLElement, container: HTMLElement) {
const headerRow = document.createElement('tr');
const data = document.createElement('td');
data.textContent = sectionName;
data.colSpan = 4;
headerRow.appendChild(data);
const twistie = document.createElement('img');
this.updateSectionCollapsedState(!this.collapsedStateCache.get(sectionName), body, twistie, sectionName);
data.prepend(twistie);
const headerData = document.createElement('td');
headerData.colSpan = 4;
headerRow.appendChild(headerData);
this.listeners.add(addDisposableListener(data, 'click', (e) => {
const headerContainer = document.createElement('div');
headerContainer.className = 'header';
headerData.appendChild(headerContainer);
const twistieContainer = document.createElement('div');
const twistieCodicon = new CodiconLabel(twistieContainer);
this.updateSectionCollapsedState(!this.collapsedStateCache.get(sectionName), body, twistieCodicon, sectionName);
headerContainer.appendChild(twistieContainer);
const headerLabel = document.createElement('span');
headerLabel.textContent = sectionName;
headerContainer.appendChild(headerLabel);
this.listeners.add(addDisposableListener(headerData, 'click', (e) => {
const isHidden = body.classList.contains('hidden');
this.updateSectionCollapsedState(isHidden, body, twistie, sectionName);
this.updateSectionCollapsedState(isHidden, body, twistieCodicon, sectionName);
}));
container.appendChild(headerRow);

View File

@@ -0,0 +1,18 @@
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' https: data: blob: vscode-remote-resource:; media-src 'none'; frame-src 'self' vscode-webview: https://*.vscode-webview-test.com; object-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' https:; font-src 'self' https: vscode-remote-resource:;">
</head>
<body aria-label="">
</body>
<!-- Init Bootstrap Helpers -->
<script src="../../../../bootstrap.js"></script>
<script src="../../../../vs/loader.js"></script>
<script src="../../../../bootstrap-window.js"></script>
<!-- Startup via workbench.js -->
<script src="workbench.js"></script>
</html>

View File

@@ -0,0 +1,74 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/// <reference path="../../../../typings/require.d.ts" />
//@ts-check
'use strict';
const perf = (function () {
globalThis.MonacoPerformanceMarks = globalThis.MonacoPerformanceMarks || [];
return {
/**
* @param {string} name
*/
mark(name) {
globalThis.MonacoPerformanceMarks.push(name, Date.now());
}
};
})();
perf.mark('renderer/started');
/**
* @type {{
* load: (modules: string[], resultCallback: (result, configuration: object) => any, options: object) => unknown,
* globals: () => typeof import('../../../base/parts/sandbox/electron-sandbox/globals')
* }}
*/
const bootstrapWindow = (() => {
// @ts-ignore (defined in bootstrap-window.js)
return window.MonacoBootstrapWindow;
})();
// Load environment in parallel to workbench loading to avoid waterfall
const whenEnvResolved = bootstrapWindow.globals().process.whenEnvResolved;
// Load workbench main JS, CSS and NLS all in parallel. This is an
// optimization to prevent a waterfall of loading to happen, because
// we know for a fact that workbench.desktop.sandbox.main will depend on
// the related CSS and NLS counterparts.
bootstrapWindow.load([
'vs/workbench/workbench.desktop.sandbox.main',
'vs/nls!vs/workbench/workbench.desktop.main',
'vs/css!vs/workbench/workbench.desktop.main'
],
async function (workbench, configuration) {
// Mark start of workbench
perf.mark('didLoadWorkbenchMain');
performance.mark('workbench-start');
// Wait for process environment being fully resolved
await whenEnvResolved;
perf.mark('main/startup');
// @ts-ignore
return require('vs/workbench/electron-sandbox/desktop.main').main(configuration);
},
{
removeDeveloperKeybindingsAfterLoad: true,
canModifyDOM: function (windowConfig) {
// TODO@sandbox part-splash is non-sandboxed only
},
beforeLoaderConfig: function (windowConfig, loaderConfig) {
loaderConfig.recordStats = true;
},
beforeRequire: function () {
perf.mark('willLoadWorkbenchMain');
}
}
);

View File

@@ -14,7 +14,7 @@ import * as paths from 'vs/base/common/path';
import { whenDeleted, writeFileSync } from 'vs/base/node/pfs';
import { findFreePort, randomPort } from 'vs/base/node/ports';
import { isWindows, isLinux } from 'vs/base/common/platform';
import { ProfilingSession, Target } from 'v8-inspect-profiler';
import type { ProfilingSession, Target } from 'v8-inspect-profiler';
import { isString } from 'vs/base/common/types';
import { hasStdinWithoutTty, stdinDataListener, getStdinFilePath, readFromStdin } from 'vs/platform/environment/node/stdin';

View File

@@ -7,7 +7,6 @@ import { localize } from 'vs/nls';
import { raceTimeout } from 'vs/base/common/async';
import product from 'vs/platform/product/common/product';
import * as path from 'vs/base/common/path';
import * as semver from 'semver-umd';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -214,6 +213,8 @@ export class Main {
throw new Error('Invalid vsix');
}
const semver = await import('semver-umd');
const extensionIdentifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) };
const installedExtensions = await this.extensionManagementService.getInstalled(ExtensionType.User);
const newer = installedExtensions.find(local => areSameExtensions(extensionIdentifier, local.identifier) && semver.gt(local.manifest.version, manifest.version));

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as cp from 'child_process';
import { spawn } from 'child_process';
import { generateUuid } from 'vs/base/common/uuid';
import { isWindows } from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log';
@@ -30,7 +30,7 @@ function getUnixShellEnvironment(logService: ILogService): Promise<typeof proces
logService.trace('getUnixShellEnvironment#env', env);
logService.trace('getUnixShellEnvironment#spawn', command);
const child = cp.spawn(process.env.SHELL!, ['-ilc', command], {
const child = spawn(process.env.SHELL!, ['-ilc', command], {
detached: true,
stdio: ['ignore', 'pipe', process.stderr],
env
@@ -82,8 +82,7 @@ function getUnixShellEnvironment(logService: ILogService): Promise<typeof proces
return promise.catch(() => ({}));
}
let _shellEnv: Promise<typeof process.env>;
let shellEnvPromise: Promise<typeof process.env> | undefined = undefined;
/**
* We need to get the environment from a user's shell.
@@ -91,21 +90,21 @@ let _shellEnv: Promise<typeof process.env>;
* from within a shell.
*/
export function getShellEnvironment(logService: ILogService, environmentService: INativeEnvironmentService): Promise<typeof process.env> {
if (_shellEnv === undefined) {
if (!shellEnvPromise) {
if (environmentService.args['disable-user-env-probe']) {
logService.trace('getShellEnvironment: disable-user-env-probe set, skipping');
_shellEnv = Promise.resolve({});
shellEnvPromise = Promise.resolve({});
} else if (isWindows) {
logService.trace('getShellEnvironment: running on Windows, skipping');
_shellEnv = Promise.resolve({});
shellEnvPromise = Promise.resolve({});
} else if (process.env['VSCODE_CLI'] === '1' && process.env['VSCODE_FORCE_USER_ENV'] !== '1') {
logService.trace('getShellEnvironment: running on CLI, skipping');
_shellEnv = Promise.resolve({});
shellEnvPromise = Promise.resolve({});
} else {
logService.trace('getShellEnvironment: running on Unix');
_shellEnv = getUnixShellEnvironment(logService);
shellEnvPromise = getUnixShellEnvironment(logService);
}
}
return _shellEnv;
return shellEnvPromise;
}

View File

@@ -28,9 +28,8 @@ suite('Windows Native Helpers', () => {
});
test('vscode-windows-ca-certs', async () => {
const windowsCerts = await new Promise<any>((resolve, reject) => {
require(['vscode-windows-ca-certs'], resolve, reject);
});
// @ts-ignore Windows only
const windowsCerts = await import('vscode-windows-ca-certs');
assert.ok(windowsCerts, 'Unable to load vscode-windows-ca-certs dependency.');
});