1use oak_core::{ElementType, Token, TokenType, UniversalElementRole, UniversalTokenRole};
2use serde::{Deserialize, Serialize};
3
4pub type ErlangToken = Token<ErlangSyntaxKind>;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
7pub enum ErlangSyntaxKind {
8 Whitespace,
10 Newline,
11 Comment,
12
13 Identifier,
15 Atom,
16 Variable,
17 Number,
18 String,
19 Character,
20
21 After,
23 And,
24 Andalso,
25 Band,
26 Begin,
27 Bnot,
28 Bor,
29 Bsl,
30 Bsr,
31 Bxor,
32 Case,
33 Catch,
34 Cond,
35 Div,
36 End,
37 Fun,
38 If,
39 Let,
40 Not,
41 Of,
42 Or,
43 Orelse,
44 Query,
45 Receive,
46 Rem,
47 Try,
48 When,
49 Xor,
50
51 Plus, Minus, Star, Slash, Equal, EqualEqual, SlashEqual, EqualColonEqual, EqualSlashEqual, Less, Greater, LessEqual, GreaterEqual, PlusPlus, MinusMinus, Exclamation, Question, LeftParen, RightParen, LeftBrace, RightBrace, LeftBracket, RightBracket, Comma, Semicolon, Dot, Colon, Arrow, Pipe, PipePipe, Hash, Root,
88 Item,
89 Module,
90 Export,
91 Attribute,
92 Function,
93 FunctionClause,
94 Pattern,
95 RecordPattern,
96 Statement,
97 Expr,
98 BinaryExpr,
99 CallExpr,
100 FunExpr,
101 CaseExpr,
102 CaseClause,
103 IfExpr,
104 IfClause,
105 TryExpr,
106 CatchClause,
107 ReceiveExpr,
108 ReceiveClause,
109 RecordExpr,
110
111 Error,
113 Eof,
114}
115
116impl ErlangSyntaxKind {
117 pub fn is_keyword(&self) -> bool {
118 matches!(
119 self,
120 Self::After
121 | Self::And
122 | Self::Andalso
123 | Self::Band
124 | Self::Begin
125 | Self::Bnot
126 | Self::Bor
127 | Self::Bsl
128 | Self::Bsr
129 | Self::Bxor
130 | Self::Case
131 | Self::Catch
132 | Self::Cond
133 | Self::Div
134 | Self::End
135 | Self::Fun
136 | Self::If
137 | Self::Let
138 | Self::Not
139 | Self::Of
140 | Self::Or
141 | Self::Orelse
142 | Self::Query
143 | Self::Receive
144 | Self::Rem
145 | Self::Try
146 | Self::When
147 | Self::Xor
148 )
149 }
150
151 pub fn is_operator(&self) -> bool {
152 matches!(
153 self,
154 Self::Plus
155 | Self::Minus
156 | Self::Star
157 | Self::Slash
158 | Self::Equal
159 | Self::EqualEqual
160 | Self::SlashEqual
161 | Self::EqualColonEqual
162 | Self::EqualSlashEqual
163 | Self::Less
164 | Self::Greater
165 | Self::LessEqual
166 | Self::GreaterEqual
167 | Self::PlusPlus
168 | Self::MinusMinus
169 | Self::Exclamation
170 | Self::Question
171 )
172 }
173
174 pub fn is_punctuation(&self) -> bool {
175 matches!(self, 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)
176 }
177}
178
179impl TokenType for ErlangSyntaxKind {
180 const END_OF_STREAM: Self = Self::Eof;
181 type Role = UniversalTokenRole;
182
183 fn role(&self) -> Self::Role {
184 match self {
185 Self::Whitespace | Self::Newline => UniversalTokenRole::Whitespace,
186 Self::Comment => UniversalTokenRole::Comment,
187 Self::Identifier | Self::Atom | Self::Variable => UniversalTokenRole::Name,
188 Self::Number | Self::String | Self::Character => UniversalTokenRole::Literal,
189 kind if kind.is_keyword() => UniversalTokenRole::Keyword,
190 kind if kind.is_operator() => UniversalTokenRole::Operator,
191 kind if kind.is_punctuation() => UniversalTokenRole::Punctuation,
192 Self::Error => UniversalTokenRole::Error,
193 _ => UniversalTokenRole::None,
194 }
195 }
196
197 fn is_comment(&self) -> bool {
198 matches!(self, Self::Comment)
199 }
200
201 fn is_whitespace(&self) -> bool {
202 matches!(self, Self::Whitespace | Self::Newline)
203 }
204}
205
206impl ElementType for ErlangSyntaxKind {
207 type Role = UniversalElementRole;
208
209 fn role(&self) -> Self::Role {
210 match self {
211 Self::Root => UniversalElementRole::Root,
212 Self::Module | Self::Function | Self::FunctionClause => UniversalElementRole::Definition,
213 Self::Statement => UniversalElementRole::Statement,
214 Self::Expr | Self::BinaryExpr | Self::CallExpr | Self::FunExpr | Self::CaseExpr | Self::IfExpr | Self::TryExpr | Self::ReceiveExpr | Self::RecordExpr => UniversalElementRole::Expression,
215 Self::Error => UniversalElementRole::Error,
216 _ => UniversalElementRole::None,
217 }
218 }
219
220 fn is_error(&self) -> bool {
221 matches!(self, Self::Error)
222 }
223
224 fn is_root(&self) -> bool {
225 matches!(self, Self::Root)
226 }
227}