ruchy/frontend/
ast.rs

1//! Abstract Syntax Tree (AST) definitions for the Ruchy programming language.
2//!
3//! This module contains the complete AST representation used by the Ruchy compiler.
4//! The AST is the primary intermediate representation produced by the parser and consumed
5//! by subsequent compilation phases including type checking, optimization, and code generation.
6//!
7//! # Architecture
8//!
9//! The AST follows a traditional expression-based design where most constructs are
10//! represented as expressions that can be composed. Key design principles:
11//!
12//! - **Location tracking**: Every AST node carries a `Span` for precise error reporting
13//! - **Attributes**: Nodes can be decorated with attributes for metadata and directives
14//! - **Pattern matching**: First-class support for destructuring and pattern matching
15//! - **Type annotations**: Optional type annotations for gradual typing
16//!
17//! # Example
18//!
19//! ```ignore
20//! use ruchy::frontend::ast::{Expr, ExprKind, Literal, Span};
21//!
22//! // Create a simple literal expression
23//! let expr = Expr::new(
24//!     ExprKind::Literal(Literal::Integer(42, None)),
25//!     Span::new(0, 2)
26//! );
27//! ```
28
29use serde::{Deserialize, Serialize};
30use std::fmt;
31
32/// Comment information for AST nodes.
33///
34/// Comments are preserved during parsing to enable accurate code formatting
35/// that maintains documentation and developer intent. Each comment tracks its
36/// text content, position, and association with AST nodes.
37///
38/// # Examples
39///
40/// ```ignore
41/// use ruchy::frontend::ast::{Comment, CommentKind, Span};
42///
43/// // Create a line comment
44/// let comment = Comment::new(
45///     CommentKind::Line("This is a comment".to_string()),
46///     Span::new(0, 20)
47/// );
48/// ```
49#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
50pub struct Comment {
51    /// The type and content of this comment.
52    pub kind: CommentKind,
53    /// Source location information for this comment.
54    pub span: Span,
55}
56
57impl Comment {
58    /// Creates a new comment with the given kind and span.
59    #[must_use]
60    pub fn new(kind: CommentKind, span: Span) -> Self {
61        Self { kind, span }
62    }
63}
64
65/// The type of comment.
66///
67/// Ruchy supports three types of comments:
68/// - Line comments starting with `//`
69/// - Doc comments starting with `///` for documentation
70/// - Block comments enclosed in `/* ... */`
71#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
72pub enum CommentKind {
73    /// A single-line comment: `// comment text`
74    Line(String),
75    /// A documentation comment: `/// doc comment text`
76    Doc(String),
77    /// A block comment: `/* comment text */`
78    Block(String),
79}
80
81/// Source location information for AST nodes.
82///
83/// A `Span` represents a contiguous range of characters in the source code,
84/// enabling precise error reporting and source mapping. All AST nodes carry
85/// span information to maintain the connection between the abstract representation
86/// and the original source text.
87///
88/// # Examples
89///
90/// ```ignore
91/// use ruchy::frontend::ast::Span;
92///
93/// // Create a span for characters 10-15 in the source
94/// let span = Span::new(10, 15);
95///
96/// // Merge two spans to get their combined range
97/// let span1 = Span::new(10, 20);
98/// let span2 = Span::new(15, 25);
99/// let merged = span1.merge(span2); // Span { start: 10, end: 25 }
100/// ```
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
102pub struct Span {
103    /// The byte offset of the first character in this span.
104    pub start: usize,
105    /// The byte offset one past the last character in this span.
106    pub end: usize,
107}
108impl Span {
109    /// Creates a new span with the given start and end positions.
110    ///
111    /// # Arguments
112    ///
113    /// * `start` - The byte offset of the first character
114    /// * `end` - The byte offset one past the last character
115    ///
116    /// # Examples
117    ///
118    /// ```ignore
119    /// use ruchy::frontend::ast::Span;
120    ///
121    /// let span = Span::new(0, 10);
122    /// assert_eq!(span.start, 0);
123    /// assert_eq!(span.end, 10);
124    /// ```
125    #[must_use]
126    pub fn new(start: usize, end: usize) -> Self {
127        Self { start, end }
128    }
129    /// Merges two spans to create a new span covering both ranges.
130    ///
131    /// This is useful when combining multiple tokens or expressions into
132    /// a larger syntactic construct. The resulting span starts at the
133    /// minimum of both start positions and ends at the maximum of both
134    /// end positions.
135    ///
136    /// # Arguments
137    ///
138    /// * `other` - The span to merge with this one
139    ///
140    /// # Returns
141    ///
142    /// A new span covering the entire range of both input spans
143    ///
144    /// # Examples
145    ///
146    /// ```ignore
147    /// use ruchy::frontend::ast::Span;
148    ///
149    /// let span1 = Span::new(10, 20);
150    /// let span2 = Span::new(15, 25);
151    /// let merged = span1.merge(span2);
152    /// assert_eq!(merged.start, 10);
153    /// assert_eq!(merged.end, 25);
154    /// ```
155    #[must_use]
156    pub fn merge(self, other: Self) -> Self {
157        Self {
158            start: self.start.min(other.start),
159            end: self.end.max(other.end),
160        }
161    }
162}
163/// A catch clause in a try-catch expression.
164///
165/// Catch clauses provide pattern-based error handling, allowing different
166/// error types or patterns to be handled with specific recovery logic.
167///
168/// # Examples
169///
170/// ```ignore
171/// // Catch a specific error pattern
172/// try {
173///     risky_operation()
174/// } catch IOError(msg) {
175///     println("IO error: {msg}")
176/// } catch e {
177///     println("Unknown error: {e}")
178/// }
179/// ```
180#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
181pub struct CatchClause {
182    /// The pattern to match against the caught error.
183    pub pattern: Pattern,
184    /// The expression to execute when this pattern matches.
185    pub body: Box<Expr>,
186}
187
188/// A single clause in a comprehension (for and optional if).
189#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
190pub struct ComprehensionClause {
191    /// The variable or pattern to bind
192    pub variable: String,
193    /// The iterable to iterate over
194    pub iterable: Box<Expr>,
195    /// Optional filter condition (if clause)
196    pub condition: Option<Box<Expr>>,
197}
198
199/// The primary AST node representing an expression in Ruchy.
200///
201/// `Expr` is the fundamental building block of Ruchy's AST. Nearly all language
202/// constructs are represented as expressions, including statements, declarations,
203/// and control flow. This expression-oriented design enables powerful composition
204/// and simplifies the language semantics.
205///
206/// Each expression consists of:
207/// - `kind`: The specific type of expression (literal, binary op, function, etc.)
208/// - `span`: Source location information for error reporting
209/// - `attributes`: Optional metadata and compiler directives
210///
211/// # Examples
212///
213/// ```ignore
214/// use ruchy::frontend::ast::{Expr, ExprKind, BinaryOp, Literal, Span};
215///
216/// // Create a binary expression: 2 + 3
217/// let left = Box::new(Expr::new(
218///     ExprKind::Literal(Literal::Integer(2, None)),
219///     Span::new(0, 1)
220/// ));
221/// let right = Box::new(Expr::new(
222///     ExprKind::Literal(Literal::Integer(3, None)),
223///     Span::new(4, 5)
224/// ));
225/// let expr = Expr::new(
226///     ExprKind::Binary { left, op: BinaryOp::Add, right },
227///     Span::new(0, 5)
228/// );
229/// ```
230#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
231pub struct Expr {
232    /// The specific type of expression.
233    pub kind: ExprKind,
234    /// Source location information for this expression.
235    pub span: Span,
236    /// Compiler attributes and metadata attached to this expression.
237    pub attributes: Vec<Attribute>,
238    /// Comments that appear before this expression.
239    ///
240    /// Leading comments are associated with the expression they precede.
241    /// These typically include documentation comments and explanatory notes.
242    pub leading_comments: Vec<Comment>,
243    /// Optional comment that appears at the end of the same line as this expression.
244    ///
245    /// Trailing comments are inline comments that provide context for the
246    /// specific line of code they follow.
247    pub trailing_comment: Option<Comment>,
248}
249impl Expr {
250    /// Creates a new expression with the given kind and span.
251    ///
252    /// This is the primary constructor for building AST nodes. The expression
253    /// starts with no attributes; use `with_attributes` if attributes are needed.
254    ///
255    /// # Arguments
256    ///
257    /// * `kind` - The specific type of expression
258    /// * `span` - The source location of this expression
259    ///
260    /// # Examples
261    ///
262    /// ```ignore
263    /// use ruchy::frontend::ast::{Expr, ExprKind, Literal, Span};
264    ///
265    /// let expr = Expr::new(
266    ///     ExprKind::Literal(Literal::Boolean(true)),
267    ///     Span::new(0, 4)
268    /// );
269    /// ```
270    #[must_use]
271    pub fn new(kind: ExprKind, span: Span) -> Self {
272        Self {
273            kind,
274            span,
275            attributes: Vec::new(),
276            leading_comments: Vec::new(),
277            trailing_comment: None,
278        }
279    }
280
281    /// Creates a new expression with comments attached.
282    ///
283    /// This constructor is used during parsing to associate comments with
284    /// their corresponding AST nodes, enabling accurate code formatting that
285    /// preserves documentation.
286    ///
287    /// # Arguments
288    ///
289    /// * `kind` - The specific type of expression
290    /// * `span` - The source location of this expression
291    /// * `leading_comments` - Comments that appear before this expression
292    /// * `trailing_comment` - Optional comment at the end of the line
293    ///
294    /// # Examples
295    ///
296    /// ```ignore
297    /// use ruchy::frontend::ast::{Expr, ExprKind, Comment, CommentKind, Span};
298    ///
299    /// let comment = Comment::new(
300    ///     CommentKind::Line("Important value".to_string()),
301    ///     Span::new(0, 18)
302    /// );
303    ///
304    /// let expr = Expr::with_comments(
305    ///     ExprKind::Literal(Literal::Integer(42, None)),
306    ///     Span::new(20, 22),
307    ///     vec![],
308    ///     Some(comment)
309    /// );
310    /// ```
311    #[must_use]
312    pub fn with_comments(
313        kind: ExprKind,
314        span: Span,
315        leading_comments: Vec<Comment>,
316        trailing_comment: Option<Comment>,
317    ) -> Self {
318        Self {
319            kind,
320            span,
321            attributes: Vec::new(),
322            leading_comments,
323            trailing_comment,
324        }
325    }
326    /// Creates a new expression with attributes attached.
327    ///
328    /// Attributes provide metadata and compiler directives that modify
329    /// how an expression is processed. Common uses include optimization
330    /// hints, debugging information, and feature flags.
331    ///
332    /// # Arguments
333    ///
334    /// * `kind` - The specific type of expression
335    /// * `span` - The source location of this expression
336    /// * `attributes` - Compiler attributes to attach
337    ///
338    /// # Examples
339    ///
340    /// ```ignore
341    /// use ruchy::frontend::ast::{Expr, ExprKind, Attribute, Literal, Span};
342    ///
343    /// let expr = Expr::with_attributes(
344    ///     ExprKind::Literal(Literal::Integer(42, None)),
345    ///     Span::new(0, 2),
346    ///     vec![Attribute::inline()]
347    /// );
348    /// ```
349    #[must_use]
350    pub fn with_attributes(kind: ExprKind, span: Span, attributes: Vec<Attribute>) -> Self {
351        Self {
352            kind,
353            span,
354            attributes,
355            leading_comments: Vec::new(),
356            trailing_comment: None,
357        }
358    }
359}
360/// The specific type of expression represented by an AST node.
361///
362/// `ExprKind` is a comprehensive enumeration of all expression types supported
363/// by the Ruchy language. This includes literals, operators, control flow,
364/// declarations, and advanced features like actors and dataframes.
365///
366/// # Expression Categories
367///
368/// ## Literals and Identifiers
369/// - `Literal`: Constant values (integers, strings, booleans, etc.)
370/// - `Identifier`: Variable references
371/// - `QualifiedName`: Module-qualified identifiers
372///
373/// ## Operations
374/// - `Binary`: Binary operations (arithmetic, logical, comparison)
375/// - `Unary`: Unary operations (negation, not)
376/// - `Pipeline`: Functional pipeline operations
377///
378/// ## Control Flow
379/// - `If`, `IfLet`: Conditional expressions
380/// - `Match`: Pattern matching
381/// - `For`, `While`, `Loop`: Iteration constructs
382/// - `TryCatch`, `Throw`: Exception handling
383///
384/// ## Declarations
385/// - `Let`, `LetPattern`: Variable bindings
386/// - `Function`, `Lambda`: Function definitions
387/// - `Struct`, `Enum`, `Trait`: Type definitions
388///
389/// ## Advanced Features
390/// - `Actor`: Actor model for concurrency
391/// - `DataFrame`: Tabular data operations
392/// - `Async`, `Await`: Asynchronous programming
393/// - `Command`: System command execution
394#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
395pub enum ExprKind {
396    /// A literal value (integer, string, boolean, etc.).
397    Literal(Literal),
398    /// A simple identifier reference.
399    Identifier(String),
400    /// A module-qualified identifier (e.g., `std::println`).
401    QualifiedName {
402        /// The module path.
403        module: String,
404        /// The identifier within the module.
405        name: String,
406    },
407    /// An interpolated string with embedded expressions.
408    StringInterpolation {
409        /// The parts of the interpolated string.
410        parts: Vec<StringPart>,
411    },
412    /// A binary operation (e.g., `a + b`, `x && y`).
413    Binary {
414        /// The left operand.
415        left: Box<Expr>,
416        /// The binary operator.
417        op: BinaryOp,
418        /// The right operand.
419        right: Box<Expr>,
420    },
421    /// A unary operation (e.g., `-x`, `!flag`).
422    Unary {
423        /// The unary operator.
424        op: UnaryOp,
425        /// The operand expression.
426        operand: Box<Expr>,
427    },
428    /// Throws an exception.
429    Throw {
430        /// The exception value to throw.
431        expr: Box<Expr>,
432    },
433    /// Exception handling with pattern-based catch clauses.
434    TryCatch {
435        /// The expression to try.
436        try_block: Box<Expr>,
437        /// Pattern-based catch handlers.
438        catch_clauses: Vec<CatchClause>,
439        /// Optional finally block executed regardless of success/failure.
440        finally_block: Option<Box<Expr>>,
441    },
442    Ok {
443        value: Box<Expr>,
444    },
445    Err {
446        error: Box<Expr>,
447    },
448    Some {
449        value: Box<Expr>,
450    },
451    None,
452    TypeCast {
453        expr: Box<Expr>,
454        target_type: String,
455    },
456    /// Ternary conditional expression (condition ? `true_expr` : `false_expr`)
457    Ternary {
458        condition: Box<Expr>,
459        true_expr: Box<Expr>,
460        false_expr: Box<Expr>,
461    },
462    Try {
463        expr: Box<Expr>,
464    },
465    Await {
466        expr: Box<Expr>,
467    },
468    Spawn {
469        actor: Box<Expr>,
470    },
471    AsyncBlock {
472        body: Box<Expr>,
473    },
474    If {
475        condition: Box<Expr>,
476        then_branch: Box<Expr>,
477        else_branch: Option<Box<Expr>>,
478    },
479    IfLet {
480        pattern: Pattern,
481        expr: Box<Expr>,
482        then_branch: Box<Expr>,
483        else_branch: Option<Box<Expr>>,
484    },
485    Let {
486        name: String,
487        type_annotation: Option<Type>,
488        value: Box<Expr>,
489        body: Box<Expr>,
490        is_mutable: bool,
491        else_block: Option<Box<Expr>>,  // For let-else: `let x = val else { diverging }`
492    },
493    LetPattern {
494        pattern: Pattern,
495        type_annotation: Option<Type>,
496        value: Box<Expr>,
497        body: Box<Expr>,
498        is_mutable: bool,
499        else_block: Option<Box<Expr>>,  // For let-else: `let Some(x) = val else { diverging }`
500    },
501    Function {
502        name: String,
503        type_params: Vec<String>,
504        params: Vec<Param>,
505        return_type: Option<Type>,
506        body: Box<Expr>,
507        is_async: bool,
508        is_pub: bool,
509    },
510    Lambda {
511        params: Vec<Param>,
512        body: Box<Expr>,
513    },
514    AsyncLambda {
515        params: Vec<String>,
516        body: Box<Expr>,
517    },
518    Struct {
519        name: String,
520        type_params: Vec<String>,
521        fields: Vec<StructField>,
522        derives: Vec<String>, // #[derive(Debug, Clone, ...)]
523        is_pub: bool,
524    },
525    TupleStruct {
526        name: String,
527        type_params: Vec<String>,
528        fields: Vec<Type>, // Just types, no names
529        derives: Vec<String>,
530        is_pub: bool,
531    },
532    Class {
533        name: String,
534        type_params: Vec<String>,
535        superclass: Option<String>, // inheritance
536        traits: Vec<String>,        // + Trait1 + Trait2
537        fields: Vec<StructField>,
538        constructors: Vec<Constructor>, // new() methods
539        methods: Vec<ClassMethod>,
540        constants: Vec<ClassConstant>,  // const NAME: TYPE = VALUE
541        properties: Vec<ClassProperty>, // property NAME: TYPE { get => ..., set(v) => ... }
542        derives: Vec<String>,           // #[derive(Debug, Clone, ...)]
543        decorators: Vec<Decorator>,     // @Serializable, @Table("users"), etc.
544        is_pub: bool,
545        is_sealed: bool,   // sealed class (no external subclassing)
546        is_abstract: bool, // abstract class (cannot be instantiated)
547    },
548    Enum {
549        name: String,
550        type_params: Vec<String>,
551        variants: Vec<EnumVariant>,
552        is_pub: bool,
553    },
554    StructLiteral {
555        name: String,
556        fields: Vec<(String, Expr)>,
557        base: Option<Box<Expr>>, // For ..expr update syntax
558    },
559    ObjectLiteral {
560        fields: Vec<ObjectField>,
561    },
562    FieldAccess {
563        object: Box<Expr>,
564        field: String,
565    },
566    OptionalFieldAccess {
567        object: Box<Expr>,
568        field: String,
569    },
570    IndexAccess {
571        object: Box<Expr>,
572        index: Box<Expr>,
573    },
574    Slice {
575        object: Box<Expr>,
576        start: Option<Box<Expr>>,
577        end: Option<Box<Expr>>,
578    },
579    Trait {
580        name: String,
581        type_params: Vec<String>,
582        associated_types: Vec<String>, // type Item, type Output, etc.
583        methods: Vec<TraitMethod>,
584        is_pub: bool,
585    },
586    Impl {
587        type_params: Vec<String>,
588        trait_name: Option<String>,
589        for_type: String,
590        methods: Vec<ImplMethod>,
591        is_pub: bool,
592    },
593    Actor {
594        name: String,
595        state: Vec<StructField>,
596        handlers: Vec<ActorHandler>,
597    },
598    Send {
599        actor: Box<Expr>,
600        message: Box<Expr>,
601    },
602    Command {
603        program: String,
604        args: Vec<String>,
605        env: Vec<(String, String)>,
606        working_dir: Option<String>,
607    },
608    Ask {
609        actor: Box<Expr>,
610        message: Box<Expr>,
611        timeout: Option<Box<Expr>>,
612    },
613    /// Fire-and-forget actor send (left <- right)
614    ActorSend {
615        actor: Box<Expr>,
616        message: Box<Expr>,
617    },
618    /// Actor query with reply (left <? right)
619    ActorQuery {
620        actor: Box<Expr>,
621        message: Box<Expr>,
622    },
623    Call {
624        func: Box<Expr>,
625        args: Vec<Expr>,
626    },
627    Macro {
628        name: String,
629        args: Vec<Expr>,
630    },
631    MethodCall {
632        receiver: Box<Expr>,
633        method: String,
634        args: Vec<Expr>,
635    },
636    OptionalMethodCall {
637        receiver: Box<Expr>,
638        method: String,
639        args: Vec<Expr>,
640    },
641    Block(Vec<Expr>),
642    Pipeline {
643        expr: Box<Expr>,
644        stages: Vec<PipelineStage>,
645    },
646    Match {
647        expr: Box<Expr>,
648        arms: Vec<MatchArm>,
649    },
650    List(Vec<Expr>),
651    Set(Vec<Expr>),
652    ArrayInit {
653        value: Box<Expr>,
654        size: Box<Expr>,
655    },
656    Tuple(Vec<Expr>),
657    Spread {
658        expr: Box<Expr>,
659    },
660    ListComprehension {
661        element: Box<Expr>,
662        clauses: Vec<ComprehensionClause>,
663    },
664    SetComprehension {
665        element: Box<Expr>,
666        clauses: Vec<ComprehensionClause>,
667    },
668    DictComprehension {
669        key: Box<Expr>,
670        value: Box<Expr>,
671        clauses: Vec<ComprehensionClause>,
672    },
673    DataFrame {
674        columns: Vec<DataFrameColumn>,
675    },
676    DataFrameOperation {
677        source: Box<Expr>,
678        operation: DataFrameOp,
679    },
680    For {
681        label: Option<String>,
682        var: String,              // Keep for backward compatibility
683        pattern: Option<Pattern>, // New: Support destructuring patterns
684        iter: Box<Expr>,
685        body: Box<Expr>,
686    },
687    While {
688        label: Option<String>,
689        condition: Box<Expr>,
690        body: Box<Expr>,
691    },
692    WhileLet {
693        label: Option<String>,
694        pattern: Pattern,
695        expr: Box<Expr>,
696        body: Box<Expr>,
697    },
698    Loop {
699        label: Option<String>,
700        body: Box<Expr>,
701    },
702    Range {
703        start: Box<Expr>,
704        end: Box<Expr>,
705        inclusive: bool,
706    },
707    Module {
708        name: String,
709        body: Box<Expr>,
710    },
711    Break {
712        label: Option<String>,
713        value: Option<Box<Expr>>,
714    },
715    Continue {
716        label: Option<String>,
717    },
718    Return {
719        value: Option<Box<Expr>>,
720    },
721    Assign {
722        target: Box<Expr>,
723        value: Box<Expr>,
724    },
725    CompoundAssign {
726        target: Box<Expr>,
727        op: BinaryOp,
728        value: Box<Expr>,
729    },
730    PreIncrement {
731        target: Box<Expr>,
732    },
733    PostIncrement {
734        target: Box<Expr>,
735    },
736    PreDecrement {
737        target: Box<Expr>,
738    },
739    PostDecrement {
740        target: Box<Expr>,
741    },
742    Extension {
743        target_type: String,
744        methods: Vec<ImplMethod>,
745    },
746    /// Import statement for modules
747    Import {
748        module: String,
749        items: Option<Vec<String>>,
750    },
751    /// Import all items with an alias (import * as name)
752    ImportAll {
753        module: String,
754        alias: String,
755    },
756    /// Import default export
757    ImportDefault {
758        module: String,
759        name: String,
760    },
761    /// Export a declaration
762    Export {
763        expr: Box<Expr>,
764        is_default: bool,
765    },
766    /// Export a list of identifiers
767    ExportList {
768        names: Vec<String>,
769    },
770    /// Re-export from another module
771    ReExport {
772        items: Vec<String>,
773        module: String,
774    },
775    /// Export default declaration
776    ExportDefault {
777        expr: Box<Expr>,
778    },
779    /// Type alias declaration (type Name = Type)
780    TypeAlias {
781        name: String,
782        target_type: Type,
783    },
784    /// Macro invocation (e.g., `println!("hello")`)
785    MacroInvocation {
786        name: String,
787        args: Vec<Expr>,
788    },
789}
790/// Literal values that can appear in the source code.
791///
792/// Literals represent compile-time constant values that are directly
793/// embedded in the program. These form the base values from which
794/// more complex expressions are constructed.
795///
796/// # Examples
797///
798/// ```ignore
799/// use ruchy::frontend::ast::Literal;
800///
801/// let int = Literal::Integer(42, None);
802/// let float = Literal::Float(3.14);
803/// let string = Literal::String("hello".to_string());
804/// let boolean = Literal::Bool(true);
805/// let character = Literal::Char('a');
806/// let unit = Literal::Unit;
807/// ```
808#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
809pub enum Literal {
810    /// A signed 64-bit integer literal with optional type suffix (e.g., i32, i64, u32).
811    Integer(i64, Option<String>),
812    /// A 64-bit floating-point literal.
813    Float(f64),
814    /// A string literal.
815    String(String),
816    /// A boolean literal (`true` or `false`).
817    Bool(bool),
818    /// A character literal.
819    Char(char),
820    /// A byte literal (0-255).
821    Byte(u8),
822    /// The unit value `()`.
823    Unit,
824    /// A null value.
825    Null,
826}
827impl Literal {
828    /// Convert a REPL Value to a Literal (for synthetic expressions)
829    pub fn from_value(value: &crate::runtime::interpreter::Value) -> Self {
830        use crate::runtime::interpreter::Value;
831        match value {
832            Value::Integer(i) => Literal::Integer(*i, None),
833            Value::Float(f) => Literal::Float(*f),
834            Value::String(s) => Literal::String(s.to_string()),
835            Value::Bool(b) => Literal::Bool(*b),
836            Value::Nil => Literal::Unit,
837            _ => Literal::Unit, // Fallback for complex types
838        }
839    }
840}
841/// String interpolation parts - either literal text or an expression
842#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
843pub enum StringPart {
844    /// Literal text portion of the string
845    Text(String),
846    /// Expression to be interpolated without format specifier
847    Expr(Box<Expr>),
848    /// Expression with format specifier (e.g., {value:.2})
849    ExprWithFormat {
850        expr: Box<Expr>,
851        format_spec: String,
852    },
853}
854/// Binary operators for two-operand expressions.
855///
856/// These operators cover arithmetic, comparison, logical, and bitwise operations.
857/// Each operator has specific precedence and associativity rules defined in the parser.
858///
859/// # Examples
860///
861/// ```ignore
862/// use ruchy::frontend::ast::BinaryOp;
863///
864/// // Arithmetic: a + b * c
865/// let add = BinaryOp::Add;
866/// let mul = BinaryOp::Multiply;
867///
868/// // Comparison: x >= y
869/// let ge = BinaryOp::GreaterEqual;
870///
871/// // Logical: flag1 && flag2
872/// let and = BinaryOp::And;
873/// ```
874#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
875pub enum BinaryOp {
876    // Arithmetic
877    Add,
878    Subtract,
879    Multiply,
880    Divide,
881    Modulo,
882    Power,
883    // Comparison
884    Equal,
885    NotEqual,
886    Less,
887    LessEqual,
888    Greater,
889    GreaterEqual,
890    Gt, // Alias for Greater (for compatibility)
891    // Logical
892    And,
893    Or,
894    NullCoalesce,
895    // Bitwise
896    BitwiseAnd,
897    BitwiseOr,
898    BitwiseXor,
899    LeftShift,
900    RightShift,
901    // Actor operations
902    Send, // Actor message passing: actor ! message
903}
904/// Unary operators for single-operand expressions.
905///
906/// These operators include logical negation, arithmetic negation,
907/// bitwise complement, and reference operations.
908///
909/// # Examples
910///
911/// ```ignore
912/// use ruchy::frontend::ast::UnaryOp;
913///
914/// // Logical negation: !flag
915/// let not = UnaryOp::Not;
916///
917/// // Arithmetic negation: -value
918/// let neg = UnaryOp::Negate;
919///
920/// // Bitwise complement: ~bits
921/// let complement = UnaryOp::BitwiseNot;
922/// ```
923#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
924pub enum UnaryOp {
925    Not,
926    Negate,
927    BitwiseNot,
928    Reference,
929    MutableReference,  // PARSER-085: Added for &mut support (GitHub Issue #71)
930    Deref,
931}
932/// A function or method parameter.
933///
934/// Parameters support pattern matching for destructuring, type annotations
935/// for type checking, default values for optional parameters, and mutability
936/// modifiers.
937///
938/// # Examples
939///
940/// ```ignore
941/// // Simple parameter: x: int
942/// // Pattern parameter: (a, b): (int, int)
943/// // Optional parameter: name: string = "default"
944/// // Mutable parameter: mut buffer: Vec<u8>
945/// ```
946#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
947pub struct Param {
948    /// The pattern for destructuring the parameter.
949    pub pattern: Pattern,
950    /// The type annotation for this parameter.
951    pub ty: Type,
952    /// Source location of this parameter.
953    pub span: Span,
954    /// Whether this parameter is mutable.
955    pub is_mutable: bool,
956    /// Optional default value for this parameter.
957    pub default_value: Option<Box<Expr>>,
958}
959impl Param {
960    /// Get the primary name from this parameter pattern.
961    /// For complex patterns, this returns the first/primary identifier.
962    /// For simple patterns, this returns the identifier itself.
963    #[must_use]
964    pub fn name(&self) -> String {
965        self.pattern.primary_name()
966    }
967}
968
969#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
970pub enum Visibility {
971    Private,
972    Public,
973    PubCrate,
974    PubSuper,
975    Protected, // For future inheritance support
976}
977
978impl Visibility {
979    pub fn is_public(&self) -> bool {
980        matches!(
981            self,
982            Visibility::Public | Visibility::PubCrate | Visibility::PubSuper
983        )
984    }
985}
986
987#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
988pub struct StructField {
989    pub name: String,
990    pub ty: Type,
991    pub visibility: Visibility,
992    pub is_mut: bool,                // mut field modifier
993    pub default_value: Option<Expr>, // Default value for class fields
994    pub decorators: Vec<Decorator>,  // @PrimaryKey, @Column("name"), etc.
995}
996#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
997pub struct EnumVariant {
998    pub name: String,
999    pub kind: EnumVariantKind,
1000    pub discriminant: Option<i64>, // Explicit discriminant value for TypeScript compatibility
1001}
1002
1003#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1004pub enum EnumVariantKind {
1005    Unit,                        // Quit
1006    Tuple(Vec<Type>),            // Write(String)
1007    Struct(Vec<StructField>),    // Move { x: i32, y: i32 }
1008}
1009#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1010pub enum ObjectField {
1011    KeyValue { key: String, value: Expr },
1012    Spread { expr: Expr },
1013}
1014#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1015pub struct TraitMethod {
1016    pub name: String,
1017    pub params: Vec<Param>,
1018    pub return_type: Option<Type>,
1019    pub body: Option<Box<Expr>>, // None for method signatures, Some for default implementations
1020    pub is_pub: bool,
1021}
1022#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1023pub struct ImplMethod {
1024    pub name: String,
1025    pub params: Vec<Param>,
1026    pub return_type: Option<Type>,
1027    pub body: Box<Expr>,
1028    pub is_pub: bool,
1029}
1030#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1031pub struct ActorHandler {
1032    pub message_type: String,
1033    pub params: Vec<Param>,
1034    pub body: Box<Expr>,
1035}
1036
1037#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1038pub struct ClassMethod {
1039    pub name: String,
1040    pub params: Vec<Param>,
1041    pub return_type: Option<Type>,
1042    pub body: Box<Expr>,
1043    pub is_pub: bool,
1044    pub is_static: bool,     // static method (no self)
1045    pub is_override: bool,   // override keyword for explicit overriding
1046    pub is_final: bool,      // final method (cannot be overridden)
1047    pub is_abstract: bool,   // abstract method (no implementation)
1048    pub self_type: SelfType, // &self, &mut self, or self (move)
1049}
1050
1051#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1052pub struct ClassConstant {
1053    pub name: String,
1054    pub ty: Type,
1055    pub value: Expr,
1056    pub is_pub: bool,
1057}
1058
1059#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1060pub struct ClassProperty {
1061    pub name: String,
1062    pub ty: Type,
1063    pub getter: Option<Box<Expr>>,
1064    pub setter: Option<PropertySetter>,
1065    pub is_pub: bool,
1066}
1067
1068#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1069pub struct PropertySetter {
1070    pub param_name: String,
1071    pub body: Box<Expr>,
1072}
1073
1074#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1075pub enum SelfType {
1076    None,        // static method
1077    Owned,       // self (move)
1078    Borrowed,    // &self
1079    MutBorrowed, // &mut self
1080}
1081
1082#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1083pub struct Constructor {
1084    pub name: Option<String>, // None for primary constructor, Some(name) for named constructors
1085    pub params: Vec<Param>,
1086    pub return_type: Option<Type>, // Optional return type for named constructors (e.g., Result<Self>)
1087    pub body: Box<Expr>,
1088    pub is_pub: bool,
1089}
1090/// Type annotations in the AST.
1091///
1092/// Types provide static type information for type checking and code generation.
1093/// Ruchy supports a rich type system including generics, optionals, references,
1094/// and specialized types for dataframes and async operations.
1095///
1096/// # Examples
1097///
1098/// ```ignore
1099/// use ruchy::frontend::ast::{Type, TypeKind, Span};
1100///
1101/// // Simple named type: int
1102/// let int_type = Type {
1103///     kind: TypeKind::Named("int".to_string()),
1104///     span: Span::new(0, 3),
1105/// };
1106///
1107/// // Generic type: Vec<string>
1108/// let vec_type = Type {
1109///     kind: TypeKind::Generic {
1110///         base: "Vec".to_string(),
1111///         params: vec![string_type],
1112///     },
1113///     span: Span::new(0, 11),
1114/// };
1115/// ```
1116#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1117pub struct Type {
1118    /// The specific type variant.
1119    pub kind: TypeKind,
1120    /// Source location of this type annotation.
1121    pub span: Span,
1122}
1123/// Specific type variants supported by Ruchy.
1124///
1125/// This enumeration covers all type forms from simple named types
1126/// to complex generic, functional, and structural types.
1127#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1128pub enum TypeKind {
1129    Named(String),
1130    Generic {
1131        base: String,
1132        params: Vec<Type>,
1133    },
1134    Optional(Box<Type>),
1135    List(Box<Type>),
1136    Array {
1137        elem_type: Box<Type>,
1138        size: usize,
1139    },
1140    Tuple(Vec<Type>),
1141    Function {
1142        params: Vec<Type>,
1143        ret: Box<Type>,
1144    },
1145    DataFrame {
1146        columns: Vec<(String, Type)>,
1147    },
1148    Series {
1149        dtype: Box<Type>,
1150    },
1151    Reference {
1152        is_mut: bool,
1153        lifetime: Option<String>,
1154        inner: Box<Type>,
1155    },
1156}
1157#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1158pub struct PipelineStage {
1159    pub op: Box<Expr>,
1160    pub span: Span,
1161}
1162/// An arm in a match expression.
1163///
1164/// Match arms consist of a pattern to match against, an optional guard
1165/// condition for additional filtering, and a body expression to execute
1166/// when the pattern matches.
1167///
1168/// # Examples
1169///
1170/// ```ignore
1171/// match value {
1172///     Some(x) if x > 0 => x * 2,  // Pattern with guard
1173///     None => 0,                   // Simple pattern
1174///     _ => -1,                     // Wildcard pattern
1175/// }
1176/// ```
1177#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1178pub struct MatchArm {
1179    /// The pattern to match against.
1180    pub pattern: Pattern,
1181    /// Optional guard condition that must be true for this arm to match.
1182    pub guard: Option<Box<Expr>>,
1183    /// The expression to execute when this arm matches.
1184    pub body: Box<Expr>,
1185    /// Source location of this match arm.
1186    pub span: Span,
1187}
1188/// Patterns for destructuring and matching values.
1189///
1190/// Patterns are used in match expressions, let bindings, function parameters,
1191/// and other contexts where values need to be destructured or tested against
1192/// a structure. Ruchy supports a rich pattern language including literals,
1193/// destructuring, ranges, and alternative patterns.
1194///
1195/// # Pattern Types
1196///
1197/// - **Wildcard**: `_` matches anything
1198/// - **Literal**: Matches exact values
1199/// - **Identifier**: Binds matched value to a name
1200/// - **Tuple/List**: Destructures sequences
1201/// - **Struct**: Destructures struct fields
1202/// - **Or**: Matches any of several patterns
1203/// - **Rest**: Captures remaining elements
1204///
1205/// # Examples
1206///
1207/// ```ignore
1208/// match value {
1209///     0 => "zero",                    // Literal pattern
1210///     1..=10 => "small",              // Range pattern
1211///     Some(x) => format!("value: {x}"), // Enum pattern
1212///     [first, ..rest] => "list",     // List pattern with rest
1213///     _ => "other",                   // Wildcard
1214/// }
1215/// ```
1216#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1217pub enum Pattern {
1218    Wildcard,
1219    Literal(Literal),
1220    Identifier(String),
1221    QualifiedName(Vec<String>), // For patterns like Ordering::Less
1222    Tuple(Vec<Pattern>),
1223    List(Vec<Pattern>),
1224    Struct {
1225        name: String,
1226        fields: Vec<StructPatternField>,
1227        has_rest: bool,
1228    },
1229    TupleVariant {
1230        path: Vec<String>,      // e.g., ["Message", "Text"]
1231        patterns: Vec<Pattern>, // Arguments like (n) or (a, b)
1232    }, // For enum tuple variants like Message::Text(n)
1233    Range {
1234        start: Box<Pattern>,
1235        end: Box<Pattern>,
1236        inclusive: bool,
1237    },
1238    Or(Vec<Pattern>),
1239    Rest,              // For ... patterns
1240    RestNamed(String), // For ..name patterns
1241    AtBinding {
1242        name: String,
1243        pattern: Box<Pattern>,
1244    }, // For @ bindings like name @ pattern
1245    WithDefault {
1246        pattern: Box<Pattern>,
1247        default: Box<Expr>,
1248    }, // For patterns with default values like a = 10
1249    Mut(Box<Pattern>), // For mutable bindings in destructuring like (mut x, mut y)
1250    Ok(Box<Pattern>),
1251    Err(Box<Pattern>),
1252    Some(Box<Pattern>),
1253    None,
1254}
1255impl Pattern {
1256    /// Get the primary identifier name from this pattern.
1257    /// For complex patterns, returns the first/most significant identifier.
1258    #[must_use]
1259    pub fn primary_name(&self) -> String {
1260        match self {
1261            Pattern::Identifier(name) => name.clone(),
1262            Pattern::QualifiedName(path) => path.join("::"),
1263            Pattern::Tuple(patterns) => {
1264                // Return the name of the first pattern
1265                patterns
1266                    .first()
1267                    .map_or_else(|| "_tuple".to_string(), Pattern::primary_name)
1268            }
1269            Pattern::List(patterns) => {
1270                // Return the name of the first pattern
1271                patterns
1272                    .first()
1273                    .map_or_else(|| "_list".to_string(), Pattern::primary_name)
1274            }
1275            Pattern::Struct { name, fields, .. } => {
1276                // Return the struct type name, or first field name if anonymous
1277                if name.is_empty() {
1278                    fields
1279                        .first()
1280                        .map_or_else(|| "_struct".to_string(), |f| f.name.clone())
1281                } else {
1282                    name.clone()
1283                }
1284            }
1285            Pattern::TupleVariant { path, patterns } => {
1286                // For enum tuple variants, get first pattern's name or variant path
1287                patterns
1288                    .first()
1289                    .map_or_else(|| path.join("::"), Pattern::primary_name)
1290            }
1291            Pattern::Ok(inner) | Pattern::Err(inner) | Pattern::Some(inner) => inner.primary_name(),
1292            Pattern::None => "_none".to_string(),
1293            Pattern::Or(patterns) => {
1294                // Return the name of the first pattern
1295                patterns
1296                    .first()
1297                    .map_or_else(|| "_or".to_string(), Pattern::primary_name)
1298            }
1299            Pattern::Wildcard => "_".to_string(),
1300            Pattern::Rest => "_rest".to_string(),
1301            Pattern::RestNamed(name) => name.clone(),
1302            Pattern::AtBinding { name, .. } => name.clone(),
1303            Pattern::WithDefault { pattern, .. } => pattern.primary_name(),
1304            Pattern::Mut(inner) => inner.primary_name(),
1305            Pattern::Literal(lit) => format!("_literal_{lit:?}"),
1306            Pattern::Range { .. } => "_range".to_string(),
1307        }
1308    }
1309}
1310/// A field in a struct destructuring pattern.
1311///
1312/// Supports both explicit field patterns (`field: pattern`) and
1313/// shorthand syntax (`field` as shorthand for `field: field`).
1314#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1315pub struct StructPatternField {
1316    /// The field name to match.
1317    pub name: String,
1318    /// The pattern for this field's value (None for shorthand syntax).
1319    pub pattern: Option<Pattern>,
1320}
1321/// Definition of a custom error type.
1322///
1323/// Custom error types allow defining domain-specific error structures
1324/// with typed fields and optional inheritance from base error types.
1325///
1326/// # Examples
1327///
1328/// ```ignore
1329/// error NetworkError {
1330///     code: int,
1331///     message: string,
1332/// } extends IOError
1333/// ```
1334#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1335pub struct ErrorTypeDef {
1336    /// The name of this error type.
1337    pub name: String,
1338    /// Fields contained in this error type.
1339    pub fields: Vec<StructField>,
1340    /// Optional parent error type to inherit from.
1341    pub extends: Option<String>,
1342}
1343/// Compiler attributes for annotating expressions.
1344///
1345/// Attributes provide metadata that influences compilation, optimization,
1346/// and runtime behavior. They use the `#[name(args)]` syntax similar to Rust.
1347///
1348/// # Common Attributes
1349///
1350/// - `#[inline]`: Hint for function inlining
1351/// - `#[test]`: Mark function as a test
1352/// - `#[property]`: Mark as a property accessor
1353/// - `#[deprecated("message")]`: Mark as deprecated
1354///
1355/// # Examples
1356///
1357/// ```ignore
1358/// #[inline]
1359/// #[property]
1360/// fn get_value() -> int {
1361///     self.value
1362/// }
1363/// ```
1364#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1365pub struct Attribute {
1366    pub name: String,
1367    pub args: Vec<String>,
1368    pub span: Span,
1369}
1370
1371/// Represents a decorator (@name or @name(...))
1372#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1373pub struct Decorator {
1374    pub name: String,
1375    pub args: Vec<String>,
1376}
1377#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1378pub struct DataFrameColumn {
1379    pub name: String,
1380    pub values: Vec<Expr>,
1381}
1382/// Operations on `DataFrame` values.
1383///
1384/// `DataFrames` are Ruchy's built-in tabular data structure, similar to
1385/// pandas `DataFrames` or SQL tables. These operations provide a fluent
1386/// API for data manipulation and analysis.
1387///
1388/// # Examples
1389///
1390/// ```ignore
1391/// df.filter(x => x.age > 18)
1392///   .select(["name", "email"])
1393///   .sort(["name"])
1394///   .limit(10)
1395/// ```
1396#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1397pub enum DataFrameOp {
1398    Filter(Box<Expr>),
1399    Select(Vec<String>),
1400    GroupBy(Vec<String>),
1401    Sort(Vec<String>),
1402    Join {
1403        other: Box<Expr>,
1404        on: Vec<String>,
1405        how: JoinType,
1406    },
1407    Aggregate(Vec<AggregateOp>),
1408    Limit(usize),
1409    Head(usize),
1410    Tail(usize),
1411}
1412#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1413pub enum JoinType {
1414    Inner,
1415    Left,
1416    Right,
1417    Outer,
1418}
1419#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1420pub enum ImportItem {
1421    /// Import a specific name: `use std::collections::HashMap`
1422    Named(String),
1423    /// Import with alias: `use std::collections::HashMap as Map`
1424    Aliased { name: String, alias: String },
1425    /// Import all: `use std::collections::*`
1426    Wildcard,
1427}
1428impl ImportItem {
1429    /// Check if this import is for a URL module
1430    pub fn is_url_import(path: &str) -> bool {
1431        path.starts_with("https://") || path.starts_with("http://")
1432    }
1433}
1434#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1435pub enum AggregateOp {
1436    Sum(String),
1437    Mean(String),
1438    Min(String),
1439    Max(String),
1440    Count(String),
1441    Std(String),
1442    Var(String),
1443}
1444impl fmt::Display for BinaryOp {
1445    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1446        match self {
1447            Self::Add => write!(f, "+"),
1448            Self::Subtract => write!(f, "-"),
1449            Self::Multiply => write!(f, "*"),
1450            Self::Divide => write!(f, "/"),
1451            Self::Modulo => write!(f, "%"),
1452            Self::Power => write!(f, "**"),
1453            Self::Equal => write!(f, "=="),
1454            Self::NotEqual => write!(f, "!="),
1455            Self::Less => write!(f, "<"),
1456            Self::LessEqual => write!(f, "<="),
1457            Self::Greater => write!(f, ">"),
1458            Self::GreaterEqual => write!(f, ">="),
1459            Self::And => write!(f, "&&"),
1460            Self::Or => write!(f, "||"),
1461            Self::NullCoalesce => write!(f, "??"),
1462            Self::BitwiseAnd => write!(f, "&"),
1463            Self::BitwiseOr => write!(f, "|"),
1464            Self::BitwiseXor => write!(f, "^"),
1465            Self::LeftShift => write!(f, "<<"),
1466            Self::RightShift => write!(f, ">>"),
1467            Self::Gt => write!(f, ">"),
1468            Self::Send => write!(f, "!"),
1469        }
1470    }
1471}
1472impl fmt::Display for UnaryOp {
1473    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1474        match self {
1475            Self::Not => write!(f, "!"),
1476            Self::Negate => write!(f, "-"),
1477            Self::BitwiseNot => write!(f, "~"),
1478            Self::Reference => write!(f, "&"),
1479            Self::MutableReference => write!(f, "&mut "),  // PARSER-085: Issue #71
1480            Self::Deref => write!(f, "*"),
1481        }
1482    }
1483}
1484#[cfg(test)]
1485#[allow(clippy::unwrap_used, clippy::panic, clippy::expect_used)]
1486mod tests {
1487    use super::*;
1488    use proptest::prelude::*;
1489    proptest! {
1490        #[test]
1491        fn test_span_merge(start1 in 0usize..1000, end1 in 0usize..1000,
1492                          start2 in 0usize..1000, end2 in 0usize..1000) {
1493            let span1 = Span::new(start1, end1);
1494            let span2 = Span::new(start2, end2);
1495            let merged = span1.merge(span2);
1496            prop_assert!(merged.start <= span1.start);
1497            prop_assert!(merged.start <= span2.start);
1498            prop_assert!(merged.end >= span1.end);
1499            prop_assert!(merged.end >= span2.end);
1500        }
1501    }
1502    #[test]
1503    fn test_ast_size() {
1504        // Track AST node sizes for optimization
1505        let expr_size = std::mem::size_of::<Expr>();
1506        let kind_size = std::mem::size_of::<ExprKind>();
1507        // Current sizes are larger than ideal but acceptable for MVP
1508        // Future optimization: Use arena allocation and indices
1509        // Increased limits after adding more OOP features and comment tracking
1510        assert!(expr_size <= 400, "Expr too large: {expr_size} bytes");
1511        assert!(kind_size <= 280, "ExprKind too large: {kind_size} bytes");
1512    }
1513    #[test]
1514    fn test_span_creation() {
1515        let span = Span::new(10, 20);
1516        assert_eq!(span.start, 10);
1517        assert_eq!(span.end, 20);
1518    }
1519    #[test]
1520    fn test_span_merge_simple() {
1521        let span1 = Span::new(5, 10);
1522        let span2 = Span::new(8, 15);
1523        let merged = span1.merge(span2);
1524        assert_eq!(merged.start, 5);
1525        assert_eq!(merged.end, 15);
1526    }
1527    #[test]
1528    fn test_span_merge_disjoint() {
1529        let span1 = Span::new(0, 5);
1530        let span2 = Span::new(10, 15);
1531        let merged = span1.merge(span2);
1532        assert_eq!(merged.start, 0);
1533        assert_eq!(merged.end, 15);
1534    }
1535    #[test]
1536    fn test_expr_creation() {
1537        let span = Span::new(0, 10);
1538        let expr = Expr::new(ExprKind::Literal(Literal::Integer(42, None)), span);
1539        assert_eq!(expr.span.start, 0);
1540        assert_eq!(expr.span.end, 10);
1541        match expr.kind {
1542            ExprKind::Literal(Literal::Integer(n, None)) => assert_eq!(n, 42),
1543            _ => panic!("Wrong expression kind"),
1544        }
1545    }
1546    #[test]
1547    fn test_literal_variants() {
1548        let literals = vec![
1549            Literal::Integer(42, None),
1550            #[allow(clippy::approx_constant)]
1551            Literal::Float(3.14), // Not PI, just a test value
1552            Literal::String("hello".to_string()),
1553            Literal::Bool(true),
1554            Literal::Unit,
1555        ];
1556        for lit in literals {
1557            let expr = Expr::new(ExprKind::Literal(lit.clone()), Span::new(0, 0));
1558            match expr.kind {
1559                ExprKind::Literal(l) => assert_eq!(l, lit),
1560                _ => panic!("Expected literal"),
1561            }
1562        }
1563    }
1564    #[test]
1565    fn test_binary_op_display() {
1566        assert_eq!(BinaryOp::Add.to_string(), "+");
1567        assert_eq!(BinaryOp::Subtract.to_string(), "-");
1568        assert_eq!(BinaryOp::Multiply.to_string(), "*");
1569        assert_eq!(BinaryOp::Divide.to_string(), "/");
1570        assert_eq!(BinaryOp::Modulo.to_string(), "%");
1571        assert_eq!(BinaryOp::Power.to_string(), "**");
1572        assert_eq!(BinaryOp::Equal.to_string(), "==");
1573        assert_eq!(BinaryOp::NotEqual.to_string(), "!=");
1574        assert_eq!(BinaryOp::Less.to_string(), "<");
1575        assert_eq!(BinaryOp::LessEqual.to_string(), "<=");
1576        assert_eq!(BinaryOp::Greater.to_string(), ">");
1577        assert_eq!(BinaryOp::GreaterEqual.to_string(), ">=");
1578        assert_eq!(BinaryOp::And.to_string(), "&&");
1579        assert_eq!(BinaryOp::Or.to_string(), "||");
1580        assert_eq!(BinaryOp::BitwiseAnd.to_string(), "&");
1581        assert_eq!(BinaryOp::BitwiseOr.to_string(), "|");
1582        assert_eq!(BinaryOp::BitwiseXor.to_string(), "^");
1583        assert_eq!(BinaryOp::LeftShift.to_string(), "<<");
1584    }
1585    #[test]
1586    fn test_unary_op_display() {
1587        assert_eq!(UnaryOp::Not.to_string(), "!");
1588        assert_eq!(UnaryOp::Negate.to_string(), "-");
1589        assert_eq!(UnaryOp::BitwiseNot.to_string(), "~");
1590        assert_eq!(UnaryOp::Reference.to_string(), "&");
1591    }
1592    #[test]
1593    fn test_binary_expression() {
1594        let left = Box::new(Expr::new(
1595            ExprKind::Literal(Literal::Integer(1, None)),
1596            Span::new(0, 1),
1597        ));
1598        let right = Box::new(Expr::new(
1599            ExprKind::Literal(Literal::Integer(2, None)),
1600            Span::new(4, 5),
1601        ));
1602        let expr = Expr::new(
1603            ExprKind::Binary {
1604                left,
1605                op: BinaryOp::Add,
1606                right,
1607            },
1608            Span::new(0, 5),
1609        );
1610        match expr.kind {
1611            ExprKind::Binary {
1612                left: l,
1613                op,
1614                right: r,
1615            } => {
1616                assert_eq!(op, BinaryOp::Add);
1617                match l.kind {
1618                    ExprKind::Literal(Literal::Integer(n, None)) => assert_eq!(n, 1),
1619                    _ => panic!("Wrong left operand"),
1620                }
1621                match r.kind {
1622                    ExprKind::Literal(Literal::Integer(n, None)) => assert_eq!(n, 2),
1623                    _ => panic!("Wrong right operand"),
1624                }
1625            }
1626            _ => panic!("Expected binary expression"),
1627        }
1628    }
1629    #[test]
1630    fn test_unary_expression() {
1631        let operand = Box::new(Expr::new(
1632            ExprKind::Literal(Literal::Bool(true)),
1633            Span::new(1, 5),
1634        ));
1635        let expr = Expr::new(
1636            ExprKind::Unary {
1637                op: UnaryOp::Not,
1638                operand,
1639            },
1640            Span::new(0, 5),
1641        );
1642        match expr.kind {
1643            ExprKind::Unary { op, operand } => {
1644                assert_eq!(op, UnaryOp::Not);
1645                match operand.kind {
1646                    ExprKind::Literal(Literal::Bool(b)) => assert!(b),
1647                    _ => panic!("Wrong operand"),
1648                }
1649            }
1650            _ => panic!("Expected unary expression"),
1651        }
1652    }
1653    #[test]
1654    fn test_if_expression() {
1655        let condition = Box::new(Expr::new(
1656            ExprKind::Literal(Literal::Bool(true)),
1657            Span::new(3, 7),
1658        ));
1659        let then_branch = Box::new(Expr::new(
1660            ExprKind::Literal(Literal::Integer(1, None)),
1661            Span::new(10, 11),
1662        ));
1663        let else_branch = Some(Box::new(Expr::new(
1664            ExprKind::Literal(Literal::Integer(2, None)),
1665            Span::new(17, 18),
1666        )));
1667        let expr = Expr::new(
1668            ExprKind::If {
1669                condition,
1670                then_branch,
1671                else_branch,
1672            },
1673            Span::new(0, 18),
1674        );
1675        match expr.kind {
1676            ExprKind::If {
1677                condition: c,
1678                then_branch: t,
1679                else_branch: e,
1680            } => {
1681                match c.kind {
1682                    ExprKind::Literal(Literal::Bool(b)) => assert!(b),
1683                    _ => panic!("Wrong condition"),
1684                }
1685                match t.kind {
1686                    ExprKind::Literal(Literal::Integer(n, None)) => assert_eq!(n, 1),
1687                    _ => panic!("Wrong then branch"),
1688                }
1689                assert!(e.is_some());
1690                if let Some(else_expr) = e {
1691                    match else_expr.kind {
1692                        ExprKind::Literal(Literal::Integer(n, None)) => assert_eq!(n, 2),
1693                        _ => panic!("Wrong else branch"),
1694                    }
1695                }
1696            }
1697            _ => panic!("Expected if expression"),
1698        }
1699    }
1700    #[test]
1701    fn test_let_expression() {
1702        let value = Box::new(Expr::new(
1703            ExprKind::Literal(Literal::Integer(42, None)),
1704            Span::new(8, 10),
1705        ));
1706        let body = Box::new(Expr::new(
1707            ExprKind::Identifier("x".to_string()),
1708            Span::new(14, 15),
1709        ));
1710        let expr = Expr::new(
1711            ExprKind::Let {
1712                name: "x".to_string(),
1713                type_annotation: None,
1714                value,
1715                body,
1716                is_mutable: false,
1717                else_block: None,
1718            },
1719            Span::new(0, 15),
1720        );
1721        match expr.kind {
1722            ExprKind::Let {
1723                name,
1724                value: v,
1725                body: b,
1726                ..
1727            } => {
1728                assert_eq!(name, "x");
1729                match v.kind {
1730                    ExprKind::Literal(Literal::Integer(n, None)) => assert_eq!(n, 42),
1731                    _ => panic!("Wrong value"),
1732                }
1733                match b.kind {
1734                    ExprKind::Identifier(id) => assert_eq!(id, "x"),
1735                    _ => panic!("Wrong body"),
1736                }
1737            }
1738            _ => panic!("Expected let expression"),
1739        }
1740    }
1741    #[test]
1742    fn test_function_expression() {
1743        let params = vec![Param {
1744            pattern: Pattern::Identifier("x".to_string()),
1745            ty: Type {
1746                kind: TypeKind::Named("i32".to_string()),
1747                span: Span::new(10, 13),
1748            },
1749            span: Span::new(8, 13),
1750            is_mutable: false,
1751            default_value: None,
1752        }];
1753        let body = Box::new(Expr::new(
1754            ExprKind::Identifier("x".to_string()),
1755            Span::new(20, 21),
1756        ));
1757        let expr = Expr::new(
1758            ExprKind::Function {
1759                name: "identity".to_string(),
1760                type_params: vec![],
1761                params,
1762                return_type: Some(Type {
1763                    kind: TypeKind::Named("i32".to_string()),
1764                    span: Span::new(16, 19),
1765                }),
1766                body,
1767                is_async: false,
1768                is_pub: false,
1769            },
1770            Span::new(0, 22),
1771        );
1772        match expr.kind {
1773            ExprKind::Function {
1774                name,
1775                params: p,
1776                return_type,
1777                body: b,
1778                ..
1779            } => {
1780                assert_eq!(name, "identity");
1781                assert_eq!(p.len(), 1);
1782                assert_eq!(p[0].name(), "x");
1783                assert!(return_type.is_some());
1784                match b.kind {
1785                    ExprKind::Identifier(id) => assert_eq!(id, "x"),
1786                    _ => panic!("Wrong body"),
1787                }
1788            }
1789            _ => panic!("Expected function expression"),
1790        }
1791    }
1792    #[test]
1793    fn test_call_expression() {
1794        let func = Box::new(Expr::new(
1795            ExprKind::Identifier("add".to_string()),
1796            Span::new(0, 3),
1797        ));
1798        let args = vec![
1799            Expr::new(
1800                ExprKind::Literal(Literal::Integer(1, None)),
1801                Span::new(4, 5),
1802            ),
1803            Expr::new(
1804                ExprKind::Literal(Literal::Integer(2, None)),
1805                Span::new(7, 8),
1806            ),
1807        ];
1808        let expr = Expr::new(ExprKind::Call { func, args }, Span::new(0, 9));
1809        match expr.kind {
1810            ExprKind::Call { func: f, args: a } => {
1811                match f.kind {
1812                    ExprKind::Identifier(name) => assert_eq!(name, "add"),
1813                    _ => panic!("Wrong function"),
1814                }
1815                assert_eq!(a.len(), 2);
1816            }
1817            _ => panic!("Expected call expression"),
1818        }
1819    }
1820    #[test]
1821    fn test_block_expression() {
1822        let exprs = vec![
1823            Expr::new(
1824                ExprKind::Literal(Literal::Integer(1, None)),
1825                Span::new(2, 3),
1826            ),
1827            Expr::new(
1828                ExprKind::Literal(Literal::Integer(2, None)),
1829                Span::new(5, 6),
1830            ),
1831        ];
1832        let expr = Expr::new(ExprKind::Block(exprs), Span::new(0, 8));
1833        match expr.kind {
1834            ExprKind::Block(block) => {
1835                assert_eq!(block.len(), 2);
1836            }
1837            _ => panic!("Expected block expression"),
1838        }
1839    }
1840    #[test]
1841    fn test_list_expression() {
1842        let items = vec![
1843            Expr::new(
1844                ExprKind::Literal(Literal::Integer(1, None)),
1845                Span::new(1, 2),
1846            ),
1847            Expr::new(
1848                ExprKind::Literal(Literal::Integer(2, None)),
1849                Span::new(4, 5),
1850            ),
1851            Expr::new(
1852                ExprKind::Literal(Literal::Integer(3, None)),
1853                Span::new(7, 8),
1854            ),
1855        ];
1856        let expr = Expr::new(ExprKind::List(items), Span::new(0, 9));
1857        match expr.kind {
1858            ExprKind::List(list) => {
1859                assert_eq!(list.len(), 3);
1860            }
1861            _ => panic!("Expected list expression"),
1862        }
1863    }
1864    #[test]
1865    fn test_for_expression() {
1866        let iter = Box::new(Expr::new(
1867            ExprKind::Range {
1868                start: Box::new(Expr::new(
1869                    ExprKind::Literal(Literal::Integer(0, None)),
1870                    Span::new(10, 11),
1871                )),
1872                end: Box::new(Expr::new(
1873                    ExprKind::Literal(Literal::Integer(10, None)),
1874                    Span::new(13, 15),
1875                )),
1876                inclusive: false,
1877            },
1878            Span::new(10, 15),
1879        ));
1880        let body = Box::new(Expr::new(
1881            ExprKind::Identifier("i".to_string()),
1882            Span::new(20, 21),
1883        ));
1884        let expr = Expr::new(
1885            ExprKind::For {
1886                label: None,
1887                var: "i".to_string(),
1888                pattern: None,
1889                iter,
1890                body,
1891            },
1892            Span::new(0, 22),
1893        );
1894        match expr.kind {
1895            ExprKind::For {
1896                label: None,
1897                var,
1898                iter: it,
1899                body: b,
1900                ..
1901            } => {
1902                assert_eq!(var, "i");
1903                match it.kind {
1904                    ExprKind::Range { .. } => {}
1905                    _ => panic!("Wrong iterator"),
1906                }
1907                match b.kind {
1908                    ExprKind::Identifier(id) => assert_eq!(id, "i"),
1909                    _ => panic!("Wrong body"),
1910                }
1911            }
1912            _ => panic!("Expected for expression"),
1913        }
1914    }
1915    #[test]
1916    fn test_range_expression() {
1917        let start = Box::new(Expr::new(
1918            ExprKind::Literal(Literal::Integer(1, None)),
1919            Span::new(0, 1),
1920        ));
1921        let end = Box::new(Expr::new(
1922            ExprKind::Literal(Literal::Integer(10, None)),
1923            Span::new(3, 5),
1924        ));
1925        let expr = Expr::new(
1926            ExprKind::Range {
1927                start,
1928                end,
1929                inclusive: false,
1930            },
1931            Span::new(0, 5),
1932        );
1933        match expr.kind {
1934            ExprKind::Range {
1935                start: s,
1936                end: e,
1937                inclusive,
1938            } => {
1939                assert!(!inclusive);
1940                match s.kind {
1941                    ExprKind::Literal(Literal::Integer(n, None)) => assert_eq!(n, 1),
1942                    _ => panic!("Wrong start"),
1943                }
1944                match e.kind {
1945                    ExprKind::Literal(Literal::Integer(n, None)) => assert_eq!(n, 10),
1946                    _ => panic!("Wrong end"),
1947                }
1948            }
1949            _ => panic!("Expected range expression"),
1950        }
1951    }
1952    // Test disabled: Import AST structure pending redesign
1953    // #[test]
1954    // fn test_import_expression() {
1955    //     let expr = Expr::new(
1956    //         ExprKind::Import {
1957    //             module: "std::collections".to_string(),
1958    //             items: Some(vec!["HashMap".to_string(), "HashSet".to_string()]),
1959    //         },
1960    //         Span::new(0, 30),
1961    //     );
1962    //     match expr.kind {
1963    //         ExprKind::Import { module, items } => {
1964    //             assert_eq!(module, "std::collections");
1965    //             assert!(items.is_some());
1966    //         }
1967    //         _ => panic!("Expected import expression"),
1968    //     }
1969    // }
1970    #[test]
1971    fn test_pipeline_expression() {
1972        let expr_start = Box::new(Expr::new(
1973            ExprKind::List(vec![
1974                Expr::new(
1975                    ExprKind::Literal(Literal::Integer(1, None)),
1976                    Span::new(1, 2),
1977                ),
1978                Expr::new(
1979                    ExprKind::Literal(Literal::Integer(2, None)),
1980                    Span::new(4, 5),
1981                ),
1982            ]),
1983            Span::new(0, 6),
1984        ));
1985        let stages = vec![PipelineStage {
1986            op: Box::new(Expr::new(
1987                ExprKind::Identifier("filter".to_string()),
1988                Span::new(10, 16),
1989            )),
1990            span: Span::new(10, 16),
1991        }];
1992        let expr = Expr::new(
1993            ExprKind::Pipeline {
1994                expr: expr_start,
1995                stages,
1996            },
1997            Span::new(0, 16),
1998        );
1999        match expr.kind {
2000            ExprKind::Pipeline { expr: e, stages: s } => {
2001                assert_eq!(s.len(), 1);
2002                match e.kind {
2003                    ExprKind::List(list) => assert_eq!(list.len(), 2),
2004                    _ => panic!("Wrong pipeline start"),
2005                }
2006            }
2007            _ => panic!("Expected pipeline expression"),
2008        }
2009    }
2010    #[test]
2011    fn test_match_expression() {
2012        let expr_to_match = Box::new(Expr::new(
2013            ExprKind::Identifier("x".to_string()),
2014            Span::new(6, 7),
2015        ));
2016        let arms = vec![
2017            MatchArm {
2018                pattern: Pattern::Literal(Literal::Integer(1, None)),
2019                guard: None,
2020                body: Box::new(Expr::new(
2021                    ExprKind::Literal(Literal::String("one".to_string())),
2022                    Span::new(15, 20),
2023                )),
2024                span: Span::new(10, 20),
2025            },
2026            MatchArm {
2027                pattern: Pattern::Wildcard,
2028                guard: None,
2029                body: Box::new(Expr::new(
2030                    ExprKind::Literal(Literal::String("other".to_string())),
2031                    Span::new(28, 35),
2032                )),
2033                span: Span::new(25, 35),
2034            },
2035        ];
2036        let expr = Expr::new(
2037            ExprKind::Match {
2038                expr: expr_to_match,
2039                arms,
2040            },
2041            Span::new(0, 36),
2042        );
2043        match expr.kind {
2044            ExprKind::Match { expr: e, arms: a } => {
2045                assert_eq!(a.len(), 2);
2046                match e.kind {
2047                    ExprKind::Identifier(id) => assert_eq!(id, "x"),
2048                    _ => panic!("Wrong match expression"),
2049                }
2050            }
2051            _ => panic!("Expected match expression"),
2052        }
2053    }
2054    #[test]
2055    fn test_pattern_variants() {
2056        let patterns = vec![
2057            Pattern::Wildcard,
2058            Pattern::Literal(Literal::Integer(42, None)),
2059            Pattern::Identifier("x".to_string()),
2060            Pattern::Tuple(vec![
2061                Pattern::Literal(Literal::Integer(1, None)),
2062                Pattern::Identifier("x".to_string()),
2063            ]),
2064            Pattern::List(vec![
2065                Pattern::Literal(Literal::Integer(1, None)),
2066                Pattern::Literal(Literal::Integer(2, None)),
2067            ]),
2068            Pattern::Struct {
2069                name: "Point".to_string(),
2070                fields: vec![StructPatternField {
2071                    name: "x".to_string(),
2072                    pattern: Some(Pattern::Identifier("x".to_string())),
2073                }],
2074                has_rest: false,
2075            },
2076            Pattern::Range {
2077                start: Box::new(Pattern::Literal(Literal::Integer(1, None))),
2078                end: Box::new(Pattern::Literal(Literal::Integer(10, None))),
2079                inclusive: true,
2080            },
2081            Pattern::Or(vec![
2082                Pattern::Literal(Literal::Integer(1, None)),
2083                Pattern::Literal(Literal::Integer(2, None)),
2084            ]),
2085            Pattern::Rest,
2086        ];
2087        for pattern in patterns {
2088            match pattern {
2089                Pattern::Tuple(list) | Pattern::List(list) => assert!(!list.is_empty()),
2090                Pattern::Struct { fields, .. } => assert!(!fields.is_empty()),
2091                Pattern::Or(patterns) => assert!(!patterns.is_empty()),
2092                Pattern::Range { .. }
2093                | Pattern::Wildcard
2094                | Pattern::Literal(_)
2095                | Pattern::Identifier(_)
2096                | Pattern::Rest
2097                | Pattern::RestNamed(_)
2098                | Pattern::Ok(_)
2099                | Pattern::Err(_)
2100                | Pattern::Some(_)
2101                | Pattern::None
2102                | Pattern::QualifiedName(_)
2103                | Pattern::AtBinding { .. }
2104                | Pattern::WithDefault { .. }
2105                | Pattern::Mut(_)
2106                | Pattern::TupleVariant { .. } => {} // Simple patterns
2107            }
2108        }
2109    }
2110    #[test]
2111    fn test_type_kinds() {
2112        let types = vec![
2113            Type {
2114                kind: TypeKind::Named("i32".to_string()),
2115                span: Span::new(0, 3),
2116            },
2117            Type {
2118                kind: TypeKind::Optional(Box::new(Type {
2119                    kind: TypeKind::Named("String".to_string()),
2120                    span: Span::new(0, 6),
2121                })),
2122                span: Span::new(0, 7),
2123            },
2124            Type {
2125                kind: TypeKind::List(Box::new(Type {
2126                    kind: TypeKind::Named("f64".to_string()),
2127                    span: Span::new(1, 4),
2128                })),
2129                span: Span::new(0, 5),
2130            },
2131            Type {
2132                kind: TypeKind::Function {
2133                    params: vec![Type {
2134                        kind: TypeKind::Named("i32".to_string()),
2135                        span: Span::new(0, 3),
2136                    }],
2137                    ret: Box::new(Type {
2138                        kind: TypeKind::Named("String".to_string()),
2139                        span: Span::new(7, 13),
2140                    }),
2141                },
2142                span: Span::new(0, 13),
2143            },
2144        ];
2145        for ty in types {
2146            match ty.kind {
2147                TypeKind::Named(name) => assert!(!name.is_empty()),
2148                TypeKind::Generic { base, params } => {
2149                    assert!(!base.is_empty());
2150                    assert!(!params.is_empty());
2151                }
2152                TypeKind::Optional(_) | TypeKind::List(_) | TypeKind::Series { .. } => {}
2153                TypeKind::Function { params, .. } => assert!(!params.is_empty()),
2154                TypeKind::DataFrame { columns } => assert!(!columns.is_empty()),
2155                TypeKind::Tuple(ref types) => assert!(!types.is_empty()),
2156                TypeKind::Reference {
2157                    is_mut: _,
2158                    lifetime: _,
2159                    ref inner,
2160                } => {
2161                    // Reference types should have a valid inner type
2162                    if let TypeKind::Named(ref name) = inner.kind {
2163                        assert!(!name.is_empty());
2164                    }
2165                }
2166                TypeKind::Array { elem_type: _, size } => {
2167                    // Array types should have a valid size
2168                    assert!(size > 0);
2169                }
2170            }
2171        }
2172    }
2173    #[test]
2174    fn test_param_creation() {
2175        let param = Param {
2176            pattern: Pattern::Identifier("count".to_string()),
2177            ty: Type {
2178                kind: TypeKind::Named("usize".to_string()),
2179                span: Span::new(6, 11),
2180            },
2181            span: Span::new(0, 11),
2182            is_mutable: false,
2183            default_value: None,
2184        };
2185        assert_eq!(param.name(), "count");
2186        match param.ty.kind {
2187            TypeKind::Named(name) => assert_eq!(name, "usize"),
2188            _ => panic!("Wrong type kind"),
2189        }
2190    }
2191
2192    #[test]
2193    fn test_string_interpolation_parts() {
2194        // Test string interpolation with mixed parts
2195        let parts = vec![
2196            StringPart::Text("Hello, ".to_string()),
2197            StringPart::Expr(Box::new(Expr::new(
2198                ExprKind::Identifier("name".to_string()),
2199                Span::new(8, 12),
2200            ))),
2201            StringPart::Text("!".to_string()),
2202        ];
2203
2204        let expr = Expr::new(ExprKind::StringInterpolation { parts }, Span::new(0, 13));
2205
2206        if let ExprKind::StringInterpolation { parts } = expr.kind {
2207            assert_eq!(parts.len(), 3);
2208            match &parts[0] {
2209                StringPart::Text(s) => assert_eq!(s, "Hello, "),
2210                _ => panic!("Expected static part"),
2211            }
2212            match &parts[1] {
2213                StringPart::Expr(e) => {
2214                    if let ExprKind::Identifier(id) = &e.kind {
2215                        assert_eq!(id, "name");
2216                    }
2217                }
2218                _ => panic!("Expected dynamic part"),
2219            }
2220        }
2221    }
2222
2223    #[test]
2224    fn test_async_function_creation() {
2225        // Test async function with await
2226        let func = Expr::new(
2227            ExprKind::Function {
2228                name: "fetch_data".to_string(),
2229                type_params: vec![],
2230                params: vec![],
2231                return_type: None,
2232                body: Box::new(Expr::new(
2233                    ExprKind::Await {
2234                        expr: Box::new(Expr::new(
2235                            ExprKind::Identifier("api_call".to_string()),
2236                            Span::new(0, 8),
2237                        )),
2238                    },
2239                    Span::new(0, 14),
2240                )),
2241                is_async: true,
2242                is_pub: false,
2243            },
2244            Span::new(0, 30),
2245        );
2246
2247        if let ExprKind::Function { is_async, body, .. } = func.kind {
2248            assert!(is_async);
2249            if let ExprKind::Await { .. } = body.kind {
2250                // Correctly contains await expression
2251            } else {
2252                panic!("Expected await in async function");
2253            }
2254        }
2255    }
2256
2257    #[test]
2258    fn test_try_catch_finally() {
2259        // Test try-catch-finally structure
2260        let try_catch = Expr::new(
2261            ExprKind::TryCatch {
2262                try_block: Box::new(Expr::new(
2263                    ExprKind::Identifier("risky_operation".to_string()),
2264                    Span::new(4, 19),
2265                )),
2266                catch_clauses: vec![CatchClause {
2267                    pattern: Pattern::Identifier("e".to_string()),
2268                    body: Box::new(Expr::new(
2269                        ExprKind::Identifier("handle_error".to_string()),
2270                        Span::new(25, 37),
2271                    )),
2272                }],
2273                finally_block: Some(Box::new(Expr::new(
2274                    ExprKind::Identifier("cleanup".to_string()),
2275                    Span::new(45, 52),
2276                ))),
2277            },
2278            Span::new(0, 52),
2279        );
2280
2281        if let ExprKind::TryCatch {
2282            catch_clauses,
2283            finally_block,
2284            ..
2285        } = try_catch.kind
2286        {
2287            assert_eq!(catch_clauses.len(), 1);
2288            assert!(finally_block.is_some());
2289        }
2290    }
2291
2292    #[test]
2293    fn test_result_option_types() {
2294        // Test Result and Option type constructors
2295        let ok_val = Expr::new(
2296            ExprKind::Ok {
2297                value: Box::new(Expr::new(
2298                    ExprKind::Literal(Literal::Integer(42, None)),
2299                    Span::new(3, 5),
2300                )),
2301            },
2302            Span::new(0, 6),
2303        );
2304
2305        let err_val = Expr::new(
2306            ExprKind::Err {
2307                error: Box::new(Expr::new(
2308                    ExprKind::Literal(Literal::String("error".to_string())),
2309                    Span::new(4, 11),
2310                )),
2311            },
2312            Span::new(0, 12),
2313        );
2314
2315        let some_val = Expr::new(
2316            ExprKind::Some {
2317                value: Box::new(Expr::new(
2318                    ExprKind::Literal(Literal::Integer(1, None)),
2319                    Span::new(5, 6),
2320                )),
2321            },
2322            Span::new(0, 7),
2323        );
2324
2325        let none_val = Expr::new(ExprKind::None, Span::new(0, 4));
2326
2327        assert!(matches!(ok_val.kind, ExprKind::Ok { .. }));
2328        assert!(matches!(err_val.kind, ExprKind::Err { .. }));
2329        assert!(matches!(some_val.kind, ExprKind::Some { .. }));
2330        assert!(matches!(none_val.kind, ExprKind::None));
2331    }
2332
2333    // Test disabled: Pipeline operator enum variant pending
2334    // #[test]
2335    // fn test_pipeline_operator() {
2336    //     // Test pipeline operator expression
2337    //     let pipeline = Expr::new(
2338    //         ExprKind::Binary {
2339    //             left: Box::new(Expr::new(
2340    //                 ExprKind::Literal(Literal::Integer(5, None)),
2341    //                 Span::new(0, 1),
2342    //             )),
2343    //             op: BinaryOp::Pipeline,
2344    //             right: Box::new(Expr::new(
2345    //                 ExprKind::Identifier("double".to_string()),
2346    //                 Span::new(5, 11),
2347    //             )),
2348    //         },
2349    //         Span::new(0, 11),
2350    //     );
2351    //
2352    //     if let ExprKind::Binary { op, .. } = pipeline.kind {
2353    //         assert_eq!(op, BinaryOp::Pipeline);
2354    //     }
2355    // }
2356
2357    #[test]
2358    fn test_destructuring_patterns() {
2359        // Test tuple and struct destructuring
2360        let tuple_pattern = Pattern::Tuple(vec![
2361            Pattern::Identifier("x".to_string()),
2362            Pattern::Identifier("y".to_string()),
2363            Pattern::Rest,
2364        ]);
2365
2366        let struct_pattern = Pattern::Struct {
2367            name: "User".to_string(),
2368            fields: vec![
2369                StructPatternField {
2370                    name: "name".to_string(),
2371                    pattern: Some(Pattern::Identifier("n".to_string())),
2372                },
2373                StructPatternField {
2374                    name: "age".to_string(),
2375                    pattern: None,
2376                },
2377            ],
2378            has_rest: true,
2379        };
2380
2381        if let Pattern::Tuple(elements) = tuple_pattern {
2382            assert_eq!(elements.len(), 3);
2383            assert!(matches!(elements[2], Pattern::Rest));
2384        }
2385
2386        if let Pattern::Struct {
2387            fields, has_rest, ..
2388        } = struct_pattern
2389        {
2390            assert_eq!(fields.len(), 2);
2391            assert!(has_rest);
2392        }
2393    }
2394
2395    #[test]
2396    fn test_qualified_names() {
2397        // Test module-qualified names
2398        let qualified = Expr::new(
2399            ExprKind::QualifiedName {
2400                module: "std".to_string(),
2401                name: "println".to_string(),
2402            },
2403            Span::new(0, 11),
2404        );
2405
2406        if let ExprKind::QualifiedName { module, name } = qualified.kind {
2407            assert_eq!(module, "std");
2408            assert_eq!(name, "println");
2409        }
2410    }
2411
2412    // Test disabled: Import AST structure pending redesign
2413    // #[test]
2414    // fn test_import_export_statements() {
2415    //     // Test import and export statements
2416    //     let import = Expr::new(
2417    //         ExprKind::Import {
2418    //             module: "std::collections".to_string(),
2419    //             items: Some(vec!["HashMap".to_string()]),
2420    //         },
2421    //         Span::new(0, 30),
2422    //     );
2423    // }
2424
2425    #[test]
2426    fn test_decorator_attributes() {
2427        // Test decorator/attribute attachment
2428        let decorated = Expr::with_attributes(
2429            ExprKind::Function {
2430                name: "test_func".to_string(),
2431                type_params: vec![],
2432                params: vec![],
2433                return_type: None,
2434                body: Box::new(Expr::new(ExprKind::Literal(Literal::Unit), Span::new(0, 0))),
2435                is_async: false,
2436                is_pub: false,
2437            },
2438            Span::new(0, 20),
2439            vec![
2440                Attribute {
2441                    name: "test".to_string(),
2442                    args: vec![],
2443                    span: Span::new(0, 5),
2444                },
2445                Attribute {
2446                    name: "bench".to_string(),
2447                    args: vec![],
2448                    span: Span::new(0, 6),
2449                },
2450            ],
2451        );
2452
2453        assert_eq!(decorated.attributes.len(), 2);
2454        assert_eq!(decorated.attributes[0].name, "test");
2455        assert_eq!(decorated.attributes[1].name, "bench");
2456    }
2457
2458    // Test removed - CompClause type not defined
2459
2460    #[test]
2461    fn test_dataframe_operations() {
2462        // Test DataFrame literal and operations
2463        let df = Expr::new(
2464            ExprKind::DataFrame {
2465                columns: vec![
2466                    DataFrameColumn {
2467                        name: "name".to_string(),
2468                        values: vec![
2469                            Expr::new(
2470                                ExprKind::Literal(Literal::String("Alice".to_string())),
2471                                Span::new(0, 7),
2472                            ),
2473                            Expr::new(
2474                                ExprKind::Literal(Literal::String("Bob".to_string())),
2475                                Span::new(8, 13),
2476                            ),
2477                        ],
2478                    },
2479                    DataFrameColumn {
2480                        name: "age".to_string(),
2481                        values: vec![
2482                            Expr::new(
2483                                ExprKind::Literal(Literal::Integer(25, None)),
2484                                Span::new(14, 16),
2485                            ),
2486                            Expr::new(
2487                                ExprKind::Literal(Literal::Integer(30, None)),
2488                                Span::new(17, 19),
2489                            ),
2490                        ],
2491                    },
2492                ],
2493            },
2494            Span::new(0, 50),
2495        );
2496
2497        if let ExprKind::DataFrame { columns } = df.kind {
2498            assert_eq!(columns.len(), 2);
2499            assert_eq!(columns[0].name, "name");
2500            assert_eq!(columns[0].values.len(), 2);
2501            assert_eq!(columns[1].name, "age");
2502            assert_eq!(columns[1].values.len(), 2);
2503        }
2504    }
2505
2506    #[test]
2507    fn test_type_cast_operations() {
2508        // Test type casting
2509        let cast = Expr::new(
2510            ExprKind::TypeCast {
2511                expr: Box::new(Expr::new(
2512                    ExprKind::Literal(Literal::Integer(42, None)),
2513                    Span::new(0, 2),
2514                )),
2515                target_type: "f64".to_string(),
2516            },
2517            Span::new(0, 10),
2518        );
2519
2520        if let ExprKind::TypeCast { target_type, .. } = cast.kind {
2521            assert_eq!(target_type, "f64");
2522        }
2523    }
2524
2525    #[test]
2526    fn test_binary_operators_complete() {
2527        // Test all binary operators
2528        let ops = vec![
2529            BinaryOp::Add,
2530            BinaryOp::Subtract,
2531            BinaryOp::Multiply,
2532            BinaryOp::Divide,
2533            BinaryOp::Modulo,
2534            BinaryOp::Power,
2535            BinaryOp::Equal,
2536            BinaryOp::NotEqual,
2537            BinaryOp::Less,
2538            BinaryOp::Greater,
2539            BinaryOp::LessEqual,
2540            BinaryOp::GreaterEqual,
2541            BinaryOp::And,
2542            BinaryOp::Or,
2543            // BinaryOp::Pipeline, // Enum variant pending
2544            BinaryOp::BitwiseAnd,
2545            BinaryOp::BitwiseOr,
2546            BinaryOp::BitwiseXor,
2547            BinaryOp::LeftShift,
2548            // BinaryOp::RightShift, // Enum variant pending
2549        ];
2550
2551        for op in ops {
2552            let expr = Expr::new(
2553                ExprKind::Binary {
2554                    left: Box::new(Expr::new(
2555                        ExprKind::Literal(Literal::Integer(1, None)),
2556                        Span::new(0, 1),
2557                    )),
2558                    op,
2559                    right: Box::new(Expr::new(
2560                        ExprKind::Literal(Literal::Integer(2, None)),
2561                        Span::new(2, 3),
2562                    )),
2563                },
2564                Span::new(0, 3),
2565            );
2566
2567            if let ExprKind::Binary { op: test_op, .. } = expr.kind {
2568                assert_eq!(test_op, op);
2569            }
2570        }
2571    }
2572
2573    #[test]
2574    fn test_span_operations() {
2575        // Test span merging and creation
2576        let span1 = Span::new(0, 10);
2577        let span2 = Span::new(5, 15);
2578        let merged = span1.merge(span2);
2579
2580        assert_eq!(merged.start, 0);
2581        assert_eq!(merged.end, 15);
2582
2583        // Test with reverse order
2584        let merged2 = span2.merge(span1);
2585        assert_eq!(merged2.start, 0);
2586        assert_eq!(merged2.end, 15);
2587    }
2588
2589    #[test]
2590    fn test_pattern_with_default() {
2591        // Test pattern with default value
2592        let pattern = Pattern::WithDefault {
2593            pattern: Box::new(Pattern::Identifier("count".to_string())),
2594            default: Box::new(Expr::new(
2595                ExprKind::Literal(Literal::Integer(0, None)),
2596                Span::new(0, 1),
2597            )),
2598        };
2599
2600        if let Pattern::WithDefault { pattern, default } = pattern {
2601            match *pattern {
2602                Pattern::Identifier(name) => assert_eq!(name, "count"),
2603                _ => panic!("Expected identifier pattern"),
2604            }
2605            match default.kind {
2606                ExprKind::Literal(Literal::Integer(val, None)) => assert_eq!(val, 0),
2607                _ => panic!("Expected integer literal"),
2608            }
2609        }
2610    }
2611
2612    // Test removed - Generator and CompClause types not defined
2613
2614    #[test]
2615    fn test_mutable_parameter() {
2616        // Test mutable parameter
2617        let param = Param {
2618            pattern: Pattern::Identifier("data".to_string()),
2619            ty: Type {
2620                kind: TypeKind::List(Box::new(Type {
2621                    kind: TypeKind::Named("i32".to_string()),
2622                    span: Span::new(0, 3),
2623                })),
2624                span: Span::new(0, 6),
2625            },
2626            span: Span::new(0, 10),
2627            is_mutable: true,
2628            default_value: None,
2629        };
2630
2631        assert!(param.is_mutable);
2632        assert_eq!(param.name(), "data");
2633    }
2634
2635    #[test]
2636    fn test_reference_types() {
2637        // Test reference and mutable reference types
2638        let ref_type = Type {
2639            kind: TypeKind::Reference {
2640                is_mut: false,
2641                lifetime: None,
2642                inner: Box::new(Type {
2643                    kind: TypeKind::Named("String".to_string()),
2644                    span: Span::new(1, 7),
2645                }),
2646            },
2647            span: Span::new(0, 7),
2648        };
2649
2650        let mut_ref_type = Type {
2651            kind: TypeKind::Reference {
2652                is_mut: true,
2653                lifetime: None,
2654                inner: Box::new(Type {
2655                    kind: TypeKind::Named("Vec".to_string()),
2656                    span: Span::new(4, 7),
2657                }),
2658            },
2659            span: Span::new(0, 7),
2660        };
2661
2662        if let TypeKind::Reference {
2663            is_mut,
2664            lifetime: _,
2665            inner,
2666        } = ref_type.kind
2667        {
2668            assert!(!is_mut);
2669            if let TypeKind::Named(name) = inner.kind {
2670                assert_eq!(name, "String");
2671            }
2672        }
2673
2674        if let TypeKind::Reference { is_mut, .. } = mut_ref_type.kind {
2675            assert!(is_mut);
2676        }
2677    }
2678
2679    // EXTREME COVERAGE TESTS FOR 100% AST.RS HOT FILE COVERAGE
2680    #[test]
2681    fn test_all_expr_kinds_systematic() {
2682        // Test every single ExprKind variant for complete coverage
2683
2684        // Test Literal variants
2685        let literals = vec![
2686            ExprKind::Literal(Literal::Integer(42, None)),
2687            ExprKind::Literal(Literal::Float(3.15)),
2688            ExprKind::Literal(Literal::Bool(true)),
2689            ExprKind::Literal(Literal::Bool(false)),
2690            ExprKind::Literal(Literal::String("test".to_string())),
2691            ExprKind::Literal(Literal::Char('a')),
2692            ExprKind::Literal(Literal::Unit),
2693        ];
2694
2695        for literal in literals {
2696            let expr = Expr {
2697                kind: literal,
2698                span: Span::new(0, 1),
2699                attributes: vec![],
2700            leading_comments: vec![],
2701            trailing_comment: None,
2702            };
2703            // Just test creation and access
2704            assert!(matches!(expr.kind, ExprKind::Literal(_)));
2705        }
2706
2707        // Test Binary operations
2708        let left = Box::new(Expr {
2709            kind: ExprKind::Literal(Literal::Integer(1, None)),
2710            span: Span::new(0, 1),
2711            attributes: vec![],
2712            leading_comments: vec![],
2713            trailing_comment: None,
2714        });
2715        let right = Box::new(Expr {
2716            kind: ExprKind::Literal(Literal::Integer(2, None)),
2717            span: Span::new(2, 3),
2718            attributes: vec![],
2719            leading_comments: vec![],
2720            trailing_comment: None,
2721        });
2722
2723        let binary_ops = vec![
2724            BinaryOp::Add,
2725            BinaryOp::Subtract,
2726            BinaryOp::Multiply,
2727            BinaryOp::Divide,
2728            BinaryOp::Modulo,
2729            BinaryOp::Power,
2730            BinaryOp::Equal,
2731            BinaryOp::NotEqual,
2732            BinaryOp::Less,
2733            BinaryOp::LessEqual,
2734            BinaryOp::Greater,
2735            BinaryOp::GreaterEqual,
2736            BinaryOp::Gt,
2737            BinaryOp::And,
2738            BinaryOp::Or,
2739            BinaryOp::BitwiseAnd,
2740            BinaryOp::BitwiseOr,
2741            BinaryOp::BitwiseXor,
2742            BinaryOp::LeftShift,
2743            BinaryOp::NullCoalesce,
2744        ];
2745
2746        for op in binary_ops {
2747            let binary_expr = ExprKind::Binary {
2748                op,
2749                left: left.clone(),
2750                right: right.clone(),
2751            };
2752            let expr = Expr {
2753                kind: binary_expr,
2754                span: Span::new(0, 3),
2755                attributes: vec![],
2756            leading_comments: vec![],
2757            trailing_comment: None,
2758            };
2759            assert!(matches!(expr.kind, ExprKind::Binary { .. }));
2760        }
2761
2762        // Test Unary operations
2763        let operand = Box::new(Expr {
2764            kind: ExprKind::Literal(Literal::Integer(42, None)),
2765            span: Span::new(1, 3),
2766            attributes: vec![],
2767            leading_comments: vec![],
2768            trailing_comment: None,
2769        });
2770
2771        let unary_ops = vec![
2772            UnaryOp::Not,
2773            UnaryOp::Negate,
2774            UnaryOp::BitwiseNot,
2775            UnaryOp::Reference,
2776        ];
2777
2778        for op in unary_ops {
2779            let unary_expr = ExprKind::Unary {
2780                op,
2781                operand: operand.clone(),
2782            };
2783            let expr = Expr {
2784                kind: unary_expr,
2785                span: Span::new(0, 3),
2786                attributes: vec![],
2787            leading_comments: vec![],
2788            trailing_comment: None,
2789            };
2790            assert!(matches!(expr.kind, ExprKind::Unary { .. }));
2791        }
2792    }
2793
2794    #[test]
2795    fn test_all_type_kinds_comprehensive() {
2796        // Test every TypeKind variant for complete coverage
2797
2798        let type_kinds = vec![
2799            TypeKind::Named("String".to_string()),
2800            TypeKind::Generic {
2801                base: "Vec".to_string(),
2802                params: vec![Type {
2803                    kind: TypeKind::Named("i32".to_string()),
2804                    span: Span::new(0, 3),
2805                }],
2806            },
2807            TypeKind::Function {
2808                params: vec![Type {
2809                    kind: TypeKind::Named("i32".to_string()),
2810                    span: Span::new(0, 3),
2811                }],
2812                ret: Box::new(Type {
2813                    kind: TypeKind::Named("String".to_string()),
2814                    span: Span::new(7, 13),
2815                }),
2816            },
2817            TypeKind::Tuple(vec![
2818                Type {
2819                    kind: TypeKind::Named("i32".to_string()),
2820                    span: Span::new(0, 3),
2821                },
2822                Type {
2823                    kind: TypeKind::Named("String".to_string()),
2824                    span: Span::new(5, 11),
2825                },
2826            ]),
2827            TypeKind::Array {
2828                elem_type: Box::new(Type {
2829                    kind: TypeKind::Named("i32".to_string()),
2830                    span: Span::new(0, 3),
2831                }),
2832                size: 10,
2833            },
2834            TypeKind::Reference {
2835                is_mut: false,
2836                lifetime: None,
2837                inner: Box::new(Type {
2838                    kind: TypeKind::Named("String".to_string()),
2839                    span: Span::new(1, 7),
2840                }),
2841            },
2842            TypeKind::Reference {
2843                is_mut: true,
2844                lifetime: None,
2845                inner: Box::new(Type {
2846                    kind: TypeKind::Named("String".to_string()),
2847                    span: Span::new(5, 11),
2848                }),
2849            },
2850            TypeKind::Optional(Box::new(Type {
2851                kind: TypeKind::Named("i32".to_string()),
2852                span: Span::new(0, 3),
2853            })),
2854            TypeKind::List(Box::new(Type {
2855                kind: TypeKind::Named("String".to_string()),
2856                span: Span::new(0, 6),
2857            })),
2858            TypeKind::DataFrame {
2859                columns: vec![
2860                    (
2861                        "id".to_string(),
2862                        Type {
2863                            kind: TypeKind::Named("i32".to_string()),
2864                            span: Span::new(0, 3),
2865                        },
2866                    ),
2867                    (
2868                        "name".to_string(),
2869                        Type {
2870                            kind: TypeKind::Named("String".to_string()),
2871                            span: Span::new(0, 6),
2872                        },
2873                    ),
2874                ],
2875            },
2876            TypeKind::Series {
2877                dtype: Box::new(Type {
2878                    kind: TypeKind::Named("f64".to_string()),
2879                    span: Span::new(0, 3),
2880                }),
2881            },
2882        ];
2883
2884        for type_kind in type_kinds {
2885            let ty = Type {
2886                kind: type_kind,
2887                span: Span::new(0, 10),
2888            };
2889            // Test construction and basic operations
2890            assert!(ty.span.start <= ty.span.end);
2891        }
2892    }
2893
2894    #[test]
2895    fn test_all_pattern_kinds_comprehensive() {
2896        // Test every Pattern variant for complete coverage
2897
2898        let patterns = vec![
2899            Pattern::Wildcard,
2900            Pattern::Literal(Literal::Integer(42, None)),
2901            Pattern::Literal(Literal::String("test".to_string())),
2902            Pattern::Literal(Literal::Bool(true)),
2903            Pattern::Identifier("variable".to_string()),
2904            Pattern::QualifiedName(vec!["Module".to_string(), "Type".to_string()]),
2905            Pattern::Tuple(vec![
2906                Pattern::Identifier("x".to_string()),
2907                Pattern::Identifier("y".to_string()),
2908            ]),
2909            Pattern::List(vec![
2910                Pattern::Identifier("head".to_string()),
2911                Pattern::Wildcard,
2912            ]),
2913            Pattern::Struct {
2914                name: "Point".to_string(),
2915                fields: vec![
2916                    StructPatternField {
2917                        name: "x".to_string(),
2918                        pattern: Some(Pattern::Identifier("x_val".to_string())),
2919                    },
2920                    StructPatternField {
2921                        name: "y".to_string(),
2922                        pattern: None, // Shorthand
2923                    },
2924                ],
2925                has_rest: false,
2926            },
2927            Pattern::Struct {
2928                name: "Point".to_string(),
2929                fields: vec![],
2930                has_rest: true, // With rest pattern
2931            },
2932        ];
2933
2934        for pattern in patterns {
2935            // Test pattern construction and basic operations
2936            match pattern {
2937                Pattern::Wildcard => {}
2938                Pattern::Literal(_) => {}
2939                Pattern::Identifier(ref name) => assert!(!name.is_empty()),
2940                Pattern::QualifiedName(ref names) => assert!(!names.is_empty()),
2941                Pattern::Tuple(ref patterns) => assert!(!patterns.is_empty()),
2942                Pattern::List(ref patterns) => assert!(!patterns.is_empty()),
2943                Pattern::Struct { ref name, .. } => assert!(!name.is_empty()),
2944                _ => {} // Handle all other pattern variants
2945            }
2946        }
2947    }
2948
2949    #[test]
2950    fn test_complex_expr_constructions() {
2951        // Test complex expression constructions for edge case coverage
2952
2953        // Complex nested call
2954        let complex_call = ExprKind::Call {
2955            func: Box::new(Expr {
2956                kind: ExprKind::FieldAccess {
2957                    object: Box::new(Expr {
2958                        kind: ExprKind::Identifier("obj".to_string()),
2959                        span: Span::new(0, 3),
2960                        attributes: vec![],
2961            leading_comments: vec![],
2962            trailing_comment: None,
2963                    }),
2964                    field: "method".to_string(),
2965                },
2966                span: Span::new(0, 10),
2967                attributes: vec![],
2968            leading_comments: vec![],
2969            trailing_comment: None,
2970            }),
2971            args: vec![
2972                Expr {
2973                    kind: ExprKind::Literal(Literal::Integer(42, None)),
2974                    span: Span::new(11, 13),
2975                    attributes: vec![],
2976            leading_comments: vec![],
2977            trailing_comment: None,
2978                },
2979                Expr {
2980                    kind: ExprKind::Literal(Literal::String("arg".to_string())),
2981                    span: Span::new(15, 20),
2982                    attributes: vec![],
2983            leading_comments: vec![],
2984            trailing_comment: None,
2985                },
2986            ],
2987        };
2988
2989        let expr = Expr {
2990            kind: complex_call,
2991            span: Span::new(0, 21),
2992            attributes: vec![],
2993            leading_comments: vec![],
2994            trailing_comment: None,
2995        };
2996        assert!(matches!(expr.kind, ExprKind::Call { .. }));
2997
2998        // Complex if expression
2999        let complex_if = ExprKind::If {
3000            condition: Box::new(Expr {
3001                kind: ExprKind::Binary {
3002                    op: BinaryOp::Greater,
3003                    left: Box::new(Expr {
3004                        kind: ExprKind::Identifier("x".to_string()),
3005                        span: Span::new(3, 4),
3006                        attributes: vec![],
3007            leading_comments: vec![],
3008            trailing_comment: None,
3009                    }),
3010                    right: Box::new(Expr {
3011                        kind: ExprKind::Literal(Literal::Integer(0, None)),
3012                        span: Span::new(7, 8),
3013                        attributes: vec![],
3014            leading_comments: vec![],
3015            trailing_comment: None,
3016                    }),
3017                },
3018                span: Span::new(3, 8),
3019                attributes: vec![],
3020            leading_comments: vec![],
3021            trailing_comment: None,
3022            }),
3023            then_branch: Box::new(Expr {
3024                kind: ExprKind::Block(vec![Expr {
3025                    kind: ExprKind::Literal(Literal::String("positive".to_string())),
3026                    span: Span::new(11, 21),
3027                    attributes: vec![],
3028            leading_comments: vec![],
3029            trailing_comment: None,
3030                }]),
3031                span: Span::new(9, 23),
3032                attributes: vec![],
3033            leading_comments: vec![],
3034            trailing_comment: None,
3035            }),
3036            else_branch: Some(Box::new(Expr {
3037                kind: ExprKind::Literal(Literal::String("negative".to_string())),
3038                span: Span::new(29, 39),
3039                attributes: vec![],
3040            leading_comments: vec![],
3041            trailing_comment: None,
3042            })),
3043        };
3044
3045        let if_expr = Expr {
3046            kind: complex_if,
3047            span: Span::new(0, 40),
3048            attributes: vec![],
3049            leading_comments: vec![],
3050            trailing_comment: None,
3051        };
3052        assert!(matches!(if_expr.kind, ExprKind::If { .. }));
3053    }
3054
3055    #[test]
3056    fn test_attribute_and_span_coverage() {
3057        // Test attribute and span functionality comprehensively
3058
3059        // Test various attribute types
3060        let attributes = vec![
3061            Attribute {
3062                name: "inline".to_string(),
3063                args: vec![],
3064                span: Span::new(0, 8),
3065            },
3066            Attribute {
3067                name: "deprecated".to_string(),
3068                args: vec!["Use new_function instead".to_string()],
3069                span: Span::new(0, 40),
3070            },
3071            Attribute {
3072                name: "derive".to_string(),
3073                args: vec!["Debug".to_string(), "Clone".to_string()],
3074                span: Span::new(0, 20),
3075            },
3076        ];
3077
3078        for attr in attributes {
3079            assert!(!attr.name.is_empty());
3080            assert!(attr.span.start <= attr.span.end);
3081        }
3082
3083        // Test expression with attributes
3084        let expr_with_attrs = Expr::with_attributes(
3085            ExprKind::Literal(Literal::Integer(42, None)),
3086            Span::new(0, 2),
3087            vec![Attribute {
3088                name: "test_attr".to_string(),
3089                args: vec![],
3090                span: Span::new(0, 10),
3091            }],
3092        );
3093
3094        assert_eq!(expr_with_attrs.attributes.len(), 1);
3095        assert_eq!(expr_with_attrs.attributes[0].name, "test_attr");
3096
3097        // Test span operations
3098        let span1 = Span::new(0, 10);
3099        let span2 = Span::new(5, 15);
3100
3101        assert_eq!(span1.start, 0);
3102        assert_eq!(span1.end, 10);
3103        assert!(span1.start <= span1.end);
3104        assert!(span2.start <= span2.end);
3105
3106        // Test default span
3107        let default_span = Span::default();
3108        assert_eq!(default_span.start, 0);
3109        assert_eq!(default_span.end, 0);
3110    }
3111
3112    #[test]
3113    fn test_all_remaining_expr_kinds() {
3114        // Test remaining ExprKind variants for 100% coverage
3115
3116        // Test collections
3117        let list_expr = ExprKind::List(vec![
3118            Expr {
3119                kind: ExprKind::Literal(Literal::Integer(1, None)),
3120                span: Span::new(1, 2),
3121                attributes: vec![],
3122            leading_comments: vec![],
3123            trailing_comment: None,
3124            },
3125            Expr {
3126                kind: ExprKind::Literal(Literal::Integer(2, None)),
3127                span: Span::new(4, 5),
3128                attributes: vec![],
3129            leading_comments: vec![],
3130            trailing_comment: None,
3131            },
3132        ]);
3133
3134        let tuple_expr = ExprKind::Tuple(vec![
3135            Expr {
3136                kind: ExprKind::Literal(Literal::String("first".to_string())),
3137                span: Span::new(1, 8),
3138                attributes: vec![],
3139            leading_comments: vec![],
3140            trailing_comment: None,
3141            },
3142            Expr {
3143                kind: ExprKind::Literal(Literal::Integer(42, None)),
3144                span: Span::new(10, 12),
3145                attributes: vec![],
3146            leading_comments: vec![],
3147            trailing_comment: None,
3148            },
3149        ]);
3150
3151        // Test assignments
3152        let assign_expr = ExprKind::Assign {
3153            target: Box::new(Expr {
3154                kind: ExprKind::Identifier("x".to_string()),
3155                span: Span::new(0, 1),
3156                attributes: vec![],
3157            leading_comments: vec![],
3158            trailing_comment: None,
3159            }),
3160            value: Box::new(Expr {
3161                kind: ExprKind::Literal(Literal::Integer(42, None)),
3162                span: Span::new(4, 6),
3163                attributes: vec![],
3164            leading_comments: vec![],
3165            trailing_comment: None,
3166            }),
3167        };
3168
3169        // Test function definitions
3170        let func_expr = ExprKind::Function {
3171            name: "add".to_string(),
3172            type_params: vec![],
3173            params: vec![
3174                Param {
3175                    pattern: Pattern::Identifier("a".to_string()),
3176                    ty: Type {
3177                        kind: TypeKind::Named("i32".to_string()),
3178                        span: Span::new(0, 3),
3179                    },
3180                    default_value: None,
3181                    is_mutable: false,
3182                    span: Span::new(0, 5),
3183                },
3184                Param {
3185                    pattern: Pattern::Identifier("b".to_string()),
3186                    ty: Type {
3187                        kind: TypeKind::Named("i32".to_string()),
3188                        span: Span::new(0, 3),
3189                    },
3190                    default_value: None,
3191                    is_mutable: false,
3192                    span: Span::new(0, 5),
3193                },
3194            ],
3195            return_type: Some(Type {
3196                kind: TypeKind::Named("i32".to_string()),
3197                span: Span::new(0, 3),
3198            }),
3199            body: Box::new(Expr {
3200                kind: ExprKind::Binary {
3201                    op: BinaryOp::Add,
3202                    left: Box::new(Expr {
3203                        kind: ExprKind::Identifier("a".to_string()),
3204                        span: Span::new(0, 1),
3205                        attributes: vec![],
3206            leading_comments: vec![],
3207            trailing_comment: None,
3208                    }),
3209                    right: Box::new(Expr {
3210                        kind: ExprKind::Identifier("b".to_string()),
3211                        span: Span::new(4, 5),
3212                        attributes: vec![],
3213            leading_comments: vec![],
3214            trailing_comment: None,
3215                    }),
3216                },
3217                span: Span::new(0, 5),
3218                attributes: vec![],
3219            leading_comments: vec![],
3220            trailing_comment: None,
3221            }),
3222            is_async: false,
3223            is_pub: false,
3224        };
3225
3226        // Test all constructions
3227        let expressions = vec![list_expr, tuple_expr, assign_expr, func_expr];
3228
3229        for expr_kind in expressions {
3230            let expr = Expr {
3231                kind: expr_kind,
3232                span: Span::new(0, 10),
3233                attributes: vec![],
3234            leading_comments: vec![],
3235            trailing_comment: None,
3236            };
3237            // Verify construction succeeded
3238            assert!(expr.span.start <= expr.span.end);
3239        }
3240    }
3241}