Merge VS Code 1.23.1 (#1520)

This commit is contained in:
Matt Irvine
2018-06-05 11:24:51 -07:00
committed by GitHub
parent e3baf5c443
commit 0c58f09e59
3651 changed files with 74249 additions and 48599 deletions

View File

@@ -0,0 +1,287 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
export const ID = 'driverService';
export const IDriver = createDecorator<IDriver>(ID);
// !! Do not remove the following START and END markers, they are parsed by the smoketest build
//*START
export interface IElement {
tagName: string;
className: string;
textContent: string;
attributes: { [name: string]: string; };
children: IElement[];
}
export interface IDriver {
_serviceBrand: any;
getWindowIds(): TPromise<number[]>;
capturePage(windowId: number): TPromise<string>;
reloadWindow(windowId: number): TPromise<void>;
dispatchKeybinding(windowId: number, keybinding: string): TPromise<void>;
click(windowId: number, selector: string, xoffset?: number | undefined, yoffset?: number | undefined): TPromise<void>;
doubleClick(windowId: number, selector: string): TPromise<void>;
move(windowId: number, selector: string): TPromise<void>;
setValue(windowId: number, selector: string, text: string): TPromise<void>;
paste(windowId: number, selector: string, text: string): TPromise<void>;
getTitle(windowId: number): TPromise<string>;
isActiveElement(windowId: number, selector: string): TPromise<boolean>;
getElements(windowId: number, selector: string, recursive?: boolean): TPromise<IElement[]>;
typeInEditor(windowId: number, selector: string, text: string): TPromise<void>;
getTerminalBuffer(windowId: number, selector: string): TPromise<string[]>;
}
//*END
export interface IDriverChannel extends IChannel {
call(command: 'getWindowIds'): TPromise<number[]>;
call(command: 'capturePage'): TPromise<string>;
call(command: 'reloadWindow', arg: number): TPromise<void>;
call(command: 'dispatchKeybinding', arg: [number, string]): TPromise<void>;
call(command: 'click', arg: [number, string, number | undefined, number | undefined]): TPromise<void>;
call(command: 'doubleClick', arg: [number, string]): TPromise<void>;
call(command: 'move', arg: [number, string]): TPromise<void>;
call(command: 'setValue', arg: [number, string, string]): TPromise<void>;
call(command: 'paste', arg: [number, string, string]): TPromise<void>;
call(command: 'getTitle', arg: [number]): TPromise<string>;
call(command: 'isActiveElement', arg: [number, string]): TPromise<boolean>;
call(command: 'getElements', arg: [number, string, boolean]): TPromise<IElement[]>;
call(command: 'typeInEditor', arg: [number, string, string]): TPromise<void>;
call(command: 'getTerminalBuffer', arg: [number, string]): TPromise<string[]>;
call(command: string, arg: any): TPromise<any>;
}
export class DriverChannel implements IDriverChannel {
constructor(private driver: IDriver) { }
call(command: string, arg?: any): TPromise<any> {
switch (command) {
case 'getWindowIds': return this.driver.getWindowIds();
case 'capturePage': return this.driver.capturePage(arg);
case 'reloadWindow': return this.driver.reloadWindow(arg);
case 'dispatchKeybinding': return this.driver.dispatchKeybinding(arg[0], arg[1]);
case 'click': return this.driver.click(arg[0], arg[1], arg[2], arg[3]);
case 'doubleClick': return this.driver.doubleClick(arg[0], arg[1]);
case 'move': return this.driver.move(arg[0], arg[1]);
case 'setValue': return this.driver.setValue(arg[0], arg[1], arg[2]);
case 'paste': return this.driver.paste(arg[0], arg[1], arg[2]);
case 'getTitle': return this.driver.getTitle(arg[0]);
case 'isActiveElement': return this.driver.isActiveElement(arg[0], arg[1]);
case 'getElements': return this.driver.getElements(arg[0], arg[1], arg[2]);
case 'typeInEditor': return this.driver.typeInEditor(arg[0], arg[1], arg[2]);
case 'getTerminalBuffer': return this.driver.getTerminalBuffer(arg[0], arg[1]);
}
return undefined;
}
}
export class DriverChannelClient implements IDriver {
_serviceBrand: any;
constructor(private channel: IDriverChannel) { }
getWindowIds(): TPromise<number[]> {
return this.channel.call('getWindowIds');
}
capturePage(windowId: number): TPromise<string> {
return this.channel.call('capturePage', windowId);
}
reloadWindow(windowId: number): TPromise<void> {
return this.channel.call('reloadWindow', windowId);
}
dispatchKeybinding(windowId: number, keybinding: string): TPromise<void> {
return this.channel.call('dispatchKeybinding', [windowId, keybinding]);
}
click(windowId: number, selector: string, xoffset: number | undefined, yoffset: number | undefined): TPromise<void> {
return this.channel.call('click', [windowId, selector, xoffset, yoffset]);
}
doubleClick(windowId: number, selector: string): TPromise<void> {
return this.channel.call('doubleClick', [windowId, selector]);
}
move(windowId: number, selector: string): TPromise<void> {
return this.channel.call('move', [windowId, selector]);
}
setValue(windowId: number, selector: string, text: string): TPromise<void> {
return this.channel.call('setValue', [windowId, selector, text]);
}
paste(windowId: number, selector: string, text: string): TPromise<void> {
return this.channel.call('paste', [windowId, selector, text]);
}
getTitle(windowId: number): TPromise<string> {
return this.channel.call('getTitle', [windowId]);
}
isActiveElement(windowId: number, selector: string): TPromise<boolean> {
return this.channel.call('isActiveElement', [windowId, selector]);
}
getElements(windowId: number, selector: string, recursive: boolean): TPromise<IElement[]> {
return this.channel.call('getElements', [windowId, selector, recursive]);
}
typeInEditor(windowId: number, selector: string, text: string): TPromise<void> {
return this.channel.call('typeInEditor', [windowId, selector, text]);
}
getTerminalBuffer(windowId: number, selector: string): TPromise<string[]> {
return this.channel.call('getTerminalBuffer', [windowId, selector]);
}
}
export interface IWindowDriverRegistry {
registerWindowDriver(windowId: number): TPromise<void>;
reloadWindowDriver(windowId: number): TPromise<void>;
}
export interface IWindowDriverRegistryChannel extends IChannel {
call(command: 'registerWindowDriver', arg: number): TPromise<void>;
call(command: 'reloadWindowDriver', arg: number): TPromise<void>;
call(command: string, arg: any): TPromise<any>;
}
export class WindowDriverRegistryChannel implements IWindowDriverRegistryChannel {
constructor(private registry: IWindowDriverRegistry) { }
call(command: string, arg?: any): TPromise<any> {
switch (command) {
case 'registerWindowDriver': return this.registry.registerWindowDriver(arg);
case 'reloadWindowDriver': return this.registry.reloadWindowDriver(arg);
}
return undefined;
}
}
export class WindowDriverRegistryChannelClient implements IWindowDriverRegistry {
_serviceBrand: any;
constructor(private channel: IWindowDriverRegistryChannel) { }
registerWindowDriver(windowId: number): TPromise<void> {
return this.channel.call('registerWindowDriver', windowId);
}
reloadWindowDriver(windowId: number): TPromise<void> {
return this.channel.call('reloadWindowDriver', windowId);
}
}
export interface IWindowDriver {
click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): TPromise<void>;
doubleClick(selector: string): TPromise<void>;
move(selector: string): TPromise<void>;
setValue(selector: string, text: string): TPromise<void>;
paste(selector: string, text: string): TPromise<void>;
getTitle(): TPromise<string>;
isActiveElement(selector: string): TPromise<boolean>;
getElements(selector: string, recursive: boolean): TPromise<IElement[]>;
typeInEditor(selector: string, text: string): TPromise<void>;
getTerminalBuffer(selector: string): TPromise<string[]>;
}
export interface IWindowDriverChannel extends IChannel {
call(command: 'click', arg: [string, number | undefined, number | undefined]): TPromise<void>;
call(command: 'doubleClick', arg: string): TPromise<void>;
call(command: 'move', arg: string): TPromise<void>;
call(command: 'setValue', arg: [string, string]): TPromise<void>;
call(command: 'paste', arg: [string, string]): TPromise<void>;
call(command: 'getTitle'): TPromise<string>;
call(command: 'isActiveElement', arg: string): TPromise<boolean>;
call(command: 'getElements', arg: [string, boolean]): TPromise<IElement[]>;
call(command: 'typeInEditor', arg: [string, string]): TPromise<void>;
call(command: 'getTerminalBuffer', arg: string): TPromise<string[]>;
call(command: string, arg: any): TPromise<any>;
}
export class WindowDriverChannel implements IWindowDriverChannel {
constructor(private driver: IWindowDriver) { }
call(command: string, arg?: any): TPromise<any> {
switch (command) {
case 'click': return this.driver.click(arg[0], arg[1], arg[2]);
case 'doubleClick': return this.driver.doubleClick(arg);
case 'move': return this.driver.move(arg);
case 'setValue': return this.driver.setValue(arg[0], arg[1]);
case 'paste': return this.driver.paste(arg[0], arg[1]);
case 'getTitle': return this.driver.getTitle();
case 'isActiveElement': return this.driver.isActiveElement(arg);
case 'getElements': return this.driver.getElements(arg[0], arg[1]);
case 'typeInEditor': return this.driver.typeInEditor(arg[0], arg[1]);
case 'getTerminalBuffer': return this.driver.getTerminalBuffer(arg);
}
return undefined;
}
}
export class WindowDriverChannelClient implements IWindowDriver {
_serviceBrand: any;
constructor(private channel: IWindowDriverChannel) { }
click(selector: string, xoffset?: number, yoffset?: number): TPromise<void> {
return this.channel.call('click', [selector, xoffset, yoffset]);
}
doubleClick(selector: string): TPromise<void> {
return this.channel.call('doubleClick', selector);
}
move(selector: string): TPromise<void> {
return this.channel.call('move', selector);
}
setValue(selector: string, text: string): TPromise<void> {
return this.channel.call('setValue', [selector, text]);
}
paste(selector: string, text: string): TPromise<void> {
return this.channel.call('paste', [selector, text]);
}
getTitle(): TPromise<string> {
return this.channel.call('getTitle');
}
isActiveElement(selector: string): TPromise<boolean> {
return this.channel.call('isActiveElement', selector);
}
getElements(selector: string, recursive: boolean): TPromise<IElement[]> {
return this.channel.call('getElements', [selector, recursive]);
}
typeInEditor(selector: string, text: string): TPromise<void> {
return this.channel.call('typeInEditor', [selector, text]);
}
getTerminalBuffer(selector: string): TPromise<string[]> {
return this.channel.call('getTerminalBuffer', selector);
}
}

