import { Program } from "../core/program.js"; import { Decorator, FunctionParameter, IntrinsicType, Namespace, TemplateParameter, Type } from "../core/types.js"; import { Realm } from "./realm.js"; /** * A description of how a specific kind of type should be mutated. * * This can either be an object specifying an optional `filter` function and one of `mutate` or `replace`, or simply a * function that mutates the type. * * If a function is provided, it is equivalent to providing an object with a `mutate` function and no `filter` function. * * @experimental */ export type MutatorRecord = MutatorReplaceRecord | MutatorMutateRecord | MutatorFn; /** * Common functionality for mutator records. * * @experimental */ export interface MutatorRecordCommon { /** * A filter function that determines if the mutator should be applied to the type. */ filter?: MutatorFilterFn; } /** * A mutator that replaces a type's clone with a new type instance. * * @experimental */ export interface MutatorReplaceRecord extends MutatorRecordCommon { /** * A mutator function that returns a new type instance to replace the cloned type instance. */ replace: MutatorReplaceFn; } /** * A mutator that changes the clone of a type in place. * * @experimental */ export interface MutatorMutateRecord extends MutatorRecordCommon { /** * A mutator function that edits the clone of the type in place. */ mutate: MutatorFn; } /** * Edits the clone of the type in place. This function _SHOULD NOT_ modify the source type. * * @see {@link mutateSubgraph} * * @param sourceType - The source type. * @param clone - The clone of the source type to mutate. * @param program - The program in which the `sourceType` occurs. * @param realm - The realm in which the `clone` resides. * * @experimental */ export type MutatorFn = (sourceType: T, clone: T, program: Program, realm: Realm) => void; /** * Determines if the mutator should be applied to the type. * * This function may either return a boolean or {@link MutatorFlow} flags: * * - If `true`, the mutator will be applied and will recur (equivalent to `MutatorFlags.MutateAndRecur`). * - If `false`, the mutator will not be applied and will recur (equivalent to `MutatorFlags.DoNotMutate`). * * This predicate runs before the type is cloned. * * @param sourceType - The source type. * @param program - The program in which the `sourceType` occurs. * @param realm - The realm where the `sourceType` will be cloned, if this type is mutated. * * @returns a boolean or {@link MutatorFlow} flags. * * @experimental */ export type MutatorFilterFn = (sourceType: T, program: Program, realm: Realm) => boolean | MutatorFlow; /** * A function that replaces a mutable type with a new type instance. * * Returning `clone` from this function is equivalent to providing a `mutate` function instead of a `replace` function. * * This function runs after the `sourceType` is cloned within the realm. * * @param sourceType - The source type. * @param clone - The clone of the source type to mutate. * @param program - The program in which the `sourceType` occurs. * @param realm - The realm in which the `clone` resides. * * @returns a new type instance to replace the cloned type instance. * * @experimental */ export type MutatorReplaceFn = (sourceType: T, clone: T, program: Program, realm: Realm) => Type; /** * Mutators describe procedures for mutating types in the type graph. * * Each entry in the mutator describes how to mutate a specific type of node. * * See {@link mutateSubgraph}. * * @experimental */ export type Mutator = { /** * The name of this mutator. */ name: string; } & { [Kind in MutableType["kind"]]?: MutatorRecord>; }; /** * A mutator that can additionally mutate namespaces. * * @experimental */ export type MutatorWithNamespace = Mutator & Partial; type NamespaceMutator = { Namespace?: MutatorRecord; }; /** * Flow control for mutators. * * When filtering types in a mutator, the filter function may return MutatorFlow flags to control how mutation should * proceed. * * @see {@link MutatorFilterFn} * * @experimental */ export declare enum MutatorFlow { /** * Mutate the type and recur, further mutating the type's children. This is the default behavior. */ MutateAndRecur = 0, /** * If this flag is set, the type will not be mutated. */ DoNotMutate = 1, /** * If this flag is set, the mutator will not proceed recursively into the children of the type. */ DoNotRecur = 2 } /** * A type that can be mutated. * * @see {@link mutateSubgraph} * * @experimental */ export type MutableType = Exclude; /** * Determines if a type is mutable. * * @experimental */ export declare function isMutableType(type: Type): type is MutableType; /** * A mutable type, inclusive of namespaces. * * @experimental */ export type MutableTypeWithNamespace = MutableType | Namespace; /** * Mutate the type graph, allowing namespaces to be mutated. * * **Warning**: This function will likely mutate the entire type graph. Most TypeSpec types relate to namespaces * in some way (e.g. through namespace parent links, or the `namespace` property of a Model). * * @param program - The program in which the `type` occurs. * @param mutators - An array of mutators to apply to the type graph rooted at `type`. * @param type - The type to mutate. * * @returns an object containing the mutated `type` and a nullable `Realm` in which the mutated type resides. * * @see {@link mutateSubgraph} * * @experimental */ export declare function mutateSubgraphWithNamespace(program: Program, mutators: MutatorWithNamespace[], type: Namespace): { realm: Realm | null; type: MutableTypeWithNamespace; }; /** * Mutate the type graph. * * Mutators clone the input `type`, creating a new type instance that is mutated in place. * * The mutator returns the mutated type and optionally a `realm` in which the mutated clone resides. * * @see {@link Mutator} * @see {@link Realm} * * **Warning**: Mutators _SHOULD NOT_ modify the source type. Modifications to the source type * will be visible to other emitters or libraries that view the original source type, and will * be sensitive to the order in which the mutator was applied. Only edit the `clone` type. * Furthermore, mutators must take care not to modify elements of the source and clone types * that are shared between the two types, such as the properties of any parent references * or the `decorators` of the type without taking care to clone them first. * * @param program - The program in which the `type` occurs. * @param mutators - An array of mutators to apply to the type graph rooted at `type`. * @param type - The type to mutate. * * @returns an object containing the mutated `type` and a nullable `Realm` in which the mutated type resides. * * @experimental */ export declare function mutateSubgraph(program: Program, mutators: Mutator[], type: T): { realm: Realm | null; type: MutableType; }; export {}; //# sourceMappingURL=mutators.d.ts.map