/**
 * Type system types for IR (IrType and its variants)
 */
import { IrParameter, IrInterfaceMember, IrTypeParameter } from "./helpers.js";
import type { TypeId } from "../type-system/index.js";
export type IrType = IrPrimitiveType | IrReferenceType | IrTypeParameterType | IrArrayType | IrTupleType | IrFunctionType | IrObjectType | IrDictionaryType | IrUnionType | IrIntersectionType | IrLiteralType | IrAnyType | IrUnknownType | IrVoidType | IrNeverType;
/**
 * Primitive types in IR.
 *
 * INVARIANT A: "number" always emits as C# "double". No exceptions.
 * INVARIANT B: "int" always emits as C# "int". No exceptions.
 *
 * These are distinct types, not decorated versions of each other.
 * - User writes `: number` → primitiveType(name="number") → emits "double"
 * - User writes `: int` → primitiveType(name="int") → emits "int"
 *
 * The numeric classification of LITERALS is separate (see IrLiteralExpression.numericIntent).
 * Type-level and expression-level concerns are strictly separated.
 */
export type IrPrimitiveType = {
    readonly kind: "primitiveType";
    readonly name: "string" | "number" | "int" | "char" | "boolean" | "null" | "undefined";
};
export type IrReferenceType = {
    readonly kind: "referenceType";
    readonly name: string;
    readonly typeArguments?: readonly IrType[];
    /** Fully-qualified CLR type for imported types (e.g., "MyApp.Models.User") */
    readonly resolvedClrType?: string;
    /**
     * Canonical type identity from UnifiedTypeCatalog.
     * When present, this is the authoritative source of type identity.
     * Use typeId.clrName for emission, typeId.stableId for equality checks.
     */
    readonly typeId?: TypeId;
    /**
     * Structural members for interfaces and type aliases that resolve to object types.
     * Populated when the reference resolves to a structural type (interface, type literal, etc.)
     * Used by TSN5110 to validate object literal properties against expected types.
     */
    readonly structuralMembers?: readonly IrInterfaceMember[];
};
/**
 * Type parameter reference (e.g., T in Container<T>)
 *
 * This is distinct from IrReferenceType to enable unambiguous detection
 * of generic type parameters during emission (for null → default conversion).
 */
export type IrTypeParameterType = {
    readonly kind: "typeParameterType";
    readonly name: string;
};
export type IrArrayType = {
    readonly kind: "arrayType";
    readonly elementType: IrType;
    /**
     * Set to "explicit" when the array type came from an explicit T[] annotation.
     * Undefined when the type was inferred.
     *
     * All array types emit as native CLR arrays (T[]).
     * Users must explicitly use List<T> to get a List.
     */
    readonly origin?: "explicit";
    /**
     * Optional tuple-like shape metadata for variadic tuples lowered to array runtime shape.
     *
     * Example:
     * - `[PathSpec, ...RequestHandler[]]` → arrayType(elementType = PathSpec | RequestHandler,
     *   tuplePrefixElementTypes = [PathSpec], tupleRestElementType = RequestHandler)
     *
     * This preserves spread-call semantics for overload resolution while still emitting
     * as a CLR array at runtime.
     */
    readonly tuplePrefixElementTypes?: readonly IrType[];
    readonly tupleRestElementType?: IrType;
    /**
     * Semantic element type preserved when the runtime storage element type was
     * intentionally erased for compiler-owned recursive carrier storage.
     *
     * Example:
     * - `type MiddlewareLike = Handler | Router | MiddlewareLike[]`
     * - runtime carrier member becomes `object[]`
     * - `storageErasedElementType` remains `MiddlewareLike`
     *
     * This metadata is for compiler-owned emitter decisions only. It does not
     * change semantic type equality or runtime storage shape.
     */
    readonly storageErasedElementType?: IrType;
};
/**
 * Tuple type for fixed-length arrays with heterogeneous element types
 *
 * Examples:
 * - `[string, number]` → IrTupleType { elementTypes: [string, number] }
 * - `[boolean, string, number]` → IrTupleType { elementTypes: [boolean, string, number] }
 *
 * Emits to C# ValueTuple<T1, T2, ...>.
 */
export type IrTupleType = {
    readonly kind: "tupleType";
    readonly elementTypes: readonly IrType[];
};
export type IrFunctionType = {
    readonly kind: "functionType";
    readonly typeParameters?: readonly IrTypeParameter[];
    readonly parameters: readonly IrParameter[];
    readonly returnType: IrType;
};
export type IrObjectType = {
    readonly kind: "objectType";
    readonly members: readonly IrInterfaceMember[];
};
/**
 * Dictionary/map type for index signatures and Record<K, V>
 *
 * Examples:
 * - `{ [k: string]: T }` → IrDictionaryType { keyType: string, valueType: T }
 * - `Record<string, T>` → IrDictionaryType { keyType: string, valueType: T }
 *
 * Emits to C# Dictionary<TKey, TValue>.
 * Access should be via indexer `d["key"]` (dot property access will fail in C#).
 */
