oak-crystal 0.0.2

Crystal language parser with support for modern Crystal syntax and Ruby-like features.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
use oak_core::{ElementType, Token, TokenType, UniversalElementRole, UniversalTokenRole};
use std::fmt::{Display, Formatter};

pub type CrystalToken = Token<CrystalSyntaxKind>;

/// Crystal syntax node types
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u16)]
pub enum CrystalSyntaxKind {
    /// Whitespace characters
    Whitespace,
    /// Comment
    Comment,
    /// Identifier
    Identifier,
    /// Number literal
    Number,
    /// String literal
    String,
    /// Character literal
    Character,
    /// Symbol
    Symbol,
    /// class keyword
    ClassKeyword,
    /// module keyword
    ModuleKeyword,
    /// def keyword
    DefKeyword,
    /// end keyword
    EndKeyword,
    /// if keyword
    IfKeyword,
    /// else keyword
    ElseKeyword,
    /// elsif keyword
    ElsifKeyword,
    /// unless keyword
    UnlessKeyword,
    /// case keyword
    CaseKeyword,
    /// when keyword
    WhenKeyword,
    /// then keyword
    ThenKeyword,
    /// while keyword
    WhileKeyword,
    /// until keyword
    UntilKeyword,
    /// for keyword
    ForKeyword,
    /// in keyword
    InKeyword,
    /// do keyword
    DoKeyword,
    /// begin keyword
    BeginKeyword,
    /// rescue keyword
    RescueKeyword,
    /// ensure keyword
    EnsureKeyword,
    /// break keyword
    BreakKeyword,
    /// next keyword
    NextKeyword,
    /// return keyword
    ReturnKeyword,
    /// yield keyword
    YieldKeyword,
    /// super keyword
    SuperKeyword,
    /// self keyword
    SelfKeyword,
    /// true keyword
    TrueKeyword,
    /// false keyword
    FalseKeyword,
    /// nil keyword
    NilKeyword,
    /// and keyword
    AndKeyword,
    /// or keyword
    OrKeyword,
    /// not keyword
    NotKeyword,
    /// plus operator
    Plus,
    /// minus operator
    Minus,
    /// multiplication operator
    Star,
    /// division operator
    Slash,
    /// modulo operator
    Percent,
    /// exponentiation operator
    StarStar,
    /// assignment operator
    Equal,
    /// equality operator
    EqualEqual,
    /// inequality operator
    NotEqual,
    /// less than operator
    Less,
    /// less than or equal operator
    LessEqual,
    /// greater than operator
    Greater,
    /// greater than or equal operator
    GreaterEqual,
    /// spaceship operator
    Spaceship,
    /// match operator
    Match,
    /// not match operator
    NotMatch,
    /// and operator
    And,
    /// or operator
    Or,
    /// not operator
    Not,
    /// bitwise and operator
    BitwiseAnd,
    /// bitwise or operator
    BitwiseOr,
    /// bitwise xor operator
    BitwiseXor,
    /// bitwise not operator
    BitwiseNot,
    /// left shift operator
    LeftShift,
    /// right shift operator
    RightShift,
    /// logical and operator
    LogicalAnd,
    /// logical or operator
    LogicalOr,
    /// plus assignment operator
    PlusEqual,
    /// minus assignment operator
    MinusEqual,
    /// multiplication assignment operator
    StarEqual,
    /// division assignment operator
    SlashEqual,
    /// modulo assignment operator
    PercentEqual,
    /// exponentiation assignment operator
    StarStarEqual,
    /// and assignment operator
    AndEqual,
    /// or assignment operator
    OrEqual,
    /// xor assignment operator
    XorEqual,
    /// left shift assignment operator
    LeftShiftEqual,
    /// right shift assignment operator
    RightShiftEqual,
    /// logical and assignment operator
    LogicalAndEqual,
    /// logical or assignment operator
    LogicalOrEqual,
    /// left parenthesis
    LeftParen,
    /// right parenthesis
    RightParen,
    /// left brace
    LeftBrace,
    /// right brace
    RightBrace,
    /// left bracket
    LeftBracket,
    /// right bracket
    RightBracket,
    /// comma
    Comma,
    /// semicolon
    Semicolon,
    /// dot
    Dot,
    /// dot dot
    DotDot,
    /// dot dot dot
    DotDotDot,
    /// colon
    Colon,
    /// double colon
    DoubleColon,
    /// arrow
    Arrow,
    /// fat arrow
    FatArrow,
    /// question mark
    Question,
    /// at sign
    At,
    /// double at sign
    DoubleAt,
    /// dollar sign
    Dollar,
    /// newline
    Newline,
    /// end of file
    Eof,
    /// error
    Error,
    /// root node
    Root,
    /// program node
    Program,
    /// source file node
    SourceFile,
    /// class definition
    ClassDef,
    /// module definition
    ModuleDef,
    /// method definition
    MethodDef,
    /// block
    Block,
    /// if expression
    IfExpr,
    /// unless expression
    UnlessExpr,
    /// case expression
    CaseExpr,
    /// when clause
    WhenClause,
    /// while expression
    WhileExpr,
    /// until expression
    UntilExpr,
    /// for expression
    ForExpr,
    /// begin expression
    BeginExpr,
    /// rescue clause
    RescueClause,
    /// ensure clause
    EnsureClause,
    /// call expression
    CallExpr,
    /// index expression
    IndexExpr,
    /// member expression
    MemberExpr,
    /// binary expression
    BinaryExpr,
    /// unary expression
    UnaryExpr,
    /// assignment expression
    AssignExpr,
    /// literal expression
    LiteralExpr,
    /// identifier expression
    IdentifierExpr,
    /// array expression
    ArrayExpr,
    /// hash expression
    HashExpr,
    /// hash pair
    HashPair,
    /// block expression
    BlockExpr,
    /// lambda expression
    LambdaExpr,
    /// yield expression
    YieldExpr,
    /// return expression
    ReturnExpr,
    /// break expression
    BreakExpr,
    /// next expression
    NextExpr,
    /// super expression
    SuperExpr,
    /// self expression
    SelfExpr,
    /// parenthesized expression
    ParenExpr,
    /// type expression
    TypeExpr,
    /// generic type
    GenericType,
    /// union type
    UnionType,
    /// tuple type
    TupleType,
    /// named tuple type
    NamedTupleType,
    /// procedure type
    ProcType,
    /// pattern
    Pattern,
    /// identifier pattern
    IdentifierPattern,
    /// literal pattern
    LiteralPattern,
    /// array pattern
    ArrayPattern,
    /// hash pattern
    HashPattern,
    /// tuple pattern
    TuplePattern,
    /// parameter list
    ParamList,
    /// parameter
    Param,
    /// splat parameter
    SplatParam,
    /// double splat parameter
    DoubleSplatParam,
    /// block parameter
    BlockParam,
    /// annotation
    Annotation,
    /// macro definition
    MacroDef,
    /// macro call
    MacroCall,
    /// macro expression
    MacroExpr,
    /// alias
    Alias,
    /// include
    Include,
    /// extend
    Extend,
    /// require
    Require,
    /// private
    Private,
    /// protected
    Protected,
    /// public
    Public,
    /// abstract
    Abstract,
    /// virtual
    Virtual,
    /// override
    Override,
    /// struct definition
    StructDef,
    /// enum definition
    EnumDef,
    /// union definition
    UnionDef,
    /// lib definition
    LibDef,
    /// raise expression
    RaiseExpr,
    /// range expression
    RangeExpr,
    /// exclusive range expression
    ExclusiveRangeExpr,
    /// regex literal
    RegexLiteral,
    /// string interpolation
    StringInterpolation,
    /// interpolation expression
    InterpolationExpr,
    /// symbol literal
    SymbolLiteral,
    /// constant reference
    ConstantRef,
    /// instance variable
    InstanceVar,
    /// class variable
    ClassVar,
    /// global variable
    GlobalVar,
    /// getter method
    Getter,
    /// setter method
    Setter,
    /// operator definition
    OperatorDef,
}

