Skip to main content

oak_python/ast/
mod.rs

1#![doc = include_str!("readme.md")]
2use core::range::Range;
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6/// Root node of a Python source file.
7#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8#[derive(Debug, Clone, PartialEq)]
9pub struct PythonRoot {
10    /// The program structure
11    pub program: Program,
12    /// Source code span
13    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
14    pub span: Range<usize>,
15}
16
17/// A Python program consisting of a list of statements.
18#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
19#[derive(Debug, Clone, PartialEq)]
20pub struct Program {
21    /// List of statements in the program
22    pub statements: Vec<Statement>,
23}
24
25/// Represents a Python statement.
26#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
27#[derive(Debug, Clone, PartialEq)]
28pub enum Statement {
29    /// Function definition
30    FunctionDef {
31        /// Decorators applied to the function
32        decorators: Vec<Expression>,
33        /// Function name
34        name: String,
35        /// List of parameters
36        parameters: Vec<Parameter>,
37        /// Optional return type annotation
38        return_type: Option<Type>,
39        /// Function body
40        body: Vec<Statement>,
41    },
42    /// Async function definition
43    AsyncFunctionDef {
44        /// Decorators applied to the function
45        decorators: Vec<Expression>,
46        /// Function name
47        name: String,
48        /// List of parameters
49        parameters: Vec<Parameter>,
50        /// Optional return type annotation
51        return_type: Option<Type>,
52        /// Function body
53        body: Vec<Statement>,
54    },
55    /// Class definition
56    ClassDef {
57        /// Decorators applied to the class
58        decorators: Vec<Expression>,
59        /// Class name
60        name: String,
61        /// Base classes
62        bases: Vec<Expression>,
63        /// Class body
64        body: Vec<Statement>,
65    },
66    /// Variable assignment
67    Assignment {
68        /// Target expression
69        target: Expression,
70        /// Value expression
71        value: Expression,
72    },
73    /// Augmented assignment (e.g., `+=`, `-=`)
74    AugmentedAssignment {
75        /// Target expression
76        target: Expression,
77        /// Augmented operator
78        operator: AugmentedOperator,
79        /// Value expression
80        value: Expression,
81    },
82    /// Expression statement
83    Expression(Expression),
84    /// Return statement
85    Return(Option<Expression>),
86    /// If statement
87    If {
88        /// Test expression
89        test: Expression,
90        /// Body of the if block
91        body: Vec<Statement>,
92        /// Else block (or empty)
93        orelse: Vec<Statement>,
94    },
95    /// For loop
96    For {
97        /// Loop target
98        target: Expression,
99        /// Iterable expression
100        iter: Expression,
101        /// Loop body
102        body: Vec<Statement>,
103        /// Else block (or empty)
104        orelse: Vec<Statement>,
105    },
106    /// Async for loop
107    AsyncFor {
108        /// Loop target
109        target: Expression,
110        /// Iterable expression
111        iter: Expression,
112        /// Loop body
113        body: Vec<Statement>,
114        /// Else block (or empty)
115        orelse: Vec<Statement>,
116    },
117    /// While loop
118    While {
119        /// Test expression
120        test: Expression,
121        /// Loop body
122        body: Vec<Statement>,
123        /// Else block (or empty)
124        orelse: Vec<Statement>,
125    },
126    /// Break statement
127    Break,
128    /// Continue statement
129    Continue,
130    /// Pass statement
131    Pass,
132    /// Import statement
133    Import {
134        /// List of names being imported
135        names: Vec<ImportName>,
136    },
137    /// From-import statement
138    ImportFrom {
139        /// Optional module name
140        module: Option<String>,
141        /// List of names being imported
142        names: Vec<ImportName>,
143    },
144    /// Global statement
145    Global {
146        /// List of global names
147        names: Vec<String>,
148    },
149    /// Nonlocal statement
150    Nonlocal {
151        /// List of nonlocal names
152        names: Vec<String>,
153    },
154    /// Try statement
155    Try {
156        /// Try body
157        body: Vec<Statement>,
158        /// Exception handlers
159        handlers: Vec<ExceptHandler>,
160        /// Else block
161        orelse: Vec<Statement>,
162        /// Finally block
163        finalbody: Vec<Statement>,
164    },
165    /// Raise statement
166    Raise {
167        /// Optional exception
168        exc: Option<Expression>,
169        /// Optional cause
170        cause: Option<Expression>,
171    },
172    /// With statement
173    With {
174        /// With items
175        items: Vec<WithItem>,
176        /// With body
177        body: Vec<Statement>,
178    },
179    /// Async with statement
180    AsyncWith {
181        /// With items
182        items: Vec<WithItem>,
183        /// With body
184        body: Vec<Statement>,
185    },
186    /// Assert statement
187    Assert {
188        /// Test expression
189        test: Expression,
190        /// Optional error message
191        msg: Option<Expression>,
192    },
193    /// Match statement
194    Match {
195        /// Subject expression
196        subject: Expression,
197        /// Match cases
198        cases: Vec<MatchCase>,
199    },
200}
201
202/// Represents a case in a match statement.
203#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
204#[derive(Debug, Clone, PartialEq)]
205pub struct MatchCase {
206    /// Pattern to match
207    pub pattern: Pattern,
208    /// Optional guard expression
209    pub guard: Option<Expression>,
210    /// Case body
211    pub body: Vec<Statement>,
212}
213
214/// Represents a pattern in a match case.
215#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
216#[derive(Debug, Clone, PartialEq)]
217pub enum Pattern {
218    /// Value pattern
219    Value(Expression),
220    /// Wildcard pattern
221    Wildcard,
222    /// As pattern
223    As {
224        /// Optional sub-pattern
225        pattern: Option<Box<Pattern>>,
226        /// Target name
227        name: String,
228    },
229    /// Sequence pattern
230    Sequence(Vec<Pattern>),
231    /// Mapping pattern
232    Mapping {
233        /// Keys to match
234        keys: Vec<Expression>,
235        /// Corresponding patterns
236        patterns: Vec<Pattern>,
237    },
238    /// Class pattern
239    Class {
240        /// Class expression
241        cls: Expression,
242        /// Positional patterns
243        patterns: Vec<Pattern>,
244        /// Keyword names
245        keywords: Vec<String>,
246        /// Keyword patterns
247        keyword_patterns: Vec<Pattern>,
248    },
249    /// Or pattern
250    Or(Vec<Pattern>),
251}
252
253/// Represents a Python expression.
254#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
255#[derive(Debug, Clone, PartialEq)]
256pub enum Expression {
257    /// Literal value
258    Literal(Literal),
259    /// Identifier name
260    Name(String),
261    /// Binary operation
262    BinaryOp {
263        /// Left operand
264        left: Box<Expression>,
265        /// Binary operator
266        operator: BinaryOperator,
267        /// Right operand
268        right: Box<Expression>,
269    },
270    /// Unary operation
271    UnaryOp {
272        /// Unary operator
273        operator: UnaryOperator,
274        /// Operand
275        operand: Box<Expression>,
276    },
277    /// Boolean operation (and, or)
278    BoolOp {
279        /// Boolean operator
280        operator: BoolOperator,
281        /// List of values
282        values: Vec<Expression>,
283    },
284    /// Comparison operation
285    Compare {
286        /// Leftmost operand
287        left: Box<Expression>,
288        /// Comparison operators
289        ops: Vec<CompareOperator>,
290        /// Subsequent operands
291        comparators: Vec<Expression>,
292    },
293    /// Function call
294    Call {
295        /// Function being called
296        func: Box<Expression>,
297        /// Positional arguments
298        args: Vec<Expression>,
299        /// Keyword arguments
300        keywords: Vec<Keyword>,
301    },
302    /// Attribute access
303    Attribute {
304        /// Base expression
305        value: Box<Expression>,
306        /// Attribute name
307        attr: String,
308    },
309    /// Subscript access
310    Subscript {
311        /// Base expression
312        value: Box<Expression>,
313        /// Slice or index expression
314        slice: Box<Expression>,
315    },
316    /// List literal
317    List {
318        /// List elements
319        elts: Vec<Expression>,
320    },
321    /// Tuple literal
322    Tuple {
323        /// Tuple elements
324        elts: Vec<Expression>,
325    },
326    /// Slice expression
327    Slice {
328        /// Optional lower bound
329        lower: Option<Box<Expression>>,
330        /// Optional upper bound
331        upper: Option<Box<Expression>>,
332        /// Optional step
333        step: Option<Box<Expression>>,
334    },
335    /// Dictionary literal
336    Dict {
337        /// Optional keys
338        keys: Vec<Option<Expression>>,
339        /// Values
340        values: Vec<Expression>,
341    },
342    /// Set literal
343    Set {
344        /// Set elements
345        elts: Vec<Expression>,
346    },
347    /// List comprehension
348    ListComp {
349        /// Result expression
350        elt: Box<Expression>,
351        /// Generators
352        generators: Vec<Comprehension>,
353    },
354    /// Dictionary comprehension
355    DictComp {
356        /// Key expression
357        key: Box<Expression>,
358        /// Value expression
359        value: Box<Expression>,
360        /// Generators
361        generators: Vec<Comprehension>,
362    },
363    /// Set comprehension
364    SetComp {
365        /// Result expression
366        elt: Box<Expression>,
367        /// Generators
368        generators: Vec<Comprehension>,
369    },
370    /// Generator expression
371    GeneratorExp {
372        /// Result expression
373        elt: Box<Expression>,
374        /// Generators
375        generators: Vec<Comprehension>,
376    },
377    /// Lambda expression
378    Lambda {
379        /// Lambda arguments
380        args: Vec<Parameter>,
381        /// Lambda body
382        body: Box<Expression>,
383    },
384    /// Conditional expression (ternary operator)
385    IfExp {
386        /// Test expression
387        test: Box<Expression>,
388        /// Body expression
389        body: Box<Expression>,
390        /// Else expression
391        orelse: Box<Expression>,
392    },
393    /// f-string
394    JoinedStr {
395        /// f-string parts
396        values: Vec<Expression>,
397    },
398    /// Formatted value within an f-string
399    FormattedValue {
400        /// Value to format
401        value: Box<Expression>,
402        /// Conversion type
403        conversion: usize,
404        /// Optional format specification
405        format_spec: Option<Box<Expression>>,
406    },
407    /// Yield expression
408    Yield(Option<Box<Expression>>),
409    /// Yield from expression
410    YieldFrom(Box<Expression>),
411    /// Await expression
412    Await(Box<Expression>),
413    /// Starred expression (*args, **kwargs)
414    Starred {
415        /// Value being starred
416        value: Box<Expression>,
417        /// Whether it's a double star (**kwargs)
418        is_double: bool,
419    },
420}
421
422/// Represents a literal value.
423#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
424#[derive(Debug, Clone, PartialEq)]
425pub enum Literal {
426    /// Integer literal
427    Integer(i64),
428    /// Float literal
429    Float(f64),
430    /// String literal
431    String(String),
432    /// Bytes literal
433    Bytes(Vec<u8>),
434    /// Boolean literal
435    Boolean(bool),
436    /// None literal
437    None,
438}
439
440/// Represents binary operators.
441#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
442#[derive(Debug, Clone, PartialEq)]
443pub enum BinaryOperator {
444    /// `+`
445    Add,
446    /// `-`
447    Sub,
448    /// `*`
449    Mult,
450    /// `/`
451    Div,
452    /// `//`
453    FloorDiv,
454    /// `%`
455    Mod,
456    /// `**`
457    Pow,
458    /// `<<`
459    LShift,
460    /// `>>`
461    RShift,
462    /// `|`
463    BitOr,
464    /// `^`
465    BitXor,
466    /// `&`
467    BitAnd,
468}
469
470/// Represents unary operators.
471#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
472#[derive(Debug, Clone, PartialEq)]
473pub enum UnaryOperator {
474    /// `~`
475    Invert,
476    /// `not`
477    Not,
478    /// `+`
479    UAdd,
480    /// `-`
481    USub,
482}
483
484/// Represents boolean operators.
485#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
486#[derive(Debug, Clone, PartialEq)]
487pub enum BoolOperator {
488    /// `and`
489    And,
490    /// `or`
491    Or,
492}
493
494/// Represents comparison operators.
495#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
496#[derive(Debug, Clone, PartialEq)]
497pub enum CompareOperator {
498    /// `==`
499    Eq,
500    /// `!=`
501    NotEq,
502    /// `<`
503    Lt,
504    /// `<=`
505    LtE,
506    /// `>`
507    Gt,
508    /// `>=`
509    GtE,
510    /// `is`
511    Is,
512    /// `is not`
513    IsNot,
514    /// `in`
515    In,
516    /// `not in`
517    NotIn,
518}
519
520/// Represents augmented assignment operators.
521#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
522#[derive(Debug, Clone, PartialEq)]
523pub enum AugmentedOperator {
524    /// `+=`
525    Add,
526    /// `-=`
527    Sub,
528    /// `*=`
529    Mult,
530    /// `/=`
531    Div,
532    /// `//= `
533    FloorDiv,
534    /// `%=`
535    Mod,
536    /// `**=`
537    Pow,
538    /// `<<=`
539    LShift,
540    /// `>>=`
541    RShift,
542    /// `|=`
543    BitOr,
544    /// `^=`
545    BitXor,
546    /// `&=`
547    BitAnd,
548}
549
550/// Represents a function parameter.
551#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
552#[derive(Debug, Clone, PartialEq)]
553pub struct Parameter {
554    /// Parameter name
555    pub name: String,
556    /// Optional type annotation
557    pub annotation: Option<Type>,
558    /// Optional default value
559    pub default: Option<Expression>,
560    /// Whether it's a variable positional argument (*args)
561    pub is_vararg: bool,
562    /// Whether it's a variable keyword argument (**kwargs)
563    pub is_kwarg: bool,
564}
565
566/// Represents a type annotation.
567#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
568#[derive(Debug, Clone, PartialEq)]
569pub enum Type {
570    /// Basic type name
571    Name(String),
572    /// Generic type
573    Generic {
574        /// Type name
575        name: String,
576        /// Type arguments
577        args: Vec<Type>,
578    },
579    /// Union type
580    Union(Vec<Type>),
581    /// Optional type
582    Optional(Box<Type>),
583}
584
585/// Represents a keyword argument.
586#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
587#[derive(Debug, Clone, PartialEq)]
588pub struct Keyword {
589    /// Optional argument name
590    pub arg: Option<String>,
591    /// Argument value
592    pub value: Expression,
593}
594
595/// Represents a comprehension in a list/dict/set/generator.
596#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
597#[derive(Debug, Clone, PartialEq)]
598pub struct Comprehension {
599    /// Target expression
600    pub target: Expression,
601    /// Iterable expression
602    pub iter: Expression,
603    /// Optional conditions
604    pub ifs: Vec<Expression>,
605    /// Whether it's an async comprehension
606    pub is_async: bool,
607}
608
609/// Represents a name in an import statement.
610#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
611#[derive(Debug, Clone, PartialEq)]
612pub struct ImportName {
613    /// Name being imported
614    pub name: String,
615    /// Optional alias (asname)
616    pub asname: Option<String>,
617}
618
619/// Represents an exception handler in a try statement.
620#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
621#[derive(Debug, Clone, PartialEq)]
622pub struct ExceptHandler {
623    /// Optional exception type
624    pub type_: Option<Expression>,
625    /// Optional name for the exception instance
626    pub name: Option<String>,
627    /// Handler body
628    pub body: Vec<Statement>,
629}
630
631/// Represents an item in a with statement.
632#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
633#[derive(Debug, Clone, PartialEq)]
634pub struct WithItem {
635    /// Context manager expression
636    pub context_expr: Expression,
637    /// Optional variables to bind to
638    pub optional_vars: Option<Expression>,
639}
640
641impl Program {
642    /// Creates a new empty program.
643    pub fn new() -> Self {
644        Self { statements: Vec::new() }
645    }
646
647    /// Adds a statement to the program.
648    pub fn add_statement(&mut self, statement: Statement) {
649        self.statements.push(statement)
650    }
651}
652
653impl Default for Program {
654    /// Returns a default empty program.
655    fn default() -> Self {
656        Self::new()
657    }
658}
659
660impl Expression {
661    /// Creates a name expression.
662    pub fn name(name: impl Into<String>) -> Self {
663        Self::Name(name.into())
664    }
665
666    /// Creates a string literal expression.
667    pub fn string(value: impl Into<String>) -> Self {
668        Self::Literal(Literal::String(value.into()))
669    }
670
671    /// Creates an integer literal expression.
672    pub fn integer(value: i64) -> Self {
673        Self::Literal(Literal::Integer(value))
674    }
675
676    /// Creates a float literal expression.
677    pub fn float(value: f64) -> Self {
678        Self::Literal(Literal::Float(value))
679    }
680
681    /// Creates a boolean literal expression.
682    pub fn boolean(value: bool) -> Self {
683        Self::Literal(Literal::Boolean(value))
684    }
685
686    /// Creates a None literal expression.
687    pub fn none() -> Self {
688        Self::Literal(Literal::None)
689    }
690}
691
692impl Statement {
693    /// Creates a function definition statement.
694    pub fn function_def(name: impl Into<String>, parameters: Vec<Parameter>, return_type: Option<Type>, body: Vec<Statement>) -> Self {
695        Self::FunctionDef { decorators: Vec::new(), name: name.into(), parameters, return_type, body }
696    }
697
698    /// Creates an assignment statement.
699    pub fn assignment(target: Expression, value: Expression) -> Self {
700        Self::Assignment { target, value }
701    }
702
703    /// Creates an expression statement.
704    pub fn expression(expr: Expression) -> Self {
705        Self::Expression(expr)
706    }
707
708    /// Creates a return statement.
709    pub fn return_stmt(value: Option<Expression>) -> Self {
710        Self::Return(value)
711    }
712}