1use cstree::Syntax;
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Syntax)]
31#[repr(u32)]
32pub enum SyntaxKind {
33 Whitespace,
36 LineComment,
38 DocComment,
40 RegionComment,
42 EndRegionComment,
44 LineContinuation,
46 NewlinePhys,
50 Bom,
55
56 Newline,
59 Indent,
61 Dedent,
63
64 Int,
67 Float,
69 String,
71 StringName,
73 NodePath,
75 Ident,
77
78 #[static_text("true")]
80 True,
81 #[static_text("false")]
82 False,
83 #[static_text("null")]
84 Null,
85
86 #[static_text("PI")]
88 ConstPi,
89 #[static_text("TAU")]
90 ConstTau,
91 #[static_text("INF")]
92 ConstInf,
93 #[static_text("NAN")]
94 ConstNan,
95
96 #[static_text("if")]
98 IfKw,
99 #[static_text("elif")]
100 ElifKw,
101 #[static_text("else")]
102 ElseKw,
103 #[static_text("for")]
104 ForKw,
105 #[static_text("while")]
106 WhileKw,
107 #[static_text("match")]
108 MatchKw,
109 #[static_text("when")]
110 WhenKw,
111 #[static_text("break")]
112 BreakKw,
113 #[static_text("continue")]
114 ContinueKw,
115 #[static_text("pass")]
116 PassKw,
117 #[static_text("return")]
118 ReturnKw,
119 #[static_text("var")]
120 VarKw,
121 #[static_text("const")]
122 ConstKw,
123 #[static_text("enum")]
124 EnumKw,
125 #[static_text("func")]
126 FuncKw,
127 #[static_text("static")]
128 StaticKw,
129 #[static_text("signal")]
130 SignalKw,
131 #[static_text("class")]
132 ClassKw,
133 #[static_text("class_name")]
134 ClassNameKw,
135 #[static_text("extends")]
136 ExtendsKw,
137 #[static_text("is")]
138 IsKw,
139 #[static_text("in")]
140 InKw,
141 #[static_text("as")]
142 AsKw,
143 #[static_text("self")]
144 SelfKw,
145 #[static_text("super")]
146 SuperKw,
147 #[static_text("void")]
148 VoidKw,
149 #[static_text("await")]
150 AwaitKw,
151 #[static_text("preload")]
152 PreloadKw,
153 #[static_text("assert")]
154 AssertKw,
155 #[static_text("breakpoint")]
156 BreakpointKw,
157 #[static_text("not")]
158 NotKw,
159 #[static_text("and")]
160 AndKw,
161 #[static_text("or")]
162 OrKw,
163 #[static_text("yield")]
165 YieldKw,
166 #[static_text("namespace")]
168 NamespaceKw,
169 #[static_text("trait")]
171 TraitKw,
172
173 #[static_text("(")]
175 LParen,
176 #[static_text(")")]
177 RParen,
178 #[static_text("[")]
179 LBrack,
180 #[static_text("]")]
181 RBrack,
182 #[static_text("{")]
183 LBrace,
184 #[static_text("}")]
185 RBrace,
186 #[static_text(",")]
187 Comma,
188 #[static_text(":")]
189 Colon,
190 #[static_text(";")]
191 Semicolon,
192 #[static_text(".")]
193 Dot,
194 #[static_text("..")]
195 DotDot,
196 #[static_text("...")]
197 Ellipsis,
198 #[static_text("@")]
199 At,
200 #[static_text("$")]
201 Dollar,
202 #[static_text("%")]
203 Percent,
204 #[static_text("&")]
205 Amp,
206 #[static_text("->")]
207 Arrow,
208 #[static_text(":=")]
209 ColonEq,
210
211 #[static_text("+")]
213 Plus,
214 #[static_text("-")]
215 Minus,
216 #[static_text("*")]
217 Star,
218 #[static_text("/")]
219 Slash,
220 #[static_text("**")]
221 StarStar,
222 #[static_text("=")]
223 Eq,
224 #[static_text("==")]
225 EqEq,
226 #[static_text("!=")]
227 Neq,
228 #[static_text("<")]
229 Lt,
230 #[static_text(">")]
231 Gt,
232 #[static_text("<=")]
233 Le,
234 #[static_text(">=")]
235 Ge,
236 #[static_text("&&")]
237 AmpAmp,
238 #[static_text("||")]
239 PipePipe,
240 #[static_text("!")]
241 Bang,
242 #[static_text("~")]
243 Tilde,
244 #[static_text("|")]
245 Pipe,
246 #[static_text("^")]
247 Caret,
248 #[static_text("<<")]
249 Shl,
250 #[static_text(">>")]
251 Shr,
252 #[static_text("+=")]
253 PlusEq,
254 #[static_text("-=")]
255 MinusEq,
256 #[static_text("*=")]
257 StarEq,
258 #[static_text("/=")]
259 SlashEq,
260 #[static_text("**=")]
261 StarStarEq,
262 #[static_text("%=")]
263 PercentEq,
264 #[static_text("&=")]
265 AmpEq,
266 #[static_text("|=")]
267 PipeEq,
268 #[static_text("^=")]
269 CaretEq,
270 #[static_text("<<=")]
271 ShlEq,
272 #[static_text(">>=")]
273 ShrEq,
274
275 Error,
278 Eof,
280
281 SourceFile,
283 ExtendsClause,
284 ClassNameDecl,
285 Annotation,
286 AnnotationArgList,
287
288 InnerClassDecl,
290 ClassBody,
291 FuncDecl,
292 ParamList,
293 Param,
294 VarargParam,
295 VarDecl,
296 ConstDecl,
297 EnumDecl,
298 EnumVariant,
299 SignalDecl,
300 PropertyBody,
301 Getter,
302 Setter,
303 Name,
304
305 TypeRef,
307 TypedArray,
308 TypedDict,
309
310 Block,
312 IfStmt,
313 ElifClause,
314 ElseClause,
315 ForStmt,
316 WhileStmt,
317 MatchStmt,
318 MatchArm,
319 ReturnStmt,
320 BreakStmt,
321 ContinueStmt,
322 PassStmt,
323 AssertStmt,
324 BreakpointStmt,
325 ExprStmt,
326 VarStmt,
327
328 PatternLiteral,
330 PatternBind,
331 PatternWildcard,
332 PatternArray,
333 PatternDict,
334 PatternRest,
335 PatternGuard,
336
337 BinExpr,
339 UnaryExpr,
340 TernaryExpr,
341 CastExpr,
342 IsExpr,
343 InExpr,
344 CallExpr,
345 ArgList,
346 IndexExpr,
347 FieldExpr,
348 AwaitExpr,
349 LambdaExpr,
350 ParenExpr,
351 ArrayLit,
352 DictLit,
353 DictEntry,
354 NameRef,
355 Literal,
356 GetNodeExpr,
357 UniqueNodeExpr,
358 PreloadExpr,
359
360 ErrorNode,
362
363 Tombstone,
365}
366
367impl SyntaxKind {
368 #[must_use]
372 pub const fn is_trivia(self) -> bool {
373 matches!(
374 self,
375 Self::Whitespace
376 | Self::LineComment
377 | Self::DocComment
378 | Self::RegionComment
379 | Self::EndRegionComment
380 | Self::LineContinuation
381 | Self::NewlinePhys
382 | Self::Bom
383 )
384 }
385
386 #[must_use]
388 pub const fn is_synthetic_layout(self) -> bool {
389 matches!(self, Self::Newline | Self::Indent | Self::Dedent)
390 }
391
392 #[must_use]
394 pub const fn is_node(self) -> bool {
395 (self as u32) >= (Self::SourceFile as u32)
397 }
398
399 #[must_use]
406 pub fn display_name(self) -> String {
407 if let Some(t) = <SyntaxKind as Syntax>::static_text(self) {
408 return format!("\"{t}\"");
409 }
410 match self {
411 Self::Ident => "identifier".to_owned(),
412 Self::Int | Self::Float | Self::String | Self::StringName | Self::NodePath => {
413 "\"Literal\"".to_owned()
414 }
415 Self::Indent => "\"Indent\"".to_owned(),
416 Self::Dedent => "\"Dedent\"".to_owned(),
417 Self::Newline => "end of statement".to_owned(),
418 _ => "token".to_owned(),
419 }
420 }
421}
422
423pub type GdNode = cstree::syntax::ResolvedNode<SyntaxKind>;
426pub type GdToken = cstree::syntax::ResolvedToken<SyntaxKind>;
428pub type SyntaxNode = cstree::syntax::SyntaxNode<SyntaxKind>;
430
431#[cfg(test)]
432mod tests {
433 use super::*;
434 use cstree::build::GreenNodeBuilder;
435 use cstree::syntax::ResolvedNode;
436
437 #[test]
442 fn three_node_tree_round_trips() {
443 let mut builder: GreenNodeBuilder<'_, '_, SyntaxKind> = GreenNodeBuilder::new();
444 builder.start_node(SyntaxKind::SourceFile);
445 builder.start_node(SyntaxKind::FuncDecl);
446 builder.static_token(SyntaxKind::FuncKw); builder.token(SyntaxKind::Whitespace, " ");
448 builder.start_node(SyntaxKind::Name);
449 builder.token(SyntaxKind::Ident, "foo");
450 builder.finish_node(); builder.token(SyntaxKind::Newline, ""); builder.finish_node(); builder.finish_node(); let (green, cache) = builder.finish();
456 let interner = cache.unwrap().into_interner().unwrap();
457 let root = ResolvedNode::<SyntaxKind>::new_root_with_resolver(green, interner);
458
459 assert_eq!(root.to_string(), "func foo");
461 assert_eq!(root.kind(), SyntaxKind::SourceFile);
462 }
463
464 #[test]
465 fn raw_kind_round_trips() {
466 for raw in 0..(SyntaxKind::Tombstone as u32) {
468 let kind = <SyntaxKind as Syntax>::from_raw(cstree::RawSyntaxKind(raw));
469 assert_eq!(<SyntaxKind as Syntax>::into_raw(kind).0, raw);
470 }
471 }
472
473 #[test]
474 fn classification_helpers() {
475 assert!(SyntaxKind::Whitespace.is_trivia());
476 assert!(!SyntaxKind::Newline.is_trivia());
477 assert!(SyntaxKind::Indent.is_synthetic_layout());
478 assert!(SyntaxKind::FuncDecl.is_node());
479 assert!(!SyntaxKind::FuncKw.is_node());
480 }
481}