View File

@@ -0,0 +1,204 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { IDisposable, toDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
import { IWindowDriver, IElement, WindowDriverChannel, WindowDriverRegistryChannelClient } from 'vs/platform/driver/common/driver';
import { IPCClient } from 'vs/base/parts/ipc/common/ipc';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { getTopLeftOffset, getClientArea } from 'vs/base/browser/dom';
import * as electron from 'electron';
function serializeElement(element: Element, recursive: boolean): IElement {
const attributes = Object.create(null);
for (let j = 0; j < element.attributes.length; j++) {
const attr = element.attributes.item(j);
attributes[attr.name] = attr.value;
}
const children = [];
if (recursive) {
for (let i = 0; i < element.children.length; i++) {
children.push(serializeElement(element.children.item(i), true));
}
}
return {
tagName: element.tagName,
className: element.className,
textContent: element.textContent || '',
attributes,
children
};
}
class WindowDriver implements IWindowDriver {
constructor() { }
async click(selector: string, xoffset?: number, yoffset?: number): TPromise<void> {
return this._click(selector, 1, xoffset, yoffset);
}
doubleClick(selector: string): TPromise<void> {
return this._click(selector, 2);
}
private async _getElementXY(selector: string, xoffset?: number, yoffset?: number): TPromise<{ x: number; y: number; }> {
const element = document.querySelector(selector);
if (!element) {
throw new Error('Element not found');
}
const { left, top } = getTopLeftOffset(element as HTMLElement);
const { width, height } = getClientArea(element as HTMLElement);
let x: number, y: number;
if ((typeof xoffset === 'number') || (typeof yoffset === 'number')) {
x = left + xoffset;
y = top + yoffset;
} else {
x = left + (width / 2);
y = top + (height / 2);
}
x = Math.round(x);
y = Math.round(y);
return { x, y };
}
private async _click(selector: string, clickCount: number, xoffset?: number, yoffset?: number): TPromise<void> {
const { x, y } = await this._getElementXY(selector, xoffset, yoffset);
const webContents = electron.remote.getCurrentWebContents();
webContents.sendInputEvent({ type: 'mouseDown', x, y, button: 'left', clickCount } as any);
webContents.sendInputEvent({ type: 'mouseUp', x, y, button: 'left', clickCount } as any);
await TPromise.timeout(100);
}
async move(selector: string): TPromise<void> {
const { x, y } = await this._getElementXY(selector);
const webContents = electron.remote.getCurrentWebContents();
webContents.sendInputEvent({ type: 'mouseMove', x, y } as any);
await TPromise.timeout(100);
}
async setValue(selector: string, text: string): TPromise<void> {
const element = document.querySelector(selector);
if (!element) {
throw new Error('Element not found');
}
const inputElement = element as HTMLInputElement;
inputElement.value = text;
const event = new Event('input', { bubbles: true, cancelable: true });
inputElement.dispatchEvent(event);
}
async paste(selector: string, text: string): TPromise<void> {
const element = document.querySelector(selector);
if (!element) {
throw new Error('Element not found');
}
const inputElement = element as HTMLInputElement;
const clipboardData = new DataTransfer();
clipboardData.setData('text/plain', text);
const event = new ClipboardEvent('paste', { clipboardData } as any);
inputElement.dispatchEvent(event);
}
async getTitle(): TPromise<string> {
return document.title;
}
async isActiveElement(selector: string): TPromise<boolean> {
const element = document.querySelector(selector);
return element === document.activeElement;
}
async getElements(selector: string, recursive: boolean): TPromise<IElement[]> {
const query = document.querySelectorAll(selector);
const result: IElement[] = [];
for (let i = 0; i < query.length; i++) {
const element = query.item(i);
result.push(serializeElement(element, recursive));
}
return result;
}
async typeInEditor(selector: string, text: string): TPromise<void> {
const element = document.querySelector(selector);
if (!element) {
throw new Error('Editor not found: ' + selector);
}
const textarea = element as HTMLTextAreaElement;
const start = textarea.selectionStart;
const newStart = start + text.length;
const value = textarea.value;
const newValue = value.substr(0, start) + text + value.substr(start);
textarea.value = newValue;
textarea.setSelectionRange(newStart, newStart);
const event = new Event('input', { 'bubbles': true, 'cancelable': true });
textarea.dispatchEvent(event);
}
async getTerminalBuffer(selector: string): TPromise<string[]> {
const element = document.querySelector(selector);
if (!element) {
throw new Error('Terminal not found: ' + selector);
}
const xterm = (element as any).xterm;
if (!xterm) {
throw new Error('Xterm not found: ' + selector);
}
const lines: string[] = [];
for (let i = 0; i < xterm.buffer.lines.length; i++) {
lines.push(xterm.buffer.translateBufferLineToString(i, true));
}
return lines;
}
}
export async function registerWindowDriver(
client: IPCClient,
windowId: number,
instantiationService: IInstantiationService
): TPromise<IDisposable> {
const windowDriver = instantiationService.createInstance(WindowDriver);
const windowDriverChannel = new WindowDriverChannel(windowDriver);
client.registerChannel('windowDriver', windowDriverChannel);
const windowDriverRegistryChannel = client.getChannel('windowDriverRegistry');
const windowDriverRegistry = new WindowDriverRegistryChannelClient(windowDriverRegistryChannel);
await windowDriverRegistry.registerWindowDriver(windowId);
const disposable = toDisposable(() => windowDriverRegistry.reloadWindowDriver(windowId));
return combinedDisposable([disposable, client]);
}

View File

@@ -0,0 +1,218 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { IDriver, DriverChannel, IElement, IWindowDriverChannel, WindowDriverChannelClient, IWindowDriverRegistry, WindowDriverRegistryChannel, IWindowDriver } from 'vs/platform/driver/common/driver';
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
import { serve as serveNet } from 'vs/base/parts/ipc/node/ipc.net';
import { combinedDisposable, IDisposable } from 'vs/base/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IPCServer, IClientRouter } from 'vs/base/parts/ipc/common/ipc';
import { SimpleKeybinding, KeyCode } from 'vs/base/common/keyCodes';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
import { OS } from 'vs/base/common/platform';
import { Emitter, toPromise } from 'vs/base/common/event';
// TODO@joao: bad layering!
import { KeybindingIO } from 'vs/workbench/services/keybinding/common/keybindingIO';
import { ScanCodeBinding } from 'vs/workbench/services/keybinding/common/scanCode';
import { NativeImage } from 'electron';
class WindowRouter implements IClientRouter {
constructor(private windowId: number) { }
route(command: string, arg: any): string {
return `window:${this.windowId}`;
}
}
function isSilentKeyCode(keyCode: KeyCode) {
return keyCode < KeyCode.KEY_0;
}
export class Driver implements IDriver, IWindowDriverRegistry {
_serviceBrand: any;
private registeredWindowIds = new Set<number>();
private reloadingWindowIds = new Set<number>();
private onDidReloadingChange = new Emitter<void>();
constructor(
private windowServer: IPCServer,
@IWindowsMainService private windowsService: IWindowsMainService
) { }
async registerWindowDriver(windowId: number): TPromise<void> {
this.registeredWindowIds.add(windowId);
this.reloadingWindowIds.delete(windowId);
this.onDidReloadingChange.fire();
}
async reloadWindowDriver(windowId: number): TPromise<void> {
this.reloadingWindowIds.add(windowId);
}
async getWindowIds(): TPromise<number[]> {
return this.windowsService.getWindows()
.map(w => w.id)
.filter(id => this.registeredWindowIds.has(id) && !this.reloadingWindowIds.has(id));
}
async capturePage(windowId: number): TPromise<string> {
await this.whenUnfrozen(windowId);
const window = this.windowsService.getWindowById(windowId);
const webContents = window.win.webContents;
const image = await new Promise<NativeImage>(c => webContents.capturePage(c));
const buffer = image.toPNG();
return buffer.toString('base64');
}
async reloadWindow(windowId: number): TPromise<void> {
await this.whenUnfrozen(windowId);
const window = this.windowsService.getWindowById(windowId);
this.reloadingWindowIds.add(windowId);
this.windowsService.reload(window);
}
async dispatchKeybinding(windowId: number, keybinding: string): TPromise<void> {
await this.whenUnfrozen(windowId);
const [first, second] = KeybindingIO._readUserBinding(keybinding);
await this._dispatchKeybinding(windowId, first);
if (second) {
await this._dispatchKeybinding(windowId, second);
}
}
private async _dispatchKeybinding(windowId: number, keybinding: SimpleKeybinding | ScanCodeBinding): TPromise<void> {
if (keybinding instanceof ScanCodeBinding) {
throw new Error('ScanCodeBindings not supported');
}
const window = this.windowsService.getWindowById(windowId);
const webContents = window.win.webContents;
const noModifiedKeybinding = new SimpleKeybinding(false, false, false, false, keybinding.keyCode);
const resolvedKeybinding = new USLayoutResolvedKeybinding(noModifiedKeybinding, OS);
const keyCode = resolvedKeybinding.getElectronAccelerator();
const modifiers = [];
if (keybinding.ctrlKey) {
modifiers.push('ctrl');
}
if (keybinding.metaKey) {
modifiers.push('meta');
}
if (keybinding.shiftKey) {
modifiers.push('shift');
}
if (keybinding.altKey) {
modifiers.push('alt');
}
webContents.sendInputEvent({ type: 'keyDown', keyCode, modifiers } as any);
if (!isSilentKeyCode(keybinding.keyCode)) {
webContents.sendInputEvent({ type: 'char', keyCode, modifiers } as any);
}
webContents.sendInputEvent({ type: 'keyUp', keyCode, modifiers } as any);
await TPromise.timeout(100);
}
async click(windowId: number, selector: string, xoffset?: number, yoffset?: number): TPromise<void> {
const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.click(selector, xoffset, yoffset);
}
async doubleClick(windowId: number, selector: string): TPromise<void> {
const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.doubleClick(selector);
}
async move(windowId: number, selector: string): TPromise<void> {
const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.move(selector);
}
async setValue(windowId: number, selector: string, text: string): TPromise<void> {
const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.setValue(selector, text);
}
async paste(windowId: number, selector: string, text: string): TPromise<void> {
const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.paste(selector, text);
}
async getTitle(windowId: number): TPromise<string> {
const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.getTitle();
}
async isActiveElement(windowId: number, selector: string): TPromise<boolean> {
const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.isActiveElement(selector);
}
async getElements(windowId: number, selector: string, recursive: boolean): TPromise<IElement[]> {
const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.getElements(selector, recursive);
}
async typeInEditor(windowId: number, selector: string, text: string): TPromise<void> {
const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.typeInEditor(selector, text);
}
async getTerminalBuffer(windowId: number, selector: string): TPromise<string[]> {
const windowDriver = await this.getWindowDriver(windowId);
return windowDriver.getTerminalBuffer(selector);
}
private async getWindowDriver(windowId: number): TPromise<IWindowDriver> {
await this.whenUnfrozen(windowId);
const router = new WindowRouter(windowId);
const windowDriverChannel = this.windowServer.getChannel<IWindowDriverChannel>('windowDriver', router);
return new WindowDriverChannelClient(windowDriverChannel);
}
private async whenUnfrozen(windowId: number): TPromise<void> {
while (this.reloadingWindowIds.has(windowId)) {
await toPromise(this.onDidReloadingChange.event);
}
}
}
export async function serve(
windowServer: IPCServer,
handle: string,
instantiationService: IInstantiationService
): TPromise<IDisposable> {
const driver = instantiationService.createInstance(Driver, windowServer);
const windowDriverRegistryChannel = new WindowDriverRegistryChannel(driver);
windowServer.registerChannel('windowDriverRegistry', windowDriverRegistryChannel);
const server = await serveNet(handle);
const channel = new DriverChannel(driver);
server.registerChannel('driver', channel);
return combinedDisposable([server, windowServer]);
}

View File

@@ -0,0 +1,17 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { IDriver, DriverChannelClient } from 'vs/platform/driver/common/driver';
import { connect as connectNet, Client } from 'vs/base/parts/ipc/node/ipc.net';
export async function connect(handle: string): TPromise<{ client: Client, driver: IDriver }> {
const client = await connectNet(handle, 'driverClient');
const channel = client.getChannel('driver');
const driver = new DriverChannelClient(channel);
return { client, driver };
}