import { types as t } from "@marko/compiler";
import { type Many, type Opt, Sorted } from "./optional";
import { type Section } from "./sections";
import { type SerializeReason } from "./serialize-reasons";
import { type Signal } from "./signals";
export declare const kBranchSerializeReason: unique symbol;
export type Aliases = undefined | Binding | {
    [property: string]: Aliases;
};
export declare enum BindingType {
    dom = 0,
    let = 1,
    input = 2,
    param = 3,
    local = 4,
    derived = 5,
    constant = 6
}
export interface Sources {
    state: Opt<Binding>;
    param: Opt<InputBinding | ParamBinding>;
}
export interface Binding {
    id: number;
    name: string;
    originalName: string | undefined;
    type: BindingType;
    loc: t.SourceLocation | null;
    section: Section;
    closureSections: Opt<Section>;
    assignmentSections: Opt<Section>;
    sources: undefined | Sources;
    reads: Set<ReferencedExtra>;
    aliases: Set<Binding>;
    hoists: Opt<Section>;
    getters: Map<Getter["hoisted"], boolean>;
    property: string | undefined;
    propertyAliases: Map<string, Binding>;
    excludeProperties: Opt<string>;
    noSerialize: boolean;
    noSerializeProperties: Opt<string>;
    upstreamAlias: Binding | undefined;
    restOffset: number | undefined;
    scopeOffset: Binding | undefined;
    scopeAccessor: string | undefined;
    export: string | undefined;
    declared: boolean;
    nullable: boolean;
    pruned: boolean | undefined;
}
export interface InputBinding extends Binding {
    type: BindingType.input;
}
export interface ParamBinding extends Binding {
    type: BindingType.param;
}
export type ReferencedBindings = Opt<Binding>;
export type Intersection = Many<Binding>;
interface ReferencedFunctionExtra extends t.FunctionExtra, ReferencedExtra {
}
export interface Getter {
    hoisted: Section | false;
    invoked: boolean;
}
interface Read {
    binding: Binding;
    extra: t.NodeExtra;
    ownVar: boolean;
    getter: Getter | undefined;
}
interface ExtraRead {
    binding: Binding;
    props: Opt<string>;
    ownVar: boolean;
    getter: Getter | undefined;
}
declare module "@marko/compiler/dist/types" {
    interface NodeExtra {
        section?: Section;
        referencedBindings?: ReferencedBindings;
        downstream?: Opt<Binding>;
        binding?: Binding;
        assignment?: Binding;
        assignmentTo?: Binding;
        read?: ExtraRead;
        pruned?: true;
        isEffect?: true;
        spreadFrom?: Binding;
        nativeTagSpread?: true;
        nativeTagSpreadMerged?: true;
        merged?: NodeExtra;
    }
    interface FunctionExtra {
        referencesScope?: boolean;
        referencedBindingsInFunction?: ReferencedBindings;
        constantBindingsInFunction?: ReferencedBindings;
        name?: string;
        registerId?: string;
        registerReason?: SerializeReason;
    }
    interface ArrowFunctionExpressionExtra extends FunctionExtra {
    }
    interface FunctionDeclarationExtra extends FunctionExtra {
    }
    interface FunctionExpressionExtra extends FunctionExtra {
    }
}
export declare function createBinding(name: string, type: Binding["type"], refSection: Section, upstreamAlias?: Binding["upstreamAlias"], property?: string, excludeProperties?: Opt<string>, loc?: t.SourceLocation | null, refDeclared?: boolean): Binding;
export declare function getOrCreatePropertyAlias(binding: Binding, property: string): Binding;
export declare function trackDomVarReferences(tag: t.NodePath<t.MarkoTag>, binding: Binding): Binding | undefined;
export declare function trackVarReferences(tag: t.NodePath<t.MarkoTag>, type: BindingType, upstreamAlias?: Binding["upstreamAlias"]): Binding | undefined;
export declare function trackParamsReferences(body: t.NodePath<t.MarkoTagBody | t.Program>, type: BindingType): Binding | undefined;
export declare function isReferenceInOwnBody(bindingPath: t.NodePath, reference: t.NodePath): boolean;
export declare function isReferenceHoisted(bindingPath: t.NodePath, reference: t.NodePath): boolean;
export declare function setReferencesScope(path: t.NodePath<any>): void;
export declare function mergeReferences<T extends t.Node>(section: Section, target: T, nodes: (t.Node | undefined)[]): NonNullable<T["extra"]> & ReferencedExtra;
export declare function compareReferences(a: ReferencedBindings, b: ReferencedBindings): number;
export declare function finalizeReferences(): void;
export declare const intersectionMeta: WeakMap<Intersection, {
    id: number;
    scopeOffset: Binding | undefined;
}>;
export declare function setBindingDownstream(binding: Binding, expr: boolean | Opt<t.NodeExtra>): void;
export declare function createSources(state: Sources["state"], param: Sources["param"]): Sources;
export declare function compareSources(a: Sources, b: Sources): number;
export declare function mergeSources(a: undefined | Sources, b: undefined | Sources): Sources | undefined;
export declare const bindingUtil: Sorted<Binding>;
export declare const propsUtil: Sorted<string>;
export declare function addRead(exprExtra: ReferencedExtra, extra: t.NodeExtra, binding: Binding, section: Section, getter: Getter | undefined): Read;
export declare function dropNodes(node: t.Node | t.Node[]): void;
export declare function getCanonicalBinding(binding: Binding): Binding;
export declare function getAllTagReferenceNodes(tag: t.MarkoTag, referenceNodes?: t.Node[]): t.Node[];
export declare function getScopeAccessorLiteral(binding: Binding, encoded?: boolean, includeId?: boolean): t.NumericLiteral | t.StringLiteral;
export declare function getScopeAccessor(binding: Binding, encoded?: boolean, includeId?: boolean): string;
export declare function getDebugScopeAccess(binding: Binding): {
    root: Binding;
    access: string;
};
export declare function getDebugName(binding: Binding): string;
export declare function getDebugNames(refs: ReferencedBindings): string;
export declare function getDebugNamesAsIdentifier(refs: ReferencedBindings): string;
export declare function getSectionInstancesAccessor(section: Section): string;
export declare function getSectionInstancesAccessorLiteral(section: Section): t.NumericLiteral | t.StringLiteral | undefined;
export declare function getReadReplacement(node: t.Identifier | t.MemberExpression | t.OptionalMemberExpression, signal?: Signal): t.Expression | undefined;
export declare function hasNonConstantPropertyAlias(ref: Binding): boolean;
export declare function pruneBinding(binding: Binding): boolean;
export declare function createRead(binding: Binding, props: Opt<string>, ownVar?: boolean): ExtraRead;
export declare function createGetterRead(binding: Binding, props: Opt<string>, getter: Getter): ExtraRead;
export interface ReferencedExtra extends t.NodeExtra {
    section: Section;
}
export declare function isReferencedExtra(extra: t.NodeExtra | undefined): extra is ReferencedExtra;
export interface AssignedBindingExtra extends ReferencedExtra {
    assignment: Binding;
    assignmentFunction: ReferencedFunctionExtra;
}
export declare function isAssignedBindingExtra(extra: t.NodeExtra | undefined): extra is AssignedBindingExtra;
export interface RegisteredFnExtra extends ReferencedExtra, t.FunctionExtra {
    name: string;
    registerId: string;
    registerReason: SerializeReason;
}
export declare function isRegisteredFnExtra(extra: t.NodeExtra | undefined): extra is RegisteredFnExtra;
export declare function getCanonicalExtra<T extends t.NodeExtra>(extra: T): T;
export declare function getAllSerializeReasonsForExtra(extra: t.NodeExtra): undefined | SerializeReason;
export declare function getAllSerializeReasonsForBinding(binding: Binding, properties?: Opt<string> | true): undefined | SerializeReason;
export {};