impl CrystalSyntaxKind {
    /// Check if the syntax kind is trivia (whitespace, comment, or newline)
    pub fn is_trivia(&self) -> bool {
        matches!(self, Self::Whitespace | Self::Comment | Self::Newline)
    }

    /// Check if the syntax kind is a keyword
    pub fn is_keyword(self) -> bool {
        matches!(
            self,
            Self::ClassKeyword
                | Self::ModuleKeyword
                | Self::DefKeyword
                | Self::EndKeyword
                | Self::IfKeyword
                | Self::ElseKeyword
                | Self::ElsifKeyword
                | Self::UnlessKeyword
                | Self::CaseKeyword
                | Self::WhenKeyword
                | Self::ThenKeyword
                | Self::WhileKeyword
                | Self::UntilKeyword
                | Self::ForKeyword
                | Self::InKeyword
                | Self::DoKeyword
                | Self::BeginKeyword
                | Self::RescueKeyword
                | Self::EnsureKeyword
                | Self::BreakKeyword
                | Self::NextKeyword
                | Self::ReturnKeyword
                | Self::YieldKeyword
                | Self::SuperKeyword
                | Self::SelfKeyword
                | Self::TrueKeyword
                | Self::FalseKeyword
                | Self::NilKeyword
                | Self::AndKeyword
                | Self::OrKeyword
                | Self::NotKeyword
        )
    }

