VSCode merge (#4610)

* Merge from vscode e388c734f30757875976c7e326d6cfeee77710de

* fix yarn lcoks

* remove small issue
This commit is contained in:
Anthony Dresser
2019-03-20 10:39:09 -07:00
committed by GitHub
parent 87765e8673
commit c814b92557
310 changed files with 6606 additions and 2129 deletions

View File

@@ -20,7 +20,7 @@ import { URI } from 'vs/base/common/uri';
import { IRemoteConsoleLog, log, parse } from 'vs/base/node/console';
import { findFreePort, randomPort } from 'vs/base/node/ports';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc';
import { Protocol, generateRandomPipeName, BufferedProtocol } from 'vs/base/parts/ipc/node/ipc.net';
import { PersistentProtocol, generateRandomPipeName } from 'vs/base/parts/ipc/node/ipc.net';
import { IBroadcast, IBroadcastService } from 'vs/workbench/services/broadcast/electron-browser/broadcastService';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { EXTENSION_ATTACH_BROADCAST_CHANNEL, EXTENSION_CLOSE_EXTHOST_BROADCAST_CHANNEL, EXTENSION_LOG_BROADCAST_CHANNEL, EXTENSION_RELOAD_BROADCAST_CHANNEL, EXTENSION_TERMINATE_BROADCAST_CHANNEL } from 'vs/platform/extensions/common/extensionHost';
@@ -32,7 +32,7 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IInitData } from 'vs/workbench/api/node/extHost.protocol';
import { IInitData } from 'vs/workbench/api/common/extHost.protocol';
import { MessageType, createMessageOfType, isMessageOfType } from 'vs/workbench/services/extensions/node/extensionHostProtocol';
import { withNullAsUndefined } from 'vs/base/common/types';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
@@ -366,7 +366,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
// using a buffered message protocol here because between now
// and the first time a `then` executes some messages might be lost
// unless we immediately register a listener for `onMessage`.
resolve(new BufferedProtocol(new Protocol(this._extensionHostConnection)));
resolve(new PersistentProtocol(this._extensionHostConnection));
});
}).then((protocol) => {

View File

@@ -10,12 +10,12 @@ import * as strings from 'vs/base/common/strings';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ExtHostCustomersRegistry } from 'vs/workbench/api/electron-browser/extHostCustomers';
import { ExtHostContext, ExtHostExtensionServiceShape, IExtHostContext, MainContext } from 'vs/workbench/api/node/extHost.protocol';
import { ExtHostCustomersRegistry } from 'vs/workbench/api/common/extHostCustomers';
import { ExtHostContext, ExtHostExtensionServiceShape, IExtHostContext, MainContext } from 'vs/workbench/api/common/extHost.protocol';
import { ProfileSession } from 'vs/workbench/services/extensions/common/extensions';
import { IExtensionHostStarter } from 'vs/workbench/services/extensions/electron-browser/extensionHost';
import { ExtensionHostProfiler } from 'vs/workbench/services/extensions/electron-browser/extensionHostProfiler';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier';
import { IRPCProtocolLogger, RPCProtocol, RequestInitiator, ResponsiveState } from 'vs/workbench/services/extensions/node/rpcProtocol';
import { ResolvedAuthority } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';

View File

@@ -32,6 +32,7 @@ import { ExtensionHostProcessManager } from 'vs/workbench/services/extensions/el
import { ExtensionIdentifier, IExtension, ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { Schemas } from 'vs/base/common/network';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IFileService } from 'vs/platform/files/common/files';
const hasOwnProperty = Object.hasOwnProperty;
const NO_OP_VOID_PROMISE = Promise.resolve<void>(undefined);
@@ -99,9 +100,16 @@ export class ExtensionService extends Disposable implements IExtensionService {
@IExtensionEnablementService private readonly _extensionEnablementService: IExtensionEnablementService,
@IExtensionManagementService private readonly _extensionManagementService: IExtensionManagementService,
@IWindowService private readonly _windowService: IWindowService,
@ILifecycleService private readonly _lifecycleService: ILifecycleService
@ILifecycleService private readonly _lifecycleService: ILifecycleService,
@IFileService fileService: IFileService
) {
super();
// help the file service to activate providers by activating extensions by file system event
this._register(fileService.onWillActivateFileSystemProvider(e => {
e.join(this.activateByEvent(`onFileSystem:${e.scheme}`));
}));
this._extensionHostLogsLocation = URI.file(path.join(this._environmentService.logsPath, `exthost${this._windowService.getCurrentWindowId()}`));
this._registry = new ExtensionDescriptionRegistry([]);
this._installedExtensionsReady = new Barrier();
@@ -127,7 +135,7 @@ export class ExtensionService extends Disposable implements IExtensionService {
}]);
}
this._extensionEnablementService.onEnablementChanged((extensions) => {
this._register(this._extensionEnablementService.onEnablementChanged((extensions) => {
let toAdd: IExtension[] = [];
let toRemove: string[] = [];
for (const extension of extensions) {
@@ -140,23 +148,23 @@ export class ExtensionService extends Disposable implements IExtensionService {
}
}
this._handleDeltaExtensions(new DeltaExtensionsQueueItem(toAdd, toRemove));
});
}));
this._extensionManagementService.onDidInstallExtension((event) => {
this._register(this._extensionManagementService.onDidInstallExtension((event) => {
if (event.local) {
if (this._extensionEnablementService.isEnabled(event.local)) {
// an extension has been installed
this._handleDeltaExtensions(new DeltaExtensionsQueueItem([event.local], []));
}
}
});
}));
this._extensionManagementService.onDidUninstallExtension((event) => {
this._register(this._extensionManagementService.onDidUninstallExtension((event) => {
if (!event.error) {
// an extension has been uninstalled
this._handleDeltaExtensions(new DeltaExtensionsQueueItem([], [event.identifier.id]));
}
});
}));
}
private _inHandleDeltaExtensions = false;
@@ -834,4 +842,4 @@ export class ExtensionService extends Disposable implements IExtensionService {
}
}
registerSingleton(IExtensionService, ExtensionService);
registerSingleton(IExtensionService, ExtensionService);

