import type { AgencyNode } from "../types.js"; /** - "liftable": the pass lifts a call or checked cast out of here. * - "stuck": inside a body the pass rewrites, in a position it leaves * inline. Moving the expression to its own statement makes it liftable. * - "outsideBodies": a module-level initializer or a parameter default. * The pass never enters these, so there is no statement to move to. * - "handlerBody": inside a handler body, which the pass never touches. */ export type HoistStatus = "liftable" | "stuck" | "outsideBodies" | "handlerBody"; export type HoistPosition = { node: AgencyNode; status: HoistStatus; }; /** * Every node under `nodes` with where it stands for the hoist pass. * hoistPositions.test.ts checks this against the pass itself. * * Which AST this reads. The type checker calls this with guards already * desugared and with `parallel` and `seq` blocks still present. The pass runs * later, after a parallel block has become a fork call and a seq block has * been inlined. Ruling: statements inside a parallel or seq block are treated * as ordinary body statements, which is what they become. The agreement test * runs the production desugars before the pass, so this ruling is checked. * * What "liftable" means. The pass MAY lift from this position. The last value * of an assignment, return, or match yield is liftable and still not lifted, * because it is already the statement's own step (the tail rule in * hoistCalls.ts). * * What is never examined. `hole` and `codeLiteral` are leaves in * expressionSlots, so a cast inside quoted code is not listed here. It is * checked when the completed program compiles. */ export declare function hoistPositions(nodes: AgencyNode[]): HoistPosition[];