make extHost-things services, setup injector

This commit is contained in:
Johannes Rieken
2019-08-07 16:11:00 +02:00
parent a7fa418e34
commit ebd96071d1
25 changed files with 338 additions and 171 deletions

View File

@@ -8,7 +8,7 @@ import { ICommandHandlerDescription, ICommandEvent } from 'vs/platform/commands/
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import * as extHostTypeConverter from 'vs/workbench/api/common/extHostTypeConverters';
import { cloneAndChange } from 'vs/base/common/objects';
import { MainContext, MainThreadCommandsShape, ExtHostCommandsShape, ObjectIdentifier, IMainContext, ICommandDto } from './extHost.protocol';
import { MainContext, MainThreadCommandsShape, ExtHostCommandsShape, ObjectIdentifier, ICommandDto } from './extHost.protocol';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import * as modes from 'vs/editor/common/modes';
import * as vscode from 'vscode';
@@ -19,6 +19,8 @@ import { Position } from 'vs/editor/common/core/position';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
interface CommandHandler {
callback: Function;
@@ -32,6 +34,8 @@ export interface ArgumentProcessor {
export class ExtHostCommands implements ExtHostCommandsShape {
readonly _serviceBrand: any;
private readonly _onDidExecuteCommand: Emitter<vscode.CommandExecutionEvent>;
readonly onDidExecuteCommand: Event<vscode.CommandExecutionEvent>;
@@ -42,10 +46,10 @@ export class ExtHostCommands implements ExtHostCommandsShape {
private readonly _argumentProcessors: ArgumentProcessor[];
constructor(
mainContext: IMainContext,
logService: ILogService
@IExtHostContextService extHostContext: IExtHostContextService,
@ILogService logService: ILogService
) {
this._proxy = mainContext.getProxy(MainContext.MainThreadCommands);
this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadCommands);
this._onDidExecuteCommand = new Emitter<vscode.CommandExecutionEvent>({
onFirstListenerDidAdd: () => this._proxy.$registerCommandListener(),
onLastListenerRemove: () => this._proxy.$unregisterCommandListener(),
@@ -282,3 +286,6 @@ export class CommandsConverter {
}
}
export interface IExtHostCommands extends ExtHostCommands { }
export const IExtHostCommands = createDecorator<IExtHostCommands>('IExtHostCommands');

View File

@@ -7,8 +7,8 @@ import { mixin, deepClone } from 'vs/base/common/objects';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import * as vscode from 'vscode';
import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { ExtHostConfigurationShape, MainThreadConfigurationShape, IWorkspaceConfigurationChangeEventData, IConfigurationInitData } from './extHost.protocol';
import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { ExtHostConfigurationShape, MainThreadConfigurationShape, IWorkspaceConfigurationChangeEventData, IConfigurationInitData, MainContext } from './extHost.protocol';
import { ConfigurationTarget as ExtHostConfigurationTarget } from './extHostTypes';
import { IConfigurationData, ConfigurationTarget, IConfigurationModel } from 'vs/platform/configuration/common/configuration';
import { Configuration, ConfigurationChangeEvent, ConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
@@ -18,6 +18,8 @@ import { ConfigurationScope, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/confi
import { isObject } from 'vs/base/common/types';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { Barrier } from 'vs/base/common/async';
import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
function lookUp(tree: any, key: string) {
if (key) {
@@ -40,13 +42,18 @@ type ConfigurationInspect<T> = {
export class ExtHostConfiguration implements ExtHostConfigurationShape {
readonly _serviceBrand: any;
private readonly _proxy: MainThreadConfigurationShape;
private readonly _extHostWorkspace: ExtHostWorkspace;
private readonly _barrier: Barrier;
private _actual: ExtHostConfigProvider | null;
constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace) {
this._proxy = proxy;
constructor(
@IExtHostContextService extHostContext: IExtHostContextService,
@IExtHostWorkspace extHostWorkspace: IExtHostWorkspace
) {
this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadConfiguration);
this._extHostWorkspace = extHostWorkspace;
this._barrier = new Barrier();
this._actual = null;
@@ -274,3 +281,6 @@ export class ExtHostConfigProvider {
return new ConfigurationModel(model.contents, model.keys, model.overrides).freeze();
}
}
export const IExtHostConfiguration = createDecorator<IExtHostConfiguration>('IExtHostConfiguration');
export interface IExtHostConfiguration extends ExtHostConfiguration { }

View File

@@ -0,0 +1,24 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IMainContext, IInitData } from './extHost.protocol';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export const IExtHostContextService = createDecorator<IExtHostContextService>('IExtHostContextService');
export interface IExtHostContextService {
_serviceBrand: undefined;
readonly rpc: IMainContext;
readonly initData: IInitData;
}
export class ExtHostContextService implements IExtHostContextService {
_serviceBrand: any;
constructor(
readonly rpc: IMainContext,
readonly initData: IInitData
) { }
}

View File

@@ -5,26 +5,31 @@
import * as vscode from 'vscode';
import { URI } from 'vs/base/common/uri';
import { MainContext, IMainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, DecorationData, DecorationRequest, DecorationReply } from 'vs/workbench/api/common/extHost.protocol';
import { MainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, DecorationData, DecorationRequest, DecorationReply } from 'vs/workbench/api/common/extHost.protocol';
import { Disposable } from 'vs/workbench/api/common/extHostTypes';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { asArray } from 'vs/base/common/arrays';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService';
interface ProviderData {
provider: vscode.DecorationProvider;
extensionId: ExtensionIdentifier;
}
export class ExtHostDecorations implements ExtHostDecorationsShape {
export class ExtHostDecorations implements IExtHostDecorations {
private static _handlePool = 0;
readonly _serviceBrand: undefined;
private readonly _provider = new Map<number, ProviderData>();
private readonly _proxy: MainThreadDecorationsShape;
constructor(mainContext: IMainContext) {
this._proxy = mainContext.getProxy(MainContext.MainThreadDecorations);
constructor(
@IExtHostContextService contextService: IExtHostContextService,
) {
this._proxy = contextService.rpc.getProxy(MainContext.MainThreadDecorations);
}
registerDecorationProvider(provider: vscode.DecorationProvider, extensionId: ExtensionIdentifier): vscode.Disposable {
@@ -70,3 +75,6 @@ export class ExtHostDecorations implements ExtHostDecorationsShape {
});
}
}
export const IExtHostDecorations = createDecorator<IExtHostDecorations>('IExtHostDecorations');
export interface IExtHostDecorations extends ExtHostDecorations, ExtHostDecorationsShape { }

View File

@@ -7,14 +7,18 @@ import * as assert from 'vs/base/common/assert';
import { Emitter, Event } from 'vs/base/common/event';
import { dispose } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta, IMainContext, MainContext } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta, MainContext } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData';
import { ExtHostTextEditor } from 'vs/workbench/api/common/extHostTextEditor';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import { Disposable } from 'vs/workbench/api/common/extHostTypes';
import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsShape {
readonly _serviceBrand: any;
private _disposables: Disposable[] = [];
private _activeEditorId: string | null = null;
@@ -33,7 +37,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
readonly onDidChangeActiveTextEditor: Event<ExtHostTextEditor | undefined> = this._onDidChangeActiveTextEditor.event;
constructor(
private readonly _mainContext: IMainContext,
@IExtHostContextService private readonly _ctx: IExtHostContextService,
) { }
dispose() {
@@ -64,7 +68,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
assert.ok(!this._documents.has(resource.toString()), `document '${resource} already exists!'`);
const documentData = new ExtHostDocumentData(
this._mainContext.getProxy(MainContext.MainThreadDocuments),
this._ctx.rpc.getProxy(MainContext.MainThreadDocuments),
resource,
data.lines,
data.EOL,
@@ -95,7 +99,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
const documentData = this._documents.get(resource.toString())!;
const editor = new ExtHostTextEditor(
this._mainContext.getProxy(MainContext.MainThreadTextEditors),
this._ctx.rpc.getProxy(MainContext.MainThreadTextEditors),
data.id,
documentData,
data.selections.map(typeConverters.Selection.to),
@@ -159,3 +163,6 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
return result;
}
}
export interface IExtHostDocumentsAndEditors extends ExtHostDocumentsAndEditors { }
export const IExtHostDocumentsAndEditors = createDecorator<IExtHostDocumentsAndEditors>('IExtHostDocumentsAndEditors');

View File

@@ -3,12 +3,14 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { MainContext, MainThreadOutputServiceShape, IMainContext, ExtHostOutputServiceShape } from './extHost.protocol';
import { MainContext, MainThreadOutputServiceShape, ExtHostOutputServiceShape } from './extHost.protocol';
import * as vscode from 'vscode';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { VSBuffer } from 'vs/base/common/buffer';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService';
export abstract class AbstractExtHostOutputChannel extends Disposable implements vscode.OutputChannel {
@@ -106,38 +108,50 @@ class ExtHostLogFileOutputChannel extends AbstractExtHostOutputChannel {
}
}
export interface IOutputChannelFactory {
createOutputChannel(name: string, logsLocation: URI, proxy: MainThreadOutputServiceShape): Promise<AbstractExtHostOutputChannel>;
}
export class LazyOutputChannel implements vscode.OutputChannel {
export const PushOutputChannelFactory = new class implements IOutputChannelFactory {
async createOutputChannel(name: string, _logsLocation: URI, proxy: MainThreadOutputServiceShape): Promise<AbstractExtHostOutputChannel> {
return new ExtHostPushOutputChannel(name, proxy);
constructor(
readonly name: string,
private readonly _channel: Promise<AbstractExtHostOutputChannel>
) { }
append(value: string): void {
this._channel.then(channel => channel.append(value));
}
};
appendLine(value: string): void {
this._channel.then(channel => channel.appendLine(value));
}
clear(): void {
this._channel.then(channel => channel.clear());
}
show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void {
this._channel.then(channel => channel.show(columnOrPreserveFocus, preserveFocus));
}
hide(): void {
this._channel.then(channel => channel.hide());
}
dispose(): void {
this._channel.then(channel => channel.dispose());
}
}
export class ExtHostOutputService implements ExtHostOutputServiceShape {
private readonly _factory: IOutputChannelFactory;
private readonly _logsLocation: URI;
private readonly _proxy: MainThreadOutputServiceShape;
private readonly _channels: Map<string, AbstractExtHostOutputChannel> = new Map<string, AbstractExtHostOutputChannel>();
private _visibleChannelDisposable?: IDisposable;
readonly _serviceBrand: any;
constructor(factory: IOutputChannelFactory, logsLocation: URI, mainContext: IMainContext) {
this._factory = factory;
this._logsLocation = logsLocation;
this._proxy = mainContext.getProxy(MainContext.MainThreadOutputService);
protected readonly _proxy: MainThreadOutputServiceShape;
protected readonly _channels: Map<string, AbstractExtHostOutputChannel> = new Map<string, AbstractExtHostOutputChannel>();
protected readonly _visibleChannelDisposable = new MutableDisposable();
constructor(@IExtHostContextService extHostContext: IExtHostContextService) {
this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadOutputService);
}
$setVisibleChannel(channelId: string): void {
if (this._visibleChannelDisposable) {
this._visibleChannelDisposable = dispose(this._visibleChannelDisposable);
}
if (channelId) {
const channel = this._channels.get(channelId);
if (channel) {
this._visibleChannelDisposable = channel.onDidAppend(() => channel.update());
this._visibleChannelDisposable.value = channel.onDidAppend(() => channel.update());
}
}
}
@@ -146,33 +160,8 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
name = name.trim();
if (!name) {
throw new Error('illegal argument `name`. must not be falsy');
} else {
const extHostOutputChannel = this._factory.createOutputChannel(name, this._logsLocation, this._proxy);
extHostOutputChannel.then(channel => channel._id.then(id => this._channels.set(id, channel)));
return {
get name(): string {
return name;
},
append(value: string): void {
extHostOutputChannel.then(channel => channel.append(value));
},
appendLine(value: string): void {
extHostOutputChannel.then(channel => channel.appendLine(value));
},
clear(): void {
extHostOutputChannel.then(channel => channel.clear());
},
show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void {
extHostOutputChannel.then(channel => channel.show(columnOrPreserveFocus, preserveFocus));
},
hide(): void {
extHostOutputChannel.then(channel => channel.hide());
},
dispose(): void {
extHostOutputChannel.then(channel => channel.dispose());
}
};
}
return new ExtHostPushOutputChannel(name, this._proxy);
}
createOutputChannelFromLogFile(name: string, file: URI): vscode.OutputChannel {
@@ -186,3 +175,6 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
return new ExtHostLogFileOutputChannel(name, file, this._proxy);
}
}
export interface IExtHostOutputService extends ExtHostOutputService { }
export const IExtHostOutputService = createDecorator<IExtHostOutputService>('IExtHostOutputService');

View File

@@ -0,0 +1,30 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { Event } from 'vs/base/common/event';
import { ExtHostTerminalServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export interface IExtHostTerminalService extends ExtHostTerminalServiceShape {
activeTerminal: vscode.Terminal | undefined;
terminals: vscode.Terminal[];
onDidCloseTerminal: Event<vscode.Terminal>;
onDidOpenTerminal: Event<vscode.Terminal>;
onDidChangeActiveTerminal: Event<vscode.Terminal | undefined>;
onDidChangeTerminalDimensions: Event<vscode.TerminalDimensionsChangeEvent>;
onDidWriteTerminalData: Event<vscode.TerminalDataWriteEvent>;
createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal;
createTerminalFromOptions(options: vscode.TerminalOptions): vscode.Terminal;
createExtensionTerminal(options: vscode.ExtensionTerminalOptions): vscode.Terminal;
attachPtyToTerminal(id: number, pty: vscode.Pseudoterminal): void;
getDefaultShell(configProvider: ExtHostConfigProvider): string;
}
export const IExtHostTerminalService = createDecorator<IExtHostTerminalService>('IExtHostTerminalService');

View File

@@ -20,11 +20,13 @@ import { Workspace, WorkspaceFolder } from 'vs/platform/workspace/common/workspa
import { Range, RelativePattern } from 'vs/workbench/api/common/extHostTypes';
import { ITextQueryBuilderOptions } from 'vs/workbench/contrib/search/common/queryBuilder';
import * as vscode from 'vscode';
import { ExtHostWorkspaceShape, IWorkspaceData, MainThreadMessageServiceShape, MainThreadWorkspaceShape, IMainContext, MainContext, IStaticWorkspaceData } from './extHost.protocol';
import { ExtHostWorkspaceShape, IWorkspaceData, MainThreadMessageServiceShape, MainThreadWorkspaceShape, MainContext } from './extHost.protocol';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { Barrier } from 'vs/base/common/async';
import { Schemas } from 'vs/base/common/network';
import { withUndefinedAsNull } from 'vs/base/common/types';
import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export interface IExtHostWorkspaceProvider {
getWorkspaceFolder2(uri: vscode.Uri, resolveParent?: boolean): Promise<vscode.WorkspaceFolder | undefined>;
@@ -153,6 +155,8 @@ class ExtHostWorkspaceImpl extends Workspace {
export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspaceProvider {
readonly _serviceBrand: any;
private readonly _onDidChangeWorkspace = new Emitter<vscode.WorkspaceFoldersChangeEvent>();
readonly onDidChangeWorkspace: Event<vscode.WorkspaceFoldersChangeEvent> = this._onDidChangeWorkspace.event;
@@ -169,20 +173,20 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
private readonly _activeSearchCallbacks: ((match: IRawFileMatch2) => any)[] = [];
constructor(
mainContext: IMainContext,
logService: ILogService,
data?: IStaticWorkspaceData
@IExtHostContextService extHostContext: IExtHostContextService,
@ILogService logService: ILogService,
) {
this._logService = logService;
this._requestIdProvider = new Counter();
this._barrier = new Barrier();
this._proxy = mainContext.getProxy(MainContext.MainThreadWorkspace);
this._messageService = mainContext.getProxy(MainContext.MainThreadMessageService);
this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadWorkspace);
this._messageService = extHostContext.rpc.getProxy(MainContext.MainThreadMessageService);
const data = extHostContext.initData.workspace;
this._confirmedWorkspace = data ? new ExtHostWorkspaceImpl(data.id, data.name, [], data.configuration ? URI.revive(data.configuration) : null, !!data.isUntitled) : undefined;
}
$initializeWorkspace(data: IWorkspaceData): void {
$initializeWorkspace(data: IWorkspaceData | null): void {
this.$acceptWorkspaceData(data);
this._barrier.open();
}
@@ -389,7 +393,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
}
}
$acceptWorkspaceData(data: IWorkspaceData): void {
$acceptWorkspaceData(data: IWorkspaceData | null): void {
const { workspace, added, removed } = ExtHostWorkspaceImpl.toExtHostWorkspace(data, this._confirmedWorkspace, this._unconfirmedWorkspace);
@@ -545,3 +549,6 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
return this._proxy.$resolveProxy(url);
}
}
export const IExtHostWorkspace = createDecorator<IExtHostWorkspace>('IExtHostWorkspace');
export interface IExtHostWorkspace extends ExtHostWorkspace, ExtHostWorkspaceShape, IExtHostWorkspaceProvider { }