Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)

* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973

* disable strict null check
This commit is contained in:
Anthony Dresser
2019-07-15 22:35:46 -07:00
committed by GitHub
parent f720ec642f
commit 0b7e7ddbf9
2406 changed files with 59140 additions and 35464 deletions

View File

@@ -6,18 +6,12 @@
import { SyncDescriptor } from './descriptors';
import { ServiceIdentifier, IConstructorSignature0 } from './instantiation';
export interface IServiceContribution<T> {
id: ServiceIdentifier<T>;
descriptor: SyncDescriptor<T>;
}
const _registry: IServiceContribution<any>[] = [];
const _registry: [ServiceIdentifier<any>, SyncDescriptor<any>][] = [];
export function registerSingleton<T>(id: ServiceIdentifier<T>, ctor: IConstructorSignature0<T>, supportsDelayedInstantiation?: boolean): void {
_registry.push({ id, descriptor: new SyncDescriptor<T>(ctor, [], supportsDelayedInstantiation) });
_registry.push([id, new SyncDescriptor<T>(ctor, [], supportsDelayedInstantiation)]);
}
export function getServices(): IServiceContribution<any>[] {
export function getSingletonServiceDescriptors(): [ServiceIdentifier<any>, SyncDescriptor<any>][] {
return _registry;
}

View File

@@ -59,7 +59,8 @@ export interface IConstructorSignature8<A1, A2, A3, A4, A5, A6, A7, A8, T> {
}
export interface ServicesAccessor {
get<T>(id: ServiceIdentifier<T>, isOptional?: typeof optional): T;
get<T>(id: ServiceIdentifier<T>): T;
get<T>(id: ServiceIdentifier<T>, isOptional: typeof optional): T | undefined;
}
export const IInstantiationService = createDecorator<IInstantiationService>('instantiationService');
@@ -114,11 +115,11 @@ export interface ServiceIdentifier<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 });
if ((target as any)[_util.DI_TARGET] === target) {
(target as any)[_util.DI_DEPENDENCIES].push({ id, index, optional });
} else {
target[_util.DI_DEPENDENCIES] = [{ id, index, optional }];
target[_util.DI_TARGET] = target;
(target as any)[_util.DI_DEPENDENCIES] = [{ id, index, optional }];
(target as any)[_util.DI_TARGET] = target;
}
}

View File

@@ -19,13 +19,20 @@ const _enableTracing = false;
declare var Proxy: any;
const _canUseProxy = typeof Proxy === 'function';
class CyclicDependencyError extends Error {
constructor(graph: Graph<any>) {
super('cyclic dependency between services');
this.message = graph.toString();
}
}
export class InstantiationService implements IInstantiationService {
_serviceBrand: any;
protected readonly _services: ServiceCollection;
protected readonly _strict: boolean;
protected readonly _parent?: InstantiationService;
private readonly _services: ServiceCollection;
private readonly _strict: boolean;
private readonly _parent?: InstantiationService;
constructor(services: ServiceCollection = new ServiceCollection(), strict: boolean = false, parent?: InstantiationService) {
this._services = services;
@@ -143,28 +150,19 @@ export class InstantiationService implements IInstantiationService {
type Triple = { id: ServiceIdentifier<any>, desc: SyncDescriptor<any>, _trace: Trace };
const graph = new Graph<Triple>(data => data.id.toString());
function throwCycleError() {
const err = new Error('[createInstance] cyclic dependency between services');
err.message = graph.toString();
throw err;
}
let count = 0;
let cycleCount = 0;
const stack = [{ id, desc, _trace }];
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
// {{SQL CARBON EDIT}} we hit ~102 with our services; when they implement graph cycle; we can remove
if (count++ > 200) {
throwCycleError();
// a weak but working heuristic for cycle checks
if (cycleCount++ > 150) { // {{SQL CARBON EDIT}} we hit ~102 with our services
throw new CyclicDependencyError(graph);
}
// check all dependencies for existence and if they need to be created first
let dependencies = _util.getServiceDependencies(item.desc.ctor);
for (let dependency of dependencies) {
for (let dependency of _util.getServiceDependencies(item.desc.ctor)) {
let instanceOrDesc = this._getServiceInstanceOrDescriptor(dependency.id);
if (!instanceOrDesc && !dependency.optional) {
@@ -180,18 +178,18 @@ export class InstantiationService implements IInstantiationService {
}
while (true) {
let roots = graph.roots();
const 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.isEmpty()) {
throwCycleError();
throw new CyclicDependencyError(graph);
}
break;
}
for (let { data } of roots) {
for (const { data } of roots) {
// create instance and overwrite the service collections
const instance = this._createServiceInstanceWithOwner(data.id, data.desc.ctor, data.desc.staticArguments, data.desc.supportsDelayedInstantiation, data._trace);
this._setServiceInstance(data.id, instance);
@@ -224,10 +222,10 @@ export class InstantiationService implements IInstantiationService {
const idle = new IdleValue(() => this._createInstance<T>(ctor, args, _trace));
return <T>new Proxy(Object.create(null), {
get(_target: T, prop: PropertyKey): any {
return idle.getValue()[prop];
return (idle.getValue() as any)[prop];
},
set(_target: T, p: PropertyKey, value: any): boolean {
idle.getValue()[p] = value;
(idle.getValue() as any)[p] = value;
return true;
}
});