import { types as t } from "@marko/compiler";
import { type Binding } from "./bindings";
import * as SlotKind from "./constants/slot-kind";
import { type Opt } from "./optional";
import { type Reason } from "./reasons";
import { type ParamReasonGroup, type Section } from "./sections";
type SlotKind = SlotKind.Value;
export { SlotKind };
export type BindingSlotKind = typeof SlotKind.Value | typeof SlotKind.ChangeHandler | typeof SlotKind.ClosureScopes | typeof SlotKind.ClosureSignalIndex | typeof SlotKind.BranchExpr | typeof SlotKind.ParamGroup;
export type SectionSlotKind = Exclude<SlotKind, BindingSlotKind>;
export type PlaceSlotKind = typeof SlotKind.Value | typeof SlotKind.ChangeHandler | typeof SlotKind.ClosureScopes | typeof SlotKind.ClosureSignalIndex | typeof SlotKind.Owner | typeof SlotKind.ReturnChangeHandler | typeof SlotKind.Instances;
/** A place in a scope that client code may read after resume, or a fact about
 * one a guard decides on (a condition changing, a branch or group resuming). */
export type Slot = BindingSlot | SectionSlot;
export type PlaceSlot = Slot & {
    kind: PlaceSlotKind;
};
interface BaseSlot {
    /** The scope it is in. */
    section: Section;
    /** The sources whose changes lead client code to read it after resume,
     * unset while nothing does. */
    reason: Reason | undefined;
    /** The expressions it holds or renders, whose sources its reason takes once
     * references finalize. */
    reasonExprs: Opt<t.NodeExtra>;
}
export interface BindingSlot extends BaseSlot {
    kind: BindingSlotKind;
    /** A canonical binding. */
    owner: Binding;
    /** The group it guards, for a param group. */
    group: ParamReasonGroup | undefined;
}
export interface SectionSlot extends BaseSlot {
    kind: SectionSlotKind;
    owner: Section;
    group: undefined;
}
export declare function ensureSlot(binding: Binding, kind?: BindingSlotKind, section?: Section, group?: ParamReasonGroup): Slot;
export declare function findSlot(binding: Binding): (BindingSlot & {
    kind: typeof SlotKind.Value;
}) | undefined;
export declare function findSlot<K extends BindingSlotKind>(binding: Binding, kind: K, section?: Section, group?: ParamReasonGroup): (BindingSlot & {
    kind: K;
}) | undefined;
export declare function ensureSectionSlot(owner: Section, kind: SectionSlotKind, section?: Section): Slot;
export declare function findSectionSlot<K extends SectionSlotKind>(owner: Section, kind: K, section?: Section): (SectionSlot & {
    kind: K;
}) | undefined;
