Merge remote-tracking branch 'upstream/master' into user/gabrield/extensionCallbackAsTask

This commit is contained in:
Gabriel DeBacker
2019-03-04 07:44:54 -08:00
32 changed files with 473 additions and 420 deletions

View File

@@ -5,7 +5,6 @@
import * as vscode from 'vscode';
import { URI } from 'vs/base/common/uri';
import { isMalformedFileUri } from 'vs/base/common/resources';
import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters';
import { CommandsRegistry, ICommandService, ICommandHandler } from 'vs/platform/commands/common/commands';
import { ITextEditorOptions } from 'vs/platform/editor/common/editor';
@@ -39,13 +38,6 @@ export class OpenFolderAPICommand {
if (!uri) {
return executor.executeCommand('_files.pickFolderAndOpen', forceNewWindow);
}
let correctedUri = isMalformedFileUri(uri);
if (correctedUri) {
// workaround for #55916 and #55891, will be removed in 1.28
console.warn(`'vscode.openFolder' command invoked with an invalid URI (file:// scheme missing): '${uri}'. Converted to a 'file://' URI: ${correctedUri}`);
uri = correctedUri;
}
return executor.executeCommand('_files.windowOpen', { urisToOpen: [{ uri }], forceNewWindow });
}
}

View File

@@ -65,6 +65,7 @@ import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/n
import * as vscode from 'vscode';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { originalFSPath } from 'vs/base/common/resources';
import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer';
export interface IExtensionApiFactory {
(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode;
@@ -113,7 +114,7 @@ export function createApiFactory(
const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures));
const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostDocumentsAndEditors));
const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands));
const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostLogService, extHostCommands));
const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostLogService));
const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService, extHostCommands));
const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService));
const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments));
@@ -124,6 +125,10 @@ export function createApiFactory(
const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress)));
const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, new ExtHostOutputService(initData.logsLocation, rpcProtocol));
rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage);
if (initData.remoteAuthority) {
const cliServer = new CLIServer(extHostCommands);
process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath;
}
// Check that no named customers are missing
const expected: ProxyIdentifier<any>[] = Object.keys(ExtHostContext).map((key) => (<any>ExtHostContext)[key]);

View File

@@ -0,0 +1,101 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { generateRandomPipeName } from 'vs/base/parts/ipc/node/ipc.net';
import * as http from 'http';
import * as fs from 'fs';
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
import { IURIToOpen, URIType } from 'vs/platform/windows/common/windows';
import { URI } from 'vs/base/common/uri';
import { hasWorkspaceFileExtension } from 'vs/platform/workspaces/common/workspaces';
export class CLIServer {
private _server: http.Server;
private _ipcHandlePath: string | undefined;
constructor(private _commands: ExtHostCommands) {
this._server = http.createServer((req, res) => this.onRequest(req, res));
this.setup().catch(err => {
console.error(err);
return '';
});
}
public get ipcHandlePath() {
return this._ipcHandlePath;
}
private async setup(): Promise<string> {
this._ipcHandlePath = generateRandomPipeName();
try {
this._server.listen(this.ipcHandlePath);
this._server.on('error', err => console.error(err));
} catch (err) {
console.error('Could not start open from terminal server.');
}
return this.ipcHandlePath;
}
private collectURIToOpen(strs: string[], typeHint: URIType, result: IURIToOpen[]): void {
if (Array.isArray(strs)) {
for (const s of strs) {
try {
result.push({ uri: URI.parse(s), typeHint });
} catch (e) {
// ignore
}
}
}
}
private onRequest(req: http.IncomingMessage, res: http.ServerResponse): void {
const chunks: string[] = [];
req.setEncoding('utf8');
req.on('data', (d: string) => chunks.push(d));
req.on('end', () => {
const data = JSON.parse(chunks.join(''));
switch (data.type) {
case 'open':
this.open(data, res);
break;
default:
res.writeHead(404);
res.write(`Unkown message type: ${data.type}`, err => {
if (err) {
console.error(err);
}
});
res.end();
break;
}
});
}
private open(data: any, res: http.ServerResponse) {
let { fileURIs, folderURIs, forceNewWindow, diffMode, addMode, forceReuseWindow } = data;
if (folderURIs && folderURIs.length || fileURIs && fileURIs.length) {
const urisToOpen: IURIToOpen[] = [];
this.collectURIToOpen(folderURIs, 'folder', urisToOpen);
this.collectURIToOpen(fileURIs, 'file', urisToOpen);
if (!forceReuseWindow && urisToOpen.some(o => o.typeHint === 'folder' || (o.typeHint === 'file' && hasWorkspaceFileExtension(o.uri.path)))) {
forceNewWindow = true;
}
this._commands.executeCommand('_files.windowOpen', { urisToOpen, forceNewWindow, diffMode, addMode, forceReuseWindow });
}
res.writeHead(200);
res.end();
}
dispose(): void {
this._server.close();
if (this._ipcHandlePath && process.platform !== 'win32' && fs.existsSync(this._ipcHandlePath)) {
fs.unlinkSync(this._ipcHandlePath);
}
}
}

View File

