mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-28 07:40:30 -04:00
SQL Operations Studio Public Preview 1 (0.23) release source code
This commit is contained in:
272
src/vs/platform/instantiation/common/descriptors.ts
Normal file
272
src/vs/platform/instantiation/common/descriptors.ts
Normal file
@@ -0,0 +1,272 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { illegalArgument } from 'vs/base/common/errors';
|
||||
import * as instantiation from './instantiation';
|
||||
|
||||
export class AbstractDescriptor<T> {
|
||||
|
||||
constructor(private _staticArguments: any[]) {
|
||||
// empty
|
||||
}
|
||||
|
||||
public appendStaticArguments(more: any[]): void {
|
||||
this._staticArguments.push.apply(this._staticArguments, more);
|
||||
}
|
||||
|
||||
public staticArguments(): any[];
|
||||
public staticArguments(nth: number): any;
|
||||
public staticArguments(nth?: number): any[] {
|
||||
if (isNaN(nth)) {
|
||||
return this._staticArguments.slice(0);
|
||||
} else {
|
||||
return this._staticArguments[nth];
|
||||
}
|
||||
}
|
||||
|
||||
_validate(type: T): void {
|
||||
if (!type) {
|
||||
throw illegalArgument('can not be falsy');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SyncDescriptor<T> extends AbstractDescriptor<T> {
|
||||
|
||||
constructor(private _ctor: any, ...staticArguments: any[]) {
|
||||
super(staticArguments);
|
||||
}
|
||||
|
||||
public get ctor(): any {
|
||||
return this._ctor;
|
||||
}
|
||||
|
||||
protected bind(...moreStaticArguments): SyncDescriptor<T> {
|
||||
let allArgs = [];
|
||||
allArgs = allArgs.concat(this.staticArguments());
|
||||
allArgs = allArgs.concat(moreStaticArguments);
|
||||
return new SyncDescriptor<T>(this._ctor, ...allArgs);
|
||||
}
|
||||
}
|
||||
|
||||
export interface CreateSyncFunc {
|
||||
|
||||
<T>(ctor: instantiation.IConstructorSignature0<T>): SyncDescriptor0<T>;
|
||||
|
||||
<A1, T>(ctor: instantiation.IConstructorSignature1<A1, T>): SyncDescriptor1<A1, T>;
|
||||
<A1, T>(ctor: instantiation.IConstructorSignature1<A1, T>, a1: A1): SyncDescriptor0<T>;
|
||||
|
||||
<A1, A2, T>(ctor: instantiation.IConstructorSignature2<A1, A2, T>): SyncDescriptor2<A1, A2, T>;
|
||||
<A1, A2, T>(ctor: instantiation.IConstructorSignature2<A1, A2, T>, a1: A1): SyncDescriptor1<A2, T>;
|
||||
<A1, A2, T>(ctor: instantiation.IConstructorSignature2<A1, A2, T>, a1: A1, a2: A2): SyncDescriptor0<T>;
|
||||
|
||||
<A1, A2, A3, T>(ctor: instantiation.IConstructorSignature3<A1, A2, A3, T>): SyncDescriptor3<A1, A2, A3, T>;
|
||||
<A1, A2, A3, T>(ctor: instantiation.IConstructorSignature3<A1, A2, A3, T>, a1: A1): SyncDescriptor2<A2, A3, T>;
|
||||
<A1, A2, A3, T>(ctor: instantiation.IConstructorSignature3<A1, A2, A3, T>, a1: A1, a2: A2): SyncDescriptor1<A3, T>;
|
||||
<A1, A2, A3, T>(ctor: instantiation.IConstructorSignature3<A1, A2, A3, T>, a1: A1, a2: A2, a3: A3): SyncDescriptor0<T>;
|
||||
|
||||
<A1, A2, A3, A4, T>(ctor: instantiation.IConstructorSignature4<A1, A2, A3, A4, T>): SyncDescriptor4<A1, A2, A3, A4, T>;
|
||||
<A1, A2, A3, A4, T>(ctor: instantiation.IConstructorSignature4<A1, A2, A3, A4, T>, a1: A1): SyncDescriptor3<A2, A3, A4, T>;
|
||||
<A1, A2, A3, A4, T>(ctor: instantiation.IConstructorSignature4<A1, A2, A3, A4, T>, a1: A1, a2: A2): SyncDescriptor2<A3, A4, T>;
|
||||
<A1, A2, A3, A4, T>(ctor: instantiation.IConstructorSignature4<A1, A2, A3, A4, T>, a1: A1, a2: A2, a3: A3): SyncDescriptor1<A4, T>;
|
||||
<A1, A2, A3, A4, T>(ctor: instantiation.IConstructorSignature4<A1, A2, A3, A4, T>, a1: A1, a2: A2, a3: A3, a4: A4): SyncDescriptor0<T>;
|
||||
|
||||
<A1, A2, A3, A4, A5, T>(ctor: instantiation.IConstructorSignature5<A1, A2, A3, A4, A5, T>): SyncDescriptor5<A1, A2, A3, A4, A5, T>;
|
||||
<A1, A2, A3, A4, A5, T>(ctor: instantiation.IConstructorSignature5<A1, A2, A3, A4, A5, T>, a1: A1): SyncDescriptor4<A2, A3, A4, A5, T>;
|
||||
<A1, A2, A3, A4, A5, T>(ctor: instantiation.IConstructorSignature5<A1, A2, A3, A4, A5, T>, a1: A1, a2: A2): SyncDescriptor3<A3, A4, A5, T>;
|
||||
<A1, A2, A3, A4, A5, T>(ctor: instantiation.IConstructorSignature5<A1, A2, A3, A4, A5, T>, a1: A1, a2: A2, a3: A3): SyncDescriptor2<A4, A5, T>;
|
||||
<A1, A2, A3, A4, A5, T>(ctor: instantiation.IConstructorSignature5<A1, A2, A3, A4, A5, T>, a1: A1, a2: A2, a3: A3, a4: A4): SyncDescriptor1<A5, T>;
|
||||
<A1, A2, A3, A4, A5, T>(ctor: instantiation.IConstructorSignature5<A1, A2, A3, A4, A5, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): SyncDescriptor0<T>;
|
||||
|
||||
<A1, A2, A3, A4, A5, A6, T>(ctor: instantiation.IConstructorSignature6<A1, A2, A3, A4, A5, A6, T>): SyncDescriptor6<A1, A2, A3, A4, A5, A6, T>;
|
||||
<A1, A2, A3, A4, A5, A6, T>(ctor: instantiation.IConstructorSignature6<A1, A2, A3, A4, A5, A6, T>, a1: A1): SyncDescriptor5<A2, A3, A4, A5, A6, T>;
|
||||
<A1, A2, A3, A4, A5, A6, T>(ctor: instantiation.IConstructorSignature6<A1, A2, A3, A4, A5, A6, T>, a1: A1, a2: A2): SyncDescriptor4<A3, A4, A5, A6, T>;
|
||||
<A1, A2, A3, A4, A5, A6, T>(ctor: instantiation.IConstructorSignature6<A1, A2, A3, A4, A5, A6, T>, a1: A1, a2: A2, a3: A3): SyncDescriptor3<A4, A5, A6, T>;
|
||||
<A1, A2, A3, A4, A5, A6, T>(ctor: instantiation.IConstructorSignature6<A1, A2, A3, A4, A5, A6, T>, a1: A1, a2: A2, a3: A3, a4: A4): SyncDescriptor2<A5, A6, T>;
|
||||
<A1, A2, A3, A4, A5, A6, T>(ctor: instantiation.IConstructorSignature6<A1, A2, A3, A4, A5, A6, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): SyncDescriptor1<A6, T>;
|
||||
<A1, A2, A3, A4, A5, A6, T>(ctor: instantiation.IConstructorSignature6<A1, A2, A3, A4, A5, A6, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): SyncDescriptor0<T>;
|
||||
|
||||
<A1, A2, A3, A4, A5, A6, A7, T>(ctor: instantiation.IConstructorSignature7<A1, A2, A3, A4, A5, A6, A7, T>): SyncDescriptor7<A1, A2, A3, A4, A5, A6, A7, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, T>(ctor: instantiation.IConstructorSignature7<A1, A2, A3, A4, A5, A6, A7, T>, a1: A1): SyncDescriptor6<A2, A3, A4, A5, A6, A7, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, T>(ctor: instantiation.IConstructorSignature7<A1, A2, A3, A4, A5, A6, A7, T>, a1: A1, a2: A2): SyncDescriptor5<A3, A4, A5, A6, A7, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, T>(ctor: instantiation.IConstructorSignature7<A1, A2, A3, A4, A5, A6, A7, T>, a1: A1, a2: A2, a3: A3): SyncDescriptor4<A4, A5, A6, A7, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, T>(ctor: instantiation.IConstructorSignature7<A1, A2, A3, A4, A5, A6, A7, T>, a1: A1, a2: A2, a3: A3, a4: A4): SyncDescriptor3<A5, A6, A7, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, T>(ctor: instantiation.IConstructorSignature7<A1, A2, A3, A4, A5, A6, A7, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): SyncDescriptor2<A6, A7, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, T>(ctor: instantiation.IConstructorSignature7<A1, A2, A3, A4, A5, A6, A7, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): SyncDescriptor1<A7, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, T>(ctor: instantiation.IConstructorSignature7<A1, A2, A3, A4, A5, A6, A7, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7): SyncDescriptor0<T>;
|
||||
|
||||
<A1, A2, A3, A4, A5, A6, A7, A8, T>(ctor: instantiation.IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T>): SyncDescriptor8<A1, A2, A3, A4, A5, A6, A7, A8, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, A8, T>(ctor: instantiation.IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T>, a1: A1): SyncDescriptor7<A2, A3, A4, A5, A6, A7, A8, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, A8, T>(ctor: instantiation.IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T>, a1: A1, a2: A2): SyncDescriptor6<A3, A4, A5, A6, A7, A8, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, A8, T>(ctor: instantiation.IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T>, a1: A1, a2: A2, a3: A3): SyncDescriptor5<A4, A5, A6, A7, A8, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, A8, T>(ctor: instantiation.IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T>, a1: A1, a2: A2, a3: A3, a4: A4): SyncDescriptor4<A5, A6, A7, A8, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, A8, T>(ctor: instantiation.IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): SyncDescriptor3<A6, A7, A8, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, A8, T>(ctor: instantiation.IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): SyncDescriptor2<A7, A8, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, A8, T>(ctor: instantiation.IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7): SyncDescriptor1<A8, T>;
|
||||
<A1, A2, A3, A4, A5, A6, A7, A8, T>(ctor: instantiation.IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7, a8: A8): SyncDescriptor0<T>;
|
||||
}
|
||||
export const createSyncDescriptor: CreateSyncFunc = <T>(ctor: any, ...staticArguments: any[]): any => {
|
||||
return new SyncDescriptor<T>(ctor, ...staticArguments);
|
||||
};
|
||||
|
||||
export interface SyncDescriptor0<T> {
|
||||
ctor: any;
|
||||
bind(): SyncDescriptor0<T>;
|
||||
}
|
||||
export interface SyncDescriptor1<A1, T> {
|
||||
ctor: any;
|
||||
bind(a1: A1): SyncDescriptor0<T>;
|
||||
}
|
||||
export interface SyncDescriptor2<A1, A2, T> {
|
||||
ctor: any;
|
||||
bind(a1: A1): SyncDescriptor1<A2, T>;
|
||||
bind(a1: A1, a2: A2): SyncDescriptor0<T>;
|
||||
}
|
||||
export interface SyncDescriptor3<A1, A2, A3, T> {
|
||||
ctor: any;
|
||||
bind(a1: A1): SyncDescriptor2<A2, A3, T>;
|
||||
bind(a1: A1, a2: A2): SyncDescriptor1<A3, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3): SyncDescriptor0<T>;
|
||||
}
|
||||
export interface SyncDescriptor4<A1, A2, A3, A4, T> {
|
||||
ctor: any;
|
||||
bind(a1: A1): SyncDescriptor3<A2, A3, A4, T>;
|
||||
bind(a1: A1, a2: A2): SyncDescriptor2<A3, A4, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3): SyncDescriptor1<A4, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4): SyncDescriptor0<T>;
|
||||
}
|
||||
export interface SyncDescriptor5<A1, A2, A3, A4, A5, T> {
|
||||
ctor: any;
|
||||
bind(a1: A1): SyncDescriptor4<A2, A3, A4, A5, T>;
|
||||
bind(a1: A1, a2: A2): SyncDescriptor3<A3, A4, A5, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3): SyncDescriptor2<A4, A5, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4): SyncDescriptor1<A5, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): SyncDescriptor0<T>;
|
||||
}
|
||||
export interface SyncDescriptor6<A1, A2, A3, A4, A5, A6, T> {
|
||||
ctor: any;
|
||||
bind(a1: A1): SyncDescriptor5<A2, A3, A4, A5, A6, T>;
|
||||
bind(a1: A1, a2: A2): SyncDescriptor4<A3, A4, A5, A6, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3): SyncDescriptor3<A4, A5, A6, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4): SyncDescriptor2<A5, A6, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): SyncDescriptor1<A6, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): SyncDescriptor0<T>;
|
||||
}
|
||||
export interface SyncDescriptor7<A1, A2, A3, A4, A5, A6, A7, T> {
|
||||
ctor: any;
|
||||
bind(a1: A1): SyncDescriptor6<A2, A3, A4, A5, A6, A7, T>;
|
||||
bind(a1: A1, a2: A2): SyncDescriptor5<A3, A4, A5, A6, A7, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3): SyncDescriptor4<A4, A5, A6, A7, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4): SyncDescriptor3<A5, A6, A7, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): SyncDescriptor2<A6, A7, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): SyncDescriptor1<A7, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7): SyncDescriptor0<T>;
|
||||
}
|
||||
export interface SyncDescriptor8<A1, A2, A3, A4, A5, A6, A7, A8, T> {
|
||||
ctor: any;
|
||||
bind(a1: A1): SyncDescriptor7<A2, A3, A4, A5, A6, A7, A8, T>;
|
||||
bind(a1: A1, a2: A2): SyncDescriptor6<A3, A4, A5, A6, A7, A8, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3): SyncDescriptor5<A4, A5, A6, A7, A8, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4): SyncDescriptor4<A5, A6, A7, A8, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): SyncDescriptor3<A6, A7, A8, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): SyncDescriptor2<A7, A8, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7): SyncDescriptor1<A8, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7, a8: A8): SyncDescriptor0<T>;
|
||||
}
|
||||
|
||||
export class AsyncDescriptor<T> extends AbstractDescriptor<T> implements AsyncDescriptor0<T> {
|
||||
|
||||
public static create<T>(moduleName: string, ctorName: string): AsyncDescriptor<T> {
|
||||
return new AsyncDescriptor<T>(moduleName, ctorName);
|
||||
}
|
||||
|
||||
constructor(private _moduleName: string, private _ctorName?: string, ...staticArguments: any[]) {
|
||||
super(staticArguments);
|
||||
if (typeof _moduleName !== 'string') {
|
||||
throw new Error('Invalid AsyncDescriptor arguments, expected `moduleName` to be a string!');
|
||||
}
|
||||
}
|
||||
|
||||
public get moduleName(): string {
|
||||
return this._moduleName;
|
||||
}
|
||||
|
||||
public get ctorName(): string {
|
||||
return this._ctorName;
|
||||
}
|
||||
|
||||
bind(...moreStaticArguments): AsyncDescriptor<T> {
|
||||
let allArgs = [];
|
||||
allArgs = allArgs.concat(this.staticArguments());
|
||||
allArgs = allArgs.concat(moreStaticArguments);
|
||||
return new AsyncDescriptor<T>(this.moduleName, this.ctorName, ...allArgs);
|
||||
}
|
||||
}
|
||||
|
||||
export interface AsyncDescriptor0<T> {
|
||||
moduleName: string;
|
||||
bind(): AsyncDescriptor0<T>;
|
||||
}
|
||||
export interface AsyncDescriptor1<A1, T> {
|
||||
moduleName: string;
|
||||
bind(a1: A1): AsyncDescriptor0<T>;
|
||||
}
|
||||
export interface AsyncDescriptor2<A1, A2, T> {
|
||||
moduleName: string;
|
||||
bind(a1: A1): AsyncDescriptor1<A2, T>;
|
||||
bind(a1: A1, a2: A2): AsyncDescriptor0<T>;
|
||||
}
|
||||
export interface AsyncDescriptor3<A1, A2, A3, T> {
|
||||
moduleName: string;
|
||||
bind(a1: A1): AsyncDescriptor2<A2, A3, T>;
|
||||
bind(a1: A1, a2: A2): AsyncDescriptor1<A3, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3): AsyncDescriptor0<T>;
|
||||
}
|
||||
export interface AsyncDescriptor4<A1, A2, A3, A4, T> {
|
||||
moduleName: string;
|
||||
bind(a1: A1): AsyncDescriptor3<A2, A3, A4, T>;
|
||||
bind(a1: A1, a2: A2): AsyncDescriptor2<A3, A4, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3): AsyncDescriptor1<A4, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4): AsyncDescriptor0<T>;
|
||||
}
|
||||
export interface AsyncDescriptor5<A1, A2, A3, A4, A5, T> {
|
||||
moduleName: string;
|
||||
bind(a1: A1): AsyncDescriptor4<A2, A3, A4, A5, T>;
|
||||
bind(a1: A1, a2: A2): AsyncDescriptor3<A3, A4, A5, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3): AsyncDescriptor2<A4, A5, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4): AsyncDescriptor1<A5, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): AsyncDescriptor0<T>;
|
||||
}
|
||||
export interface AsyncDescriptor6<A1, A2, A3, A4, A5, A6, T> {
|
||||
moduleName: string;
|
||||
bind(a1: A1): AsyncDescriptor5<A2, A3, A4, A5, A6, T>;
|
||||
bind(a1: A1, a2: A2): AsyncDescriptor4<A3, A4, A5, A6, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3): AsyncDescriptor3<A4, A5, A6, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4): AsyncDescriptor2<A5, A6, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): AsyncDescriptor1<A6, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): AsyncDescriptor0<T>;
|
||||
}
|
||||
export interface AsyncDescriptor7<A1, A2, A3, A4, A5, A6, A7, T> {
|
||||
moduleName: string;
|
||||
bind(a1: A1): AsyncDescriptor6<A2, A3, A4, A5, A6, A7, T>;
|
||||
bind(a1: A1, a2: A2): AsyncDescriptor5<A3, A4, A5, A6, A7, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3): AsyncDescriptor4<A4, A5, A6, A7, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4): AsyncDescriptor3<A5, A6, A7, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): AsyncDescriptor2<A6, A7, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): AsyncDescriptor1<A7, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7): AsyncDescriptor0<T>;
|
||||
}
|
||||
export interface AsyncDescriptor8<A1, A2, A3, A4, A5, A6, A7, A8, T> {
|
||||
moduleName: string;
|
||||
bind(a1: A1): AsyncDescriptor7<A2, A3, A4, A5, A6, A7, A8, T>;
|
||||
bind(a1: A1, a2: A2): AsyncDescriptor6<A3, A4, A5, A6, A7, A8, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3): AsyncDescriptor5<A4, A5, A6, A7, A8, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4): AsyncDescriptor4<A5, A6, A7, A8, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): AsyncDescriptor3<A6, A7, A8, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): AsyncDescriptor2<A7, A8, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7): AsyncDescriptor1<A8, T>;
|
||||
bind(a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7, a8: A8): AsyncDescriptor0<T>;
|
||||
}
|
||||
25
src/vs/platform/instantiation/common/extensions.ts
Normal file
25
src/vs/platform/instantiation/common/extensions.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { SyncDescriptor } from './descriptors';
|
||||
import { ServiceIdentifier, IConstructorSignature0 } from './instantiation';
|
||||
|
||||
export const Services = 'di.services';
|
||||
|
||||
export interface IServiceContribution<T> {
|
||||
id: ServiceIdentifier<T>;
|
||||
descriptor: SyncDescriptor<T>;
|
||||
}
|
||||
|
||||
const _registry: IServiceContribution<any>[] = [];
|
||||
|
||||
export function registerSingleton<T>(id: ServiceIdentifier<T>, ctor: IConstructorSignature0<T>): void {
|
||||
_registry.push({ id, descriptor: new SyncDescriptor<T>(ctor) });
|
||||
}
|
||||
|
||||
export function getServices(): IServiceContribution<any>[] {
|
||||
return _registry;
|
||||
}
|
||||
218
src/vs/platform/instantiation/common/instantiation.ts
Normal file
218
src/vs/platform/instantiation/common/instantiation.ts
Normal file
@@ -0,0 +1,218 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ServiceCollection } from './serviceCollection';
|
||||
import * as descriptors from './descriptors';
|
||||
|
||||
// ------ internal util
|
||||
|
||||
export namespace _util {
|
||||
|
||||
export const serviceIds = new Map<string, ServiceIdentifier<any>>();
|
||||
|
||||
export const DI_TARGET = '$di$target';
|
||||
export const DI_DEPENDENCIES = '$di$dependencies';
|
||||
|
||||
export function getServiceDependencies(ctor: any): { id: ServiceIdentifier<any>, index: number, optional: boolean }[] {
|
||||
return ctor[DI_DEPENDENCIES] || [];
|
||||
}
|
||||
}
|
||||
|
||||
// --- interfaces ------
|
||||
|
||||
export interface IConstructorSignature0<T> {
|
||||
new(...services: { _serviceBrand: any; }[]): T;
|
||||
}
|
||||
|
||||
export interface IConstructorSignature1<A1, T> {
|
||||
new(first: A1, ...services: { _serviceBrand: any; }[]): T;
|
||||
}
|
||||
|
||||
export interface IConstructorSignature2<A1, A2, T> {
|
||||
new(first: A1, second: A2, ...services: { _serviceBrand: any; }[]): T;
|
||||
}
|
||||
|
||||
export interface IConstructorSignature3<A1, A2, A3, T> {
|
||||
new(first: A1, second: A2, third: A3, ...services: { _serviceBrand: any; }[]): T;
|
||||
}
|
||||
|
||||
export interface IConstructorSignature4<A1, A2, A3, A4, T> {
|
||||
new(first: A1, second: A2, third: A3, fourth: A4, ...services: { _serviceBrand: any; }[]): T;
|
||||
}
|
||||
|
||||
export interface IConstructorSignature5<A1, A2, A3, A4, A5, T> {
|
||||
new(first: A1, second: A2, third: A3, fourth: A4, fifth: A5, ...services: { _serviceBrand: any; }[]): T;
|
||||
}
|
||||
|
||||
export interface IConstructorSignature6<A1, A2, A3, A4, A5, A6, T> {
|
||||
new(first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, ...services: { _serviceBrand: any; }[]): T;
|
||||
}
|
||||
|
||||
export interface IConstructorSignature7<A1, A2, A3, A4, A5, A6, A7, T> {
|
||||
new(first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, ...services: { _serviceBrand: any; }[]): T;
|
||||
}
|
||||
|
||||
export interface IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T> {
|
||||
new(first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, eigth: A8, ...services: { _serviceBrand: any; }[]): T;
|
||||
}
|
||||
|
||||
export interface ServicesAccessor {
|
||||
get<T>(id: ServiceIdentifier<T>, isOptional?: typeof optional): T;
|
||||
}
|
||||
|
||||
export interface IFunctionSignature0<R> {
|
||||
(accessor: ServicesAccessor): R;
|
||||
}
|
||||
|
||||
export interface IFunctionSignature1<A1, R> {
|
||||
(accessor: ServicesAccessor, first: A1): R;
|
||||
}
|
||||
|
||||
export interface IFunctionSignature2<A1, A2, R> {
|
||||
(accessor: ServicesAccessor, first: A1, second: A2): R;
|
||||
}
|
||||
|
||||
export interface IFunctionSignature3<A1, A2, A3, R> {
|
||||
(accessor: ServicesAccessor, first: A1, second: A2, third: A3): R;
|
||||
}
|
||||
|
||||
export interface IFunctionSignature4<A1, A2, A3, A4, R> {
|
||||
(accessor: ServicesAccessor, first: A1, second: A2, third: A3, fourth: A4): R;
|
||||
}
|
||||
|
||||
export interface IFunctionSignature5<A1, A2, A3, A4, A5, R> {
|
||||
(accessor: ServicesAccessor, first: A1, second: A2, third: A3, fourth: A4, fifth: A5): R;
|
||||
}
|
||||
|
||||
export interface IFunctionSignature6<A1, A2, A3, A4, A5, A6, R> {
|
||||
(accessor: ServicesAccessor, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6): R;
|
||||
}
|
||||
|
||||
export interface IFunctionSignature7<A1, A2, A3, A4, A5, A6, A7, R> {
|
||||
(accessor: ServicesAccessor, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7): R;
|
||||
}
|
||||
|
||||
export interface IFunctionSignature8<A1, A2, A3, A4, A5, A6, A7, A8, R> {
|
||||
(accessor: ServicesAccessor, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, eigth: A8): R;
|
||||
}
|
||||
|
||||
export const IInstantiationService = createDecorator<IInstantiationService>('instantiationService');
|
||||
|
||||
export interface IInstantiationService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
/**
|
||||
* Synchronously creates an instance that is denoted by
|
||||
* the descriptor
|
||||
*/
|
||||
createInstance<T>(descriptor: descriptors.SyncDescriptor0<T>): T;
|
||||
createInstance<A1, T>(descriptor: descriptors.SyncDescriptor1<A1, T>, a1: A1): T;
|
||||
createInstance<A1, A2, T>(descriptor: descriptors.SyncDescriptor2<A1, A2, T>, a1: A1, a2: A2): T;
|
||||
createInstance<A1, A2, A3, T>(descriptor: descriptors.SyncDescriptor3<A1, A2, A3, T>, a1: A1, a2: A2, a3: A3): T;
|
||||
createInstance<A1, A2, A3, A4, T>(descriptor: descriptors.SyncDescriptor4<A1, A2, A3, A4, T>, a1: A1, a2: A2, a3: A3, a4: A4): T;
|
||||
createInstance<A1, A2, A3, A4, A5, T>(descriptor: descriptors.SyncDescriptor5<A1, A2, A3, A4, A5, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): T;
|
||||
createInstance<A1, A2, A3, A4, A5, A6, T>(descriptor: descriptors.SyncDescriptor6<A1, A2, A3, A4, A5, A6, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): T;
|
||||
createInstance<A1, A2, A3, A4, A5, A6, A7, T>(descriptor: descriptors.SyncDescriptor7<A1, A2, A3, A4, A5, A6, A7, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7): T;
|
||||
createInstance<A1, A2, A3, A4, A5, A6, A7, A8, T>(descriptor: descriptors.SyncDescriptor8<A1, A2, A3, A4, A5, A6, A7, A8, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7, a8: A8): T;
|
||||
|
||||
createInstance<T>(ctor: IConstructorSignature0<T>): T;
|
||||
createInstance<A1, T>(ctor: IConstructorSignature1<A1, T>, first: A1): T;
|
||||
createInstance<A1, A2, T>(ctor: IConstructorSignature2<A1, A2, T>, first: A1, second: A2): T;
|
||||
createInstance<A1, A2, A3, T>(ctor: IConstructorSignature3<A1, A2, A3, T>, first: A1, second: A2, third: A3): T;
|
||||
createInstance<A1, A2, A3, A4, T>(ctor: IConstructorSignature4<A1, A2, A3, A4, T>, first: A1, second: A2, third: A3, fourth: A4): T;
|
||||
createInstance<A1, A2, A3, A4, A5, T>(ctor: IConstructorSignature5<A1, A2, A3, A4, A5, T>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5): T;
|
||||
createInstance<A1, A2, A3, A4, A5, A6, T>(ctor: IConstructorSignature6<A1, A2, A3, A4, A5, A6, T>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6): T;
|
||||
createInstance<A1, A2, A3, A4, A5, A6, A7, T>(ctor: IConstructorSignature7<A1, A2, A3, A4, A5, A6, A7, T>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7): T;
|
||||
createInstance<A1, A2, A3, A4, A5, A6, A7, A8, T>(ctor: IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, eigth: A8): T;
|
||||
|
||||
/**
|
||||
* Asynchronously creates an instance that is denoted by
|
||||
* the descriptor
|
||||
*/
|
||||
createInstance<T>(descriptor: descriptors.AsyncDescriptor0<T>): TPromise<T>;
|
||||
createInstance<A1, T>(descriptor: descriptors.AsyncDescriptor1<A1, T>, a1: A1): TPromise<T>;
|
||||
createInstance<A1, A2, T>(descriptor: descriptors.AsyncDescriptor2<A1, A2, T>, a1: A1, a2: A2): TPromise<T>;
|
||||
createInstance<A1, A2, A3, T>(descriptor: descriptors.AsyncDescriptor3<A1, A2, A3, T>, a1: A1, a2: A2, a3: A3): TPromise<T>;
|
||||
createInstance<A1, A2, A3, A4, T>(descriptor: descriptors.AsyncDescriptor4<A1, A2, A3, A4, T>, a1: A1, a2: A2, a3: A3, a4: A4): TPromise<T>;
|
||||
createInstance<A1, A2, A3, A4, A5, T>(descriptor: descriptors.AsyncDescriptor5<A1, A2, A3, A4, A5, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): TPromise<T>;
|
||||
createInstance<A1, A2, A3, A4, A5, A6, T>(descriptor: descriptors.AsyncDescriptor6<A1, A2, A3, A4, A5, A6, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): TPromise<T>;
|
||||
createInstance<A1, A2, A3, A4, A5, A6, A7, T>(descriptor: descriptors.AsyncDescriptor7<A1, A2, A3, A4, A5, A6, A7, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7): TPromise<T>;
|
||||
createInstance<A1, A2, A3, A4, A5, A6, A7, A8, T>(descriptor: descriptors.AsyncDescriptor8<A1, A2, A3, A4, A5, A6, A7, A8, T>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6, a7: A7, a8: A8): TPromise<T>;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
invokeFunction<R>(ctor: IFunctionSignature0<R>): R;
|
||||
invokeFunction<A1, R>(ctor: IFunctionSignature1<A1, R>, first: A1): R;
|
||||
invokeFunction<A1, A2, R>(ctor: IFunctionSignature2<A1, A2, R>, first: A1, second: A2): R;
|
||||
invokeFunction<A1, A2, A3, R>(ctor: IFunctionSignature3<A1, A2, A3, R>, first: A1, second: A2, third: A3): R;
|
||||
invokeFunction<A1, A2, A3, A4, R>(ctor: IFunctionSignature4<A1, A2, A3, A4, R>, first: A1, second: A2, third: A3, fourth: A4): R;
|
||||
invokeFunction<A1, A2, A3, A4, A5, R>(ctor: IFunctionSignature5<A1, A2, A3, A4, A5, R>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5): R;
|
||||
invokeFunction<A1, A2, A3, A4, A5, A6, R>(ctor: IFunctionSignature6<A1, A2, A3, A4, A5, A6, R>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6): R;
|
||||
invokeFunction<A1, A2, A3, A4, A5, A6, A7, R>(ctor: IFunctionSignature7<A1, A2, A3, A4, A5, A6, A7, R>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7): R;
|
||||
invokeFunction<A1, A2, A3, A4, A5, A6, A7, A8, R>(ctor: IFunctionSignature8<A1, A2, A3, A4, A5, A6, A7, A8, R>, first: A1, second: A2, third: A3, fourth: A4, fifth: A5, sixth: A6, seventh: A7, eigth: A8): R;
|
||||
|
||||
/**
|
||||
* Creates a child of this service which inherts all current services
|
||||
* and adds/overwrites the given services
|
||||
*/
|
||||
createChild(services: ServiceCollection): IInstantiationService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Identifies a service of type T
|
||||
*/
|
||||
export interface ServiceIdentifier<T> {
|
||||
(...args: any[]): void;
|
||||
type: T;
|
||||
}
|
||||
|
||||
function storeServiceDependency(id: Function, target: Function, index: number, optional: boolean): void {
|
||||
if (target[_util.DI_TARGET] === target) {
|
||||
target[_util.DI_DEPENDENCIES].push({ id, index, optional });
|
||||
} else {
|
||||
target[_util.DI_DEPENDENCIES] = [{ id, index, optional }];
|
||||
target[_util.DI_TARGET] = target;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A *only* valid way to create a {{ServiceIdentifier}}.
|
||||
*/
|
||||
export function createDecorator<T>(serviceId: string): { (...args: any[]): void; type: T; } {
|
||||
|
||||
if (_util.serviceIds.has(serviceId)) {
|
||||
return _util.serviceIds.get(serviceId);
|
||||
}
|
||||
|
||||
const id = <any>function (target: Function, key: string, index: number): any {
|
||||
if (arguments.length !== 3) {
|
||||
throw new Error('@IServiceName-decorator can only be used to decorate a parameter');
|
||||
}
|
||||
storeServiceDependency(id, target, index, false);
|
||||
};
|
||||
|
||||
id.toString = () => serviceId;
|
||||
|
||||
_util.serviceIds.set(serviceId, id);
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a service dependency as optional.
|
||||
*/
|
||||
export function optional<T>(serviceIdentifier: ServiceIdentifier<T>) {
|
||||
|
||||
return function (target: Function, key: string, index: number) {
|
||||
if (arguments.length !== 3) {
|
||||
throw new Error('@optional-decorator can only be used to decorate a parameter');
|
||||
}
|
||||
storeServiceDependency(serviceIdentifier, target, index, true);
|
||||
};
|
||||
}
|
||||
238
src/vs/platform/instantiation/common/instantiationService.ts
Normal file
238
src/vs/platform/instantiation/common/instantiationService.ts
Normal file
@@ -0,0 +1,238 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { illegalArgument, illegalState, canceled } from 'vs/base/common/errors';
|
||||
import { create } from 'vs/base/common/types';
|
||||
import * as assert from 'vs/base/common/assert';
|
||||
import { Graph } from 'vs/base/common/graph';
|
||||
import { SyncDescriptor, AsyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { ServiceIdentifier, IInstantiationService, ServicesAccessor, _util, optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
|
||||
|
||||
export class InstantiationService implements IInstantiationService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private _services: ServiceCollection;
|
||||
private _strict: boolean;
|
||||
|
||||
constructor(services: ServiceCollection = new ServiceCollection(), strict: boolean = false) {
|
||||
this._services = services;
|
||||
this._strict = strict;
|
||||
|
||||
this._services.set(IInstantiationService, this);
|
||||
}
|
||||
|
||||
createChild(services: ServiceCollection): IInstantiationService {
|
||||
this._services.forEach((id, thing) => {
|
||||
if (services.has(id)) {
|
||||
return;
|
||||
}
|
||||
// If we copy descriptors we might end up with
|
||||
// multiple instances of the same service
|
||||
if (thing instanceof SyncDescriptor) {
|
||||
thing = this._createAndCacheServiceInstance(id, thing);
|
||||
}
|
||||
services.set(id, thing);
|
||||
});
|
||||
return new InstantiationService(services, this._strict);
|
||||
}
|
||||
|
||||
invokeFunction<R>(signature: (accessor: ServicesAccessor, ...more: any[]) => R, ...args: any[]): R {
|
||||
let accessor: ServicesAccessor;
|
||||
try {
|
||||
accessor = {
|
||||
get: <T>(id: ServiceIdentifier<T>, isOptional?: typeof optional) => {
|
||||
const result = this._getOrCreateServiceInstance(id);
|
||||
if (!result && isOptional !== optional) {
|
||||
throw new Error(`[invokeFunction] unkown service '${id}'`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
return signature.apply(undefined, [accessor].concat(args));
|
||||
} finally {
|
||||
accessor.get = function () {
|
||||
throw illegalState('service accessor is only valid during the invocation of its target method');
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
createInstance<T>(param: any, ...rest: any[]): any {
|
||||
|
||||
if (param instanceof AsyncDescriptor) {
|
||||
// async
|
||||
return this._createInstanceAsync(param, rest);
|
||||
|
||||
} else if (param instanceof SyncDescriptor) {
|
||||
// sync
|
||||
return this._createInstance(param, rest);
|
||||
|
||||
} else {
|
||||
// sync, just ctor
|
||||
return this._createInstance(new SyncDescriptor(param), rest);
|
||||
}
|
||||
}
|
||||
|
||||
private _createInstanceAsync<T>(descriptor: AsyncDescriptor<T>, args: any[]): TPromise<T> {
|
||||
|
||||
let canceledError: Error;
|
||||
|
||||
return new TPromise((c, e, p) => {
|
||||
require([descriptor.moduleName], (_module?: any) => {
|
||||
if (canceledError) {
|
||||
e(canceledError);
|
||||
}
|
||||
|
||||
if (!_module) {
|
||||
return e(illegalArgument('module not found: ' + descriptor.moduleName));
|
||||
}
|
||||
|
||||
let ctor: Function;
|
||||
if (!descriptor.ctorName) {
|
||||
ctor = _module;
|
||||
} else {
|
||||
ctor = _module[descriptor.ctorName];
|
||||
}
|
||||
|
||||
if (typeof ctor !== 'function') {
|
||||
return e(illegalArgument('not a function: ' + descriptor.ctorName || descriptor.moduleName));
|
||||
}
|
||||
|
||||
try {
|
||||
args.unshift.apply(args, descriptor.staticArguments()); // instead of spread in ctor call
|
||||
c(this._createInstance(new SyncDescriptor<T>(ctor), args));
|
||||
} catch (error) {
|
||||
return e(error);
|
||||
}
|
||||
}, e);
|
||||
}, () => {
|
||||
canceledError = canceled();
|
||||
});
|
||||
}
|
||||
|
||||
private _createInstance<T>(desc: SyncDescriptor<T>, args: any[]): T {
|
||||
|
||||
// arguments given by createInstance-call and/or the descriptor
|
||||
let staticArgs = desc.staticArguments().concat(args);
|
||||
|
||||
// arguments defined by service decorators
|
||||
let serviceDependencies = _util.getServiceDependencies(desc.ctor).sort((a, b) => a.index - b.index);
|
||||
let serviceArgs: any[] = [];
|
||||
for (const dependency of serviceDependencies) {
|
||||
let service = this._getOrCreateServiceInstance(dependency.id);
|
||||
if (!service && this._strict && !dependency.optional) {
|
||||
throw new Error(`[createInstance] ${desc.ctor.name} depends on UNKNOWN service ${dependency.id}.`);
|
||||
}
|
||||
serviceArgs.push(service);
|
||||
}
|
||||
|
||||
let firstServiceArgPos = serviceDependencies.length > 0 ? serviceDependencies[0].index : staticArgs.length;
|
||||
|
||||
// check for argument mismatches, adjust static args if needed
|
||||
if (staticArgs.length !== firstServiceArgPos) {
|
||||
console.warn(`[createInstance] First service dependency of ${desc.ctor.name} at position ${
|
||||
firstServiceArgPos + 1} conflicts with ${staticArgs.length} static arguments`);
|
||||
|
||||
let delta = firstServiceArgPos - staticArgs.length;
|
||||
if (delta > 0) {
|
||||
staticArgs = staticArgs.concat(new Array(delta));
|
||||
} else {
|
||||
staticArgs = staticArgs.slice(0, firstServiceArgPos);
|
||||
}
|
||||
}
|
||||
|
||||
// // check for missing args
|
||||
// for (let i = 0; i < serviceArgs.length; i++) {
|
||||
// if (!serviceArgs[i]) {
|
||||
// console.warn(`${desc.ctor.name} MISSES service dependency ${serviceDependencies[i].id}`, new Error().stack);
|
||||
// }
|
||||
// }
|
||||
|
||||
// now create the instance
|
||||
const argArray = [desc.ctor];
|
||||
argArray.push(...staticArgs);
|
||||
argArray.push(...serviceArgs);
|
||||
|
||||
const instance = create.apply(null, argArray);
|
||||
desc._validate(instance);
|
||||
return <T>instance;
|
||||
}
|
||||
|
||||
private _getOrCreateServiceInstance<T>(id: ServiceIdentifier<T>): T {
|
||||
let thing = this._services.get(id);
|
||||
if (thing instanceof SyncDescriptor) {
|
||||
return this._createAndCacheServiceInstance(id, thing);
|
||||
} else {
|
||||
return thing;
|
||||
}
|
||||
}
|
||||
|
||||
private _createAndCacheServiceInstance<T>(id: ServiceIdentifier<T>, desc: SyncDescriptor<T>): T {
|
||||
assert.ok(this._services.get(id) instanceof SyncDescriptor);
|
||||
|
||||
const graph = new Graph<{ id: ServiceIdentifier<any>, desc: SyncDescriptor<any> }>(data => data.id.toString());
|
||||
|
||||
function throwCycleError() {
|
||||
const err = new Error('[createInstance] cyclic dependency between services');
|
||||
err.message = graph.toString();
|
||||
throw err;
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
const stack = [{ id, desc }];
|
||||
while (stack.length) {
|
||||
const item = stack.pop();
|
||||
graph.lookupOrInsertNode(item);
|
||||
|
||||
// TODO@joh use the graph to find a cycle
|
||||
// a weak heuristic for cycle checks
|
||||
if (count++ > 100) {
|
||||
throwCycleError();
|
||||
}
|
||||
|
||||
// check all dependencies for existence and if the need to be created first
|
||||
let dependencies = _util.getServiceDependencies(item.desc.ctor);
|
||||
for (let dependency of dependencies) {
|
||||
|
||||
let instanceOrDesc = this._services.get(dependency.id);
|
||||
if (!instanceOrDesc) {
|
||||
console.warn(`[createInstance] ${id} depends on ${dependency.id} which is NOT registered.`);
|
||||
}
|
||||
|
||||
if (instanceOrDesc instanceof SyncDescriptor) {
|
||||
const d = { id: dependency.id, desc: instanceOrDesc };
|
||||
graph.insertEdge(item, d);
|
||||
stack.push(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
let roots = graph.roots();
|
||||
|
||||
// if there is no more roots but still
|
||||
// nodes in the graph we have a cycle
|
||||
if (roots.length === 0) {
|
||||
if (graph.length !== 0) {
|
||||
throwCycleError();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for (let root of roots) {
|
||||
// create instance and overwrite the service collections
|
||||
const instance = this._createInstance(root.data.desc, []);
|
||||
this._services.set(root.data.id, instance);
|
||||
graph.removeNode(root.data);
|
||||
}
|
||||
}
|
||||
|
||||
return <T>this._services.get(id);
|
||||
}
|
||||
}
|
||||
37
src/vs/platform/instantiation/common/serviceCollection.ts
Normal file
37
src/vs/platform/instantiation/common/serviceCollection.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { SyncDescriptor } from './descriptors';
|
||||
|
||||
export class ServiceCollection {
|
||||
|
||||
private _entries = new Map<ServiceIdentifier<any>, any>();
|
||||
|
||||
constructor(...entries: [ServiceIdentifier<any>, any][]) {
|
||||
for (let [id, service] of entries) {
|
||||
this.set(id, service);
|
||||
}
|
||||
}
|
||||
|
||||
set<T>(id: ServiceIdentifier<T>, instanceOrDescriptor: T | SyncDescriptor<T>): T | SyncDescriptor<T> {
|
||||
const result = this._entries.get(id);
|
||||
this._entries.set(id, instanceOrDescriptor);
|
||||
return result;
|
||||
}
|
||||
|
||||
forEach(callback: (id: ServiceIdentifier<any>, instanceOrDescriptor: any) => any): void {
|
||||
this._entries.forEach((value, key) => callback(key, value));
|
||||
}
|
||||
|
||||
has(id: ServiceIdentifier<any>): boolean {
|
||||
return this._entries.has(id);
|
||||
}
|
||||
|
||||
get<T>(id: ServiceIdentifier<T>): T | SyncDescriptor<T> {
|
||||
return this._entries.get(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
|
||||
import assert = require('assert');
|
||||
import { createDecorator, optional, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
|
||||
let IService1 = createDecorator<IService1>('service1');
|
||||
|
||||
interface IService1 {
|
||||
_serviceBrand: any;
|
||||
c: number;
|
||||
}
|
||||
|
||||
class Service1 implements IService1 {
|
||||
_serviceBrand: any;
|
||||
c = 1;
|
||||
}
|
||||
|
||||
let IService2 = createDecorator<IService2>('service2');
|
||||
|
||||
interface IService2 {
|
||||
_serviceBrand: any;
|
||||
d: boolean;
|
||||
}
|
||||
|
||||
class Service2 implements IService2 {
|
||||
_serviceBrand: any;
|
||||
d = true;
|
||||
}
|
||||
|
||||
let IService3 = createDecorator<IService3>('service3');
|
||||
|
||||
interface IService3 {
|
||||
_serviceBrand: any;
|
||||
s: string;
|
||||
}
|
||||
|
||||
class Service3 implements IService3 {
|
||||
_serviceBrand: any;
|
||||
s = 'farboo';
|
||||
}
|
||||
|
||||
let IDependentService = createDecorator<IDependentService>('dependentService');
|
||||
|
||||
interface IDependentService {
|
||||
_serviceBrand: any;
|
||||
name: string;
|
||||
}
|
||||
|
||||
class DependentService implements IDependentService {
|
||||
_serviceBrand: any;
|
||||
constructor( @IService1 service: IService1) {
|
||||
assert.equal(service.c, 1);
|
||||
}
|
||||
|
||||
name = 'farboo';
|
||||
}
|
||||
|
||||
class Service1Consumer {
|
||||
|
||||
constructor( @IService1 service1: IService1) {
|
||||
assert.ok(service1);
|
||||
assert.equal(service1.c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
class Target2Dep {
|
||||
|
||||
constructor( @IService1 service1: IService1, @IService2 service2) {
|
||||
assert.ok(service1 instanceof Service1);
|
||||
assert.ok(service2 instanceof Service2);
|
||||
}
|
||||
}
|
||||
|
||||
class TargetWithStaticParam {
|
||||
constructor(v: boolean, @IService1 service1: IService1) {
|
||||
assert.ok(v);
|
||||
assert.ok(service1);
|
||||
assert.equal(service1.c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
class TargetNotOptional {
|
||||
constructor( @IService1 service1: IService1, @IService2 service2: IService2) {
|
||||
|
||||
}
|
||||
}
|
||||
class TargetOptional {
|
||||
constructor( @IService1 service1: IService1, @optional(IService2) service2: IService2) {
|
||||
assert.ok(service1);
|
||||
assert.equal(service1.c, 1);
|
||||
assert.ok(service2 === void 0);
|
||||
}
|
||||
}
|
||||
|
||||
class DependentServiceTarget {
|
||||
constructor( @IDependentService d) {
|
||||
assert.ok(d);
|
||||
assert.equal(d.name, 'farboo');
|
||||
}
|
||||
}
|
||||
|
||||
class DependentServiceTarget2 {
|
||||
constructor( @IDependentService d: IDependentService, @IService1 s: IService1) {
|
||||
assert.ok(d);
|
||||
assert.equal(d.name, 'farboo');
|
||||
assert.ok(s);
|
||||
assert.equal(s.c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ServiceLoop1 implements IService1 {
|
||||
_serviceBrand: any;
|
||||
c = 1;
|
||||
|
||||
constructor( @IService2 s: IService2) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class ServiceLoop2 implements IService2 {
|
||||
_serviceBrand: any;
|
||||
d = true;
|
||||
|
||||
constructor( @IService1 s: IService1) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
suite('Instantiation Service', () => {
|
||||
|
||||
test('service collection, cannot overwrite', function () {
|
||||
let collection = new ServiceCollection();
|
||||
let result = collection.set(IService1, null);
|
||||
assert.equal(result, undefined);
|
||||
result = collection.set(IService1, new Service1());
|
||||
assert.equal(result, null);
|
||||
});
|
||||
|
||||
test('service collection, add/has', function () {
|
||||
let collection = new ServiceCollection();
|
||||
collection.set(IService1, null);
|
||||
assert.ok(collection.has(IService1));
|
||||
|
||||
collection.set(IService2, null);
|
||||
assert.ok(collection.has(IService1));
|
||||
assert.ok(collection.has(IService2));
|
||||
});
|
||||
|
||||
test('@Param - simple clase', function () {
|
||||
let collection = new ServiceCollection();
|
||||
let service = new InstantiationService(collection);
|
||||
collection.set(IService1, new Service1());
|
||||
collection.set(IService2, new Service2());
|
||||
collection.set(IService3, new Service3());
|
||||
|
||||
service.createInstance(Service1Consumer);
|
||||
});
|
||||
|
||||
test('@Param - fixed args', function () {
|
||||
let collection = new ServiceCollection();
|
||||
let service = new InstantiationService(collection);
|
||||
collection.set(IService1, new Service1());
|
||||
collection.set(IService2, new Service2());
|
||||
collection.set(IService3, new Service3());
|
||||
|
||||
service.createInstance(TargetWithStaticParam, true);
|
||||
});
|
||||
|
||||
test('service collection is live', function () {
|
||||
|
||||
let collection = new ServiceCollection();
|
||||
collection.set(IService1, new Service1());
|
||||
|
||||
let service = new InstantiationService(collection);
|
||||
service.createInstance(Service1Consumer);
|
||||
|
||||
// no IService2
|
||||
assert.throws(() => service.createInstance(Target2Dep));
|
||||
service.invokeFunction(function (a) {
|
||||
assert.ok(a.get(IService1));
|
||||
assert.ok(!a.get(IService2, optional));
|
||||
});
|
||||
|
||||
collection.set(IService2, new Service2());
|
||||
|
||||
service.createInstance(Target2Dep);
|
||||
service.invokeFunction(function (a) {
|
||||
assert.ok(a.get(IService1));
|
||||
assert.ok(a.get(IService2));
|
||||
});
|
||||
});
|
||||
|
||||
test('@Param - optional', function () {
|
||||
let collection = new ServiceCollection([IService1, new Service1()]);
|
||||
let service = new InstantiationService(collection, true);
|
||||
|
||||
service.createInstance(TargetOptional);
|
||||
assert.throws(() => service.createInstance(TargetNotOptional));
|
||||
|
||||
service = new InstantiationService(collection, false);
|
||||
service.createInstance(TargetOptional);
|
||||
service.createInstance(TargetNotOptional);
|
||||
});
|
||||
|
||||
// we made this a warning
|
||||
// test('@Param - too many args', function () {
|
||||
// let service = instantiationService.create(Object.create(null));
|
||||
// service.addSingleton(IService1, new Service1());
|
||||
// service.addSingleton(IService2, new Service2());
|
||||
// service.addSingleton(IService3, new Service3());
|
||||
|
||||
// assert.throws(() => service.createInstance(ParameterTarget2, true, 2));
|
||||
// });
|
||||
|
||||
// test('@Param - too few args', function () {
|
||||
// let service = instantiationService.create(Object.create(null));
|
||||
// service.addSingleton(IService1, new Service1());
|
||||
// service.addSingleton(IService2, new Service2());
|
||||
// service.addSingleton(IService3, new Service3());
|
||||
|
||||
// assert.throws(() => service.createInstance(ParameterTarget2));
|
||||
// });
|
||||
|
||||
test('SyncDesc - no dependencies', function () {
|
||||
let collection = new ServiceCollection();
|
||||
let service = new InstantiationService(collection);
|
||||
collection.set(IService1, new SyncDescriptor<IService1>(Service1));
|
||||
|
||||
service.invokeFunction(accessor => {
|
||||
|
||||
let service1 = accessor.get(IService1);
|
||||
assert.ok(service1);
|
||||
assert.equal(service1.c, 1);
|
||||
|
||||
let service2 = accessor.get(IService1);
|
||||
assert.ok(service1 === service2);
|
||||
});
|
||||
});
|
||||
|
||||
test('SyncDesc - service with service dependency', function () {
|
||||
let collection = new ServiceCollection();
|
||||
let service = new InstantiationService(collection);
|
||||
collection.set(IService1, new SyncDescriptor<IService1>(Service1));
|
||||
collection.set(IDependentService, new SyncDescriptor<IDependentService>(DependentService));
|
||||
|
||||
service.invokeFunction(accessor => {
|
||||
let d = accessor.get(IDependentService);
|
||||
assert.ok(d);
|
||||
assert.equal(d.name, 'farboo');
|
||||
});
|
||||
});
|
||||
|
||||
test('SyncDesc - target depends on service future', function () {
|
||||
let collection = new ServiceCollection();
|
||||
let service = new InstantiationService(collection);
|
||||
collection.set(IService1, new SyncDescriptor<IService1>(Service1));
|
||||
collection.set(IDependentService, new SyncDescriptor<IDependentService>(DependentService));
|
||||
|
||||
let d = service.createInstance(DependentServiceTarget);
|
||||
assert.ok(d instanceof DependentServiceTarget);
|
||||
|
||||
let d2 = service.createInstance(DependentServiceTarget2);
|
||||
assert.ok(d2 instanceof DependentServiceTarget2);
|
||||
});
|
||||
|
||||
test('SyncDesc - explode on loop', function () {
|
||||
let collection = new ServiceCollection();
|
||||
let service = new InstantiationService(collection);
|
||||
collection.set(IService1, new SyncDescriptor<IService1>(ServiceLoop1));
|
||||
collection.set(IService2, new SyncDescriptor<IService2>(ServiceLoop2));
|
||||
|
||||
assert.throws(() => {
|
||||
service.invokeFunction(accessor => {
|
||||
accessor.get(IService1);
|
||||
});
|
||||
});
|
||||
assert.throws(() => {
|
||||
service.invokeFunction(accessor => {
|
||||
accessor.get(IService2);
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
service.invokeFunction(accessor => {
|
||||
accessor.get(IService1);
|
||||
});
|
||||
} catch (err) {
|
||||
assert.ok(err.name);
|
||||
assert.ok(err.message);
|
||||
}
|
||||
});
|
||||
|
||||
test('Invoke - get services', function () {
|
||||
let collection = new ServiceCollection();
|
||||
let service = new InstantiationService(collection);
|
||||
collection.set(IService1, new Service1());
|
||||
collection.set(IService2, new Service2());
|
||||
|
||||
function test(accessor: ServicesAccessor) {
|
||||
assert.ok(accessor.get(IService1) instanceof Service1);
|
||||
assert.equal(accessor.get(IService1).c, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
assert.equal(service.invokeFunction(test), true);
|
||||
});
|
||||
|
||||
test('Invoke - get service, optional', function () {
|
||||
let collection = new ServiceCollection([IService1, new Service1()]);
|
||||
let service = new InstantiationService(collection);
|
||||
|
||||
function test(accessor: ServicesAccessor) {
|
||||
assert.ok(accessor.get(IService1) instanceof Service1);
|
||||
assert.throws(() => accessor.get(IService2));
|
||||
assert.equal(accessor.get(IService2, optional), undefined);
|
||||
return true;
|
||||
}
|
||||
assert.equal(service.invokeFunction(test), true);
|
||||
});
|
||||
|
||||
test('Invoke - keeping accessor NOT allowed', function () {
|
||||
let collection = new ServiceCollection();
|
||||
let service = new InstantiationService(collection);
|
||||
collection.set(IService1, new Service1());
|
||||
collection.set(IService2, new Service2());
|
||||
|
||||
let cached: ServicesAccessor;
|
||||
|
||||
function test(accessor: ServicesAccessor) {
|
||||
assert.ok(accessor.get(IService1) instanceof Service1);
|
||||
assert.equal(accessor.get(IService1).c, 1);
|
||||
cached = accessor;
|
||||
return true;
|
||||
}
|
||||
|
||||
assert.equal(service.invokeFunction(test), true);
|
||||
|
||||
assert.throws(() => cached.get(IService2));
|
||||
});
|
||||
|
||||
test('Invoke - throw error', function () {
|
||||
let collection = new ServiceCollection();
|
||||
let service = new InstantiationService(collection);
|
||||
collection.set(IService1, new Service1());
|
||||
collection.set(IService2, new Service2());
|
||||
|
||||
function test(accessor: ServicesAccessor) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
assert.throws(() => service.invokeFunction(test));
|
||||
});
|
||||
|
||||
test('Create child', function () {
|
||||
|
||||
let serviceInstanceCount = 0;
|
||||
|
||||
const CtorCounter = class implements Service1 {
|
||||
_serviceBrand: any;
|
||||
c = 1;
|
||||
constructor() {
|
||||
serviceInstanceCount += 1;
|
||||
}
|
||||
};
|
||||
|
||||
// creating the service instance BEFORE the child service
|
||||
let service = new InstantiationService(new ServiceCollection([IService1, new SyncDescriptor(CtorCounter)]));
|
||||
service.createInstance(Service1Consumer);
|
||||
|
||||
// second instance must be earlier ONE
|
||||
let child = service.createChild(new ServiceCollection([IService2, new Service2()]));
|
||||
child.createInstance(Service1Consumer);
|
||||
|
||||
assert.equal(serviceInstanceCount, 1);
|
||||
|
||||
// creating the service instance AFTER the child service
|
||||
serviceInstanceCount = 0;
|
||||
service = new InstantiationService(new ServiceCollection([IService1, new SyncDescriptor(CtorCounter)]));
|
||||
child = service.createChild(new ServiceCollection([IService2, new Service2()]));
|
||||
|
||||
// second instance must be earlier ONE
|
||||
service.createInstance(Service1Consumer);
|
||||
child.createInstance(Service1Consumer);
|
||||
|
||||
assert.equal(serviceInstanceCount, 1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,138 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as sinon from 'sinon';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
interface IServiceMock<T> {
|
||||
id: ServiceIdentifier<T>;
|
||||
service: any;
|
||||
}
|
||||
|
||||
export class TestInstantiationService extends InstantiationService {
|
||||
|
||||
private _servciesMap: Map<ServiceIdentifier<any>, any>;
|
||||
|
||||
constructor(private _serviceCollection: ServiceCollection = new ServiceCollection()) {
|
||||
super(_serviceCollection);
|
||||
|
||||
this._servciesMap = new Map<ServiceIdentifier<any>, any>();
|
||||
}
|
||||
|
||||
public get<T>(service: ServiceIdentifier<T>): T {
|
||||
return <T>this._serviceCollection.get(service);
|
||||
}
|
||||
|
||||
public set<T>(service: ServiceIdentifier<T>, instance: T): T {
|
||||
return <T>this._serviceCollection.set(service, instance);
|
||||
}
|
||||
|
||||
public mock<T>(service: ServiceIdentifier<T>): T | sinon.SinonMock {
|
||||
return <T>this._create(service, { mock: true });
|
||||
}
|
||||
|
||||
public stub<T>(service?: ServiceIdentifier<T>, ctor?: any): T
|
||||
public stub<T>(service?: ServiceIdentifier<T>, obj?: any): T
|
||||
public stub<T>(service?: ServiceIdentifier<T>, ctor?: any, property?: string, value?: any): sinon.SinonStub
|
||||
public stub<T>(service?: ServiceIdentifier<T>, obj?: any, property?: string, value?: any): sinon.SinonStub
|
||||
public stub<T>(service?: ServiceIdentifier<T>, property?: string, value?: any): sinon.SinonStub
|
||||
public stub<T>(serviceIdentifier?: ServiceIdentifier<T>, arg2?: any, arg3?: string, arg4?: any): sinon.SinonStub {
|
||||
let service = typeof arg2 !== 'string' ? arg2 : void 0;
|
||||
let serviceMock: IServiceMock<any> = { id: serviceIdentifier, service: service };
|
||||
let property = typeof arg2 === 'string' ? arg2 : arg3;
|
||||
let value = typeof arg2 === 'string' ? arg3 : arg4;
|
||||
|
||||
let stubObject = <any>this._create(serviceMock, { stub: true });
|
||||
if (property) {
|
||||
if (stubObject[property]) {
|
||||
if (stubObject[property].hasOwnProperty('restore')) {
|
||||
stubObject[property].restore();
|
||||
}
|
||||
if (typeof value === 'function') {
|
||||
stubObject[property] = value;
|
||||
} else {
|
||||
let stub = value ? sinon.stub().returns(value) : sinon.stub();
|
||||
stubObject[property] = stub;
|
||||
return stub;
|
||||
}
|
||||
} else {
|
||||
stubObject[property] = value;
|
||||
}
|
||||
}
|
||||
return stubObject;
|
||||
}
|
||||
|
||||
public stubPromise<T>(service?: ServiceIdentifier<T>, fnProperty?: string, value?: any): T | sinon.SinonStub
|
||||
public stubPromise<T>(service?: ServiceIdentifier<T>, ctor?: any, fnProperty?: string, value?: any): sinon.SinonStub
|
||||
public stubPromise<T>(service?: ServiceIdentifier<T>, obj?: any, fnProperty?: string, value?: any): sinon.SinonStub
|
||||
public stubPromise<T>(arg1?: any, arg2?: any, arg3?: any, arg4?: any): sinon.SinonStub {
|
||||
arg3 = typeof arg2 === 'string' ? TPromise.as(arg3) : arg3;
|
||||
arg4 = typeof arg2 !== 'string' && typeof arg3 === 'string' ? TPromise.as(arg4) : arg4;
|
||||
return this.stub(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
public spy<T>(service: ServiceIdentifier<T>, fnProperty: string): sinon.SinonSpy {
|
||||
let spy = sinon.spy();
|
||||
this.stub(service, fnProperty, spy);
|
||||
return spy;
|
||||
}
|
||||
|
||||
private _create<T>(serviceMock: IServiceMock<T>, options: SinonOptions): any
|
||||
private _create<T>(ctor: any, options: SinonOptions): any
|
||||
private _create<T>(arg1: any, options: SinonOptions): any {
|
||||
if (this.isServiceMock(arg1)) {
|
||||
let service = this._getOrCreateService(arg1, options);
|
||||
this._serviceCollection.set(arg1.id, service);
|
||||
return service;
|
||||
}
|
||||
return options.mock ? sinon.mock(arg1) : this._createStub(arg1);
|
||||
}
|
||||
|
||||
private _getOrCreateService<T>(serviceMock: IServiceMock<T>, opts: SinonOptions): any {
|
||||
let service: any = this._serviceCollection.get(serviceMock.id);
|
||||
if (service) {
|
||||
if (opts.mock && service['sinonOptions'] && !!service['sinonOptions'].mock) {
|
||||
return service;
|
||||
}
|
||||
if (opts.stub && service['sinonOptions'] && !!service['sinonOptions'].stub) {
|
||||
return service;
|
||||
}
|
||||
}
|
||||
return this._createService(serviceMock, opts);
|
||||
}
|
||||
|
||||
private _createService(serviceMock: IServiceMock<any>, opts: SinonOptions): any {
|
||||
serviceMock.service = serviceMock.service ? serviceMock.service : this._servciesMap.get(serviceMock.id);
|
||||
let service = opts.mock ? sinon.mock(serviceMock.service) : this._createStub(serviceMock.service);
|
||||
service['sinonOptions'] = opts;
|
||||
return service;
|
||||
}
|
||||
|
||||
private _createStub(arg: any): any {
|
||||
return typeof arg === 'object' ? arg : sinon.createStubInstance(arg);
|
||||
}
|
||||
|
||||
private isServiceMock(arg1: any): boolean {
|
||||
return typeof arg1 === 'object' && arg1.hasOwnProperty('id');
|
||||
}
|
||||
}
|
||||
|
||||
export function stubFunction<T>(ctor: any, fnProperty: string, value: any): T | sinon.SinonStub {
|
||||
let stub = sinon.createStubInstance(ctor);
|
||||
stub[fnProperty].restore();
|
||||
sinon.stub(stub, fnProperty, types.isFunction(value) ? value : () => { return value; });
|
||||
return stub;
|
||||
}
|
||||
|
||||
interface SinonOptions {
|
||||
mock?: boolean;
|
||||
stub?: boolean;
|
||||
}
|
||||
Reference in New Issue
Block a user