SQL Operations Studio Public Preview 1 (0.23) release source code

This commit is contained in:
Karl Burtram
2017-11-09 14:30:27 -08:00
parent b88ecb8d93
commit 3cdac41339
8829 changed files with 759707 additions and 286 deletions

View 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>;
}

View 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;
}

View 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);
};
}

View 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);
}
}

View 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);
}
}

View File

@@ -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);
});
});

View File

@@ -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;
}