提交 0abd8212 编写于 作者: A Alex Dima

Further simplifications (#36972)

上级 252d49c6
......@@ -6,7 +6,7 @@
'use strict';
import { IDisposable } from 'vs/base/common/lifecycle';
import { ProxyIdentifier } from 'vs/workbench/services/thread/common/threadService';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier';
import { IConstructorSignature1 } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostContext } from 'vs/workbench/api/node/extHost.protocol';
......
......@@ -49,7 +49,7 @@ import * as paths from 'vs/base/common/paths';
import { MainContext, ExtHostContext, IInitData, IExtHostContext } from './extHost.protocol';
import * as languageConfiguration from 'vs/editor/common/modes/languageConfiguration';
import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
import { ProxyIdentifier } from 'vs/workbench/services/thread/common/threadService';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier';
import { ExtHostDialogs } from 'vs/workbench/api/node/extHostDialogs';
import { ExtHostFileSystem } from 'vs/workbench/api/node/extHostFileSystem';
import { FileChangeType, FileType } from 'vs/platform/files/common/files';
......
......@@ -8,7 +8,7 @@ import {
createMainContextProxyIdentifier as createMainId,
createExtHostContextProxyIdentifier as createExtId,
ProxyIdentifier
} from 'vs/workbench/services/thread/common/threadService';
} from 'vs/workbench/services/extensions/node/proxyIdentifier';
import * as vscode from 'vscode';
......
......@@ -25,7 +25,7 @@ import { createLogService } from 'vs/platform/log/node/spdlogService';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ILogService } from 'vs/platform/log/common/log';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
import { AbstractThreadService } from 'vs/workbench/services/thread/node/abstractThreadService';
import { RPCProtocol } from 'vs/workbench/services/extensions/node/rpcProtocol';
// const nativeExit = process.exit.bind(process);
function patchProcess(allowExit: boolean) {
......@@ -88,8 +88,8 @@ export class ExtensionHostMain {
patchProcess(allowExit);
// services
const threadService = new AbstractThreadService(protocol, false);
const extHostWorkspace = new ExtHostWorkspace(threadService, initData.workspace);
const rpcProtocol = new RPCProtocol(protocol);
const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, initData.workspace);
const environmentService = new EnvironmentService(initData.args, initData.execPath);
this._logService = createLogService(`exthost${initData.windowId}`, environmentService);
this.disposables.push(this._logService);
......@@ -97,8 +97,8 @@ export class ExtensionHostMain {
this._logService.info('extension host started');
this._logService.trace('initData', initData);
this._extHostConfiguration = new ExtHostConfiguration(threadService.get(MainContext.MainThreadConfiguration), extHostWorkspace, initData.configuration);
this._extensionService = new ExtHostExtensionService(initData, threadService, extHostWorkspace, this._extHostConfiguration, this._logService);
this._extHostConfiguration = new ExtHostConfiguration(rpcProtocol.get(MainContext.MainThreadConfiguration), extHostWorkspace, initData.configuration);
this._extensionService = new ExtHostExtensionService(initData, rpcProtocol, extHostWorkspace, this._extHostConfiguration, this._logService);
// error forwarding and stack trace scanning
const extensionErrors = new WeakMap<Error, IExtensionDescription>();
......@@ -119,8 +119,8 @@ export class ExtensionHostMain {
return `${error.name || 'Error'}: ${error.message || ''}${stackTraceMessage}`;
};
});
const mainThreadExtensions = threadService.get(MainContext.MainThreadExtensionService);
const mainThreadErrors = threadService.get(MainContext.MainThreadErrors);
const mainThreadExtensions = rpcProtocol.get(MainContext.MainThreadExtensionService);
const mainThreadErrors = rpcProtocol.get(MainContext.MainThreadErrors);
errors.setUnexpectedErrorHandler(err => {
const data = errors.transformErrorForSerialization(err);
const extension = extensionErrors.get(err);
......
......@@ -21,7 +21,7 @@ import { areSameExtensions, BetterMergeId, BetterMergeDisabledNowKey } from 'vs/
import { ExtensionsRegistry, ExtensionPoint, IExtensionPointUser, ExtensionMessageCollector, IExtensionPoint } from 'vs/platform/extensions/common/extensionsRegistry';
import { ExtensionScanner, ILog, ExtensionScannerInput } from 'vs/workbench/services/extensions/electron-browser/extensionPoints';
import { IMessageService, CloseAction } from 'vs/platform/message/common/message';
import { ProxyIdentifier } from 'vs/workbench/services/thread/common/threadService';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier';
import { ExtHostContext, ExtHostExtensionServiceShape, IExtHostContext, MainContext } from 'vs/workbench/api/node/extHost.protocol';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
......@@ -41,7 +41,7 @@ import { ExtensionHostProfiler } from 'vs/workbench/services/extensions/electron
import { ReloadWindowAction } from 'vs/workbench/electron-browser/actions';
import product from 'vs/platform/node/product';
import * as strings from 'vs/base/common/strings';
import { AbstractThreadService } from 'vs/workbench/services/thread/node/abstractThreadService';
import { RPCProtocol } from 'vs/workbench/services/extensions/node/rpcProtocol';
const SystemExtensionsRoot = path.normalize(path.join(URI.parse(require.toUrl('')).fsPath, '..', 'extensions'));
......@@ -85,7 +85,7 @@ export class ExtensionService extends Disposable implements IExtensionService {
private _extensionHostProcessActivationTimes: { [id: string]: ActivationTimes; };
private _extensionHostExtensionRuntimeErrors: { [id: string]: Error[]; };
private _extensionHostProcessWorker: ExtensionHostProcessWorker;
private _extensionHostProcessThreadService: AbstractThreadService;
private _extensionHostProcessRPCProtocol: RPCProtocol;
private _extensionHostProcessCustomers: IDisposable[];
/**
* winjs believes a proxy is a promise because it has a `then` method, so wrap the result in an object.
......@@ -115,7 +115,7 @@ export class ExtensionService extends Disposable implements IExtensionService {
this._extensionHostProcessActivationTimes = Object.create(null);
this._extensionHostExtensionRuntimeErrors = Object.create(null);
this._extensionHostProcessWorker = null;
this._extensionHostProcessThreadService = null;
this._extensionHostProcessRPCProtocol = null;
this._extensionHostProcessCustomers = [];
this._extensionHostProcessProxy = null;
......@@ -167,9 +167,9 @@ export class ExtensionService extends Disposable implements IExtensionService {
this._extensionHostProcessWorker.dispose();
this._extensionHostProcessWorker = null;
}
if (this._extensionHostProcessThreadService) {
this._extensionHostProcessThreadService.dispose();
this._extensionHostProcessThreadService = null;
if (this._extensionHostProcessRPCProtocol) {
this._extensionHostProcessRPCProtocol.dispose();
this._extensionHostProcessRPCProtocol = null;
}
for (let i = 0, len = this._extensionHostProcessCustomers.length; i < len; i++) {
const customer = this._extensionHostProcessCustomers[i];
......@@ -238,8 +238,8 @@ export class ExtensionService extends Disposable implements IExtensionService {
protocol = asLoggingProtocol(protocol);
}
this._extensionHostProcessThreadService = new AbstractThreadService(protocol, true);
const extHostContext: IExtHostContext = this._extensionHostProcessThreadService;
this._extensionHostProcessRPCProtocol = new RPCProtocol(protocol);
const extHostContext: IExtHostContext = this._extensionHostProcessRPCProtocol;
// Named customers
const namedCustomers = ExtHostCustomersRegistry.getNamedCustomers();
......@@ -247,7 +247,7 @@ export class ExtensionService extends Disposable implements IExtensionService {
const [id, ctor] = namedCustomers[i];
const instance = this._instantiationService.createInstance(ctor, extHostContext);
this._extensionHostProcessCustomers.push(instance);
this._extensionHostProcessThreadService.set(id, instance);
this._extensionHostProcessRPCProtocol.set(id, instance);
}
// Customers
......@@ -260,9 +260,9 @@ export class ExtensionService extends Disposable implements IExtensionService {
// Check that no named customers are missing
const expected: ProxyIdentifier<any>[] = Object.keys(MainContext).map((key) => MainContext[key]);
this._extensionHostProcessThreadService.assertRegistered(expected);
this._extensionHostProcessRPCProtocol.assertRegistered(expected);
return this._extensionHostProcessThreadService.get(ExtHostContext.ExtHostExtensionService);
return this._extensionHostProcessRPCProtocol.get(ExtHostContext.ExtHostExtensionService);
}
// ---- begin IExtensionService
......
......@@ -9,15 +9,16 @@ 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 } 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 {
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 +26,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,6 +44,41 @@ export class RPCProtocol {
});
}
public get<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.fancyRemoteCall(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) {
return;
......@@ -72,10 +109,6 @@ export class RPCProtocol {
}
private _receiveRequest(msg: RequestMessage | FancyRequestMessage): void {
if (!this._bigHandler) {
throw new Error('got message before big handler attached!');
}
const callId = msg.id;
const proxyId = msg.proxyId;
const isFancy = (msg.type === MessageType.FancyRequest); // a fancy request gets a fancy reply
......@@ -135,12 +168,24 @@ export class RPCProtocol {
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);
}
}
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);
}
public remoteCall(proxyId: string, methodName: string, args: any[]): TPromise<any> {
return this._remoteCall(proxyId, methodName, args, false);
}
......@@ -169,10 +214,6 @@ export class RPCProtocol {
return result;
}
public setDispatcher(handler: IDispatcher): void {
this._bigHandler = handler;
}
}
/**
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { IDispatcher, RPCProtocol } from 'vs/workbench/services/extensions/node/rpcProtocol';
import { ProxyIdentifier } from 'vs/workbench/services/thread/common/threadService';
import { CharCode } from 'vs/base/common/charCode';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
declare var Proxy: any; // TODO@TypeScript
export class AbstractThreadService implements IDispatcher {
private readonly _rpcProtocol: RPCProtocol;
private readonly _isMain: boolean;
protected readonly _locals: { [id: string]: any; };
private readonly _proxies: { [id: string]: any; } = Object.create(null);
constructor(protocol: IMessagePassingProtocol, isMain: boolean) {
this._rpcProtocol = new RPCProtocol(protocol);
this._isMain = isMain;
this._locals = Object.create(null);
this._proxies = Object.create(null);
this._rpcProtocol.setDispatcher(this);
}
public dispose(): void {
this._rpcProtocol.dispose();
}
public invoke(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);
}
get<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._callOnRemote(proxyId, name, myArgs);
};
}
return target[name];
}
};
return new Proxy(Object.create(null), handler);
}
set<T, R extends T>(identifier: ProxyIdentifier<T>, value: R): R {
if (identifier.isMain !== this._isMain) {
throw new Error('Mismatch in object registration!');
}
this._locals[identifier.id] = value;
return value;
}
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 _callOnRemote(proxyId: string, methodName: string, args: any[]): TPromise<any> {
return this._rpcProtocol.fancyRemoteCall(proxyId, methodName, args);
}
}
......@@ -6,7 +6,7 @@
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { ProxyIdentifier } from 'vs/workbench/services/thread/common/threadService';
import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier';
export function OneGetThreadService(thing: any) {
return {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册