import type { PipelineStages, TSNodeLike } from './types.ts';
import { ProcessSubDirection, Redirect } from './types.ts';
export declare function getText(node: TSNodeLike): string;
/** The root of the tree `node` belongs to. */
export declare function treeRoot(node: TSNodeLike): TSNodeLike;
/**
 * Whether `after` stands on `before`'s line within `root`: no newline between
 * them. The parse has joined continued lines and folded each heredoc body
 * into its statement, so a newline between two statements is a line break.
 * Mirrors Python's same_line.
 */
export declare function sameLine(root: TSNodeLike, before: TSNodeLike, after: TSNodeLike): boolean;
/**
 * The row the shell began reading `node`'s command on. bash reads a whole
 * line before running any of it, and a complete command spanning lines
 * whole, with the rest of the line it ends on: a command after a `;`, or
 * inside a group that spans rows, was read with the ones before it. Mirrors
 * Python's read_row.
 */
export declare function readRow(node: TSNodeLike): number;
/**
 * A node's children with the source text between them, the twin of
 * python's `source_parts`.
 *
 * The parser consumes some text without giving it a node:
 * whitespace and newlines inside a double-quoted string, and the whitespace
 * or line continuation opening a `${v:-word}` operand. Only the node's own
 * source still holds that text, so it is sliced out between child extents
 * rather than rebuilt from row or byte counts, which lose tabs, newlines and
 * escapes. The parser counts `startIndex` here in UTF-16 code units, the
 * units `text.slice` takes.
 */
export declare function sourceParts(node: TSNodeLike): Generator<string | TSNodeLike>;
/**
 * Walk a double-quoted string without losing scanner-owned text.
 *
 * The text between children is the string's own, and the closing quote
 * token can carry the whitespace before it. Expansion nodes keep their own
 * folded prefixes.
 */
export declare function quotedParts(node: TSNodeLike): Generator<string | TSNodeLike>;
/**
 * Where an index into a node's text falls in the parser's offsets, the twin
 * of python's `byte_offset`.
 *
 * The Python parser places a node by the bytes of the UTF-8 source, so an
 * index counted in code units reads one place too early for every
 * multibyte character before it. `grep -ob` reads the same answer for the
 * same reason.
 * `encodeText` rather than `TextEncoder` because a byte that is not valid
 * UTF-8 rides as a surrogate escape and stands for one byte. That is a
 * requirement on the caller, not a hope: grep's family decodes every line
 * through `decodeText` for it.
 */
export declare function byteOffset(text: string, index: number): number;
export declare function getCommandName(node: TSNodeLike): string;
export declare function getParts(node: TSNodeLike): TSNodeLike[];
/**
 * Whether unquoted text holds a brace expansion (`{a,b}`, `{1..3}`),
 * which the shell turns into several words.
 */
export declare function braceExpands(text: string): boolean;
/**
 * The text a word names before any expansion, or null.
 *
 * A word is literal when nothing in it waits on the shell: a plain
 * word, a number, a quoted string with no expansion inside, or a
 * concatenation of those. Quotes are removed, escapes resolved and a
 * leading unquoted `~` expanded the way expansion would (`home` null
 * leaves it literal, as bash does with no `$HOME`). A word carrying a
 * parameter, command, arithmetic or process substitution, or a brace
 * expression, answers null: what it names is known only when it runs.
 */
export declare function literalWord(node: TSNodeLike, home?: string | null): string | null;
/** Split FOO=1 BAR=2 cmd parts into [assignments, remaining]. */
export declare function splitEnvPrefix(parts: TSNodeLike[]): [TSNodeLike[], TSNodeLike[]];
export declare function getPipelineCommands(node: TSNodeLike): [TSNodeLike[], boolean[]];
/**
 * A pipeline's stages as bash reads them, whatever shape the parse gave
 * them.
 *
 * The parser lets a redirect close over everything to its left up
 * to the next pipe, so `a && b | c < f | d` parses as a pipeline whose
 * first stage is `redirected(a && b | c, < f)`, and `! a < f | b` as one
 * whose first stage is `redirected(! a, < f)`. Bash reads them as
 * `a && (b | c <f | d)` and `! (a <f | b)`: the redirect binds to the
 * command it follows, the stages on both sides of it are one pipeline, a
 * `!` negates all of it, and a list the parse pulled into the first
 * stage runs ahead of the pipeline and decides whether it runs at all.
 * This is the last-command chain the admission gate climbs for a
 * redirect's target (`statementRedirects`), read in the direction the
 * executor walks. `redirects` are hoisted over the whole pipeline and
 * bind to its last stage.
 */
export declare function getPipelineStages(node: TSNodeLike, redirects?: readonly Redirect[]): PipelineStages;
export declare function getWhileParts(node: TSNodeLike): [TSNodeLike[], TSNodeLike[]];
/**
 * Get (variable, values, bodyCommands) from for/select. `values` is null for
 * a header with no `in` (`for f do`), which loops over `"$@"`.
 */
export declare function getForParts(node: TSNodeLike): [string, TSNodeLike[] | null, TSNodeLike[]];
/**
 * ([init, cond, update], body) from a C-style for. The expression slots
 * are positional between the (( )) delimiters, separated by `;` tokens,
 * and any of them may be empty: `for ((;;))`. A slot holds every node and
 * token the parser found in it, in order, commas and stray operators
 * included, since bash evaluates the slot's text as one expression: `for
 * ((a=1, i=0; ...))` assigns both, and `i<1 2` is an error, not two
 * expressions.
 */
