emmylua_parser/syntax/node/token/
tokens.rs1use crate::{
2 LuaOpKind, LuaSyntaxToken, LuaTypeBinaryOperator, LuaTypeUnaryOperator, LuaVersionNumber,
3 VisibilityKind,
4 kind::{BinaryOperator, LuaTokenKind, UnaryOperator},
5 syntax::traits::LuaAstToken,
6};
7
8use super::{float_token_value, int_token_value, string_token_value};
9
10#[derive(Debug, Clone, PartialEq, Eq, Hash)]
11pub struct LuaGeneralToken {
12 token: LuaSyntaxToken,
13}
14
15impl LuaAstToken for LuaGeneralToken {
16 fn syntax(&self) -> &LuaSyntaxToken {
17 &self.token
18 }
19
20 fn can_cast(_: LuaTokenKind) -> bool
21 where
22 Self: Sized,
23 {
24 true
25 }
26
27 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
28 where
29 Self: Sized,
30 {
31 Some(LuaGeneralToken { token: syntax })
32 }
33}
34
35#[derive(Debug, Clone, PartialEq, Eq, Hash)]
36pub struct LuaNameToken {
37 token: LuaSyntaxToken,
38}
39
40impl LuaAstToken for LuaNameToken {
41 fn syntax(&self) -> &LuaSyntaxToken {
42 &self.token
43 }
44
45 fn can_cast(kind: LuaTokenKind) -> bool
46 where
47 Self: Sized,
48 {
49 kind == LuaTokenKind::TkName
50 }
51
52 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
53 where
54 Self: Sized,
55 {
56 if Self::can_cast(syntax.kind().into()) {
57 Some(LuaNameToken { token: syntax })
58 } else {
59 None
60 }
61 }
62}
63
64impl LuaNameToken {
65 pub fn get_name_text(&self) -> &str {
66 self.token.text()
67 }
68}
69
70#[derive(Debug, Clone, PartialEq, Eq, Hash)]
71pub struct LuaStringToken {
72 token: LuaSyntaxToken,
73}
74
75impl LuaAstToken for LuaStringToken {
76 fn syntax(&self) -> &LuaSyntaxToken {
77 &self.token
78 }
79
80 fn can_cast(kind: LuaTokenKind) -> bool
81 where
82 Self: Sized,
83 {
84 kind == LuaTokenKind::TkString || kind == LuaTokenKind::TkLongString
85 }
86
87 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
88 where
89 Self: Sized,
90 {
91 if Self::can_cast(syntax.kind().into()) {
92 Some(LuaStringToken { token: syntax })
93 } else {
94 None
95 }
96 }
97}
98
99impl LuaStringToken {
100 pub fn get_value(&self) -> String {
101 string_token_value(&self.token).unwrap_or_default()
102 }
103}
104
105#[derive(Debug, Clone, PartialEq, Eq, Hash)]
106pub struct LuaNumberToken {
107 token: LuaSyntaxToken,
108}
109
110impl LuaAstToken for LuaNumberToken {
111 fn syntax(&self) -> &LuaSyntaxToken {
112 &self.token
113 }
114
115 fn can_cast(kind: LuaTokenKind) -> bool
116 where
117 Self: Sized,
118 {
119 kind == LuaTokenKind::TkFloat || kind == LuaTokenKind::TkInt
120 }
121
122 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
123 where
124 Self: Sized,
125 {
126 if Self::can_cast(syntax.kind().into()) {
127 Some(LuaNumberToken { token: syntax })
128 } else {
129 None
130 }
131 }
132}
133
134impl LuaNumberToken {
135 pub fn is_float(&self) -> bool {
136 self.token.kind() == LuaTokenKind::TkFloat.into()
137 }
138
139 pub fn is_int(&self) -> bool {
140 self.token.kind() == LuaTokenKind::TkInt.into()
141 }
142
143 pub fn get_float_value(&self) -> f64 {
144 if !self.is_float() {
145 return 0.0;
146 }
147 float_token_value(&self.token).unwrap_or(0.0)
148 }
149
150 pub fn get_int_value(&self) -> i64 {
151 if !self.is_int() {
152 return 0;
153 }
154 match int_token_value(&self.token) {
155 Ok(value) => value.as_integer().unwrap_or(0),
156 Err(_) => 0,
157 }
158 }
159}
160
161#[derive(Debug, Clone, PartialEq, Eq, Hash)]
162pub struct LuaBinaryOpToken {
163 token: LuaSyntaxToken,
164}
165
166impl LuaAstToken for LuaBinaryOpToken {
167 fn syntax(&self) -> &LuaSyntaxToken {
168 &self.token
169 }
170
171 fn can_cast(kind: LuaTokenKind) -> bool
172 where
173 Self: Sized,
174 {
175 LuaOpKind::to_binary_operator(kind) != BinaryOperator::OpNop
176 }
177
178 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
179 where
180 Self: Sized,
181 {
182 if Self::can_cast(syntax.kind().into()) {
183 Some(LuaBinaryOpToken { token: syntax })
184 } else {
185 None
186 }
187 }
188}
189
190impl LuaBinaryOpToken {
191 pub fn get_op(&self) -> BinaryOperator {
192 LuaOpKind::to_binary_operator(self.token.kind().into())
193 }
194}
195
196#[derive(Debug, Clone, PartialEq, Eq, Hash)]
197pub struct LuaUnaryOpToken {
198 token: LuaSyntaxToken,
199}
200
201impl LuaAstToken for LuaUnaryOpToken {
202 fn syntax(&self) -> &LuaSyntaxToken {
203 &self.token
204 }
205
206 fn can_cast(kind: LuaTokenKind) -> bool
207 where
208 Self: Sized,
209 {
210 LuaOpKind::to_unary_operator(kind) != UnaryOperator::OpNop
211 }
212
213 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
214 where
215 Self: Sized,
216 {
217 if Self::can_cast(syntax.kind().into()) {
218 Some(LuaUnaryOpToken { token: syntax })
219 } else {
220 None
221 }
222 }
223}
224
225impl LuaUnaryOpToken {
226 pub fn get_op(&self) -> UnaryOperator {
227 LuaOpKind::to_unary_operator(self.token.kind().into())
228 }
229}
230
231#[derive(Debug, Clone, PartialEq, Eq, Hash)]
232pub struct LuaKeywordToken {
233 token: LuaSyntaxToken,
234}
235
236impl LuaAstToken for LuaKeywordToken {
237 fn syntax(&self) -> &LuaSyntaxToken {
238 &self.token
239 }
240
241 fn can_cast(kind: LuaTokenKind) -> bool
242 where
243 Self: Sized,
244 {
245 matches!(
246 kind,
247 LuaTokenKind::TkAnd
248 | LuaTokenKind::TkBreak
249 | LuaTokenKind::TkDo
250 | LuaTokenKind::TkElse
251 | LuaTokenKind::TkElseIf
252 | LuaTokenKind::TkEnd
253 | LuaTokenKind::TkFalse
254 | LuaTokenKind::TkFor
255 | LuaTokenKind::TkFunction
256 | LuaTokenKind::TkGoto
257 | LuaTokenKind::TkIf
258 | LuaTokenKind::TkIn
259 | LuaTokenKind::TkLocal
260 | LuaTokenKind::TkNil
261 | LuaTokenKind::TkNot
262 | LuaTokenKind::TkOr
263 | LuaTokenKind::TkRepeat
264 | LuaTokenKind::TkReturn
265 | LuaTokenKind::TkThen
266 | LuaTokenKind::TkTrue
267 | LuaTokenKind::TkUntil
268 | LuaTokenKind::TkWhile
269 )
270 }
271
272 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
273 where
274 Self: Sized,
275 {
276 if Self::can_cast(syntax.kind().into()) {
277 Some(LuaKeywordToken { token: syntax })
278 } else {
279 None
280 }
281 }
282}
283
284impl LuaKeywordToken {
285 pub fn get_keyword(&self) -> LuaTokenKind {
286 self.token.kind().into()
287 }
288}
289
290#[derive(Debug, Clone, PartialEq, Eq, Hash)]
291pub struct LuaBoolToken {
292 token: LuaSyntaxToken,
293}
294
295impl LuaAstToken for LuaBoolToken {
296 fn syntax(&self) -> &LuaSyntaxToken {
297 &self.token
298 }
299
300 fn can_cast(kind: LuaTokenKind) -> bool
301 where
302 Self: Sized,
303 {
304 kind == LuaTokenKind::TkTrue || kind == LuaTokenKind::TkFalse
305 }
306
307 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
308 where
309 Self: Sized,
310 {
311 if Self::can_cast(syntax.kind().into()) {
312 Some(LuaBoolToken { token: syntax })
313 } else {
314 None
315 }
316 }
317}
318
319impl LuaBoolToken {
320 pub fn is_true(&self) -> bool {
321 self.token.kind() == LuaTokenKind::TkTrue.into()
322 }
323}
324
325#[derive(Debug, Clone, PartialEq, Eq, Hash)]
326pub struct LuaNilToken {
327 token: LuaSyntaxToken,
328}
329
330impl LuaAstToken for LuaNilToken {
331 fn syntax(&self) -> &LuaSyntaxToken {
332 &self.token
333 }
334
335 fn can_cast(kind: LuaTokenKind) -> bool
336 where
337 Self: Sized,
338 {
339 kind == LuaTokenKind::TkNil
340 }
341
342 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
343 where
344 Self: Sized,
345 {
346 if Self::can_cast(syntax.kind().into()) {
347 Some(LuaNilToken { token: syntax })
348 } else {
349 None
350 }
351 }
352}
353
354#[derive(Debug, Clone, PartialEq, Eq, Hash)]
355pub enum LuaLiteralToken {
356 String(LuaStringToken),
357 Number(LuaNumberToken),
358 Bool(LuaBoolToken),
359 Nil(LuaNilToken),
360 Dots(LuaGeneralToken),
361 Question(LuaGeneralToken),
362}
363
364impl LuaAstToken for LuaLiteralToken {
365 fn syntax(&self) -> &LuaSyntaxToken {
366 match self {
367 LuaLiteralToken::String(token) => token.syntax(),
368 LuaLiteralToken::Number(token) => token.syntax(),
369 LuaLiteralToken::Bool(token) => token.syntax(),
370 LuaLiteralToken::Nil(token) => token.syntax(),
371 LuaLiteralToken::Dots(token) => token.syntax(),
372 LuaLiteralToken::Question(token) => token.syntax(),
373 }
374 }
375
376 fn can_cast(kind: LuaTokenKind) -> bool
377 where
378 Self: Sized,
379 {
380 matches!(
381 kind,
382 LuaTokenKind::TkInt
383 | LuaTokenKind::TkFloat
384 | LuaTokenKind::TkComplex
385 | LuaTokenKind::TkNil
386 | LuaTokenKind::TkTrue
387 | LuaTokenKind::TkFalse
388 | LuaTokenKind::TkDots
389 | LuaTokenKind::TkString
390 | LuaTokenKind::TkLongString
391 | LuaTokenKind::TkDocQuestion
392 )
393 }
394
395 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
396 where
397 Self: Sized,
398 {
399 match syntax.kind().into() {
400 LuaTokenKind::TkString | LuaTokenKind::TkLongString => {
401 LuaStringToken::cast(syntax).map(LuaLiteralToken::String)
402 }
403 LuaTokenKind::TkFloat | LuaTokenKind::TkInt | LuaTokenKind::TkComplex => {
404 LuaNumberToken::cast(syntax).map(LuaLiteralToken::Number)
405 }
406 LuaTokenKind::TkTrue | LuaTokenKind::TkFalse => {
407 LuaBoolToken::cast(syntax).map(LuaLiteralToken::Bool)
408 }
409 LuaTokenKind::TkNil => LuaNilToken::cast(syntax).map(LuaLiteralToken::Nil),
410 LuaTokenKind::TkDots => LuaGeneralToken::cast(syntax).map(LuaLiteralToken::Dots),
411 LuaTokenKind::TkDocQuestion => {
412 LuaGeneralToken::cast(syntax).map(LuaLiteralToken::Question)
413 }
414 _ => None,
415 }
416 }
417}
418
419#[derive(Debug, Clone, PartialEq, Eq, Hash)]
420pub struct LuaSpaceToken {
421 token: LuaSyntaxToken,
422}
423
424impl LuaAstToken for LuaSpaceToken {
425 fn syntax(&self) -> &LuaSyntaxToken {
426 &self.token
427 }
428
429 fn can_cast(kind: LuaTokenKind) -> bool
430 where
431 Self: Sized,
432 {
433 matches!(kind, LuaTokenKind::TkWhitespace | LuaTokenKind::TkEndOfLine)
434 }
435
436 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
437 where
438 Self: Sized,
439 {
440 if Self::can_cast(syntax.kind().into()) {
441 Some(LuaSpaceToken { token: syntax })
442 } else {
443 None
444 }
445 }
446}
447
448#[derive(Debug, Clone, PartialEq, Eq, Hash)]
449pub struct LuaIndexToken {
450 token: LuaSyntaxToken,
451}
452
453impl LuaAstToken for LuaIndexToken {
454 fn syntax(&self) -> &LuaSyntaxToken {
455 &self.token
456 }
457
458 fn can_cast(kind: LuaTokenKind) -> bool
459 where
460 Self: Sized,
461 {
462 kind == LuaTokenKind::TkDot
463 || kind == LuaTokenKind::TkColon
464 || kind == LuaTokenKind::TkLeftBracket
465 }
466
467 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
468 where
469 Self: Sized,
470 {
471 if Self::can_cast(syntax.kind().into()) {
472 Some(LuaIndexToken { token: syntax })
473 } else {
474 None
475 }
476 }
477}
478
479impl LuaIndexToken {
480 pub fn is_dot(&self) -> bool {
481 self.token.kind() == LuaTokenKind::TkDot.into()
482 }
483
484 pub fn is_colon(&self) -> bool {
485 self.token.kind() == LuaTokenKind::TkColon.into()
486 }
487
488 pub fn is_left_bracket(&self) -> bool {
489 self.token.kind() == LuaTokenKind::TkLeftBracket.into()
490 }
491}
492
493#[derive(Debug, Clone, PartialEq, Eq, Hash)]
494pub struct LuaDocDetailToken {
495 token: LuaSyntaxToken,
496}
497
498impl LuaAstToken for LuaDocDetailToken {
499 fn syntax(&self) -> &LuaSyntaxToken {
500 &self.token
501 }
502
503 fn can_cast(kind: LuaTokenKind) -> bool
504 where
505 Self: Sized,
506 {
507 kind == LuaTokenKind::TkDocDetail
508 }
509
510 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
511 where
512 Self: Sized,
513 {
514 if Self::can_cast(syntax.kind().into()) {
515 Some(LuaDocDetailToken { token: syntax })
516 } else {
517 None
518 }
519 }
520}
521
522impl LuaDocDetailToken {
523 pub fn get_detail(&self) -> &str {
524 self.token.text()
525 }
526}
527
528#[derive(Debug, Clone, PartialEq, Eq, Hash)]
529pub struct LuaDocVisibilityToken {
530 token: LuaSyntaxToken,
531}
532
533impl LuaAstToken for LuaDocVisibilityToken {
534 fn syntax(&self) -> &LuaSyntaxToken {
535 &self.token
536 }
537
538 fn can_cast(kind: LuaTokenKind) -> bool
539 where
540 Self: Sized,
541 {
542 kind == LuaTokenKind::TkDocVisibility || kind == LuaTokenKind::TkTagVisibility
543 }
544
545 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
546 where
547 Self: Sized,
548 {
549 if Self::can_cast(syntax.kind().into()) {
550 Some(LuaDocVisibilityToken { token: syntax })
551 } else {
552 None
553 }
554 }
555}
556
557impl LuaDocVisibilityToken {
558 pub fn get_visibility(&self) -> Option<VisibilityKind> {
559 VisibilityKind::to_visibility_kind(self.token.text())
560 }
561}
562
563#[derive(Debug, Clone, PartialEq, Eq, Hash)]
564pub struct LuaDocVersionNumberToken {
565 token: LuaSyntaxToken,
566}
567
568impl LuaAstToken for LuaDocVersionNumberToken {
569 fn syntax(&self) -> &LuaSyntaxToken {
570 &self.token
571 }
572
573 fn can_cast(kind: LuaTokenKind) -> bool
574 where
575 Self: Sized,
576 {
577 kind == LuaTokenKind::TkDocVersionNumber
578 }
579
580 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
581 where
582 Self: Sized,
583 {
584 if Self::can_cast(syntax.kind().into()) {
585 Some(LuaDocVersionNumberToken { token: syntax })
586 } else {
587 None
588 }
589 }
590}
591
592impl LuaDocVersionNumberToken {
593 pub fn get_version_number(&self) -> Option<LuaVersionNumber> {
594 let text = self.token.text();
595 LuaVersionNumber::from_str(text)
596 }
597}
598
599#[derive(Debug, Clone, PartialEq, Eq, Hash)]
600pub struct LuaDocTypeBinaryToken {
601 token: LuaSyntaxToken,
602}
603
604impl LuaAstToken for LuaDocTypeBinaryToken {
605 fn syntax(&self) -> &LuaSyntaxToken {
606 &self.token
607 }
608
609 fn can_cast(kind: LuaTokenKind) -> bool
610 where
611 Self: Sized,
612 {
613 kind == LuaTokenKind::TkDocOr
614 || kind == LuaTokenKind::TkDocAnd
615 || kind == LuaTokenKind::TkDocExtends
616 || kind == LuaTokenKind::TkDocIn
617 || kind == LuaTokenKind::TkDocContinueOr
618 || kind == LuaTokenKind::TkPlus
619 || kind == LuaTokenKind::TkMinus
620 }
621
622 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
623 where
624 Self: Sized,
625 {
626 if Self::can_cast(syntax.kind().into()) {
627 Some(LuaDocTypeBinaryToken { token: syntax })
628 } else {
629 None
630 }
631 }
632}
633
634impl LuaDocTypeBinaryToken {
635 pub fn get_op(&self) -> LuaTypeBinaryOperator {
636 LuaOpKind::to_type_binary_operator(self.token.kind().into())
637 }
638}
639
640#[derive(Debug, Clone, PartialEq, Eq, Hash)]
641pub struct LuaDocTypeUnaryToken {
642 token: LuaSyntaxToken,
643}
644
645impl LuaAstToken for LuaDocTypeUnaryToken {
646 fn syntax(&self) -> &LuaSyntaxToken {
647 &self.token
648 }
649
650 fn can_cast(kind: LuaTokenKind) -> bool
651 where
652 Self: Sized,
653 {
654 kind == LuaTokenKind::TkDocKeyOf || kind == LuaTokenKind::TkMinus
655 }
656
657 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
658 where
659 Self: Sized,
660 {
661 if Self::can_cast(syntax.kind().into()) {
662 Some(LuaDocTypeUnaryToken { token: syntax })
663 } else {
664 None
665 }
666 }
667}
668
669impl LuaDocTypeUnaryToken {
670 pub fn get_op(&self) -> LuaTypeUnaryOperator {
671 LuaOpKind::to_type_unary_operator(self.token.kind().into())
672 }
673}
674
675#[derive(Debug, Clone, PartialEq, Eq, Hash)]
676pub struct LuaPathToken {
677 token: LuaSyntaxToken,
678}
679
680impl LuaAstToken for LuaPathToken {
681 fn syntax(&self) -> &LuaSyntaxToken {
682 &self.token
683 }
684
685 fn can_cast(kind: LuaTokenKind) -> bool
686 where
687 Self: Sized,
688 {
689 kind == LuaTokenKind::TKDocPath
690 }
691
692 fn cast(syntax: LuaSyntaxToken) -> Option<Self>
693 where
694 Self: Sized,
695 {
696 if Self::can_cast(syntax.kind().into()) {
697 Some(LuaPathToken { token: syntax })
698 } else {
699 None
700 }
701 }
702}
703
704impl LuaPathToken {
705 pub fn get_path(&self) -> &str {
706 let text = self.token.text();
707 if text.starts_with('\"') || text.starts_with('\'') {
708 &text[1..text.len() - 1]
709 } else {
710 text
711 }
712 }
713}