mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-26 17:23:15 -05:00
Merge VS Code 1.21 source code (#1067)
* Initial VS Code 1.21 file copy with patches * A few more merges * Post npm install * Fix batch of build breaks * Fix more build breaks * Fix more build errors * Fix more build breaks * Runtime fixes 1 * Get connection dialog working with some todos * Fix a few packaging issues * Copy several node_modules to package build to fix loader issues * Fix breaks from master * A few more fixes * Make tests pass * First pass of license header updates * Second pass of license header updates * Fix restore dialog issues * Remove add additional themes menu items * fix select box issues where the list doesn't show up * formatting * Fix editor dispose issue * Copy over node modules to correct location on all platforms
This commit is contained in:
@@ -5,19 +5,19 @@
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as marshalling from 'vs/base/common/marshalling';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { LazyPromise } from 'vs/workbench/services/extensions/node/lazyPromise';
|
||||
import { ProxyIdentifier, IRPCProtocol } from 'vs/workbench/services/extensions/node/proxyIdentifier';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
|
||||
export interface IDispatcher {
|
||||
invoke(proxyId: string, methodName: string, args: any[]): any;
|
||||
}
|
||||
declare var Proxy: any; // TODO@TypeScript
|
||||
|
||||
export class RPCProtocol {
|
||||
export class RPCProtocol implements IRPCProtocol {
|
||||
|
||||
private _isDisposed: boolean;
|
||||
private _bigHandler: IDispatcher;
|
||||
private readonly _locals: { [id: string]: any; };
|
||||
private readonly _proxies: { [id: string]: any; };
|
||||
private _lastMessageId: number;
|
||||
private readonly _invokedHandlers: { [req: string]: TPromise<any>; };
|
||||
private readonly _pendingRPCReplies: { [msgId: string]: LazyPromise; };
|
||||
@@ -25,7 +25,8 @@ export class RPCProtocol {
|
||||
|
||||
constructor(protocol: IMessagePassingProtocol) {
|
||||
this._isDisposed = false;
|
||||
this._bigHandler = null;
|
||||
this._locals = Object.create(null);
|
||||
this._proxies = Object.create(null);
|
||||
this._lastMessageId = 0;
|
||||
this._invokedHandlers = Object.create(null);
|
||||
this._pendingRPCReplies = {};
|
||||
@@ -42,96 +43,151 @@ export class RPCProtocol {
|
||||
});
|
||||
}
|
||||
|
||||
public getProxy<T>(identifier: ProxyIdentifier<T>): T {
|
||||
if (!this._proxies[identifier.id]) {
|
||||
this._proxies[identifier.id] = this._createProxy(identifier.id);
|
||||
}
|
||||
return this._proxies[identifier.id];
|
||||
}
|
||||
|
||||
private _createProxy<T>(proxyId: string): T {
|
||||
let handler = {
|
||||
get: (target, name: string) => {
|
||||
if (!target[name] && name.charCodeAt(0) === CharCode.DollarSign) {
|
||||
target[name] = (...myArgs: any[]) => {
|
||||
return this._remoteCall(proxyId, name, myArgs);
|
||||
};
|
||||
}
|
||||
return target[name];
|
||||
}
|
||||
};
|
||||
return new Proxy(Object.create(null), handler);
|
||||
}
|
||||
|
||||
public set<T, R extends T>(identifier: ProxyIdentifier<T>, value: R): R {
|
||||
this._locals[identifier.id] = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
public assertRegistered(identifiers: ProxyIdentifier<any>[]): void {
|
||||
for (let i = 0, len = identifiers.length; i < len; i++) {
|
||||
const identifier = identifiers[i];
|
||||
if (!this._locals[identifier.id]) {
|
||||
throw new Error(`Missing actor ${identifier.id} (isMain: ${identifier.isMain})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _receiveOneMessage(rawmsg: string): void {
|
||||
if (this._isDisposed) {
|
||||
console.warn('Received message after being shutdown: ', rawmsg);
|
||||
return;
|
||||
}
|
||||
let msg = marshalling.parse(rawmsg);
|
||||
|
||||
if (msg.seq) {
|
||||
if (!this._pendingRPCReplies.hasOwnProperty(msg.seq)) {
|
||||
console.warn('Got reply to unknown seq');
|
||||
return;
|
||||
}
|
||||
let reply = this._pendingRPCReplies[msg.seq];
|
||||
delete this._pendingRPCReplies[msg.seq];
|
||||
|
||||
if (msg.err) {
|
||||
let err = msg.err;
|
||||
if (msg.err.$isError) {
|
||||
err = new Error();
|
||||
err.name = msg.err.name;
|
||||
err.message = msg.err.message;
|
||||
err.stack = msg.err.stack;
|
||||
}
|
||||
reply.resolveErr(err);
|
||||
return;
|
||||
}
|
||||
|
||||
reply.resolveOk(msg.res);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.cancel) {
|
||||
if (this._invokedHandlers[msg.cancel]) {
|
||||
this._invokedHandlers[msg.cancel].cancel();
|
||||
}
|
||||
return;
|
||||
let msg = <RPCMessage>JSON.parse(rawmsg);
|
||||
|
||||
switch (msg.type) {
|
||||
case MessageType.Request:
|
||||
this._receiveRequest(msg);
|
||||
break;
|
||||
case MessageType.Cancel:
|
||||
this._receiveCancel(msg);
|
||||
break;
|
||||
case MessageType.Reply:
|
||||
this._receiveReply(msg);
|
||||
break;
|
||||
case MessageType.ReplyErr:
|
||||
this._receiveReplyErr(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (msg.err) {
|
||||
console.error(msg.err);
|
||||
return;
|
||||
}
|
||||
private _receiveRequest(msg: RequestMessage): void {
|
||||
const callId = msg.id;
|
||||
const proxyId = msg.proxyId;
|
||||
|
||||
let rpcId = msg.rpcId;
|
||||
this._invokedHandlers[callId] = this._invokeHandler(proxyId, msg.method, msg.args);
|
||||
|
||||
if (!this._bigHandler) {
|
||||
throw new Error('got message before big handler attached!');
|
||||
}
|
||||
|
||||
let req = msg.req;
|
||||
|
||||
this._invokedHandlers[req] = this._invokeHandler(rpcId, msg.method, msg.args);
|
||||
|
||||
this._invokedHandlers[req].then((r) => {
|
||||
delete this._invokedHandlers[req];
|
||||
this._multiplexor.send(MessageFactory.replyOK(req, r));
|
||||
this._invokedHandlers[callId].then((r) => {
|
||||
delete this._invokedHandlers[callId];
|
||||
this._multiplexor.send(MessageFactory.replyOK(callId, r));
|
||||
}, (err) => {
|
||||
delete this._invokedHandlers[req];
|
||||
this._multiplexor.send(MessageFactory.replyErr(req, err));
|
||||
delete this._invokedHandlers[callId];
|
||||
this._multiplexor.send(MessageFactory.replyErr(callId, err));
|
||||
});
|
||||
}
|
||||
|
||||
private _receiveCancel(msg: CancelMessage): void {
|
||||
const callId = msg.id;
|
||||
if (this._invokedHandlers[callId]) {
|
||||
this._invokedHandlers[callId].cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private _receiveReply(msg: ReplyMessage): void {
|
||||
const callId = msg.id;
|
||||
if (!this._pendingRPCReplies.hasOwnProperty(callId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pendingReply = this._pendingRPCReplies[callId];
|
||||
delete this._pendingRPCReplies[callId];
|
||||
|
||||
pendingReply.resolveOk(msg.res);
|
||||
}
|
||||
|
||||
private _receiveReplyErr(msg: ReplyErrMessage): void {
|
||||
const callId = msg.id;
|
||||
if (!this._pendingRPCReplies.hasOwnProperty(callId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pendingReply = this._pendingRPCReplies[callId];
|
||||
delete this._pendingRPCReplies[callId];
|
||||
|
||||
let err: Error = null;
|
||||
if (msg.err && msg.err.$isError) {
|
||||
err = new Error();
|
||||
err.name = msg.err.name;
|
||||
err.message = msg.err.message;
|
||||
err.stack = msg.err.stack;
|
||||
}
|
||||
pendingReply.resolveErr(err);
|
||||
}
|
||||
|
||||
private _invokeHandler(proxyId: string, methodName: string, args: any[]): TPromise<any> {
|
||||
try {
|
||||
return TPromise.as(this._bigHandler.invoke(proxyId, methodName, args));
|
||||
return TPromise.as(this._doInvokeHandler(proxyId, methodName, args));
|
||||
} catch (err) {
|
||||
return TPromise.wrapError(err);
|
||||
}
|
||||
}
|
||||
|
||||
public callOnRemote(proxyId: string, methodName: string, args: any[]): TPromise<any> {
|
||||
private _doInvokeHandler(proxyId: string, methodName: string, args: any[]): any {
|
||||
if (!this._locals[proxyId]) {
|
||||
throw new Error('Unknown actor ' + proxyId);
|
||||
}
|
||||
let actor = this._locals[proxyId];
|
||||
let method = actor[methodName];
|
||||
if (typeof method !== 'function') {
|
||||
throw new Error('Unknown method ' + methodName + ' on actor ' + proxyId);
|
||||
}
|
||||
return method.apply(actor, args);
|
||||
}
|
||||
|
||||
private _remoteCall(proxyId: string, methodName: string, args: any[]): TPromise<any> {
|
||||
if (this._isDisposed) {
|
||||
return TPromise.wrapError<any>(errors.canceled());
|
||||
}
|
||||
|
||||
let req = String(++this._lastMessageId);
|
||||
let result = new LazyPromise(() => {
|
||||
this._multiplexor.send(MessageFactory.cancel(req));
|
||||
const callId = String(++this._lastMessageId);
|
||||
const result = new LazyPromise(() => {
|
||||
this._multiplexor.send(MessageFactory.cancel(callId));
|
||||
});
|
||||
|
||||
this._pendingRPCReplies[req] = result;
|
||||
|
||||
this._multiplexor.send(MessageFactory.request(req, proxyId, methodName, args));
|
||||
|
||||
this._pendingRPCReplies[callId] = result;
|
||||
this._multiplexor.send(MessageFactory.request(callId, proxyId, methodName, args));
|
||||
return result;
|
||||
}
|
||||
|
||||
public setDispatcher(handler: IDispatcher): void {
|
||||
this._bigHandler = handler;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,24 +231,55 @@ class RPCMultiplexer {
|
||||
|
||||
class MessageFactory {
|
||||
public static cancel(req: string): string {
|
||||
return `{"cancel":"${req}"}`;
|
||||
return `{"type":${MessageType.Cancel},"id":"${req}"}`;
|
||||
}
|
||||
|
||||
public static request(req: string, rpcId: string, method: string, args: any[]): string {
|
||||
return `{"req":"${req}","rpcId":"${rpcId}","method":"${method}","args":${marshalling.stringify(args)}}`;
|
||||
return `{"type":${MessageType.Request},"id":"${req}","proxyId":"${rpcId}","method":"${method}","args":${JSON.stringify(args)}}`;
|
||||
}
|
||||
|
||||
public static replyOK(req: string, res: any): string {
|
||||
if (typeof res === 'undefined') {
|
||||
return `{"seq":"${req}"}`;
|
||||
return `{"type":${MessageType.Reply},"id":"${req}"}`;
|
||||
}
|
||||
return `{"seq":"${req}","res":${marshalling.stringify(res)}}`;
|
||||
return `{"type":${MessageType.Reply},"id":"${req}","res":${JSON.stringify(res)}}`;
|
||||
}
|
||||
|
||||
public static replyErr(req: string, err: any): string {
|
||||
if (typeof err === 'undefined') {
|
||||
return `{"seq":"${req}","err":null}`;
|
||||
if (err instanceof Error) {
|
||||
return `{"type":${MessageType.ReplyErr},"id":"${req}","err":${JSON.stringify(errors.transformErrorForSerialization(err))}}`;
|
||||
}
|
||||
return `{"seq":"${req}","err":${marshalling.stringify(errors.transformErrorForSerialization(err))}}`;
|
||||
return `{"type":${MessageType.ReplyErr},"id":"${req}","err":null}`;
|
||||
}
|
||||
}
|
||||
|
||||
const enum MessageType {
|
||||
Request = 1,
|
||||
Cancel = 2,
|
||||
Reply = 3,
|
||||
ReplyErr = 4
|
||||
}
|
||||
|
||||
class RequestMessage {
|
||||
type: MessageType.Request;
|
||||
id: string;
|
||||
proxyId: string;
|
||||
method: string;
|
||||
args: any[];
|
||||
}
|
||||
class CancelMessage {
|
||||
type: MessageType.Cancel;
|
||||
id: string;
|
||||
}
|
||||
class ReplyMessage {
|
||||
type: MessageType.Reply;
|
||||
id: string;
|
||||
res: any;
|
||||
}
|
||||
class ReplyErrMessage {
|
||||
type: MessageType.ReplyErr;
|
||||
id: string;
|
||||
err: errors.SerializedError;
|
||||
}
|
||||
|
||||
type RPCMessage = RequestMessage | CancelMessage | ReplyMessage | ReplyErrMessage;
|
||||
|
||||
Reference in New Issue
Block a user