Skip to main content

darklua_core/nodes/expressions/
prefix.rs

1use crate::nodes::{
2    Expression, FieldExpression, FunctionCall, Identifier, IndexExpression, ParentheseExpression,
3    Token, TypeInstantiationExpression,
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    /// A type instantiation expression (e.g., `var<<Type1, Type2>>`)
23    TypeInstantiation(Box<TypeInstantiationExpression>),
24}
25
26impl Prefix {
27    /// Creates a new prefix from a name/identifier.
28    pub fn from_name<S: Into<Identifier>>(name: S) -> Self {
29        Self::Identifier(name.into())
30    }
31
32    /// Returns a mutable reference to the first token for this prefix chain,
33    /// creating it if missing.
34    pub fn mutate_first_token(&mut self) -> &mut Token {
35        let mut current = self;
36        loop {
37            match current {
38                Prefix::Call(call) => {
39                    current = call.mutate_prefix();
40                }
41                Prefix::Field(field_expression) => {
42                    current = field_expression.mutate_prefix();
43                }
44                Prefix::Index(index_expression) => {
45                    current = index_expression.mutate_prefix();
46                }
47                Prefix::Identifier(identifier) => {
48                    break identifier.mutate_or_insert_token();
49                }
50                Prefix::Parenthese(parenthese_expression) => {
51                    break parenthese_expression.mutate_first_token();
52                }
53                Prefix::TypeInstantiation(type_instantiation_expression) => {
54                    current = type_instantiation_expression.mutate_prefix();
55                }
56            }
57        }
58    }
59
60    /// Returns a mutable reference to the last token for this prefix chain,
61    /// creating it if missing.
62    pub fn mutate_last_token(&mut self) -> &mut Token {
63        match self {
64            Prefix::Call(call) => call.mutate_last_token(),
65            Prefix::Field(field_expression) => field_expression.mutate_last_token(),
66            Prefix::Identifier(identifier) => identifier.mutate_or_insert_token(),
67            Prefix::Index(index_expression) => index_expression.mutate_last_token(),
68            Prefix::Parenthese(parenthese_expression) => parenthese_expression.mutate_last_token(),
69            Prefix::TypeInstantiation(type_instantiation_expression) => {
70                type_instantiation_expression.mutate_last_token()
71            }
72        }
73    }
74}
75
76impl From<Expression> for Prefix {
77    fn from(expression: Expression) -> Self {
78        match expression {
79            Expression::Call(call) => Prefix::Call(call),
80            Expression::Field(field) => Prefix::Field(field),
81            Expression::Identifier(identifier) => Prefix::Identifier(identifier),
82            Expression::Index(index) => Prefix::Index(index),
83            Expression::Parenthese(parenthese) => Prefix::Parenthese(parenthese),
84            Expression::TypeInstantiation(type_instantiation) => {
85                Prefix::TypeInstantiation(type_instantiation)
86            }
87            Expression::Binary(_)
88            | Expression::False(_)
89            | Expression::Function(_)
90            | Expression::If(_)
91            | Expression::Nil(_)
92            | Expression::Number(_)
93            | Expression::String(_)
94            | Expression::InterpolatedString(_)
95            | Expression::Table(_)
96            | Expression::True(_)
97            | Expression::TypeCast(_)
98            | Expression::Unary(_)
99            | Expression::VariableArguments(_) => {
100                Prefix::Parenthese(Box::new(ParentheseExpression::new(expression)))
101            }
102        }
103    }
104}
105
106impl From<FunctionCall> for Prefix {
107    fn from(call: FunctionCall) -> Self {
108        Self::Call(Box::new(call))
109    }
110}
111
112impl From<FieldExpression> for Prefix {
113    fn from(field: FieldExpression) -> Self {
114        Self::Field(field.into())
115    }
116}
117
118impl From<Box<FieldExpression>> for Prefix {
119    fn from(field: Box<FieldExpression>) -> Self {
120        Self::Field(field)
121    }
122}
123
124impl From<Identifier> for Prefix {
125    fn from(identifier: Identifier) -> Self {
126        Self::Identifier(identifier)
127    }
128}
129
130impl From<IndexExpression> for Prefix {
131    fn from(index: IndexExpression) -> Self {
132        Self::Index(index.into())
133    }
134}
135
136impl From<Box<IndexExpression>> for Prefix {
137    fn from(index: Box<IndexExpression>) -> Self {
138        Self::Index(index)
139    }
140}
141
142impl From<ParentheseExpression> for Prefix {
143    fn from(expression: ParentheseExpression) -> Self {
144        Self::Parenthese(Box::new(expression))
145    }
146}
147
148impl From<TypeInstantiationExpression> for Prefix {
149    fn from(type_instantiation: TypeInstantiationExpression) -> Self {
150        Self::TypeInstantiation(Box::new(type_instantiation))
151    }
152}
153
154impl From<Box<TypeInstantiationExpression>> for Prefix {
155    fn from(type_instantiation: Box<TypeInstantiationExpression>) -> Self {
156        Self::TypeInstantiation(type_instantiation)
157    }
158}