export type IrDictionaryType = {
    readonly kind: "dictionaryType";
    readonly keyType: IrType;
    readonly valueType: IrType;
};
export type IrUnionType = {
    readonly kind: "unionType";
    readonly types: readonly IrType[];
    /**
     * Preserve explicit member order and duplicate carrier slots when this union
     * is used as a runtime-union carrier.
     *
     * This is for compiler-authored runtime carrier layout only. It does not
     * change semantic type equality.
     */
    readonly preserveRuntimeLayout?: true;
    /**
     * Compiler-owned runtime carrier family identity.
     *
     * When present, emitter-side runtime union carrier selection must reuse this
     * family key instead of recomputing identity from fully-substituted emitted
     * member types. This keeps generic template unions and their concrete
     * specializations on the same carrier family.
     */
    readonly runtimeCarrierFamilyKey?: string;
    /**
     * Preferred emitted runtime carrier class name for source-owned unions.
     *
     * This is metadata only; semantic type equality is still structural over
     * union members.
     */
    readonly runtimeCarrierName?: string;
    /**
     * Preferred emitted runtime carrier namespace for source-owned unions.
     *
     * Anonymous compiler-created unions omit this and stay under
     * `Tsonic.Internal`.
     */
    readonly runtimeCarrierNamespace?: string;
    /**
     * Source type parameters owned by a named source-union carrier.
     *
     * Anonymous compiler-created unions omit this and stay generic over their
     * runtime member slots. Source-owned unions use these names so
     * `type Result<T> = T | Error` emits as `Result<T>`.
     */
    readonly runtimeCarrierTypeParameters?: readonly string[];
    /**
     * Concrete source type arguments for a source-owned carrier reference after
     * alias substitution.
     */
    readonly runtimeCarrierTypeArguments?: readonly IrType[];
};
export type IrIntersectionType = {
    readonly kind: "intersectionType";
    readonly types: readonly IrType[];
};
export type IrLiteralType = {
    readonly kind: "literalType";
    readonly value: string | number | boolean;
};
export type IrAnyType = {
    readonly kind: "anyType";
};
export type IrUnknownType = {
    readonly kind: "unknownType";
    /**
     * Present only when the source program explicitly authored `unknown`.
     *
     * Absence means this unknown originated from an unresolved / poison path.
     */
    readonly explicit?: true;
};
export type IrVoidType = {
    readonly kind: "voidType";
};
export type IrNeverType = {
    readonly kind: "neverType";
};
/**
 * C# Attribute attached to a declaration (class, function, method, property, parameter)
 *
 * Attributes are collected from marker calls like `A<T>().add(Attr)` and
 * attached to the corresponding IR declaration nodes.
 *
 * Example:
 * ```typescript
 * A<User>().add(SerializableAttribute);
 * A<User>().add(DataContractAttribute, { Name: "UserDTO" });
 * ```
 *
 * Emits to C#:
 * ```csharp
 * [global::System.SerializableAttribute]
 * [global::System.Runtime.Serialization.DataContractAttribute(Name = "UserDTO")]
 * public class User { ... }
 * ```
 */
export type IrAttributeTarget = "assembly" | "module" | "type" | "method" | "property" | "field" | "event" | "param" | "return";
export type IrAttribute = {
    readonly kind: "attribute";
    /**
     * C# attribute target specifier (e.g., `[return: Attr]`, `[field: Attr]`).
     *
     * Note:
     * - Not all targets are valid for all declaration kinds.
     * - Invalid combinations are rejected earlier in the pipeline.
     */
    readonly target?: IrAttributeTarget;
    /** The attribute class type (e.g., SerializableAttribute) */
    readonly attributeType: IrType;
    /** Positional constructor arguments (string, number, boolean, typeof) */
    readonly positionalArgs: readonly IrAttributeArg[];
    /** Named property assignments (e.g., { Name: "UserDTO" }) */
    readonly namedArgs: ReadonlyMap<string, IrAttributeArg>;
};
/**
 * Attribute argument value - must be a constant expression.
 * C# attributes only accept compile-time constants.
 */
export type IrAttributePrimitiveArg = {
    readonly kind: "string";
    readonly value: string;
} | {
    readonly kind: "number";
    readonly value: number;
} | {
    readonly kind: "boolean";
    readonly value: boolean;
} | {
    readonly kind: "typeof";
    readonly type: IrType;
} | {
    readonly kind: "enum";
    readonly type: IrType;
    readonly member: string;
};
export type IrAttributeArg = IrAttributePrimitiveArg | {
    readonly kind: "array";
    readonly elements: readonly IrAttributePrimitiveArg[];
};
//# sourceMappingURL=ir-types.d.ts.map