@@ -8,9 +8,9 @@ import { IMarkerData, MarkerSeverity } from 'vs/platform/markers/common/markers'
import { URI } from 'vs/base/common/uri';
import * as vscode from 'vscode';
import { MainContext, MainThreadDiagnosticsShape, ExtHostDiagnosticsShape, IMainContext } from './extHost.protocol';
import { DiagnosticSeverity, Diagnostic } from './extHostTypes';
import { DiagnosticSeverity } from './extHostTypes';
import * as converter from './extHostTypeConverters';
import { mergeSort, equals } from 'vs/base/common/arrays';
import { mergeSort } from 'vs/base/common/arrays';
import { Event, Emitter } from 'vs/base/common/event';
import { keys } from 'vs/base/common/map';
@@ -61,13 +61,9 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
this._checkDisposed();
let toSync: vscode.Uri[] = [];
let hasChanged = true;
if (first instanceof URI) {
// check if this has actually changed
hasChanged = hasChanged && !equals(diagnostics, this.get(first), Diagnostic.isEqual);
if (!diagnostics) {
// remove this entry
this.delete(first);
@@ -109,14 +105,6 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
// send event for extensions
this._onDidChangeDiagnostics.fire(toSync);
// if nothing has changed then there is nothing else to do
// we have updated the diagnostics but we don't send a message
// to the renderer. tho we have still send an event for other
// extensions because the diagnostic might carry more information
// than known to us
if (!hasChanged) {
return;
}
// compute change and send to main side
const entries: [URI, IMarkerData[]][] = [];
for (let uri of toSync) {

View File

@@ -14,12 +14,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { EXT_HOST_CREATION_DELAY } from 'vs/workbench/contrib/terminal/common/terminal';
import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess';
import { timeout } from 'vs/base/common/async';
import { generateRandomPipeName } from 'vs/base/parts/ipc/node/ipc.net';
import * as http from 'http';
import * as fs from 'fs';
import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands';
import { sanitizeProcessEnvironment } from 'vs/base/node/processes';
import { IURIToOpen, URIType } from 'vs/platform/windows/common/windows';
const RENDERER_NO_PROCESS_ID = -1;
@@ -284,7 +279,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
private _terminalProcesses: { [id: number]: TerminalProcess } = {};
private _terminalRenderers: ExtHostTerminalRenderer[] = [];
private _getTerminalPromises: { [id: number]: Promise<ExtHostTerminal> } = {};
private _cliServer: CLIServer | undefined;
public get activeTerminal(): ExtHostTerminal { return this._activeTerminal; }
public get terminals(): ExtHostTerminal[] { return this._terminals; }
@@ -302,7 +296,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
mainContext: IMainContext,
private _extHostConfiguration: ExtHostConfiguration,
private _logService: ILogService,
private _commands: ExtHostCommands
) {
this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService);
}
@@ -483,17 +476,12 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
// Sanitize the environment, removing any undesirable VS Code and Electron environment
// variables
sanitizeProcessEnvironment(env);
sanitizeProcessEnvironment(env, 'VSCODE_IPC_HOOK_CLI');
// Continue env initialization, merging in the env from the launch
// config and adding keys that are needed to create the process
terminalEnvironment.addTerminalEnvironmentKeys(env, platform.locale, terminalConfig.get('setLocaleVariables'));
if (!this._cliServer) {
this._cliServer = new CLIServer(this._commands);
}
env['VSCODE_IPC_HOOK_CLI'] = this._cliServer.ipcHandlePath;
// Fork the process and listen for messages
this._logService.debug(`Terminal process launching on ext host`, shellLaunchConfig, initialCwd, cols, rows, env);
const p = new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, terminalConfig.get('windowsEnableConpty'));
@@ -542,11 +530,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
// Send exit event to main side
this._proxy.$sendProcessExit(id, exitCode);
if (this._cliServer && !Object.keys(this._terminalProcesses).length) {
this._cliServer.dispose();
this._cliServer = undefined;
}
}
private _getTerminalByIdEventually(id: number, retries: number = 5): Promise<ExtHostTerminal> {
@@ -618,74 +601,3 @@ class ApiRequest {
this._callback.apply(proxy, [id].concat(this._args));
}
}
class CLIServer {
private _server: http.Server;
private _ipcHandlePath: string | undefined;
constructor(private _commands: ExtHostCommands) {
this._server = http.createServer((req, res) => this.onRequest(req, res));
this.setup().catch(err => {
console.error(err);
return '';
});
}
public get ipcHandlePath() {
return this._ipcHandlePath;
}
private async setup(): Promise<string> {
this._ipcHandlePath = generateRandomPipeName();
try {
this._server.listen(this.ipcHandlePath);
this._server.on('error', err => console.error(err));
} catch (err) {
console.error('Could not start open from terminal server.');
}
return this.ipcHandlePath;
}
private collectURIToOpen(strs: string[], typeHint: URIType, result: IURIToOpen[]): void {
if (Array.isArray(strs)) {
for (const s of strs) {
try {
result.push({ uri: URI.parse(s), typeHint });
} catch (e) {
// ignore
}
}
}
}
private onRequest(req: http.IncomingMessage, res: http.ServerResponse): void {
const chunks: string[] = [];
req.setEncoding('utf8');
req.on('data', (d: string) => chunks.push(d));
req.on('end', () => {
let { fileURIs, folderURIs, forceNewWindow, diffMode, addMode, forceReuseWindow } = JSON.parse(chunks.join(''));
if (folderURIs && folderURIs.length || fileURIs && fileURIs.length) {
if (folderURIs && folderURIs.length && !forceReuseWindow) {
forceNewWindow = true;
}
const urisToOpen: IURIToOpen[] = [];
this.collectURIToOpen(folderURIs, 'folder', urisToOpen);
this.collectURIToOpen(fileURIs, 'file', urisToOpen);
this._commands.executeCommand('_files.windowOpen', { urisToOpen, forceNewWindow, diffMode, addMode, forceReuseWindow });
}
res.writeHead(200);
res.end();
});
}
dispose(): void {
this._server.close();
if (this._ipcHandlePath && process.platform !== 'win32' && fs.existsSync(this._ipcHandlePath)) {
fs.unlinkSync(this._ipcHandlePath);
}
}
}