import type { BindingElem, ClassMember, Decl, GetAccessorDecl, MethodDecl, ParameterDecl, SetAccessorDecl, VariableDecl } from "./declaration";
import { BaseNode, FunctionlessNode } from "./node";
import { NodeKind } from "./node-kind";
import type { BlockStmt, Stmt } from "./statement";
import type { AnyClass, AnyFunction } from "./util";
/**
 * An {@link Expr} (Expression) is a Node that will be interpreted to a value.
 */
export declare type Expr = Argument | ArrayLiteralExpr | ArrowFunctionExpr | AwaitExpr | BigIntExpr | BinaryExpr | BooleanLiteralExpr | CallExpr | ClassExpr | ComputedPropertyNameExpr | ConditionExpr | DeleteExpr | ElementAccessExpr | FunctionExpr | Identifier | NewExpr | NullLiteralExpr | NumberLiteralExpr | ObjectLiteralExpr | OmittedExpr | ParenthesizedExpr | PostfixUnaryExpr | PrivateIdentifier | PropAccessExpr | PropAssignExpr | ReferenceExpr | RegexExpr | SpreadAssignExpr | SpreadElementExpr | StringLiteralExpr | TaggedTemplateExpr | TemplateExpr | ThisExpr | TypeOfExpr | UnaryExpr | UndefinedLiteralExpr | VoidExpr | YieldExpr;
export declare abstract class BaseExpr<Kind extends NodeKind, Parent extends FunctionlessNode | undefined = BindingElem | Expr | Stmt | VariableDecl | undefined> extends BaseNode<Kind, Parent> {
    readonly nodeKind: "Expr";
}
export declare class ArrowFunctionExpr<F extends AnyFunction = AnyFunction> extends BaseExpr<NodeKind.ArrowFunctionExpr> {
    readonly parameters: ParameterDecl[];
    readonly body: BlockStmt;
    /**
     * true if this function has an `async` modifier
     * ```ts
     * async () =>  {}
     * ```
     */
    readonly isAsync: boolean;
    readonly _functionBrand?: F;
    constructor(parameters: ParameterDecl[], body: BlockStmt, 
    /**
     * true if this function has an `async` modifier
     * ```ts
     * async () =>  {}
     * ```
     */
    isAsync: boolean);
}
export declare class FunctionExpr<F extends AnyFunction = AnyFunction> extends BaseExpr<NodeKind.FunctionExpr> {
    readonly name: string | undefined;
    readonly parameters: ParameterDecl[];
    readonly body: BlockStmt;
    /**
     * true if this function has an `async` modifier
     * ```ts
     * async function foo() {}
     * // asterisk can co-exist
     * async function *foo() {}
     * ```
     */
    readonly isAsync: boolean;
    /**
     * true if this function has an `*` modifier
     *
     * ```ts
     * function foo*() {}
     *
     * // async can co-exist
     * async function *foo() {}
     * ```
     */
    readonly isAsterisk: boolean;
    readonly _functionBrand?: F;
    constructor(name: string | undefined, parameters: ParameterDecl[], body: BlockStmt, 
    /**
     * true if this function has an `async` modifier
     * ```ts
     * async function foo() {}
     * // asterisk can co-exist
     * async function *foo() {}
     * ```
     */
    isAsync: boolean, 
    /**
     * true if this function has an `*` modifier
     *
     * ```ts
     * function foo*() {}
     *
     * // async can co-exist
     * async function *foo() {}
     * ```
     */
    isAsterisk: boolean);
}
export declare class ClassExpr<C extends AnyClass = AnyClass> extends BaseExpr<NodeKind.ClassExpr, undefined> {
    readonly name: string | undefined;
    readonly heritage: Expr | undefined;
    readonly members: ClassMember[];
    readonly _classBrand?: C;
    constructor(name: string | undefined, heritage: Expr | undefined, members: ClassMember[]);
}
export declare class ReferenceExpr<R = unknown> extends BaseExpr<NodeKind.ReferenceExpr> {
    readonly name: string;
    readonly ref: () => R;
    constructor(name: string, ref: () => R);
}
export declare type VariableReference = Identifier | PropAccessExpr | ElementAccessExpr;
export declare class Identifier extends BaseExpr<NodeKind.Identifier> {
    readonly name: string;
    constructor(name: string);
    lookup(): Decl | undefined;
}
export declare class PrivateIdentifier extends BaseExpr<NodeKind.PrivateIdentifier> {
    readonly name: `#${string}`;
    constructor(name: `#${string}`);
    lookup(): Decl | undefined;
}
export declare class PropAccessExpr extends BaseExpr<NodeKind.PropAccessExpr> {
    readonly expr: Expr;
    readonly name: Identifier | PrivateIdentifier;
    /**
     * Whether this is using optional chaining.
     * ```ts
     * a?.prop
     * ```
     */
    readonly isOptional: boolean;
    constructor(expr: Expr, name: Identifier | PrivateIdentifier, 
    /**
     * Whether this is using optional chaining.
     * ```ts
     * a?.prop
     * ```
     */
    isOptional: boolean);
}
export declare class ElementAccessExpr extends BaseExpr<NodeKind.ElementAccessExpr> {
    readonly expr: Expr;
    readonly element: Expr;
    /**
     * Whether this is using optional chaining.
     * ```ts
     * a?.[element]
     * ```
     */
    readonly isOptional: boolean;
    constructor(expr: Expr, element: Expr, 
    /**
     * Whether this is using optional chaining.
     * ```ts
     * a?.[element]
     * ```
     */
    isOptional: boolean);
}
export declare class Argument extends BaseExpr<NodeKind.Argument, CallExpr | NewExpr> {
    readonly expr?: Expr | undefined;
    constructor(expr?: Expr | undefined);
    clone(): this;
}
export declare class CallExpr<E extends Expr | SuperKeyword | ImportKeyword = Expr | SuperKeyword | ImportKeyword> extends BaseExpr<NodeKind.CallExpr> {
    readonly expr: E;
    readonly args: Argument[];
    constructor(expr: E, args: Argument[]);
}
export declare class NewExpr extends BaseExpr<NodeKind.NewExpr> {
    readonly expr: Expr;
    readonly args: Argument[];
    constructor(expr: Expr, args: Argument[]);
}
export declare class ConditionExpr extends BaseExpr<NodeKind.ConditionExpr> {
    readonly when: Expr;
    readonly then: Expr;
    readonly _else: Expr;
    constructor(when: Expr, then: Expr, _else: Expr);
}
export declare type ValueComparisonBinaryOp = "==" | "!=" | "<" | "<=" | ">" | ">=";
export declare type MathBinaryOp = "/" | "*" | "+" | "-" | "%";
export declare type MutationMathBinaryOp = "+=" | "*=" | "-=" | "/=" | "%=";
export declare type ComparatorOp = "&&" | "||" | "??";
export declare type BinaryOp = MathBinaryOp | MutationMathBinaryOp | ValueComparisonBinaryOp | ComparatorOp | "," | "=" | "in";
export declare class BinaryExpr extends BaseExpr<NodeKind.BinaryExpr> {
    readonly left: Expr;
    readonly op: BinaryOp;
    readonly right: Expr;
    constructor(left: Expr, op: BinaryOp, right: Expr);
}
export declare type PostfixUnaryOp = "--" | "++";
export declare type UnaryOp = "!" | "-" | "~" | PostfixUnaryOp;
export declare class UnaryExpr extends BaseExpr<NodeKind.UnaryExpr> {
    readonly op: UnaryOp;
    readonly expr: Expr;
    constructor(op: UnaryOp, expr: Expr);
}
export declare class PostfixUnaryExpr extends BaseExpr<NodeKind.PostfixUnaryExpr> {
    readonly op: PostfixUnaryOp;
    readonly expr: Expr;
    constructor(op: PostfixUnaryOp, expr: Expr);
}
export declare class NullLiteralExpr extends BaseExpr<NodeKind.NullLiteralExpr> {
    readonly value: null;
    constructor();
}
export declare class UndefinedLiteralExpr extends BaseExpr<NodeKind.UndefinedLiteralExpr> {
    readonly value: undefined;
    constructor();
}
export declare class BooleanLiteralExpr extends BaseExpr<NodeKind.BooleanLiteralExpr> {
    readonly value: boolean;
    constructor(value: boolean);
}
export declare class BigIntExpr extends BaseExpr<NodeKind.BigIntExpr> {
    readonly value: bigint;
    constructor(value: bigint);
}
export declare class NumberLiteralExpr extends BaseExpr<NodeKind.NumberLiteralExpr> {
    readonly value: number;
    constructor(value: number);
}
export declare class StringLiteralExpr extends BaseExpr<NodeKind.StringLiteralExpr> {
    readonly value: string;
    constructor(value: string);
}
export declare class ArrayLiteralExpr extends BaseExpr<NodeKind.ArrayLiteralExpr> {
    readonly items: Expr[];
    constructor(items: Expr[]);
}
export declare type ObjectElementExpr = GetAccessorDecl | MethodDecl | PropAssignExpr | SetAccessorDecl | SpreadAssignExpr;
export declare class ObjectLiteralExpr extends BaseExpr<NodeKind.ObjectLiteralExpr> {
    readonly properties: ObjectElementExpr[];
    constructor(properties: ObjectElementExpr[]);
    getProperty(name: string): ObjectElementExpr | undefined;
}
export declare type PropName = Identifier | PrivateIdentifier | ComputedPropertyNameExpr | StringLiteralExpr | NumberLiteralExpr;
export declare class PropAssignExpr extends BaseExpr<NodeKind.PropAssignExpr, ObjectLiteralExpr> {
    readonly name: PropName;
    readonly expr: Expr;
    constructor(name: PropName, expr: Expr);
}
export declare class ComputedPropertyNameExpr extends BaseExpr<NodeKind.ComputedPropertyNameExpr, PropAssignExpr> {
    readonly expr: Expr;
    constructor(expr: Expr);
}
export declare class SpreadAssignExpr extends BaseExpr<NodeKind.SpreadAssignExpr, ObjectLiteralExpr> {
    readonly expr: Expr;
    constructor(expr: Expr);
}
export declare class SpreadElementExpr extends BaseExpr<NodeKind.SpreadElementExpr, ObjectLiteralExpr> {
    readonly expr: Expr;
    constructor(expr: Expr);
}
/**
 * A quasi string in a {@link TemplateExpr} or {@link TaggedTemplateExpr}.
 *
 * ```ts
 * const s = `abc${def}`
 *          // ^ quasi
 * ```
 */
