diff --git a/src/vs/workbench/api/electron-browser/extensionHost.contribution.ts b/src/vs/workbench/api/electron-browser/extensionHost.contribution.ts index 257382a93300274343c29090c2558fdd5f7f134e..696c48ea8b27e19e24bd3f745458c377fa0fb626 100644 --- a/src/vs/workbench/api/electron-browser/extensionHost.contribution.ts +++ b/src/vs/workbench/api/electron-browser/extensionHost.contribution.ts @@ -8,16 +8,14 @@ import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { Registry } from 'vs/platform/registry/common/platform'; import { IInstantiationService, IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation'; -import { IThreadService } from 'vs/workbench/services/thread/common/threadService'; -import { MainContext, InstanceCollection } from '../node/extHost.protocol'; +import { IThreadService, ProxyIdentifier } from 'vs/workbench/services/thread/common/threadService'; +import { MainContext, InstanceCollection, IExtHostContext } from '../node/extHost.protocol'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; import { ExtHostCustomersRegistry } from "vs/workbench/api/electron-browser/extHostCustomers"; // --- addressable import { MainThreadDiagnostics } from './mainThreadDiagnostics'; -import { MainThreadDocuments } from './mainThreadDocuments'; import { MainThreadDocumentContentProviders } from './mainThreadDocumentContentProviders'; -import { MainThreadEditors } from './mainThreadEditors'; import { MainThreadErrors } from './mainThreadErrors'; import { MainThreadTreeViews } from './mainThreadTreeViews'; import { MainThreadLanguages } from './mainThreadLanguages'; @@ -34,7 +32,6 @@ import { MainThreadTask } from './mainThreadTask'; import { MainThreadSCM } from './mainThreadSCM'; // --- other interested parties -import { MainThreadDocumentsAndEditors } from './mainThreadDocumentsAndEditors'; import { JSONValidationExtensionPoint } from 'vs/platform/jsonschemas/common/jsonValidationExtensionPoint'; import { ColorExtensionPoint } from 'vs/platform/theme/common/colorExtensionPoint'; import { LanguageConfigurationFileHandler } from 'vs/workbench/parts/codeEditor/electron-browser/languageConfiguration/languageConfigurationExtensionPoint'; @@ -49,10 +46,10 @@ import './mainThreadConfiguration'; import './mainThreadCredentials'; import './mainThreadDebugService'; // import './mainThreadDiagnostics'; -// import './mainThreadDocuments'; -// import './mainThreadDocumentsAndEditors'; +import './mainThreadDocuments'; +import './mainThreadDocumentsAndEditors'; import './mainThreadEditor'; -// import './mainThreadEditors'; +import './mainThreadEditors'; // import './mainThreadErrors'; // import './mainThreadExtensionService'; import './mainThreadFileSystemEventService'; @@ -92,14 +89,25 @@ export class ExtHostContribution implements IWorkbenchContribution { return this.instantiationService.createInstance(ctor); }; - const documentsAndEditors = this.instantiationService.createInstance(MainThreadDocumentsAndEditors); + let col = new InstanceCollection(); + + const extHostContext = new class implements IExtHostContext { + + constructor(private readonly _threadService: IThreadService) { + } + + get(identifier: ProxyIdentifier): T { + return this._threadService.get(identifier); + } + + set(identifier: ProxyIdentifier, instance: T): void { + col.define(identifier).set(instance); + } + }(this.threadService); // Addressable instances - const col = new InstanceCollection(); col.define(MainContext.MainThreadDiagnostics).set(create(MainThreadDiagnostics)); col.define(MainContext.MainThreadDocumentContentProviders).set(create(MainThreadDocumentContentProviders)); - col.define(MainContext.MainThreadDocuments).set(this.instantiationService.createInstance(MainThreadDocuments, documentsAndEditors)); - col.define(MainContext.MainThreadEditors).set(this.instantiationService.createInstance(MainThreadEditors, documentsAndEditors)); col.define(MainContext.MainThreadErrors).set(create(MainThreadErrors)); col.define(MainContext.MainThreadTreeViews).set(create(MainThreadTreeViews)); col.define(MainContext.MainThreadLanguages).set(create(MainThreadLanguages)); @@ -119,7 +127,7 @@ export class ExtHostContribution implements IWorkbenchContribution { const namedCustomers = ExtHostCustomersRegistry.getNamedCustomers(); for (let i = 0, len = namedCustomers.length; i < len; i++) { const [id, ctor] = namedCustomers[i]; - const obj = this.instantiationService.createInstance(ctor, this.threadService); + const obj = this.instantiationService.createInstance(ctor, extHostContext); col.define(id).set(obj); } @@ -127,11 +135,13 @@ export class ExtHostContribution implements IWorkbenchContribution { const customers = ExtHostCustomersRegistry.getCustomers(); for (let i = 0, len = customers.length; i < len; i++) { const ctor = customers[i]; - this.instantiationService.createInstance(ctor, this.threadService); + this.instantiationService.createInstance(ctor, extHostContext); } col.finish(true, this.threadService); + col = null; + // Other interested parties create(JSONValidationExtensionPoint); // TODO@rehost: can survive an ext host restart create(ColorExtensionPoint); // TODO@rehost: can survive an ext host restart diff --git a/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts b/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts index 474f6e7fc4fdda528cd64cc229ecd6a6b12ac6de..1c5186a7144f710de8b27a04235da36d99ff8e0e 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts @@ -7,14 +7,13 @@ import URI from 'vs/base/common/uri'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { IModelService } from 'vs/editor/common/services/modelService'; -import { IThreadService } from 'vs/workbench/services/thread/common/threadService'; import { IDisposable, dispose, IReference } from 'vs/base/common/lifecycle'; import { TextFileModelChangeEvent, ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { TPromise } from 'vs/base/common/winjs.base'; import { IFileService } from 'vs/platform/files/common/files'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; -import { ExtHostContext, MainThreadDocumentsShape, ExtHostDocumentsShape } from '../node/extHost.protocol'; +import { ExtHostContext, MainThreadDocumentsShape, ExtHostDocumentsShape, IExtHostContext } from '../node/extHost.protocol'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { MainThreadDocumentsAndEditors } from './mainThreadDocumentsAndEditors'; import * as editorCommon from 'vs/editor/common/editorCommon'; @@ -81,7 +80,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { constructor( documentsAndEditors: MainThreadDocumentsAndEditors, - @IThreadService threadService: IThreadService, + extHostContext: IExtHostContext, @IModelService modelService: IModelService, @IModeService modeService: IModeService, @ITextFileService textFileService: ITextFileService, @@ -96,7 +95,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { this._fileService = fileService; this._untitledEditorService = untitledEditorService; - this._proxy = threadService.get(ExtHostContext.ExtHostDocuments); + this._proxy = extHostContext.get(ExtHostContext.ExtHostDocuments); this._modelIsSynced = {}; this._toDispose = []; diff --git a/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts b/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts index a6be9198dd5c633bb3ccfa70c1853607df44538b..e7da606a317718e1b852f8f75a6c4aa1299c7043 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts @@ -11,12 +11,20 @@ import { delta } from 'vs/base/common/arrays'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { ICodeEditorService } from 'vs/editor/common/services/codeEditorService'; import Event, { Emitter } from 'vs/base/common/event'; -import { ExtHostContext, ExtHostDocumentsAndEditorsShape, IModelAddedData, ITextEditorAddData, IDocumentsAndEditorsDelta } from '../node/extHost.protocol'; +import { ExtHostContext, ExtHostDocumentsAndEditorsShape, IModelAddedData, ITextEditorAddData, IDocumentsAndEditorsDelta, IExtHostContext, MainContext } from '../node/extHost.protocol'; import { MainThreadTextEditor } from './mainThreadEditor'; -import { IThreadService } from 'vs/workbench/services/thread/common/threadService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { Position as EditorPosition, IEditor } from 'vs/platform/editor/common/editor'; +import { extHostCustomer } from "vs/workbench/api/electron-browser/extHostCustomers"; +import { MainThreadDocuments } from "vs/workbench/api/electron-browser/mainThreadDocuments"; +import { MainThreadEditors } from "vs/workbench/api/electron-browser/mainThreadEditors"; +import { IModeService } from "vs/editor/common/services/modeService"; +import { IFileService } from "vs/platform/files/common/files"; +import { ITextModelService } from "vs/editor/common/services/resolverService"; +import { IUntitledEditorService } from "vs/workbench/services/untitled/common/untitledEditorService"; +import { IEditorGroupService } from "vs/workbench/services/group/common/groupService"; +import { ITelemetryService } from "vs/platform/telemetry/common/telemetry"; namespace cmp { export function compareModels(a: IModel, b: IModel): number { @@ -205,6 +213,7 @@ class MainThreadDocumentAndEditorStateComputer { } } +@extHostCustomer export class MainThreadDocumentsAndEditors { private _toDispose: IDisposable[]; @@ -223,17 +232,36 @@ export class MainThreadDocumentsAndEditors { readonly onDocumentRemove: Event = this._onDocumentRemove.event; constructor( + extHostContext: IExtHostContext, @IModelService private _modelService: IModelService, @ITextFileService private _textFileService: ITextFileService, @IWorkbenchEditorService private _workbenchEditorService: IWorkbenchEditorService, - @IThreadService threadService: IThreadService, @ICodeEditorService codeEditorService: ICodeEditorService, + @IModeService modeService: IModeService, + @IFileService fileService: IFileService, + @ITextModelService textModelResolverService: ITextModelService, + @IUntitledEditorService untitledEditorService: IUntitledEditorService, + @IEditorGroupService editorGroupService: IEditorGroupService, + @ITelemetryService telemetryService: ITelemetryService ) { - this._proxy = threadService.get(ExtHostContext.ExtHostDocumentsAndEditors); + this._proxy = extHostContext.get(ExtHostContext.ExtHostDocumentsAndEditors); this._stateComputer = new MainThreadDocumentAndEditorStateComputer(_modelService, codeEditorService, _workbenchEditorService); + + const mainThreadDocuments = new MainThreadDocuments(this, extHostContext, this._modelService, modeService, this._textFileService, fileService, textModelResolverService, untitledEditorService); + extHostContext.set(MainContext.MainThreadDocuments, mainThreadDocuments); + + const mainThreadEditors = new MainThreadEditors(this, extHostContext, codeEditorService, this._workbenchEditorService, editorGroupService, telemetryService); + extHostContext.set(MainContext.MainThreadEditors, mainThreadEditors); + this._toDispose = [ + mainThreadDocuments, + mainThreadEditors, this._stateComputer, - this._stateComputer.onDidChangeState(this._onDelta, this) + this._stateComputer.onDidChangeState(this._onDelta, this), + this._onTextEditorAdd, + this._onTextEditorRemove, + this._onDocumentAdd, + this._onDocumentRemove, ]; } diff --git a/src/vs/workbench/api/electron-browser/mainThreadEditors.ts b/src/vs/workbench/api/electron-browser/mainThreadEditors.ts index 29621db99d48228f7f61716337fd41edd065ea1d..b55e298c67f1d707b8ed6042919a53ba3383d1c8 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadEditors.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadEditors.ts @@ -7,7 +7,6 @@ import URI from 'vs/base/common/uri'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IThreadService } from 'vs/workbench/services/thread/common/threadService'; import { ISingleEditOperation, IDecorationRenderOptions, IDecorationOptions, ILineChange } from 'vs/editor/common/editorCommon'; import { ICodeEditorService } from 'vs/editor/common/services/codeEditorService'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -15,11 +14,10 @@ import { IEditorGroupService } from 'vs/workbench/services/group/common/groupSer import { Position as EditorPosition, ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { MainThreadTextEditor } from './mainThreadEditor'; import { ITextEditorConfigurationUpdate, TextEditorRevealType, IApplyEditsOptions, IUndoStopOptions } from 'vs/workbench/api/node/extHost.protocol'; - import { MainThreadDocumentsAndEditors } from './mainThreadDocumentsAndEditors'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { equals as objectEquals } from 'vs/base/common/objects'; -import { ExtHostContext, MainThreadEditorsShape, ExtHostEditorsShape, ITextDocumentShowOptions, ITextEditorPositionData } from '../node/extHost.protocol'; +import { ExtHostContext, MainThreadEditorsShape, ExtHostEditorsShape, ITextDocumentShowOptions, ITextEditorPositionData, IExtHostContext } from '../node/extHost.protocol'; import { IRange } from 'vs/editor/common/core/range'; import { ISelection } from 'vs/editor/common/core/selection'; @@ -35,13 +33,13 @@ export class MainThreadEditors implements MainThreadEditorsShape { constructor( documentsAndEditors: MainThreadDocumentsAndEditors, + extHostContext: IExtHostContext, @ICodeEditorService private _codeEditorService: ICodeEditorService, - @IThreadService threadService: IThreadService, @IWorkbenchEditorService workbenchEditorService: IWorkbenchEditorService, @IEditorGroupService editorGroupService: IEditorGroupService, @ITelemetryService telemetryService: ITelemetryService ) { - this._proxy = threadService.get(ExtHostContext.ExtHostEditors); + this._proxy = extHostContext.get(ExtHostContext.ExtHostEditors); this._documentsAndEditors = documentsAndEditors; this._workbenchEditorService = workbenchEditorService; this._telemetryService = telemetryService; diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 725deb61dce8a8390cc9baedaef4d3a7b16f1b6b..2f79661983f1abeb3907056c06cc0a268b36d9e0 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -78,6 +78,8 @@ export interface IExtHostContext { * Returns a proxy to an object addressable/named in the extension host process. */ get(identifier: ProxyIdentifier): T; + + set(identifier: ProxyIdentifier, instance: T): void; } export interface IMainContext { diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadDocumentsAndEditors.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadDocumentsAndEditors.test.ts index 86713fd841058c797f0851d63c0bba1f429e7af5..a65ccb9fc40d18c4a4dcc11c58159718b6ad2a41 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadDocumentsAndEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadDocumentsAndEditors.test.ts @@ -16,6 +16,8 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta } from 'vs/workbench/api/node/extHost.protocol'; import { mockCodeEditor } from 'vs/editor/test/common/mocks/mockCodeEditor'; import { mock } from "vs/workbench/test/electron-browser/api/mock"; +import { IEditorGroupService } from "vs/workbench/services/group/common/groupService"; +import Event from 'vs/base/common/event'; suite('MainThreadDocumentsAndEditors', () => { @@ -33,17 +35,37 @@ suite('MainThreadDocumentsAndEditors', () => { configService.setUserConfiguration('editor', { 'detectIndentation': false }); modelService = new ModelServiceImpl(null, configService); codeEditorService = new MockCodeEditorService(); - textFileService = { isDirty() { return false; } }; + textFileService = new class extends mock() { + isDirty() { return false; }; + models = { + onModelSaved: Event.None, + onModelReverted: Event.None, + onModelDirty: Event.None, + }; + }; workbenchEditorService = { getVisibleEditors() { return []; }, getActiveEditor() { return undefined; } }; + const editorGroupService = new class extends mock() { + onEditorsChanged = Event.None; + onEditorsMoved = Event.None; + }; documentAndEditor = new MainThreadDocumentsAndEditors( - modelService, textFileService, workbenchEditorService, OneGetThreadService(new class extends mock() { $acceptDocumentsAndEditorsDelta(delta) { deltas.push(delta); } - }), codeEditorService + }), + modelService, + textFileService, + workbenchEditorService, + codeEditorService, + null, + null, + null, + null, + editorGroupService, + null ); }); diff --git a/src/vs/workbench/test/electron-browser/api/testThreadService.ts b/src/vs/workbench/test/electron-browser/api/testThreadService.ts index 4500472b55b812431b39def84c92e2b03547e94a..5ca2a4fb331af04293df70f1fc296ccd48aba919 100644 --- a/src/vs/workbench/test/electron-browser/api/testThreadService.ts +++ b/src/vs/workbench/test/electron-browser/api/testThreadService.ts @@ -15,7 +15,6 @@ export function OneGetThreadService(thing: any): IThreadService { return thing; }, set(): void { - throw new Error(); } }; }