diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts index 558cfe7e..d4cebac1 100644 --- a/src/InputHandler.test.ts +++ b/src/InputHandler.test.ts @@ -15,6 +15,8 @@ import { AttributeData } from 'common/buffer/AttributeData'; import { Params } from 'common/parser/Params'; import { MockCoreService, MockBufferService, MockDirtyRowService, MockOptionsService, MockLogService } from 'common/TestUtils.test'; import { IBufferService } from 'common/services/Services'; +import { DEFAULT_OPTIONS } from '../out/common/services/OptionsService'; +import { clone } from '../out/common/Clone'; function getCursor(term: TestTerminal): number[] { return [ @@ -49,43 +51,43 @@ describe('InputHandler', () => { }); describe('setCursorStyle', () => { it('should call Terminal.setOption with correct params', () => { - const terminal = new MockInputHandlingTerminal(); - const inputHandler = new InputHandler(terminal, new MockBufferService(80, 30), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService()); + const optionsService = new MockOptionsService(); + const inputHandler = new InputHandler(new MockInputHandlingTerminal(), new MockBufferService(80, 30), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), optionsService); const collect = ' '; inputHandler.setCursorStyle(Params.fromArray([0]), collect); - assert.equal(terminal.options['cursorStyle'], 'block'); - assert.equal(terminal.options['cursorBlink'], true); + assert.equal(optionsService.options['cursorStyle'], 'block'); + assert.equal(optionsService.options['cursorBlink'], true); - terminal.options = {}; + optionsService.options = clone(DEFAULT_OPTIONS); inputHandler.setCursorStyle(Params.fromArray([1]), collect); - assert.equal(terminal.options['cursorStyle'], 'block'); - assert.equal(terminal.options['cursorBlink'], true); + assert.equal(optionsService.options['cursorStyle'], 'block'); + assert.equal(optionsService.options['cursorBlink'], true); - terminal.options = {}; + optionsService.options = clone(DEFAULT_OPTIONS); inputHandler.setCursorStyle(Params.fromArray([2]), collect); - assert.equal(terminal.options['cursorStyle'], 'block'); - assert.equal(terminal.options['cursorBlink'], false); + assert.equal(optionsService.options['cursorStyle'], 'block'); + assert.equal(optionsService.options['cursorBlink'], false); - terminal.options = {}; + optionsService.options = clone(DEFAULT_OPTIONS); inputHandler.setCursorStyle(Params.fromArray([3]), collect); - assert.equal(terminal.options['cursorStyle'], 'underline'); - assert.equal(terminal.options['cursorBlink'], true); + assert.equal(optionsService.options['cursorStyle'], 'underline'); + assert.equal(optionsService.options['cursorBlink'], true); - terminal.options = {}; + optionsService.options = clone(DEFAULT_OPTIONS); inputHandler.setCursorStyle(Params.fromArray([4]), collect); - assert.equal(terminal.options['cursorStyle'], 'underline'); - assert.equal(terminal.options['cursorBlink'], false); + assert.equal(optionsService.options['cursorStyle'], 'underline'); + assert.equal(optionsService.options['cursorBlink'], false); - terminal.options = {}; + optionsService.options = clone(DEFAULT_OPTIONS); inputHandler.setCursorStyle(Params.fromArray([5]), collect); - assert.equal(terminal.options['cursorStyle'], 'bar'); - assert.equal(terminal.options['cursorBlink'], true); + assert.equal(optionsService.options['cursorStyle'], 'bar'); + assert.equal(optionsService.options['cursorBlink'], true); - terminal.options = {}; + optionsService.options = clone(DEFAULT_OPTIONS); inputHandler.setCursorStyle(Params.fromArray([6]), collect); - assert.equal(terminal.options['cursorStyle'], 'bar'); - assert.equal(terminal.options['cursorBlink'], false); + assert.equal(optionsService.options['cursorStyle'], 'bar'); + assert.equal(optionsService.options['cursorBlink'], false); }); }); describe('setMode', () => { diff --git a/src/Terminal.ts b/src/Terminal.ts index aee393b3..8760a4dd 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -590,7 +590,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp this._compositionView = document.createElement('div'); this._compositionView.classList.add('composition-view'); - this._compositionHelper = new CompositionHelper(this.textarea, this._compositionView, this._bufferService, this.optionsService, this._charSizeService, this._coreService); + this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView); this._helperContainer.appendChild(this._compositionView); // Performance: Add viewport and helper elements from the fragment diff --git a/src/common/services/InstantiationService.ts b/src/common/services/InstantiationService.ts index 037fbcfd..abce8ac5 100644 --- a/src/common/services/InstantiationService.ts +++ b/src/common/services/InstantiationService.ts @@ -55,23 +55,23 @@ export class InstantiationService implements IInstantiationService { public createInstance(ctor: any, ...args: any[]): any { const serviceDependencies = getServiceDependencies(ctor).sort((a, b) => a.index - b.index); - let serviceArgs: any[] = []; - for (const dependency of serviceDependencies) { - let service = this._services.get(dependency.id); - if (!service) { - throw new Error(`[createInstance] ${ctor.name} depends on UNKNOWN service ${dependency.id}.`); - } - serviceArgs.push(service); - } - - let firstServiceArgPos = serviceDependencies.length > 0 ? serviceDependencies[0].index : args.length; - - // check for argument mismatches, adjust static args if needed - if (args.length !== firstServiceArgPos) { - throw new Error(`[createInstance] First service dependency of ${ctor.name} at position ${firstServiceArgPos + 1} conflicts with ${args.length} static arguments`); + const serviceArgs: any[] = []; + for (const dependency of serviceDependencies) { + const service = this._services.get(dependency.id); + if (!service) { + throw new Error(`[createInstance] ${ctor.name} depends on UNKNOWN service ${dependency.id}.`); + } + serviceArgs.push(service); } - // now create the instance - return new ctor(...[...args, ...serviceArgs]); + const firstServiceArgPos = serviceDependencies.length > 0 ? serviceDependencies[0].index : args.length; + + // check for argument mismatches, adjust static args if needed + if (args.length !== firstServiceArgPos) { + throw new Error(`[createInstance] First service dependency of ${ctor.name} at position ${firstServiceArgPos + 1} conflicts with ${args.length} static arguments`); + } + + // now create the instance + return new ctor(...[...args, ...serviceArgs]); } } diff --git a/src/common/services/Services.ts b/src/common/services/Services.ts index 3433af28..4ff0bc0c 100644 --- a/src/common/services/Services.ts +++ b/src/common/services/Services.ts @@ -42,7 +42,7 @@ export interface ICoreService { * - Scroll to the bottom of the buffer.s * - Fire the `onUserInput` event (so selection can be cleared). */ - triggerDataEvent(data: string, wasUserInput?: boolean): void; + triggerDataEvent(data: string, wasUserInput?: boolean): void; } export const IDirtyRowService = createDecorator('DirtyRowService'); @@ -64,54 +64,54 @@ export interface IServiceIdentifier { } export interface IConstructorSignature0 { - new(...services: { _serviceBrand: any; }[]): T; + new(...services: { _serviceBrand: any; }[]): T; } export interface IConstructorSignature1 { - new(first: A1, ...services: { _serviceBrand: any; }[]): T; + new(first: A1, ...services: { _serviceBrand: any; }[]): T; } export interface IConstructorSignature2 { - new(first: A1, second: A2, ...services: { _serviceBrand: any; }[]): T; + new(first: A1, second: A2, ...services: { _serviceBrand: any; }[]): T; } export interface IConstructorSignature3 { - new(first: A1, second: A2, third: A3, ...services: { _serviceBrand: any; }[]): T; + new(first: A1, second: A2, third: A3, ...services: { _serviceBrand: any; }[]): T; } export interface IConstructorSignature4 { - new(first: A1, second: A2, third: A3, fourth: A4, ...services: { _serviceBrand: any; }[]): T; + new(first: A1, second: A2, third: A3, fourth: A4, ...services: { _serviceBrand: any; }[]): T; } export interface IConstructorSignature5 { - new(first: A1, second: A2, third: A3, fourth: A4, fifth: A5, ...services: { _serviceBrand: any; }[]): T; + new(first: A1, second: A2, third: A3, fourth: A4, fifth: A5, ...services: { _serviceBrand: any; }[]): T; } export interface IConstructorSignature6 { - new(first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, ...services: { _serviceBrand: any; }[]): T; + new(first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, ...services: { _serviceBrand: any; }[]): T; } export interface IConstructorSignature7 { - new(first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, ...services: { _serviceBrand: any; }[]): T; + new(first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, ...services: { _serviceBrand: any; }[]): T; } export interface IConstructorSignature8 { - new(first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, eigth: A8, ...services: { _serviceBrand: any; }[]): T; + new(first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, eigth: A8, ...services: { _serviceBrand: any; }[]): T; } export const IInstantiationService = createDecorator('InstantiationService'); export interface IInstantiationService { setService(id: IServiceIdentifier, instance: T): void; - createInstance(ctor: IConstructorSignature0): T; - createInstance(ctor: IConstructorSignature1, first: A1): T; - createInstance(ctor: IConstructorSignature2, first: A1, second: A2): T; - createInstance(ctor: IConstructorSignature3, first: A1, second: A2, third: A3): T; - createInstance(ctor: IConstructorSignature4, first: A1, second: A2, third: A3, fourth: A4): T; - createInstance(ctor: IConstructorSignature5, first: A1, second: A2, third: A3, fourth: A4, fifth: A5): T; - createInstance(ctor: IConstructorSignature6, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6): T; - createInstance(ctor: IConstructorSignature7, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7): T; - createInstance(ctor: IConstructorSignature8, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, eigth: A8): T; + createInstance(ctor: IConstructorSignature0): T; + createInstance(ctor: IConstructorSignature1, first: A1): T; + createInstance(ctor: IConstructorSignature2, first: A1, second: A2): T; + createInstance(ctor: IConstructorSignature3, first: A1, second: A2, third: A3): T; + createInstance(ctor: IConstructorSignature4, first: A1, second: A2, third: A3, fourth: A4): T; + createInstance(ctor: IConstructorSignature5, first: A1, second: A2, third: A3, fourth: A4, fifth: A5): T; + createInstance(ctor: IConstructorSignature6, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6): T; + createInstance(ctor: IConstructorSignature7, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7): T; + createInstance(ctor: IConstructorSignature8, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, eigth: A8): T; } export const ILogService = createDecorator('LogService'); diff --git a/src/renderer/Renderer.ts b/src/renderer/Renderer.ts index 80d17cde..574d107a 100644 --- a/src/renderer/Renderer.ts +++ b/src/renderer/Renderer.ts @@ -26,12 +26,12 @@ export class Renderer extends Disposable implements IRenderer { constructor( private _colors: IColorSet, private readonly _terminal: ITerminal, - readonly _bufferService: IBufferService, + readonly bufferService: IBufferService, private readonly _charSizeService: ICharSizeService ) { super(); const allowTransparency = this._terminal.options.allowTransparency; - this._characterJoinerRegistry = new CharacterJoinerRegistry(this._bufferService); + this._characterJoinerRegistry = new CharacterJoinerRegistry(bufferService); this._renderLayers = [ new TextRenderLayer(this._terminal.screenElement, 0, this._colors, this._characterJoinerRegistry, allowTransparency), diff --git a/tslint.json b/tslint.json index 43662039..4445e97c 100644 --- a/tslint.json +++ b/tslint.json @@ -94,6 +94,8 @@ {"type": "member", "modifiers": ["private"], "format": "camelCase", "leadingUnderscore": "require"}, {"type": "variable", "modifiers": ["const"], "format": ["camelCase", "UPPER_CASE"]}, {"type": "variable", "modifiers": ["const", "export"], "filter": "^I.+Service$", "format": "PascalCase", "prefix": "I"}, + {"type": "member", "filter": "^_serviceBrand$", "leadingUnderscore": "require"}, + {"type": "property", "filter": "^_serviceBrand$", "leadingUnderscore": "require"}, {"type": "interface", "prefix": "I"} ], "no-else-after-return": {