import { types as t } from "@marko/compiler"; import { ReservedId } from "../../common/types"; import * as BindingType from "./constants/binding-type"; import { type Opt, type SortedMany, type SortedOpt, Sorted } from "./optional"; import { type KnownExprs } from "./reasons"; import { type AssignedBindingExtra, type Read, type ReferencedExtra } from "./references"; import { type Section } from "./sections"; import { type Sources } from "./sources"; type BindingType = BindingType.Value; export { BindingType }; export interface Binding { /** Its scope accessor id, allocated per section once references finalize. */ id: number; /** Creation order, never renumbered: the order `bindingUtil` sorts by. */ uid: number; name: string; originalName: string | undefined; type: BindingType; loc: t.SourceLocation | null; section: Section; closureSections: SortedOpt
; /** The id its closure accessors take, past its section's and ancestors' ids. */ closureId: number | undefined; /** The identifier of each emitted assignment to it (set in finalize). */ assignments: Opt; sources: undefined | Sources; /** The intersection whose work computes it, or the nearest one it derives * from. Set on alias roots only. */ intersection: Intersection | undefined; /** The expressions its value is computed from, `false` for none; unset when * analysis cannot see them, which makes it its own source. */ derivedFrom: Opt | false; /** Its reads by expression, complete once `finalizeReferences` runs: pruning * hands an expression's reads to the nearest ancestor it also reads. */ reads: Map>; aliases: Set; /** The sections reading it through a hoist: its own or its ancestors, so * the first is the outermost. */ hoists: SortedOpt
; getters: Map; property: string | undefined; propertyAliases: Map; excludeProperties: SortedOpt; /** Its properties code assigns in place (`obj.x = 1`), all of them for a * computed one. */ assignedProperties: SortedOpt | true; aliasOf: Binding | undefined; /** The value these `` params iterate, by `of` or `in`. */ iterates: { expr: t.NodeExtra; type: "of" | "in"; } | undefined; /** For an array rest, the source index it starts at: `rest[0]` of * `[a, ...rest]` is the source's `[1]`. */ restOffset: number | undefined; /** For a tag variable a `` writes, the call's scope binding and, for * a known tag, its body and the expressions it passes. */ returnedBy: { scope: Binding; section?: Section; exprs?: KnownExprs; } | undefined; /** For the node a control flow tag renders at, the bodies it renders there: * an `` chain's in order, a loop's, an ``'s, a ``'s. */ branchBodies: Opt
; /** Scope ids it holds right after its own, up to its highest `ReservedId`: * a controllable ``'s change handler, or a tag's scope offset. */ reserveSize: number; scopeAccessor: string | undefined; /** A name declared for this value, or all of it but its `excludeProperties` * (a rest element), even once pruned. */ declaredAlias: Binding | undefined; /** The attribute tag `` param a local closure holds in its section. */ localOf: Binding | undefined; /** An attribute tag `` param's local closure in each content the loop * creates that reads it. */ localClosures: Map | undefined; /** Declared by its own name in its own section; an alias only in a pattern * holding a rest or where what it reads from is hidden from a read of it. */ declared: boolean; nullable: boolean; /** Settled only once `finalizeReferences` runs at program analyze exit. */ pruned: boolean | undefined; /** In a template's or ``'s params tree, which known call sites set * directly. */ exposed: boolean; /** Read on invocation from its own scope slot, so its signal stores it. */ hasLazyReads: boolean; } /** A param of a template or of a tag body, which its caller supplies. */ export interface ParamBinding extends Binding { type: typeof BindingType.param; } export type ReferencedBindings = SortedOpt; export type Intersection = SortedMany; /** Every member computed from one local source in the same pass, or the * intersection's own render id and the tag whose scope offset it renders after. */ export type IntersectionMeta = { source: Binding; id?: undefined; returnedBy?: undefined; } | { source: undefined; id: number; returnedBy: Binding | undefined; }; export interface Getter { hoisted: Section | false; invoked: boolean; } export declare const getBindings: () => Set; export declare function createBinding(name: string, type: Binding["type"], refSection: Section, aliased?: Binding["aliasOf"], property?: string, excludeProperties?: SortedOpt, loc?: t.SourceLocation | null, refDeclared?: boolean, restOffset?: number): Binding; export declare function reserveId(binding: Binding, offset: ReservedId): void; export declare function ensurePropertyAlias(binding: Binding, property: string): Binding; export declare function addAssignedProperty(binding: Binding, property: string | undefined): void; export declare function getAssignedObject(binding: Binding): Binding | undefined; export declare function getPropertyAlias(binding: Binding, properties: Opt): Binding | undefined; export declare function getDeepestPropertyAlias(binding: Binding, properties: Opt): Binding; export declare function compareReferences(a: ReferencedBindings, b: ReferencedBindings): number; /** * reference group priority is sorted by number of references, * then if needed by reference order. */ export declare function compareIntersections(a: Intersection, b: Intersection): number; export declare function getAliasRoot(binding: Binding): Binding; export declare const bindingUtil: Sorted; export declare const propsUtil: Sorted; export declare function getCanonicalBinding(binding: Binding): Binding; export declare function someAlias(binding: Binding, test: (binding: Binding, arg: A) => boolean, arg: A, directOnly?: boolean): boolean; export declare function someUpToAliasRoot(binding: Binding | undefined, test: (binding: Binding, arg: A) => boolean, arg: A): boolean; export declare function getNearestDeclared(binding: Binding): Binding | undefined; export declare function getDeclaredAlias(binding: Binding): false | Binding | undefined; export declare function isDirectAlias(binding: Binding): boolean; export declare function isRest(binding: Binding): boolean; export declare function getDebugAccess(binding: Binding, toParam: boolean, formatProperty: (property: string) => string): { root: Binding; access: string; }; export declare function isTemplateParam(binding: Binding): boolean; export declare function getDebugName(binding: Binding): string; export declare function getDebugNames(refs: ReferencedBindings): string; export declare function getDebugNamesAsIdentifier(refs: ReferencedBindings): string; export declare function isInvokeOnlyBinding(binding: Binding): boolean; export declare function isOwnBinding(binding: Binding): boolean; export declare function hasNonConstantPropertyAlias(ref: Binding): boolean; export declare function getPropertyPath(binding: Binding, ancestor: Binding): Opt; export declare function isIndexProperty(property: string): boolean;