View File

@@ -10,13 +10,14 @@ import { Counter } from 'vs/base/common/numbers';
import { URI, setUriThrowOnMissingScheme } from 'vs/base/common/uri';
import { IURITransformer } from 'vs/base/common/uriIpc';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc';
import { IEnvironment, IInitData, MainContext, MainThreadConsoleShape } from 'vs/workbench/api/node/extHost.protocol';
import { IEnvironment, IInitData, MainContext, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration';
import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService';
import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService';
import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
import { RPCProtocol } from 'vs/workbench/services/extensions/node/rpcProtocol';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { withNullAsUndefined } from 'vs/base/common/types';
// we don't (yet) throw when extensions parse
// uris that have no scheme
@@ -73,7 +74,7 @@ export class ExtensionHostMain {
this.disposables.push(this._extHostLogService);
this._searchRequestIdProvider = new Counter();
const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, this._extHostLogService, this._searchRequestIdProvider, initData.workspace);
const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, this._extHostLogService, this._searchRequestIdProvider, withNullAsUndefined(initData.workspace));
this._extHostLogService.info('extension host started');
this._extHostLogService.trace('initData', initData);

View File

@@ -4,14 +4,14 @@
*--------------------------------------------------------------------------------------------*/
import * as nativeWatchdog from 'native-watchdog';
import { createConnection } from 'net';
import * as net from 'net';
import { onUnexpectedError } from 'vs/base/common/errors';
import { Event } from 'vs/base/common/event';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc';
import { Protocol } from 'vs/base/parts/ipc/node/ipc.net';
import { PersistentProtocol, ProtocolConstants } from 'vs/base/parts/ipc/node/ipc.net';
import product from 'vs/platform/product/node/product';
import { IInitData } from 'vs/workbench/api/node/extHost.protocol';
import { MessageType, createMessageOfType, isMessageOfType } from 'vs/workbench/services/extensions/node/extensionHostProtocol';
import { IInitData } from 'vs/workbench/api/common/extHost.protocol';
import { MessageType, createMessageOfType, isMessageOfType, IExtHostSocketMessage, IExtHostReadyMessage } from 'vs/workbench/services/extensions/node/extensionHostProtocol';
import { exit, ExtensionHostMain } from 'vs/workbench/services/extensions/node/extensionHostMain';
// With Electron 2.x and node.js 8.x the "natives" module
@@ -43,40 +43,93 @@ let onTerminate = function () {
exit();
};
function createExtHostProtocol(): Promise<IMessagePassingProtocol> {
function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
if (process.env.VSCODE_EXTHOST_WILL_SEND_SOCKET) {
const pipeName = process.env.VSCODE_IPC_HOOK_EXTHOST!;
return new Promise<IMessagePassingProtocol>((resolve, reject) => {
return new Promise<IMessagePassingProtocol>((resolve, reject) => {
let protocol: PersistentProtocol | null = null;
const socket = createConnection(pipeName, () => {
socket.removeListener('error', reject);
resolve(new Protocol(socket));
});
socket.once('error', reject);
let timer = setTimeout(() => {
reject(new Error('VSCODE_EXTHOST_IPC_SOCKET timeout'));
}, 60000);
}).then(protocol => {
let disconnectWaitTimer: NodeJS.Timeout | null = null;
return new class implements IMessagePassingProtocol {
process.on('message', (msg: IExtHostSocketMessage, handle: net.Socket) => {
if (msg && msg.type === 'VSCODE_EXTHOST_IPC_SOCKET') {
const initialDataChunk = Buffer.from(msg.initialDataChunk, 'base64');
if (protocol) {
// reconnection case
if (disconnectWaitTimer) {
clearTimeout(disconnectWaitTimer);
disconnectWaitTimer = null;
}
protocol.beginAcceptReconnection(handle, initialDataChunk);
protocol.endAcceptReconnection();
} else {
clearTimeout(timer);
protocol = new PersistentProtocol(handle, initialDataChunk);
protocol.onClose(() => onTerminate());
resolve(protocol);
private _terminating = false;
readonly onMessage: Event<any> = Event.filter(protocol.onMessage, msg => {
if (!isMessageOfType(msg, MessageType.Terminate)) {
return true;
protocol.onSocketClose(() => {
// The socket has closed, let's give the renderer a certain amount of time to reconnect
disconnectWaitTimer = setTimeout(() => {
disconnectWaitTimer = null;
onTerminate();
}, ProtocolConstants.ReconnectionGraceTime);
});
}
}
this._terminating = true;
onTerminate();
return false;
});
send(msg: any): void {
if (!this._terminating) {
protocol.send(msg);
}
// Now that we have managed to install a message listener, ask the other side to send us the socket
const req: IExtHostReadyMessage = { type: 'VSCODE_EXTHOST_IPC_READY' };
if (process.send) {
process.send(req);
}
};
});
});
} else {
const pipeName = process.env.VSCODE_IPC_HOOK_EXTHOST!;
return new Promise<IMessagePassingProtocol>((resolve, reject) => {
const socket = net.createConnection(pipeName, () => {
socket.removeListener('error', reject);
resolve(new PersistentProtocol(socket));
});
socket.once('error', reject);
});
}
}
async function createExtHostProtocol(): Promise<IMessagePassingProtocol> {
const protocol = await _createExtHostProtocol();
return new class implements IMessagePassingProtocol {
private _terminating = false;
readonly onMessage: Event<any> = Event.filter(protocol.onMessage, msg => {
if (!isMessageOfType(msg, MessageType.Terminate)) {
return true;
}
this._terminating = true;
onTerminate();
return false;
});
send(msg: any): void {
if (!this._terminating) {
protocol.send(msg);
}
}
};
}
function connectToRenderer(protocol: IMessagePassingProtocol): Promise<IRendererConnection> {

View File

@@ -3,6 +3,15 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export interface IExtHostReadyMessage {
type: 'VSCODE_EXTHOST_IPC_READY';
}
export interface IExtHostSocketMessage {
type: 'VSCODE_EXTHOST_IPC_SOCKET';
initialDataChunk: string;
}
export const enum MessageType {
Initialized,
Ready,

View File

@@ -16,7 +16,7 @@ import { endsWith } from 'vs/base/common/strings';
import { IExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace';
import { ExtHostConfigProvider } from 'vs/workbench/api/node/extHostConfiguration';
import { ProxyAgent } from 'vscode-proxy-agent';
import { MainThreadTelemetryShape } from 'vs/workbench/api/node/extHost.protocol';
import { MainThreadTelemetryShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService';
import { toErrorMessage } from 'vs/base/common/errorMessage';
import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService';
@@ -150,7 +150,7 @@ function setupProxyResolution(
return;
}
if (envNoProxy(hostname, String(parsedUrl.port || (<any>opts.agent).defaultPort))) {
if (typeof hostname === 'string' && envNoProxy(hostname, String(parsedUrl.port || (<any>opts.agent).defaultPort))) {
envNoProxyCount++;
callback('DIRECT');
extHostLogService.trace('ProxyResolver#resolveProxy envNoProxy', url, 'DIRECT');
@@ -184,8 +184,10 @@ function setupProxyResolution(
const start = Date.now();
extHostWorkspace.resolveProxy(url) // Use full URL to ensure it is an actually used one.
.then(proxy => {
cacheProxy(key, proxy);
collectResult(results, proxy, parsedUrl.protocol === 'https:' ? 'HTTPS' : 'HTTP', req);
if (proxy) {
cacheProxy(key, proxy);
collectResult(results, proxy, parsedUrl.protocol === 'https:' ? 'HTTPS' : 'HTTP', req);
}
callback(proxy);
extHostLogService.debug('ProxyResolver#resolveProxy', url, proxy);
}).then(() => {
@@ -314,7 +316,7 @@ function patches(originals: typeof http | typeof https, resolveProxy: ReturnType
};
function patch(original: typeof http.get) {
function patched(url: string | URL, options?: http.RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest {
function patched(url?: string | URL | null, options?: http.RequestOptions | null, callback?: (res: http.IncomingMessage) => void): http.ClientRequest {
if (typeof url !== 'string' && !(url && (<any>url).searchParams)) {
callback = <any>options;
options = url;
@@ -457,10 +459,10 @@ async function readCaCertificates() {
function readWindowsCaCertificates() {
const winCA = require.__$__nodeRequire<any>('win-ca-lib');
let ders = [];
let ders: any[] = [];
const store = winCA();
try {
let der;
let der: any;
while (der = store.next()) {
ders.push(der);
}

View File

@@ -12,7 +12,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { IURITransformer, transformIncomingURIs } from 'vs/base/common/uriIpc';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc';
import { LazyPromise } from 'vs/workbench/services/extensions/node/lazyPromise';
import { IRPCProtocol, ProxyIdentifier, getStringIdentifierForProxy } from 'vs/workbench/services/extensions/node/proxyIdentifier';
import { IRPCProtocol, ProxyIdentifier, getStringIdentifierForProxy } from 'vs/workbench/services/extensions/common/proxyIdentifier';
export interface JSONStringifyReplacer {
(key: string, value: any): any;
@@ -274,6 +274,9 @@ export class RPCProtocol extends Disposable implements IRPCProtocol {
this._receiveReplyErr(msgLength, req, undefined);
break;
}
default:
console.error(`received unexpected message`);
console.error(rawmsg);
}
}

View File

@@ -7,7 +7,7 @@ import * as assert from 'assert';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { Emitter, Event } from 'vs/base/common/event';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier';
import { RPCProtocol } from 'vs/workbench/services/extensions/node/rpcProtocol';
suite('RPCProtocol', () => {