darklua_core/nodes/expressions/
prefix.rs

1use crate::nodes::{
2    Expression, FieldExpression, FunctionCall, Identifier, IndexExpression, ParentheseExpression,
3    Token,
4};
5
6/// Represents a prefix expression.
7///
8/// Prefix expressions form the base for more complex expressions like method calls
9/// and property access chains.
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub enum Prefix {
12    /// A function call expression (e.g., `func()`)
13    Call(Box<FunctionCall>),
14    /// A field access expression (e.g., `object.field`)
15    Field(Box<FieldExpression>),
16    /// A simple name/variable (e.g., `variable_name`)
17    Identifier(Identifier),
18    /// An indexed access expression (e.g., `table[key]`)
19    Index(Box<IndexExpression>),
20    /// A parenthesized expression (e.g., `(expression)`)
21    Parenthese(Box<ParentheseExpression>),
22}
23
24impl Prefix {
25    /// Creates a new prefix from a name/identifier.
26    pub fn from_name<S: Into<Identifier>>(name: S) -> Self {
27        Self::Identifier(name.into())
28    }
29
30    /// Returns a mutable reference to the first token for this prefix chain,
31    /// creating it if missing.
32    pub fn mutate_first_token(&mut self) -> &mut Token {
33        let mut current = self;
34        loop {
35            match current {
36                Prefix::Call(call) => {
37                    current = call.mutate_prefix();
38                }
39                Prefix::Field(field_expression) => {
40                    current = field_expression.mutate_prefix();
41                }
42                Prefix::Index(index_expression) => {
43                    current = index_expression.mutate_prefix();
44                }
45                Prefix::Identifier(identifier) => {
46                    break identifier.mutate_or_insert_token();
47                }
48                Prefix::Parenthese(parenthese_expression) => {
49                    break parenthese_expression.mutate_first_token();
50                }
51            }
52        }
53    }
54
55    /// Returns a mutable reference to the last token for this prefix chain,
56    /// creating it if missing.
57    pub fn mutate_last_token(&mut self) -> &mut Token {
58        match self {
59            Prefix::Call(call) => call.mutate_last_token(),
60            Prefix::Field(field_expression) => field_expression.mutate_last_token(),
61            Prefix::Identifier(identifier) => identifier.mutate_or_insert_token(),
62            Prefix::Index(index_expression) => index_expression.mutate_last_token(),
63            Prefix::Parenthese(parenthese_expression) => parenthese_expression.mutate_last_token(),
64        }
65    }
66}
67
68impl From<Expression> for Prefix {
69    fn from(expression: Expression) -> Self {
70        match expression {
71            Expression::Call(call) => Prefix::Call(call),
72            Expression::Field(field) => Prefix::Field(field),
73            Expression::Identifier(identifier) => Prefix::Identifier(identifier),
74            Expression::Index(index) => Prefix::Index(index),
75            Expression::Parenthese(parenthese) => Prefix::Parenthese(parenthese),
76            Expression::Binary(_)
77            | Expression::False(_)
78            | Expression::Function(_)
79            | Expression::If(_)
80            | Expression::Nil(_)
81            | Expression::Number(_)
82            | Expression::String(_)
83            | Expression::InterpolatedString(_)
84            | Expression::Table(_)
85            | Expression::True(_)
86            | Expression::TypeCast(_)
87            | Expression::Unary(_)
88            | Expression::VariableArguments(_) => {
89                Prefix::Parenthese(Box::new(ParentheseExpression::new(expression)))
90            }
91        }
92    }
93}
94
95impl From<FunctionCall> for Prefix {
96    fn from(call: FunctionCall) -> Self {
97        Self::Call(Box::new(call))
98    }
99}
100
101impl From<FieldExpression> for Prefix {
102    fn from(field: FieldExpression) -> Self {
103        Self::Field(field.into())
104    }
105}
106
107impl From<Box<FieldExpression>> for Prefix {
108    fn from(field: Box<FieldExpression>) -> Self {
109        Self::Field(field)
110    }
111}
112
113impl From<Identifier> for Prefix {
114    fn from(identifier: Identifier) -> Self {
115        Self::Identifier(identifier)
116    }
117}
118
119impl From<IndexExpression> for Prefix {
120    fn from(index: IndexExpression) -> Self {
121        Self::Index(index.into())
122    }
123}
124
125impl From<Box<IndexExpression>> for Prefix {
126    fn from(index: Box<IndexExpression>) -> Self {
127        Self::Index(index)
128    }
129}
130
131impl From<ParentheseExpression> for Prefix {
132    fn from(expression: ParentheseExpression) -> Self {
133        Self::Parenthese(Box::new(expression))
134    }
135}