1
>
/*---------------------------------------------------------------------------------------------
instantiation.ts
2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { DisposableStore } from '../../../base/common/lifecycle.js';
7
>
import * as descriptors from './descriptors.js';
8
>
import { ServiceCollection } from './serviceCollection.js';
9
>
10
>
// ------ internal util
11
>
12
>
export namespace _util {
13
>
14
>
export const serviceIds = new Map<string, ServiceIdentifier<any>>();
15
>
16
>
export const DI_TARGET = '$di$target';
17
>
export const DI_DEPENDENCIES = '$di$dependencies';
18
>
19
>
export function getServiceDependencies(ctor: DI_TARGET_OBJ): { id: ServiceIdentifier<any>; index: number }[] {
20
return ctor[DI_DEPENDENCIES] || [];
21
}
23
>
export interface DI_TARGET_OBJ extends Function {
24
>
[DI_TARGET]: Function;
25
>
[DI_DEPENDENCIES]: { id: ServiceIdentifier<any>; index: number }[];
26
>
}
27
>
}
28
>
29
>
// --- interfaces ------
30
>
31
>
export type BrandedService = { _serviceBrand: undefined };
32
>
33
>
export interface IConstructorSignature<T, Args extends any[] = []> {
34
>
new <Services extends BrandedService[]>(...args: [...Args, ...Services]): T;
35
>
}
36
>
37
>
export interface ServicesAccessor {
38
>
get<T>(id: ServiceIdentifier<T>): T;
39
>
}
40
>
41
>
export const IInstantiationService = createDecorator<IInstantiationService>('instantiationService');
42
>
43
>
/**
44
>
* Given a list of arguments as a tuple, attempt to extract the leading, non-service arguments
45
>
* to their own tuple.
46
>
*/
47
>
export type GetLeadingNonServiceArgs<TArgs extends any[]> =
48
>
TArgs extends [] ? []
49
>
: TArgs extends [...infer TFirst, BrandedService] ? GetLeadingNonServiceArgs<TFirst>
50
>
: TArgs;
51
>
52
>
export interface IInstantiationService {
53
>
54
>
readonly _serviceBrand: undefined;
55
>
56
>
/**
57
>
* Synchronously creates an instance that is denoted by the descriptor
58
>
*/
59
>
createInstance<T>(descriptor: descriptors.SyncDescriptor0<T>): T;
60
>
createInstance<Ctor extends new (...args: any[]) => unknown, R extends InstanceType<Ctor>>(ctor: Ctor, ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>): R;
61
>
62
>
/**
63
>
* Calls a function with a service accessor.
64
>
*/
65
>
invokeFunction<R, TS extends any[] = []>(fn: (accessor: ServicesAccessor, ...args: TS) => R, ...args: TS): R;
66
>
67
>
/**
68
>
* Creates a child of this service which inherits all current services
69
>
* and adds/overwrites the given services.
70
>
*
71
>
* NOTE that the returned child is `disposable` and should be disposed when not used
72
>
* anymore. This will also dispose all the services that this service has created.
73
>
*/
74
>
createChild(services: ServiceCollection, store?: DisposableStore): IInstantiationService;
75
>
76
>
/**
77
>
* Disposes this instantiation service.
78
>
*
79
>
* - Will dispose all services that this instantiation service has created.
80
>
* - Will dispose all its children but not its parent.
81
>
* - Will NOT dispose services-instances that this service has been created with
82
>
* - Will NOT dispose consumer-instances this service has created
83
>
*/
84
>
dispose(): void;
85
>
}
86
>
87
>
88
>
/**
89
>
* Identifies a service of type `T`.
90
>
*/
91
>
export interface ServiceIdentifier<T> {
92
>
(...args: any[]): void;
93
>
type: T;
94
>
}
95
>
96
>
97
function storeServiceDependency(id: ServiceIdentifier<unknown>, target: Function, index: number): void {
98
if ((target as _util.DI_TARGET_OBJ)[_util.DI_TARGET] === target) {