export declare class QuasiString extends BaseNode<NodeKind.QuasiString> {
    readonly value: string;
    readonly nodeKind = "Node";
    constructor(value: string);
}
/**
 * A span of text within a {@link TemplateExpr} or {@link TaggedTemplateExpr}.
 *
 * ```ts
 * const s = `quasi ${expr}`
 *           // ^ Quasi string
 * const s = `quasi ${expr}`
 *                  // ^ expression to splice
 * ```
 */
export declare type TemplateSpan = QuasiString | Expr;
/**
 * Interpolates a TemplateExpr to a string `this ${is} a template expression`
 */
export declare class TemplateExpr extends BaseExpr<NodeKind.TemplateExpr> {
    readonly spans: TemplateSpan[];
    constructor(spans: TemplateSpan[]);
}
export declare class TaggedTemplateExpr extends BaseExpr<NodeKind.TaggedTemplateExpr> {
    readonly tag: Expr;
    readonly spans: TemplateSpan[];
    constructor(tag: Expr, spans: TemplateSpan[]);
}
export declare class TypeOfExpr extends BaseExpr<NodeKind.TypeOfExpr> {
    readonly expr: Expr;
    constructor(expr: Expr);
}
export declare class AwaitExpr extends BaseExpr<NodeKind.AwaitExpr> {
    readonly expr: Expr;
    constructor(expr: Expr);
}
export declare class ThisExpr<T = any> extends BaseExpr<NodeKind.ThisExpr> {
    /**
     * Produce the value of `this`
     */
    readonly ref: () => T;
    constructor(
    /**
     * Produce the value of `this`
     */
    ref: () => T);
}
export declare class SuperKeyword extends BaseNode<NodeKind.SuperKeyword> {
    readonly nodeKind = "Node";
    constructor();
}
export declare class ImportKeyword extends BaseNode<NodeKind.ImportKeyword> {
    readonly nodeKind = "Node";
    constructor();
}
export declare class YieldExpr extends BaseExpr<NodeKind.YieldExpr> {
    /**
     * The expression to yield (or delegate) to.
     */
    readonly expr: Expr | undefined;
    /**
     * Is a `yield*` delegate expression.
     */
    readonly delegate: boolean;
    constructor(
    /**
     * The expression to yield (or delegate) to.
     */
    expr: Expr | undefined, 
    /**
     * Is a `yield*` delegate expression.
     */
    delegate: boolean);
}
export declare class RegexExpr extends BaseExpr<NodeKind.RegexExpr> {
    readonly regex: RegExp;
    constructor(regex: RegExp);
}
export declare class VoidExpr extends BaseExpr<NodeKind.VoidExpr> {
    /**
     * The expression to yield (or delegate) to.
     */
    readonly expr: Expr;
    constructor(
    /**
     * The expression to yield (or delegate) to.
     */
    expr: Expr);
}
export declare class DeleteExpr extends BaseExpr<NodeKind.DeleteExpr> {
    readonly expr: PropAccessExpr | ElementAccessExpr;
    constructor(expr: PropAccessExpr | ElementAccessExpr);
}
export declare class ParenthesizedExpr extends BaseExpr<NodeKind.ParenthesizedExpr> {
    readonly expr: Expr;
    constructor(expr: Expr);
    unwrap(): Expr | undefined;
}
export declare class OmittedExpr extends BaseExpr<NodeKind.OmittedExpr> {
    constructor();
}
export declare const deploymentOnlyModule = true;
//# sourceMappingURL=expression.d.ts.map