emmylua_parser/syntax/node/token/
tokens.rs

1use crate::{
2    kind::{BinaryOperator, LuaTokenKind, UnaryOperator},
3    syntax::traits::LuaAstToken,
4    LuaOpKind, LuaSyntaxToken, LuaTypeBinaryOperator, LuaTypeUnaryOperator, LuaVersionNumber,
5    VisibilityKind,
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        int_token_value(&self.token).unwrap_or_default()
155    }
156}
157
158#[derive(Debug, Clone, PartialEq, Eq, Hash)]
159pub struct LuaBinaryOpToken {
160    token: LuaSyntaxToken,
161}
162
163impl LuaAstToken for LuaBinaryOpToken {
164    fn syntax(&self) -> &LuaSyntaxToken {
165        &self.token
166    }
167
168    fn can_cast(kind: LuaTokenKind) -> bool
169    where
170        Self: Sized,
171    {
172        LuaOpKind::to_binary_operator(kind) != BinaryOperator::OpNop
173    }
174
175    fn cast(syntax: LuaSyntaxToken) -> Option<Self>
176    where
177        Self: Sized,
178    {
179        if Self::can_cast(syntax.kind().into()) {
180            Some(LuaBinaryOpToken { token: syntax })
181        } else {
182            None
183        }
184    }
185}
186
187impl LuaBinaryOpToken {
188    pub fn get_op(&self) -> BinaryOperator {
189        LuaOpKind::to_binary_operator(self.token.kind().into())
190    }
191}
192
193#[derive(Debug, Clone, PartialEq, Eq, Hash)]
194pub struct LuaUnaryOpToken {
195    token: LuaSyntaxToken,
196}
197
198impl LuaAstToken for LuaUnaryOpToken {
199    fn syntax(&self) -> &LuaSyntaxToken {
200        &self.token
201    }
202
203    fn can_cast(kind: LuaTokenKind) -> bool
204    where
205        Self: Sized,
206    {
207        LuaOpKind::to_unary_operator(kind) != UnaryOperator::OpNop
208    }
209
210    fn cast(syntax: LuaSyntaxToken) -> Option<Self>
211    where
212        Self: Sized,
213    {
214        if Self::can_cast(syntax.kind().into()) {
215            Some(LuaUnaryOpToken { token: syntax })
216        } else {
217            None
218        }
219    }
220}
221
222impl LuaUnaryOpToken {
223    pub fn get_op(&self) -> UnaryOperator {
224        LuaOpKind::to_unary_operator(self.token.kind().into())
225    }
226}
227
228#[derive(Debug, Clone, PartialEq, Eq, Hash)]
229pub struct LuaKeywordToken {
230    token: LuaSyntaxToken,
231}
232
233impl LuaAstToken for LuaKeywordToken {
234    fn syntax(&self) -> &LuaSyntaxToken {
235        &self.token
236    }
237
238    fn can_cast(kind: LuaTokenKind) -> bool
239    where
240        Self: Sized,
241    {
242        match kind {
243            LuaTokenKind::TkAnd
244            | LuaTokenKind::TkBreak
245            | LuaTokenKind::TkDo
246            | LuaTokenKind::TkElse
247            | LuaTokenKind::TkElseIf
248            | LuaTokenKind::TkEnd
249            | LuaTokenKind::TkFalse
250            | LuaTokenKind::TkFor
251            | LuaTokenKind::TkFunction
252            | LuaTokenKind::TkGoto
253            | LuaTokenKind::TkIf
254            | LuaTokenKind::TkIn
255            | LuaTokenKind::TkLocal
256            | LuaTokenKind::TkNil
257            | LuaTokenKind::TkNot
258            | LuaTokenKind::TkOr
259            | LuaTokenKind::TkRepeat
260            | LuaTokenKind::TkReturn
261            | LuaTokenKind::TkThen
262            | LuaTokenKind::TkTrue
263            | LuaTokenKind::TkUntil
264            | LuaTokenKind::TkWhile => true,
265            _ => false,
266        }
267    }
268
269    fn cast(syntax: LuaSyntaxToken) -> Option<Self>
270    where
271        Self: Sized,
272    {
273        if Self::can_cast(syntax.kind().into()) {
274            Some(LuaKeywordToken { token: syntax })
275        } else {
276            None
277        }
278    }
279}
280
281impl LuaKeywordToken {
282    pub fn get_keyword(&self) -> LuaTokenKind {
283        self.token.kind().into()
284    }
285}
286
287#[derive(Debug, Clone, PartialEq, Eq, Hash)]
288pub struct LuaBoolToken {
289    token: LuaSyntaxToken,
290}
291
292impl LuaAstToken for LuaBoolToken {
293    fn syntax(&self) -> &LuaSyntaxToken {
294        &self.token
295    }
296
297    fn can_cast(kind: LuaTokenKind) -> bool
298    where
299        Self: Sized,
300    {
301        kind == LuaTokenKind::TkTrue || kind == LuaTokenKind::TkFalse
302    }
303
304    fn cast(syntax: LuaSyntaxToken) -> Option<Self>
305    where
306        Self: Sized,
307    {
308        if Self::can_cast(syntax.kind().into()) {
309            Some(LuaBoolToken { token: syntax })
310        } else {
311            None
312        }
313    }
314}
315
316impl LuaBoolToken {
317    pub fn is_true(&self) -> bool {
318        self.token.kind() == LuaTokenKind::TkTrue.into()
319    }
320}
321
322#[derive(Debug, Clone, PartialEq, Eq, Hash)]
323pub struct LuaNilToken {
324    token: LuaSyntaxToken,
325}
326
327impl LuaAstToken for LuaNilToken {
328    fn syntax(&self) -> &LuaSyntaxToken {
329        &self.token
330    }
331
332    fn can_cast(kind: LuaTokenKind) -> bool
333    where
334        Self: Sized,
335    {
336        kind == LuaTokenKind::TkNil
337    }
338
339    fn cast(syntax: LuaSyntaxToken) -> Option<Self>
340    where
341        Self: Sized,
342    {
343        if Self::can_cast(syntax.kind().into()) {
344            Some(LuaNilToken { token: syntax })
345        } else {
346            None
347        }
348    }
349}
350
351#[derive(Debug, Clone, PartialEq, Eq, Hash)]
352pub enum LuaLiteralToken {
353    String(LuaStringToken),
354    Number(LuaNumberToken),
355    Bool(LuaBoolToken),
356    Nil(LuaNilToken),
357    Dots(LuaGeneralToken),
358    Question(LuaGeneralToken),
359}
360
361impl LuaAstToken for LuaLiteralToken {
362    fn syntax(&self) -> &LuaSyntaxToken {
363        match self {
364            LuaLiteralToken::String(token) => token.syntax(),
365            LuaLiteralToken::Number(token) => token.syntax(),
366            LuaLiteralToken::Bool(token) => token.syntax(),
367            LuaLiteralToken::Nil(token) => token.syntax(),
368            LuaLiteralToken::Dots(token) => token.syntax(),
369            LuaLiteralToken::Question(token) => token.syntax(),
370        }
371    }
372
373    fn can_cast(kind: LuaTokenKind) -> bool
374    where
375        Self: Sized,
376    {
377        match kind {
378            LuaTokenKind::TkInt
379            | LuaTokenKind::TkFloat
380            | LuaTokenKind::TkComplex
381            | LuaTokenKind::TkNil
382            | LuaTokenKind::TkTrue
383            | LuaTokenKind::TkFalse
384            | LuaTokenKind::TkDots
385            | LuaTokenKind::TkString
386            | LuaTokenKind::TkLongString
387            | LuaTokenKind::TkDocQuestion => true,
388            _ => false,
389        }
390    }
391
392    fn cast(syntax: LuaSyntaxToken) -> Option<Self>
393    where
394        Self: Sized,
395    {
396        match syntax.kind().into() {
397            LuaTokenKind::TkString | LuaTokenKind::TkLongString => {
398                LuaStringToken::cast(syntax).map(LuaLiteralToken::String)
399            }
400            LuaTokenKind::TkFloat | LuaTokenKind::TkInt | LuaTokenKind::TkComplex => {
401                LuaNumberToken::cast(syntax).map(LuaLiteralToken::Number)
402            }
403            LuaTokenKind::TkTrue | LuaTokenKind::TkFalse => {
404                LuaBoolToken::cast(syntax).map(LuaLiteralToken::Bool)
405            }
406            LuaTokenKind::TkNil => LuaNilToken::cast(syntax).map(LuaLiteralToken::Nil),
407            LuaTokenKind::TkDots => LuaGeneralToken::cast(syntax).map(LuaLiteralToken::Dots),
408            LuaTokenKind::TkDocQuestion => {
409                LuaGeneralToken::cast(syntax).map(LuaLiteralToken::Question)
410            }
411            _ => None,
412        }
413    }
414}
415
416#[derive(Debug, Clone, PartialEq, Eq, Hash)]
417pub struct LuaSpaceToken {
418    token: LuaSyntaxToken,
419}
420
421impl LuaAstToken for LuaSpaceToken {
422    fn syntax(&self) -> &LuaSyntaxToken {
423        &self.token
424    }
425
426    fn can_cast(kind: LuaTokenKind) -> bool
427    where
428        Self: Sized,
429    {
430        match kind {
431            LuaTokenKind::TkWhitespace | LuaTokenKind::TkEndOfLine => true,
432            _ => false,
433        }
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) -> 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}