Skip to main content

oak_crystal/parser/
element_type.rs

1//! Crystal element types.
2
3use oak_core::{ElementType, UniversalElementRole};
4use std::fmt::{Display, Formatter};
5
6/// Enum representing all possible element types in Crystal.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[repr(u16)]
10pub enum CrystalElementType {
11    /// Whitespace characters.
12    Whitespace,
13    /// Comments.
14    Comment,
15    /// Identifiers.
16    Identifier,
17    /// Numeric literals.
18    Number,
19    /// String literals.
20    String,
21    /// Character literals.
22    Character,
23    /// Symbol literals.
24    Symbol,
25    /// `class` keyword.
26    ClassKeyword,
27    /// `module` keyword.
28    ModuleKeyword,
29    /// `def` keyword.
30    DefKeyword,
31    /// `end` keyword.
32    EndKeyword,
33    /// `if` keyword.
34    IfKeyword,
35    /// `else` keyword.
36    ElseKeyword,
37    /// `elsif` keyword.
38    ElsifKeyword,
39    /// `unless` keyword.
40    UnlessKeyword,
41    /// `case` keyword.
42    CaseKeyword,
43    /// `when` keyword.
44    WhenKeyword,
45    /// `then` keyword.
46    ThenKeyword,
47    /// `while` keyword.
48    WhileKeyword,
49    /// `until` keyword.
50    UntilKeyword,
51    /// `for` keyword.
52    ForKeyword,
53    /// `in` keyword.
54    InKeyword,
55    /// `do` keyword.
56    DoKeyword,
57    /// `begin` keyword.
58    BeginKeyword,
59    /// `rescue` keyword.
60    RescueKeyword,
61    /// `ensure` keyword.
62    EnsureKeyword,
63    /// `break` keyword.
64    BreakKeyword,
65    /// `next` keyword.
66    NextKeyword,
67    /// `return` keyword.
68    ReturnKeyword,
69    /// `yield` keyword.
70    YieldKeyword,
71    /// `super` keyword.
72    SuperKeyword,
73    /// `self` keyword.
74    SelfKeyword,
75    /// `true` keyword.
76    TrueKeyword,
77    /// `false` keyword.
78    FalseKeyword,
79    /// `nil` keyword.
80    NilKeyword,
81    /// `and` keyword.
82    AndKeyword,
83    /// `or` keyword.
84    OrKeyword,
85    /// `not` keyword.
86    NotKeyword,
87    /// `+` operator.
88    Plus,
89    /// `-` operator.
90    Minus,
91    /// `*` operator.
92    Star,
93    /// `/` operator.
94    Slash,
95    /// `%` operator.
96    Percent,
97    /// `**` operator.
98    StarStar,
99    /// `=` operator.
100    Equal,
101    /// `==` operator.
102    EqualEqual,
103    /// `!=` operator.
104    NotEqual,
105    /// `<` operator.
106    Less,
107    /// `<=` operator.
108    LessEqual,
109    /// `>` operator.
110    Greater,
111    /// `>=` operator.
112    GreaterEqual,
113    /// `<=>` operator.
114    Spaceship,
115    /// `=~` operator.
116    Match,
117    /// `!~` operator.
118    NotMatch,
119    /// `&` operator.
120    And,
121    /// `|` operator.
122    Or,
123    /// `!` operator.
124    Not,
125    /// `&` bitwise operator.
126    BitwiseAnd,
127    /// `|` bitwise operator.
128    BitwiseOr,
129    /// `^` bitwise operator.
130    BitwiseXor,
131    /// `~` bitwise operator.
132    BitwiseNot,
133    /// `<<` operator.
134    LeftShift,
135    /// `>>` operator.
136    RightShift,
137    /// `&&` operator.
138    LogicalAnd,
139    /// `||` operator.
140    LogicalOr,
141    /// `+=` operator.
142    PlusEqual,
143    /// `-=` operator.
144    MinusEqual,
145    /// `*=` operator.
146    StarEqual,
147    /// `/=` operator.
148    SlashEqual,
149    /// `%=` operator.
150    PercentEqual,
151    /// `**=` operator.
152    StarStarEqual,
153    /// `&=` operator.
154    AndEqual,
155    /// `|=` operator.
156    OrEqual,
157    /// `^=` operator.
158    XorEqual,
159    /// `<<=` operator.
160    LeftShiftEqual,
161    /// `>>=` operator.
162    RightShiftEqual,
163    /// `&&=` operator.
164    LogicalAndEqual,
165    /// `||=` operator.
166    LogicalOrEqual,
167    /// `(` symbol.
168    LeftParen,
169    /// `)` symbol.
170    RightParen,
171    /// `{` symbol.
172    LeftBrace,
173    /// `}` symbol.
174    RightBrace,
175    /// `[` symbol.
176    LeftBracket,
177    /// `]` symbol.
178    RightBracket,
179    /// `,` symbol.
180    Comma,
181    /// `;` symbol.
182    Semicolon,
183    /// `.` symbol.
184    Dot,
185    /// `..` symbol.
186    DotDot,
187    /// `...` symbol.
188    DotDotDot,
189    /// `:` symbol.
190    Colon,
191    /// `::` symbol.
192    DoubleColon,
193    /// `->` symbol.
194    Arrow,
195    /// `=>` symbol.
196    FatArrow,
197    /// `?` symbol.
198    Question,
199    /// `@` symbol.
200    At,
201    /// `@@` symbol.
202    DoubleAt,
203    /// `$` symbol.
204    Dollar,
205    /// Newline character.
206    Newline,
207    /// End of file.
208    Eof,
209    /// Error element.
210    Error,
211    /// Root node.
212    Root,
213    /// Program node.
214    Program,
215    /// Source file node.
216    SourceFile,
217    /// Class definition.
218    ClassDef,
219    /// Module definition.
220    ModuleDef,
221    /// Method definition.
222    MethodDef,
223    /// Block node.
224    Block,
225    /// `if` expression.
226    IfExpr,
227    /// `unless` expression.
228    UnlessExpr,
229    /// `case` expression.
230    CaseExpr,
231    /// `when` clause.
232    WhenClause,
233    /// `while` expression.
234    WhileExpr,
235    /// `until` expression.
236    UntilExpr,
237    /// `for` expression.
238    ForExpr,
239    /// `begin` expression.
240    BeginExpr,
241    /// `rescue` clause.
242    RescueClause,
243    /// `ensure` clause.
244    EnsureClause,
245    /// Call expression.
246    CallExpr,
247    /// Index expression.
248    IndexExpr,
249    /// Member expression.
250    MemberExpr,
251    /// Binary expression.
252    BinaryExpr,
253    /// Unary expression.
254    UnaryExpr,
255    /// Assignment expression.
256    AssignExpr,
257    /// Literal expression.
258    LiteralExpr,
259    /// Identifier expression.
260    IdentifierExpr,
261    /// Array expression.
262    ArrayExpr,
263    /// Hash expression.
264    HashExpr,
265    /// Hash pair.
266    HashPair,
267    /// Block expression.
268    BlockExpr,
269    /// Lambda expression.
270    LambdaExpr,
271    /// `yield` expression.
272    YieldExpr,
273    /// `return` expression.
274    ReturnExpr,
275    /// `break` expression.
276    BreakExpr,
277    /// `next` expression.
278    NextExpr,
279    /// `super` expression.
280    SuperExpr,
281    /// `self` expression.
282    SelfExpr,
283    /// Parenthesized expression.
284    ParenExpr,
285    /// Type expression.
286    TypeExpr,
287    /// Generic type.
288    GenericType,
289    /// Union type.
290    UnionType,
291    /// Tuple type.
292    TupleType,
293    /// Named tuple type.
294    NamedTupleType,
295    /// Proc type.
296    ProcType,
297    /// Pattern node.
298    Pattern,
299    /// Identifier pattern.
300    IdentifierPattern,
301    /// Literal pattern.
302    LiteralPattern,
303    /// Array pattern.
304    ArrayPattern,
305    /// Hash pattern.
306    HashPattern,
307    /// Tuple pattern.
308    TuplePattern,
309    /// Parameter list.
310    ParamList,
311    /// Parameter node.
312    Param,
313    /// Splat parameter.
314    SplatParam,
315    /// Double splat parameter.
316    DoubleSplatParam,
317    /// Block parameter.
318    BlockParam,
319    /// Annotation node.
320    Annotation,
321    /// Macro definition.
322    MacroDef,
323    /// Macro call.
324    MacroCall,
325    /// Macro expression.
326    MacroExpr,
327    /// Alias definition.
328    Alias,
329    /// `include` statement.
330    Include,
331    /// `extend` statement.
332    Extend,
333    /// `require` statement.
334    Require,
335    /// `private` visibility.
336    Private,
337    /// `protected` visibility.
338    Protected,
339    /// `public` visibility.
340    Public,
341    /// `abstract` modifier.
342    Abstract,
343    /// `virtual` modifier.
344    Virtual,
345    /// `override` modifier.
346    Override,
347    /// Struct definition.
348    StructDef,
349    /// Enum definition.
350    EnumDef,
351    /// Union definition.
352    UnionDef,
353    /// Lib definition.
354    LibDef,
355    /// `raise` expression.
356    RaiseExpr,
357    /// Range expression.
358    RangeExpr,
359    /// Exclusive range expression.
360    ExclusiveRangeExpr,
361    /// Regex literal.
362    RegexLiteral,
363    /// String interpolation.
364    StringInterpolation,
365    /// Interpolation expression.
366    InterpolationExpr,
367    /// Symbol literal.
368    SymbolLiteral,
369    /// Constant reference.
370    ConstantRef,
371    /// Instance variable.
372    InstanceVar,
373    /// Class variable.
374    ClassVar,
375    /// Global variable.
376    GlobalVar,
377    /// Getter method.
378    Getter,
379    /// Setter method.
380    Setter,
381    /// Operator definition.
382    OperatorDef,
383}
384
385impl CrystalElementType {
386    /// Check if the syntax kind is trivia (whitespace, comment, or newline)
387    pub fn is_trivia(&self) -> bool {
388        matches!(self, Self::Whitespace | Self::Comment | Self::Newline)
389    }
390
391    /// Check if the syntax kind is a keyword
392    pub fn is_keyword(self) -> bool {
393        matches!(
394            self,
395            Self::ClassKeyword
396                | Self::ModuleKeyword
397                | Self::DefKeyword
398                | Self::EndKeyword
399                | Self::IfKeyword
400                | Self::ElseKeyword
401                | Self::ElsifKeyword
402                | Self::UnlessKeyword
403                | Self::CaseKeyword
404                | Self::WhenKeyword
405                | Self::ThenKeyword
406                | Self::WhileKeyword
407                | Self::UntilKeyword
408                | Self::ForKeyword
409                | Self::InKeyword
410                | Self::DoKeyword
411                | Self::BeginKeyword
412                | Self::RescueKeyword
413                | Self::EnsureKeyword
414                | Self::BreakKeyword
415                | Self::NextKeyword
416                | Self::ReturnKeyword
417                | Self::YieldKeyword
418                | Self::SuperKeyword
419                | Self::SelfKeyword
420                | Self::TrueKeyword
421                | Self::FalseKeyword
422                | Self::NilKeyword
423                | Self::AndKeyword
424                | Self::OrKeyword
425                | Self::NotKeyword
426        )
427    }
428
429    /// Check if the syntax kind is a literal
430    pub fn is_literal(self) -> bool {
431        matches!(self, Self::Number | Self::String | Self::Character | Self::Symbol | Self::RegexLiteral | Self::SymbolLiteral)
432    }
433
434    /// Check if the syntax kind is an operator
435    pub fn is_operator(self) -> bool {
436        matches!(
437            self,
438            Self::Plus
439                | Self::Minus
440                | Self::Star
441                | Self::Slash
442                | Self::Percent
443                | Self::StarStar
444                | Self::Equal
445                | Self::EqualEqual
446                | Self::NotEqual
447                | Self::Less
448                | Self::LessEqual
449                | Self::Greater
450                | Self::GreaterEqual
451                | Self::Spaceship
452                | Self::Match
453                | Self::NotMatch
454                | Self::And
455                | Self::Or
456                | Self::Not
457                | Self::BitwiseAnd
458                | Self::BitwiseOr
459                | Self::BitwiseXor
460                | Self::BitwiseNot
461                | Self::LeftShift
462                | Self::RightShift
463                | Self::LogicalAnd
464                | Self::LogicalOr
465        )
466    }
467
468    /// Check if the syntax kind is an assignment operator
469    pub fn is_assignment_operator(self) -> bool {
470        matches!(
471            self,
472            Self::PlusEqual
473                | Self::MinusEqual
474                | Self::StarEqual
475                | Self::SlashEqual
476                | Self::PercentEqual
477                | Self::StarStarEqual
478                | Self::AndEqual
479                | Self::OrEqual
480                | Self::XorEqual
481                | Self::LeftShiftEqual
482                | Self::RightShiftEqual
483                | Self::LogicalAndEqual
484                | Self::LogicalOrEqual
485        )
486    }
487
488    /// Check if the syntax kind is a delimiter
489    pub fn is_delimiter(self) -> bool {
490        matches!(self, Self::LeftParen | Self::RightParen | Self::LeftBrace | Self::RightBrace | Self::LeftBracket | Self::RightBracket | Self::Comma | Self::Semicolon)
491    }
492}
493
494impl Display for CrystalElementType {
495    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
496        write!(f, "{:?}", self)
497    }
498}
499
500impl ElementType for CrystalElementType {
501    type Role = UniversalElementRole;
502
503    fn role(&self) -> Self::Role {
504        match self {
505            Self::Root => UniversalElementRole::Root,
506            Self::SourceFile => UniversalElementRole::Root,
507            Self::Error => UniversalElementRole::Error,
508            _ => UniversalElementRole::None,
509        }
510    }
511}
512
513impl From<crate::lexer::token_type::CrystalTokenType> for CrystalElementType {
514    fn from(token: crate::lexer::token_type::CrystalTokenType) -> Self {
515        unsafe { std::mem::transmute(token) }
516    }
517}