debt - use Map for service collection

This commit is contained in:
Johannes Rieken
2017-01-09 12:07:34 +01:00
parent 5819ecc86b
commit 32d16d301f
2 changed files with 19 additions and 45 deletions

View File

@@ -12,6 +12,8 @@ import * as descriptors from './descriptors';
export namespace _util {
export const serviceIds = new Map<string, ServiceIdentifier<any>>();
export const DI_TARGET = '$di$target';
export const DI_DEPENDENCIES = '$di$dependencies';
@@ -98,7 +100,7 @@ export interface IFunctionSignature8<A1, A2, A3, A4, A5, A6, A7, A8, R> {
(accessor: ServicesAccessor, first: A1, second: A2, third: A3, forth: A4, fifth: A5, sixth: A6, seventh: A7, eigth: A8): R;
}
export var IInstantiationService = createDecorator<IInstantiationService>('instantiationService');
export const IInstantiationService = createDecorator<IInstantiationService>('instantiationService');
export interface IInstantiationService {
@@ -185,7 +187,11 @@ function storeServiceDependency(id: Function, target: Function, index: number, o
*/
export function createDecorator<T>(serviceId: string): { (...args: any[]): void; type: T; } {
let id = function (target: Function, key: string, index: number): any {
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');
}
@@ -194,7 +200,8 @@ export function createDecorator<T>(serviceId: string): { (...args: any[]): void;
id.toString = () => serviceId;
return <any>id;
_util.serviceIds.set(serviceId, id);
return id;
}
/**

View File

@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { binarySearch } from 'vs/base/common/arrays';
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
import { SyncDescriptor } from './descriptors';
@@ -12,61 +11,29 @@ type Entry = [ServiceIdentifier<any>, any];
export class ServiceCollection {
private _entries: Entry[] = [];
private _entries = new Map<ServiceIdentifier<any>, any>();
constructor(...entries: [ServiceIdentifier<any>, any][]) {
for (let entry of entries) {
this.set(entry[0], entry[1]);
for (let [id, service] of entries) {
this.set(id, service);
}
}
set<T>(id: ServiceIdentifier<T>, instanceOrDescriptor: T | SyncDescriptor<T>): T | SyncDescriptor<T> {
const entry: Entry = [id, instanceOrDescriptor];
const idx = binarySearch(this._entries, entry, ServiceCollection._entryCompare);
if (idx < 0) {
// new element
this._entries.splice(~idx, 0, entry);
} else {
const old = this._entries[idx];
this._entries[idx] = entry;
return old[1];
}
const result = this._entries.get(id);
this._entries.set(id, instanceOrDescriptor);
return result;
}
forEach(callback: (id: ServiceIdentifier<any>, instanceOrDescriptor: any) => any): void {
for (let entry of this._entries) {
let [id, instanceOrDescriptor] = entry;
callback(id, instanceOrDescriptor);
}
this._entries.forEach((value, key) => callback(key, value));
}
has(id: ServiceIdentifier<any>): boolean {
return binarySearch(this._entries, ServiceCollection._searchEntry(id), ServiceCollection._entryCompare) >= 0;
return this._entries.has(id);
}
get<T>(id: ServiceIdentifier<T>): T | SyncDescriptor<T> {
const idx = binarySearch(this._entries, ServiceCollection._searchEntry(id), ServiceCollection._entryCompare);
if (idx >= 0) {
return this._entries[idx][1];
}
}
private static _dummy: Entry = [undefined, undefined];
private static _searchEntry(id: ServiceIdentifier<any>): Entry {
ServiceCollection._dummy[0] = id;
return ServiceCollection._dummy;
}
private static _entryCompare(a: Entry, b: Entry): number {
const _a = a[0].toString();
const _b = b[0].toString();
if (_a < _b) {
return -1;
} else if (_a > _b) {
return 1;
} else {
return 0;
}
return this._entries.get(id);
}
}