Skip to main content

oak_ruby/parser/
element_type.rs

1use oak_core::{ElementType, UniversalElementRole};
2use serde::{Deserialize, Serialize};
3use std::fmt;
4
5/// Element types for Ruby.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8#[repr(u8)]
9pub enum RubyElementType {
10    /// An identifier.
11    Identifier,
12    /// A global variable (e.g., `$stdout`).
13    GlobalVariable,
14    /// An instance variable (e.g., `@name`).
15    InstanceVariable,
16    /// A class variable (e.g., `@@name`).
17    ClassVariable,
18    /// A constant (e.g., `MATH`).
19    Constant,
20    /// An integer literal.
21    IntegerLiteral,
22    /// A float literal.
23    FloatLiteral,
24    /// A string literal.
25    StringLiteral,
26    /// A general literal.
27    Literal,
28    /// A symbol (e.g., `:name`).
29    Symbol,
30    /// A regular expression literal.
31    RegexLiteral,
32
33    /// The `if` keyword.
34    If,
35    /// The `unless` keyword.
36    Unless,
37    /// The `elsif` keyword.
38    Elsif,
39    /// The `else` keyword.
40    Else,
41    /// The `case` keyword.
42    Case,
43    /// The `when` keyword.
44    When,
45    /// The `then` keyword.
46    Then,
47    /// The `for` keyword.
48    For,
49    /// The `while` keyword.
50    While,
51    /// The `until` keyword.
52    Until,
53    /// The `break` keyword.
54    Break,
55    /// The `next` keyword.
56    Next,
57    /// The `redo` keyword.
58    Redo,
59    /// The `retry` keyword.
60    Retry,
61    /// The `return` keyword.
62    Return,
63    /// The `yield` keyword.
64    Yield,
65    /// The `def` keyword.
66    Def,
67    /// The `class` keyword.
68    Class,
69    /// The `module` keyword.
70    Module,
71    /// The `end` keyword.
72    End,
73    /// The `lambda` keyword.
74    Lambda,
75    /// The `proc` keyword.
76    Proc,
77    /// The `begin` keyword.
78    Begin,
79    /// The `rescue` keyword.
80    Rescue,
81    /// The `ensure` keyword.
82    Ensure,
83    /// The `raise` keyword.
84    Raise,
85    /// The `require` keyword.
86    Require,
87    /// The `load` keyword.
88    Load,
89    /// The `include` keyword.
90    Include,
91    /// The `extend` keyword.
92    Extend,
93    /// The `prepend` keyword.
94    Prepend,
95    /// The `and` keyword.
96    And,
97    /// The `or` keyword.
98    Or,
99    /// The `not` keyword.
100    Not,
101    /// The `in` keyword.
102    In,
103    /// The `true` keyword.
104    True,
105    /// The `false` keyword.
106    False,
107    /// The `nil` keyword.
108    Nil,
109    /// The `super` keyword.
110    Super,
111    /// The `self` keyword.
112    Self_,
113    /// The `alias` keyword.
114    Alias,
115    /// The `undef` keyword.
116    Undef,
117    /// The `defined?` keyword.
118    Defined,
119    /// The `do` keyword.
120    Do,
121
122    /// Plus operator `+`.
123    Plus,
124    /// Minus operator `-`.
125    Minus,
126    /// Multiply operator `*`.
127    Multiply,
128    /// Divide operator `/`.
129    Divide,
130    /// Modulo operator `%`.
131    Modulo,
132    /// Power operator `**`.
133    Power,
134    /// Equality operator `==`.
135    EqualEqual,
136    /// Inequality operator `!=`.
137    NotEqual,
138    /// Less than operator `<`.
139    Less,
140    /// Greater than operator `>`.
141    Greater,
142    /// Less than or equal operator `<=`.
143    LessEqual,
144    /// Greater than or equal operator `>=`.
145    GreaterEqual,
146    /// Case equality operator `===`.
147    EqualEqualEqual,
148    /// Spaceship operator `<=>`.
149    Spaceship,
150    /// Assignment operator `=`.
151    Assign,
152    /// Plus assignment operator `+=`.
153    PlusAssign,
154    /// Minus assignment operator `-=`.
155    MinusAssign,
156    /// Multiply assignment operator `*=`.
157    MultiplyAssign,
158    /// Divide assignment operator `/=`.
159    DivideAssign,
160    /// Modulo assignment operator `%=`.
161    ModuloAssign,
162    /// Power assignment operator `**=`.
163    PowerAssign,
164    /// Bitwise AND operator `&`.
165    BitAnd,
166    /// Bitwise OR operator `|`.
167    BitOr,
168    /// Bitwise XOR operator `^`.
169    Xor,
170    /// Logical NOT operator `!`.
171    LogicalNot,
172    /// Bitwise NOT operator `~`.
173    Tilde,
174    /// Left shift operator `<<`.
175    LeftShift,
176    /// Right shift operator `>>`.
177    RightShift,
178    /// AND assignment operator `&=`.
179    AndAssign,
180    /// OR assignment operator `|=`.
181    OrAssign,
182    /// XOR assignment operator `^=`.
183    XorAssign,
184    /// Left shift assignment operator `<<=`.
185    LeftShiftAssign,
186    /// Right shift assignment operator `>>=`.
187    RightShiftAssign,
188    /// Logical AND operator `&&`.
189    AndAnd,
190    /// Logical OR operator `||`.
191    OrOr,
192    /// OR OR assignment operator `||=`.
193    OrOrAssign,
194    /// AND AND assignment operator `&&=`.
195    AndAndAssign,
196    /// Question mark `?`.
197    Question,
198    /// Range operator `..`.
199    DotDot,
200    /// Range operator `...`.
201    DotDotDot,
202    /// Match operator `=~`.
203    Match,
204    /// Not match operator `!~`.
205    NotMatch,
206
207    /// Left parenthesis `(`.
208    LeftParen,
209    /// Right parenthesis `)`.
210    RightParen,
211    /// Left bracket `[`.
212    LeftBracket,
213    /// Right bracket `]`.
214    RightBracket,
215    /// Left brace `{`.
216    LeftBrace,
217    /// Right brace `}`.
218    RightBrace,
219    /// Comma `,`.
220    Comma,
221    /// Colon `:`.
222    Colon,
223    /// Semicolon `;`.
224    Semicolon,
225    /// Dot `.`.
226    Dot,
227    /// Double colon `::`.
228    DoubleColon,
229    /// At symbol `@`.
230    At,
231    /// Dollar sign `$`.
232    Dollar,
233
234    /// Whitespace.
235    Whitespace,
236    /// Newline.
237    Newline,
238    /// Comment.
239    Comment,
240    /// End of file.
241    Eof,
242    /// Invalid token.
243    Invalid,
244    /// Root element.
245    Root,
246    /// A binary expression.
247    BinaryExpression,
248    /// A unary expression.
249    UnaryExpression,
250    /// A literal expression.
251    LiteralExpression,
252    /// A parenthesized expression.
253    ParenExpression,
254    /// A parenthesized expression (alternative).
255    ParenthesizedExpression,
256    /// A method definition.
257    MethodDefinition,
258    /// A class definition.
259    ClassDefinition,
260    /// A module definition.
261    ModuleDefinition,
262    /// An if statement.
263    IfStatement,
264    /// A while statement.
265    WhileStatement,
266    /// An unless statement.
267    UnlessStatement,
268    /// An until statement.
269    UntilStatement,
270    /// A for statement.
271    ForStatement,
272    /// A case statement.
273    CaseStatement,
274    /// A when clause.
275    WhenClause,
276    /// A begin statement.
277    BeginStatement,
278    /// A rescue clause.
279    RescueClause,
280    /// An ensure clause.
281    EnsureClause,
282    /// A return statement.
283    ReturnStatement,
284    /// An if expression.
285    IfExpression,
286    /// A call expression.
287    CallExpression,
288    /// A member access expression.
289    MemberAccess,
290    /// A parameter list.
291    ParameterList,
292    /// An argument list.
293    ArgumentList,
294    /// An error element.
295    Error,
296    /// Equal operator `=`.
297    Equal,
298}
299
300impl RubyElementType {
301    /// Returns true if the element is ignored (whitespace, newline, or comment).
302    pub fn is_ignored(&self) -> bool {
303        matches!(self, Self::Whitespace | Self::Newline | Self::Comment)
304    }
305
306    /// Returns true if the element is a keyword.
307    pub fn is_keyword(&self) -> bool {
308        matches!(
309            self,
310            Self::If
311                | Self::Unless
312                | Self::Elsif
313                | Self::Else
314                | Self::Case
315                | Self::When
316                | Self::Then
317                | Self::For
318                | Self::While
319                | Self::Until
320                | Self::Break
321                | Self::Next
322                | Self::Redo
323                | Self::Retry
324                | Self::Return
325                | Self::Yield
326                | Self::Def
327                | Self::Class
328                | Self::Module
329                | Self::End
330                | Self::Lambda
331                | Self::Proc
332                | Self::Begin
333                | Self::Rescue
334                | Self::Ensure
335                | Self::Raise
336                | Self::Require
337                | Self::Load
338                | Self::Include
339                | Self::Extend
340                | Self::Prepend
341                | Self::And
342                | Self::Or
343                | Self::Not
344                | Self::In
345                | Self::True
346                | Self::False
347                | Self::Nil
348                | Self::Super
349                | Self::Self_
350                | Self::Alias
351                | Self::Undef
352                | Self::Defined
353                | Self::Do
354        )
355    }
356}
357
358impl fmt::Display for RubyElementType {
359    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
360        let name = match self {
361            Self::Identifier => "Identifier",
362            Self::GlobalVariable => "GlobalVariable",
363            Self::InstanceVariable => "InstanceVariable",
364            Self::ClassVariable => "ClassVariable",
365            Self::Constant => "Constant",
366            Self::IntegerLiteral => "IntegerLiteral",
367            Self::FloatLiteral => "FloatLiteral",
368            Self::StringLiteral => "StringLiteral",
369            Self::Literal => "Literal",
370            Self::Symbol => "Symbol",
371            Self::RegexLiteral => "RegexLiteral",
372
373            Self::If => "If",
374            Self::Unless => "Unless",
375            Self::Elsif => "Elsif",
376            Self::Else => "Else",
377            Self::Case => "Case",
378            Self::When => "When",
379            Self::Then => "Then",
380            Self::For => "For",
381            Self::While => "While",
382            Self::Until => "Until",
383            Self::Break => "Break",
384            Self::Next => "Next",
385            Self::Redo => "Redo",
386            Self::Retry => "Retry",
387            Self::Return => "Return",
388            Self::Yield => "Yield",
389            Self::Def => "Def",
390            Self::Class => "Class",
391            Self::Module => "Module",
392            Self::End => "End",
393            Self::Lambda => "Lambda",
394            Self::Proc => "Proc",
395            Self::Begin => "Begin",
396            Self::Rescue => "Rescue",
397            Self::Ensure => "Ensure",
398            Self::Raise => "Raise",
399            Self::Require => "Require",
400            Self::Load => "Load",
401            Self::Include => "Include",
402            Self::Extend => "Extend",
403            Self::Prepend => "Prepend",
404            Self::And => "And",
405            Self::Or => "Or",
406            Self::Not => "Not",
407            Self::In => "In",
408            Self::True => "True",
409            Self::False => "False",
410            Self::Nil => "Nil",
411            Self::Super => "Super",
412            Self::Self_ => "Self",
413            Self::Alias => "Alias",
414            Self::Undef => "Undef",
415            Self::Defined => "Defined",
416            Self::Do => "Do",
417
418            Self::Plus => "Plus",
419            Self::Minus => "Minus",
420            Self::Multiply => "Multiply",
421            Self::Divide => "Divide",
422            Self::Modulo => "Modulo",
423            Self::Power => "Power",
424            Self::EqualEqual => "EqualEqual",
425            Self::NotEqual => "NotEqual",
426            Self::Less => "Less",
427            Self::Greater => "Greater",
428            Self::LessEqual => "LessEqual",
429            Self::GreaterEqual => "GreaterEqual",
430            Self::EqualEqualEqual => "EqualEqualEqual",
431            Self::Spaceship => "Spaceship",
432            Self::Assign => "Assign",
433            Self::PlusAssign => "PlusAssign",
434            Self::MinusAssign => "MinusAssign",
435            Self::MultiplyAssign => "MultiplyAssign",
436            Self::DivideAssign => "DivideAssign",
437            Self::ModuloAssign => "ModuloAssign",
438            Self::PowerAssign => "PowerAssign",
439            Self::BitAnd => "BitAnd",
440            Self::BitOr => "BitOr",
441            Self::Xor => "Xor",
442            Self::LogicalNot => "LogicalNot",
443            Self::Tilde => "Tilde",
444            Self::LeftShift => "LeftShift",
445            Self::RightShift => "RightShift",
446            Self::AndAssign => "AndAssign",
447            Self::OrAssign => "OrAssign",
448            Self::XorAssign => "XorAssign",
449            Self::LeftShiftAssign => "LeftShiftAssign",
450            Self::RightShiftAssign => "RightShiftAssign",
451            Self::AndAnd => "AndAnd",
452            Self::OrOr => "OrOr",
453            Self::OrOrAssign => "OrOrAssign",
454            Self::AndAndAssign => "AndAndAssign",
455            Self::Question => "Question",
456            Self::DotDot => "DotDot",
457            Self::DotDotDot => "DotDotDot",
458            Self::Match => "Match",
459            Self::NotMatch => "NotMatch",
460
461            Self::LeftParen => "LeftParen",
462            Self::RightParen => "RightParen",
463            Self::LeftBracket => "LeftBracket",
464            Self::RightBracket => "RightBracket",
465            Self::LeftBrace => "LeftBrace",
466            Self::RightBrace => "RightBrace",
467            Self::Comma => "Comma",
468            Self::Colon => "Colon",
469            Self::Semicolon => "Semicolon",
470            Self::Dot => "Dot",
471            Self::DoubleColon => "DoubleColon",
472            Self::At => "At",
473            Self::Dollar => "Dollar",
474
475            Self::Whitespace => "Whitespace",
476            Self::Newline => "Newline",
477            Self::Comment => "Comment",
478            Self::Eof => "Eof",
479            Self::Invalid => "Invalid",
480            Self::Root => "Root",
481            Self::BinaryExpression => "BinaryExpression",
482            Self::UnaryExpression => "UnaryExpression",
483            Self::LiteralExpression => "LiteralExpression",
484            Self::ParenExpression => "ParenExpression",
485            Self::ParenthesizedExpression => "ParenthesizedExpression",
486            Self::MethodDefinition => "MethodDefinition",
487            Self::ClassDefinition => "ClassDefinition",
488            Self::ModuleDefinition => "ModuleDefinition",
489            Self::IfStatement => "IfStatement",
490            Self::WhileStatement => "WhileStatement",
491            Self::UnlessStatement => "UnlessStatement",
492            Self::UntilStatement => "UntilStatement",
493            Self::ForStatement => "ForStatement",
494            Self::CaseStatement => "CaseStatement",
495            Self::WhenClause => "WhenClause",
496            Self::BeginStatement => "BeginStatement",
497            Self::RescueClause => "RescueClause",
498            Self::EnsureClause => "EnsureClause",
499            Self::ReturnStatement => "ReturnStatement",
500            Self::IfExpression => "IfExpression",
501            Self::CallExpression => "CallExpression",
502            Self::MemberAccess => "MemberAccess",
503            Self::ParameterList => "ParameterList",
504            Self::ArgumentList => "ArgumentList",
505            Self::Error => "Error",
506            Self::Equal => "Equal",
507        };
508        write!(f, "{}", name)
509    }
510}
511
512impl ElementType for RubyElementType {
513    type Role = UniversalElementRole;
514
515    fn role(&self) -> Self::Role {
516        match self {
517            _ => UniversalElementRole::None,
518        }
519    }
520}
521
522impl From<crate::lexer::token_type::RubyTokenType> for RubyElementType {
523    fn from(token: crate::lexer::token_type::RubyTokenType) -> Self {
524        unsafe { std::mem::transmute(token) }
525    }
526}