import type { ScopeValueSets, NameValue, ValueScope, ValueScopeName } from "./scope";
import { _Code, Code, Name } from "./code";
import { Scope } from "./scope";
export { _, str, strConcat, nil, getProperty, stringify, regexpCode, Name, Code } from "./code";
export { Scope, ScopeStore, ValueScope, ValueScopeName, ScopeValueSets, varKinds } from "./scope";
export type SafeExpr = Code | number | boolean | null;
export type Block = Code | (() => void);
export declare const operators: {
    GT: _Code;
    GTE: _Code;
    LT: _Code;
    LTE: _Code;
    EQ: _Code;
    NEQ: _Code;
    NOT: _Code;
    OR: _Code;
    AND: _Code;
    ADD: _Code;
};
export interface CodeGenOptions {
    es5?: boolean;
    lines?: boolean;
    ownProperties?: boolean;
}
export declare class CodeGen {
    readonly _scope: Scope;
    readonly _extScope: ValueScope;
    readonly _values: ScopeValueSets;
    private readonly _nodes;
    private readonly _blockStarts;
    private readonly _constants;
    private readonly opts;
    constructor(extScope: ValueScope, opts?: CodeGenOptions);
    toString(): string;
    name(prefix: string): Name;
    scopeName(prefix: string): ValueScopeName;
    scopeValue(prefixOrName: ValueScopeName | string, value: NameValue): Name;
    getScopeValue(prefix: string, keyOrRef: unknown): ValueScopeName | undefined;
    scopeRefs(scopeName: Name): Code;
    scopeCode(): Code;
    private _def;
    const(nameOrPrefix: Name | string, rhs: SafeExpr, _constant?: boolean): Name;
    let(nameOrPrefix: Name | string, rhs?: SafeExpr, _constant?: boolean): Name;
    var(nameOrPrefix: Name | string, rhs?: SafeExpr, _constant?: boolean): Name;
    assign(lhs: Code, rhs: SafeExpr, sideEffects?: boolean): CodeGen;
    add(lhs: Code, rhs: SafeExpr): CodeGen;
    code(c: Block | SafeExpr): CodeGen;
    object(...keyValues: [Name | string, SafeExpr | string][]): _Code;
    if(condition: Code | boolean, thenBody?: Block, elseBody?: Block): CodeGen;
    elseIf(condition: Code | boolean): CodeGen;
    else(): CodeGen;
    endIf(): CodeGen;
    private _for;
    for(iteration: Code, forBody?: Block): CodeGen;
    forRange(nameOrPrefix: Name | string, from: SafeExpr, to: SafeExpr, forBody: (index: Name) => void, varKind?: Code): CodeGen;
    forOf(nameOrPrefix: Name | string, iterable: Code, forBody: (item: Name) => void, varKind?: Code): CodeGen;
    forIn(nameOrPrefix: Name | string, obj: Code, forBody: (item: Name) => void, varKind?: Code): CodeGen;
    endFor(): CodeGen;
    label(label: Name): CodeGen;
    break(label?: Code): CodeGen;
    return(value: Block | SafeExpr): CodeGen;
    try(tryBody: Block, catchCode?: (e: Name) => void, finallyCode?: Block): CodeGen;
    throw(error: Code): CodeGen;
    block(body?: Block, nodeCount?: number): CodeGen;
    endBlock(nodeCount?: number): CodeGen;
    func(name: Name, args?: Code, async?: boolean, funcBody?: Block): CodeGen;
    endFunc(): CodeGen;
    optimize(n?: number): void;
    private _leafNode;
    private _blockNode;
    private _endBlockNode;
    private _elseNode;
    private get _root();
    private get _currNode();
    private set _currNode(value);
}
export declare function not<T extends Code | SafeExpr>(x: T): T;
export declare function and(...args: Code[]): Code;
export declare function or(...args: Code[]): Code;
