Skip to main content

oak_elixir/kind/
mod.rs

1use oak_core::{ElementType, Token, TokenType, UniversalElementRole, UniversalTokenRole};
2use serde::{Deserialize, Serialize};
3
4pub type ElixirToken = Token<ElixirSyntaxKind>;
5
6/// Represents all possible syntax kinds in the Elixir programming language.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
8pub enum ElixirSyntaxKind {
9    /// Root node of the syntax tree
10    Root,
11    /// Whitespace characters (spaces, tabs)
12    Whitespace,
13    /// Newline character
14    Newline,
15    /// Comment
16    Comment,
17    /// Identifier (variable names, function names, etc.)
18    Identifier,
19    /// Atom literal
20    Atom,
21    /// Variable name
22    Variable,
23    /// Number literal
24    Number,
25    /// Float literal
26    Float,
27    /// String literal
28    String,
29    /// Character literal
30    Character,
31    /// Sigil literal
32    Sigil,
33
34    /// after keyword
35    After,
36    /// and keyword
37    And,
38    /// case keyword
39    Case,
40    /// catch keyword
41    Catch,
42    /// cond keyword
43    Cond,
44    /// def keyword
45    Def,
46    /// defp keyword (private function)
47    Defp,
48    /// defmodule keyword
49    Defmodule,
50    /// defstruct keyword
51    Defstruct,
52    /// defprotocol keyword
53    Defprotocol,
54    /// defimpl keyword
55    Defimpl,
56    /// defmacro keyword
57    Defmacro,
58    /// defmacrop keyword (private macro)
59    Defmacrop,
60    /// do keyword
61    Do,
62    /// else keyword
63    Else,
64    /// elsif keyword
65    Elsif,
66    /// end keyword
67    End,
68    /// false keyword
69    False,
70    /// fn keyword
71    Fn,
72    /// if keyword
73    If,
74    /// in keyword
75    In,
76    /// not keyword
77    Not,
78    /// or keyword
79    Or,
80    /// receive keyword
81    Receive,
82    /// rescue keyword
83    Rescue,
84    /// true keyword
85    True,
86    /// try keyword
87    Try,
88    /// unless keyword
89    Unless,
90    /// when keyword
91    When,
92    /// with keyword
93    With,
94
95    /// plus operator (+)
96    Plus,
97    /// minus operator (-)
98    Minus,
99    /// multiplication operator (*)
100    Star,
101    /// division operator (/)
102    Slash,
103    /// assignment operator (=)
104    Equal,
105    /// equality operator (==)
106    EqualEqual,
107    /// inequality operator (!=)
108    NotEqual,
109    /// strict equality operator (===)
110    EqualEqualEqual,
111    /// strict inequality operator (!==)
112    NotEqualEqual,
113    /// less than operator (<)
114    Less,
115    /// greater than operator (>)
116    Greater,
117    /// less than or equal operator (<=)
118    LessEqual,
119    /// greater than or equal operator (>=)
120    GreaterEqual,
121    /// concatenation operator (++)
122    PlusPlus,
123    /// subtraction operator (--)
124    MinusMinus,
125    /// exponentiation operator (**)
126    StarStar,
127    /// exclamation mark (!)
128    Exclamation,
129    /// question mark (?)
130    Question,
131    /// ampersand (&)
132    Ampersand,
133    /// at symbol (@)
134    At,
135    /// caret (^)
136    Caret,
137    /// tilde (~)
138    Tilde,
139    /// left shift operator (<<)
140    LeftShift,
141    /// right shift operator (>>)
142    RightShift,
143    /// match operator (=~)
144    MatchOp,
145    /// pipe right operator (|>)
146    PipeRight,
147
148    // 分隔符
149    LeftParen,    // (
150    RightParen,   // )
151    LeftBrace,    // {
152    RightBrace,   // }
153    LeftBracket,  // [
154    RightBracket, // ]
155    Comma,        // ,
156    Semicolon,    // ;
157    Dot,          // .
158    Colon,        // :
159    Arrow,        // ->
160    Pipe,         // |
161    PipePipe,     // ||
162    Hash,         // #
163
164    // 特殊
165    Error,
166    Eof,
167
168    // 语法节点类型 (非终结符)
169    SourceFile,
170    Module,
171    Function,
172    ParameterList,
173    Parameter,
174    BlockExpression,
175    LetStatement,
176    ExpressionStatement,
177    IdentifierExpression,
178    LiteralExpression,
179    BooleanLiteral,
180    ParenthesizedExpression,
181    BinaryExpression,
182    UnaryExpression,
183    CallExpression,
184    FieldExpression,
185    IndexExpression,
186    IfExpression,
187    MatchExpression,
188    LoopExpression,
189    WhileExpression,
190    ForExpression,
191    BreakExpression,
192    ContinueExpression,
193    ReturnExpression,
194    StructExpression,
195    TupleExpression,
196    ArrayExpression,
197    RangeExpression,
198    ClosureExpression,
199    AsyncBlockExpression,
200    UnsafeBlockExpression,
201    TryExpression,
202    AwaitExpression,
203    MacroCall,
204    Path,
205    PathSegment,
206    GenericArgs,
207    TypePath,
208    TupleType,
209    ArrayType,
210    SliceType,
211    ReferenceType,
212    PointerType,
213    FunctionType,
214    TraitObjectType,
215    ImplTraitType,
216    InferredType,
217    NeverType,
218    Pattern,
219    IdentifierPattern,
220    WildcardPattern,
221    TuplePattern,
222    StructPattern,
223    TupleStructPattern,
224    SlicePattern,
225    ReferencePattern,
226    LiteralPattern,
227    RangePattern,
228    OrPattern,
229    RestPattern,
230    StructDeclaration,
231    EnumDeclaration,
232    UnionDeclaration,
233    TraitDeclaration,
234    ImplDeclaration,
235    ModuleDeclaration,
236    UseDeclaration,
237    ConstDeclaration,
238    StaticDeclaration,
239    TypeAliasDeclaration,
240    ExternBlock,
241    ExternFunction,
242    Attribute,
243    Visibility,
244    GenericParams,
245    GenericParam,
246    TypeParam,
247    ConstParam,
248    LifetimeParam,
249    WhereClause,
250    WherePredicate,
251    ReturnType,
252    FieldList,
253    Field,
254    Variant,
255    VariantList,
256    AssociatedItem,
257    TraitItem,
258    ImplItem,
259}
260
261impl TokenType for ElixirSyntaxKind {
262    const END_OF_STREAM: Self = Self::Eof;
263    type Role = UniversalTokenRole;
264
265    fn role(&self) -> Self::Role {
266        match self {
267            Self::Whitespace | Self::Newline => UniversalTokenRole::Whitespace,
268            Self::Comment => UniversalTokenRole::Comment,
269            _ if self.is_keyword() => UniversalTokenRole::Keyword,
270            Self::Identifier | Self::Variable | Self::Atom => UniversalTokenRole::Name,
271            Self::Number | Self::Float | Self::String | Self::Character | Self::Sigil => UniversalTokenRole::Literal,
272            Self::Plus
273            | Self::Minus
274            | Self::Star
275            | Self::Slash
276            | Self::Equal
277            | Self::EqualEqual
278            | Self::NotEqual
279            | Self::EqualEqualEqual
280            | Self::NotEqualEqual
281            | Self::Less
282            | Self::Greater
283            | Self::LessEqual
284            | Self::GreaterEqual
285            | Self::PlusPlus
286            | Self::MinusMinus
287            | Self::StarStar
288            | Self::Exclamation
289            | Self::Question
290            | Self::Ampersand
291            | Self::At
292            | Self::Caret
293            | Self::Tilde
294            | Self::LeftShift
295            | Self::RightShift
296            | Self::MatchOp
297            | Self::PipeRight => UniversalTokenRole::Operator,
298            Self::LeftParen | Self::RightParen | Self::LeftBrace | Self::RightBrace | Self::LeftBracket | Self::RightBracket | Self::Comma | Self::Semicolon | Self::Dot | Self::Colon | Self::Arrow | Self::Pipe | Self::PipePipe | Self::Hash => {
299                UniversalTokenRole::Punctuation
300            }
301            Self::Eof => UniversalTokenRole::Eof,
302            _ => UniversalTokenRole::None,
303        }
304    }
305
306    fn is_comment(&self) -> bool {
307        matches!(self, Self::Comment)
308    }
309
310    fn is_whitespace(&self) -> bool {
311        matches!(self, Self::Whitespace | Self::Newline)
312    }
313}
314
315impl ElementType for ElixirSyntaxKind {
316    type Role = UniversalElementRole;
317
318    fn role(&self) -> Self::Role {
319        match self {
320            Self::Root | Self::SourceFile => UniversalElementRole::Root,
321            Self::Module
322            | Self::Function
323            | Self::StructDeclaration
324            | Self::EnumDeclaration
325            | Self::UnionDeclaration
326            | Self::TraitDeclaration
327            | Self::ImplDeclaration
328            | Self::ModuleDeclaration
329            | Self::UseDeclaration
330            | Self::ConstDeclaration
331            | Self::StaticDeclaration
332            | Self::TypeAliasDeclaration => UniversalElementRole::Definition,
333            Self::BlockExpression | Self::AsyncBlockExpression | Self::UnsafeBlockExpression => UniversalElementRole::Container,
334            Self::LetStatement | Self::ExpressionStatement => UniversalElementRole::Statement,
335            Self::CallExpression | Self::MacroCall => UniversalElementRole::Call,
336            Self::IdentifierExpression => UniversalElementRole::Reference,
337            Self::LiteralExpression | Self::BooleanLiteral => UniversalElementRole::Value,
338            Self::IfExpression | Self::MatchExpression | Self::LoopExpression | Self::WhileExpression | Self::ForExpression | Self::BreakExpression | Self::ContinueExpression | Self::ReturnExpression | Self::TryExpression | Self::AwaitExpression => {
339                UniversalElementRole::Expression
340            }
341            Self::Error => UniversalElementRole::Error,
342            _ => UniversalElementRole::None,
343        }
344    }
345
346    fn is_error(&self) -> bool {
347        matches!(self, Self::Error)
348    }
349
350    fn is_root(&self) -> bool {
351        matches!(self, Self::Root | Self::SourceFile)
352    }
353}
354
355impl ElixirSyntaxKind {
356    pub fn is_keyword(self) -> bool {
357        matches!(
358            self,
359            Self::After
360                | Self::And
361                | Self::Case
362                | Self::Catch
363                | Self::Cond
364                | Self::Def
365                | Self::Defp
366                | Self::Defmodule
367                | Self::Defstruct
368                | Self::Defprotocol
369                | Self::Defimpl
370                | Self::Defmacro
371                | Self::Defmacrop
372                | Self::Do
373                | Self::Else
374                | Self::Elsif
375                | Self::End
376                | Self::False
377                | Self::Fn
378                | Self::If
379                | Self::In
380                | Self::Not
381                | Self::Or
382                | Self::Receive
383                | Self::Rescue
384                | Self::True
385                | Self::Try
386                | Self::Unless
387                | Self::When
388                | Self::With
389        )
390    }
391}