    /// Check if the syntax kind is a literal
    pub fn is_literal(self) -> bool {
        matches!(self, Self::Number | Self::String | Self::Character | Self::Symbol | Self::RegexLiteral | Self::SymbolLiteral)
    }

    /// Check if the syntax kind is an operator
    pub fn is_operator(self) -> bool {
        matches!(
            self,
            Self::Plus
                | Self::Minus
                | Self::Star
                | Self::Slash
                | Self::Percent
                | Self::StarStar
                | Self::Equal
                | Self::EqualEqual
                | Self::NotEqual
                | Self::Less
                | Self::LessEqual
                | Self::Greater
                | Self::GreaterEqual
                | Self::Spaceship
                | Self::Match
                | Self::NotMatch
                | Self::And
                | Self::Or
                | Self::Not
                | Self::BitwiseAnd
                | Self::BitwiseOr
                | Self::BitwiseXor
                | Self::BitwiseNot
                | Self::LeftShift
                | Self::RightShift
                | Self::LogicalAnd
                | Self::LogicalOr
        )
    }

    /// Check if the syntax kind is an assignment operator
    pub fn is_assignment_operator(self) -> bool {
        matches!(
            self,
            Self::PlusEqual
                | Self::MinusEqual
                | Self::StarEqual
                | Self::SlashEqual
                | Self::PercentEqual
                | Self::StarStarEqual
                | Self::AndEqual
                | Self::OrEqual
                | Self::XorEqual
                | Self::LeftShiftEqual
                | Self::RightShiftEqual
                | Self::LogicalAndEqual
                | Self::LogicalOrEqual
        )
    }

    /// Check if the syntax kind is a delimiter
    pub fn is_delimiter(self) -> bool {
        matches!(self, Self::LeftParen | Self::RightParen | Self::LeftBrace | Self::RightBrace | Self::LeftBracket | Self::RightBracket | Self::Comma | Self::Semicolon)
    }
}

impl TokenType for CrystalSyntaxKind {
    const END_OF_STREAM: Self = Self::Eof;
    type Role = UniversalTokenRole;

    fn role(&self) -> Self::Role {
        match self {
            Self::Whitespace | Self::Newline => UniversalTokenRole::Whitespace,
            Self::Comment => UniversalTokenRole::Comment,
            Self::Identifier => UniversalTokenRole::Name,
            Self::Number | Self::String | Self::Character | Self::Symbol | Self::RegexLiteral | Self::SymbolLiteral => UniversalTokenRole::Literal,
            Self::Error => UniversalTokenRole::Error,
            Self::Eof => UniversalTokenRole::Eof,
            k if k.is_keyword() => UniversalTokenRole::Keyword,
            k if k.is_operator() || k.is_assignment_operator() => UniversalTokenRole::Operator,
            k if k.is_delimiter() => UniversalTokenRole::Punctuation,
            _ => UniversalTokenRole::None,
        }
    }
}

impl ElementType for CrystalSyntaxKind {
    type Role = UniversalElementRole;

    fn role(&self) -> Self::Role {
        match self {
            Self::Root => UniversalElementRole::Root,
            Self::Error => UniversalElementRole::Error,
            _ => UniversalElementRole::None,
        }
    }
}

impl Display for CrystalSyntaxKind {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:?}", self)
    }
}