export declare function getCforParts(node: TSNodeLike): [TSNodeLike[][], TSNodeLike[]];
/**
 * Whether a statement's terminator is `&`.
 *
 * The parser puts the `&` beside the statement it ends, inside whatever
 * body holds them both, so a body read as named children (every
 * extractor above) never sees it. Asking the statement about its own
 * next sibling is what lets a loop body, an if/case arm, a brace group
 * and a function body launch the job the program loop launches for a
 * top-level `cmd &`.
 */
export declare function isBackgrounded(node: TSNodeLike): boolean;
export declare const REDIRECT_NODE_TYPES: ReadonlySet<string>;
/**
 * Parse all redirects from a redirected_statement.
 *
 * Returns [command, redirects]; command is null for a bare redirect
 * like `> file` (bash runs the empty command and applies redirects,
 * creating/truncating the file).
 */
export declare function getRedirects(node: TSNodeLike): [TSNodeLike | null, Redirect[]];
/**
 * The redirects written among a simple command's words, in order: bash
 * applies them wherever they stand (`> f echo hi`, `cat <<< x`).
 */
export declare function commandRedirects(node: TSNodeLike): Redirect[];
/**
 * Redirects hoisted onto a command, after the ones written among its words:
 * bash applies them in source order (`true && > a echo > b`). Mirrors
 * Python's with_own_redirects.
 */
export declare function withOwnRedirects(command: TSNodeLike, redirects: readonly Redirect[]): Redirect[];
export declare function getListParts(node: TSNodeLike): [TSNodeLike, string | null, TSNodeLike];
export declare function getIfBranches(node: TSNodeLike): [[TSNodeLike[], TSNodeLike[]][], TSNodeLike[] | null];
export declare function getCaseWord(node: TSNodeLike): TSNodeLike;
/**
 * Get (patternNodes, bodyStatements, terminator) triples from case.
 *
 * Patterns are every named child before the arm's `)`, kept as nodes so
 * quoting survives to the matcher: 'a'), "$x") and $'a\n') all mean literal
 * text where a bare word keeps its globs live. An arm's body is every
 * statement up to its terminator, so multi-statement arms
 * (x) cmd1; cmd2;;) keep all commands.
 */
export declare function getCaseItems(node: TSNodeLike): [TSNodeLike[], TSNodeLike[], string][];
export declare function getDeclarationKeyword(node: TSNodeLike): string;
/**
 * Get every operand word of an unset_command, keeping `-f`/`-v`/`-n` and
 * keeping a subscript target (`unset arr[1]`, quoted or not) as one word.
 * A redirect among or before the words is no operand. Mirrors Python's
 * `get_unset_args`.
 */
export declare function getUnsetArgs(node: TSNodeLike): string[];
/** The command a `!` negates; null for a bare `!`, which negates the empty command. */
export declare function getNegatedCommand(node: TSNodeLike): TSNodeLike | null;
export declare function getProcessSubDirection(node: TSNodeLike): ProcessSubDirection | null;
/**
 * Bash's single-file command substitution, measured against 5.2.37.
 * Only a lone foreground `< file` (optionally `0<`) reads input into
 * the substitution. Extra redirects, commands, heredocs and descriptor
 * duplication retain ordinary redirect-only semantics.
 */
export declare function inputSubstitutionRedirect(node: TSNodeLike): Redirect | null;
/** A process substitution's command text, with the heredoc bodies the line
 * reads after it moved inside it. */
export declare function getProcessSubBody(node: TSNodeLike): string;
export declare function getFunctionName(node: TSNodeLike): string;
/**
 * Get function body commands: the compound_statement's children, or any
 * other compound command (`f() ( ... )`) as the one statement. The redirects
 * a definition carries, its own and those of a statement it is the body of
 * (`f() { ...; } >o 2>&1`), apply at every call, as bash's do, so then the
 * body is one statement: the group under them. Mirrors Python's
 * get_function_body.
 */
/**
 * The redirects a function definition carries: its own, and those of a
 * statement it is the body of (`f() { ...; } >o 2>&1`, whose second
 * redirect the parser hangs on a redirected_statement around it).
 */
export declare function getFunctionRedirects(node: TSNodeLike): TSNodeLike[];
/** The definition's source, including redirects and heredoc bodies. */
export declare function getFunctionSource(node: TSNodeLike): string;
/** Parse one stored definition inside the caller's owned parse scope. */
export declare function parseFunction(source: string, parse: (source: string) => TSNodeLike): TSNodeLike[];
export declare function getFunctionBody(node: TSNodeLike): TSNodeLike[] | null;
/**
 * What an unquoted plain word parses as: the only words bash checks for an
 * alias, a name of digits included. Mirrors Python's ALIAS_WORD_TYPES.
 */
export declare const ALIAS_WORD_TYPES: ReadonlySet<string>;
/**
 * A command with its alias words replaced as bash reads it, and the aliases
 * being expanded at each unit of the result. An insertion carries the
 * replaced word's guards and its own name, so no alias expands inside its own
 * text, while the words around it keep theirs. A value ending in a blank
 * checks the command's next word, the next child of the command, which an
 * unquoted word must be. Mirrors Python's alias_rewrite.
 */
export declare function aliasRewrite(node: TSNodeLike, head: TSNodeLike, value: (name: string, blocked: ReadonlySet<string>) => string | null, guards: readonly ReadonlySet<string>[]): [string, ReadonlySet<string>[]] | null;
//# sourceMappingURL=helpers.d.ts.map