Path: blob/main/src/vs/platform/instantiation/common/instantiation.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { DisposableStore } from '../../../base/common/lifecycle.js';6import * as descriptors from './descriptors.js';7import { ServiceCollection } from './serviceCollection.js';89// ------ internal util1011export namespace _util {1213export const serviceIds = new Map<string, ServiceIdentifier<any>>();1415export const DI_TARGET = '$di$target';16export const DI_DEPENDENCIES = '$di$dependencies';1718export function getServiceDependencies(ctor: any): { id: ServiceIdentifier<any>; index: number }[] {19return ctor[DI_DEPENDENCIES] || [];20}21}2223// --- interfaces ------2425export type BrandedService = { _serviceBrand: undefined };2627export interface IConstructorSignature<T, Args extends any[] = []> {28new <Services extends BrandedService[]>(...args: [...Args, ...Services]): T;29}3031export interface ServicesAccessor {32get<T>(id: ServiceIdentifier<T>): T;33getIfExists<T>(id: ServiceIdentifier<T>): T | undefined;34}3536export const IInstantiationService = createDecorator<IInstantiationService>('instantiationService');3738/**39* Given a list of arguments as a tuple, attempt to extract the leading, non-service arguments40* to their own tuple.41*/42export type GetLeadingNonServiceArgs<TArgs extends any[]> =43TArgs extends [] ? []44: TArgs extends [...infer TFirst, BrandedService] ? GetLeadingNonServiceArgs<TFirst>45: TArgs;4647export interface IInstantiationService {4849readonly _serviceBrand: undefined;5051/**52* Synchronously creates an instance that is denoted by the descriptor53*/54createInstance<T>(descriptor: descriptors.SyncDescriptor0<T>): T;55createInstance<Ctor extends new (...args: any[]) => unknown, R extends InstanceType<Ctor>>(ctor: Ctor, ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>): R;5657/**58* Calls a function with a service accessor.59*/60invokeFunction<R, TS extends any[] = []>(fn: (accessor: ServicesAccessor, ...args: TS) => R, ...args: TS): R;6162/**63* Creates a child of this service which inherits all current services64* and adds/overwrites the given services.65*66* NOTE that the returned child is `disposable` and should be disposed when not used67* anymore. This will also dispose all the services that this service has created.68*/69createChild(services: ServiceCollection, store?: DisposableStore): IInstantiationService;7071/**72* Disposes this instantiation service.73*74* - Will dispose all services that this instantiation service has created.75* - Will dispose all its children but not its parent.76* - Will NOT dispose services-instances that this service has been created with77* - Will NOT dispose consumer-instances this service has created78*/79dispose(): void;80}818283/**84* Identifies a service of type `T`.85*/86export interface ServiceIdentifier<T> {87(...args: any[]): void;88type: T;89}9091function storeServiceDependency(id: Function, target: Function, index: number): void {92if ((target as any)[_util.DI_TARGET] === target) {93(target as any)[_util.DI_DEPENDENCIES].push({ id, index });94} else {95(target as any)[_util.DI_DEPENDENCIES] = [{ id, index }];96(target as any)[_util.DI_TARGET] = target;97}98}99100/**101* The *only* valid way to create a {{ServiceIdentifier}}.102*/103export function createDecorator<T>(serviceId: string): ServiceIdentifier<T> {104105if (_util.serviceIds.has(serviceId)) {106return _util.serviceIds.get(serviceId)!;107}108109const id = <any>function (target: Function, key: string, index: number) {110if (arguments.length !== 3) {111throw new Error('@IServiceName-decorator can only be used to decorate a parameter');112}113storeServiceDependency(id, target, index);114};115116id.toString = () => serviceId;117118_util.serviceIds.set(serviceId, id);119return id;120}121122export function refineServiceDecorator<T1, T extends T1>(serviceIdentifier: ServiceIdentifier<T1>): ServiceIdentifier<T> {123return <ServiceIdentifier<T>>serviceIdentifier;124}125126127