emmylua_parser/syntax/node/lua/
expr.rs1use crate::{
2 kind::LuaSyntaxKind,
3 syntax::{
4 comment_trait::LuaCommentOwner,
5 node::{LuaBinaryOpToken, LuaNameToken, LuaUnaryOpToken},
6 traits::{LuaAstChildren, LuaAstNode},
7 },
8 LuaAstToken, LuaIndexToken, LuaLiteralToken, LuaSyntaxNode, LuaSyntaxToken, LuaTokenKind,
9};
10
11use super::{
12 path_trait::PathTrait, LuaBlock, LuaCallArgList, LuaIndexKey, LuaParamList, LuaTableField,
13};
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash)]
16pub enum LuaExpr {
17 CallExpr(LuaCallExpr),
18 TableExpr(LuaTableExpr),
19 LiteralExpr(LuaLiteralExpr),
20 BinaryExpr(LuaBinaryExpr),
21 UnaryExpr(LuaUnaryExpr),
22 ClosureExpr(LuaClosureExpr),
23 ParenExpr(LuaParenExpr),
24 NameExpr(LuaNameExpr),
25 IndexExpr(LuaIndexExpr),
26}
27
28impl LuaAstNode for LuaExpr {
29 fn syntax(&self) -> &LuaSyntaxNode {
30 match self {
31 LuaExpr::CallExpr(node) => node.syntax(),
32 LuaExpr::TableExpr(node) => node.syntax(),
33 LuaExpr::LiteralExpr(node) => node.syntax(),
34 LuaExpr::BinaryExpr(node) => node.syntax(),
35 LuaExpr::UnaryExpr(node) => node.syntax(),
36 LuaExpr::ClosureExpr(node) => node.syntax(),
37 LuaExpr::ParenExpr(node) => node.syntax(),
38 LuaExpr::NameExpr(node) => node.syntax(),
39 LuaExpr::IndexExpr(node) => node.syntax(),
40 }
41 }
42
43 fn can_cast(kind: LuaSyntaxKind) -> bool
44 where
45 Self: Sized,
46 {
47 match kind {
48 LuaSyntaxKind::CallExpr
49 | LuaSyntaxKind::AssertCallExpr
50 | LuaSyntaxKind::ErrorCallExpr
51 | LuaSyntaxKind::RequireCallExpr
52 | LuaSyntaxKind::TypeCallExpr
53 | LuaSyntaxKind::SetmetatableCallExpr => true,
54 LuaSyntaxKind::TableArrayExpr
55 | LuaSyntaxKind::TableObjectExpr
56 | LuaSyntaxKind::TableEmptyExpr => true,
57 LuaSyntaxKind::LiteralExpr => true,
58 LuaSyntaxKind::BinaryExpr => true,
59 LuaSyntaxKind::UnaryExpr => true,
60 LuaSyntaxKind::ClosureExpr => true,
61 LuaSyntaxKind::ParenExpr => true,
62 LuaSyntaxKind::NameExpr => true,
63 LuaSyntaxKind::IndexExpr => true,
64 _ => false,
65 }
66 }
67
68 fn cast(syntax: LuaSyntaxNode) -> Option<Self>
69 where
70 Self: Sized,
71 {
72 match syntax.kind().into() {
73 LuaSyntaxKind::CallExpr
74 | LuaSyntaxKind::AssertCallExpr
75 | LuaSyntaxKind::ErrorCallExpr
76 | LuaSyntaxKind::RequireCallExpr
77 | LuaSyntaxKind::TypeCallExpr
78 | LuaSyntaxKind::SetmetatableCallExpr => {
79 LuaCallExpr::cast(syntax).map(LuaExpr::CallExpr)
80 }
81 LuaSyntaxKind::TableArrayExpr
82 | LuaSyntaxKind::TableObjectExpr
83 | LuaSyntaxKind::TableEmptyExpr => LuaTableExpr::cast(syntax).map(LuaExpr::TableExpr),
84 LuaSyntaxKind::LiteralExpr => LuaLiteralExpr::cast(syntax).map(LuaExpr::LiteralExpr),
85 LuaSyntaxKind::BinaryExpr => LuaBinaryExpr::cast(syntax).map(LuaExpr::BinaryExpr),
86 LuaSyntaxKind::UnaryExpr => LuaUnaryExpr::cast(syntax).map(LuaExpr::UnaryExpr),
87 LuaSyntaxKind::ClosureExpr => LuaClosureExpr::cast(syntax).map(LuaExpr::ClosureExpr),
88 LuaSyntaxKind::ParenExpr => LuaParenExpr::cast(syntax).map(LuaExpr::ParenExpr),
89 LuaSyntaxKind::NameExpr => LuaNameExpr::cast(syntax).map(LuaExpr::NameExpr),
90 LuaSyntaxKind::IndexExpr => LuaIndexExpr::cast(syntax).map(LuaExpr::IndexExpr),
91 _ => None,
92 }
93 }
94}
95
96#[derive(Debug, Clone, PartialEq, Eq, Hash)]
97pub enum LuaVarExpr {
98 NameExpr(LuaNameExpr),
99 IndexExpr(LuaIndexExpr),
100}
101
102impl LuaAstNode for LuaVarExpr {
103 fn syntax(&self) -> &LuaSyntaxNode {
104 match self {
105 LuaVarExpr::NameExpr(node) => node.syntax(),
106 LuaVarExpr::IndexExpr(node) => node.syntax(),
107 }
108 }
109
110 fn can_cast(kind: LuaSyntaxKind) -> bool
111 where
112 Self: Sized,
113 {
114 match kind {
115 LuaSyntaxKind::NameExpr => true,
116 LuaSyntaxKind::IndexExpr => true,
117 _ => false,
118 }
119 }
120
121 fn cast(syntax: LuaSyntaxNode) -> Option<Self>
122 where
123 Self: Sized,
124 {
125 match syntax.kind().into() {
126 LuaSyntaxKind::NameExpr => LuaNameExpr::cast(syntax).map(LuaVarExpr::NameExpr),
127 LuaSyntaxKind::IndexExpr => LuaIndexExpr::cast(syntax).map(LuaVarExpr::IndexExpr),
128 _ => None,
129 }
130 }
131}
132
133impl From<LuaVarExpr> for LuaExpr {
134 fn from(expr: LuaVarExpr) -> Self {
135 match expr {
136 LuaVarExpr::NameExpr(node) => LuaExpr::NameExpr(node),
137 LuaVarExpr::IndexExpr(node) => LuaExpr::IndexExpr(node),
138 }
139 }
140}
141
142impl PathTrait for LuaVarExpr {}
143
144#[derive(Debug, Clone, PartialEq, Eq, Hash)]
145pub enum LuaSingleArgExpr {
146 TableExpr(LuaTableExpr),
147 LiteralExpr(LuaLiteralExpr),
148}
149
150impl LuaAstNode for LuaSingleArgExpr {
151 fn syntax(&self) -> &LuaSyntaxNode {
152 match self {
153 LuaSingleArgExpr::TableExpr(node) => node.syntax(),
154 LuaSingleArgExpr::LiteralExpr(node) => node.syntax(),
155 }
156 }
157
158 fn can_cast(kind: LuaSyntaxKind) -> bool
159 where
160 Self: Sized,
161 {
162 match kind {
163 LuaSyntaxKind::TableArrayExpr
164 | LuaSyntaxKind::TableObjectExpr
165 | LuaSyntaxKind::TableEmptyExpr => true,
166 LuaSyntaxKind::LiteralExpr => true,
167 _ => false,
168 }
169 }
170
171 fn cast(syntax: LuaSyntaxNode) -> Option<Self>
172 where
173 Self: Sized,
174 {
175 match syntax.kind().into() {
176 LuaSyntaxKind::TableArrayExpr
177 | LuaSyntaxKind::TableObjectExpr
178 | LuaSyntaxKind::TableEmptyExpr => {
179 LuaTableExpr::cast(syntax).map(LuaSingleArgExpr::TableExpr)
180 }
181 LuaSyntaxKind::LiteralExpr => {
182 LuaLiteralExpr::cast(syntax).map(LuaSingleArgExpr::LiteralExpr)
183 }
184 _ => None,
185 }
186 }
187}
188
189impl From<LuaSingleArgExpr> for LuaExpr {
190 fn from(expr: LuaSingleArgExpr) -> Self {
191 match expr {
192 LuaSingleArgExpr::TableExpr(node) => LuaExpr::TableExpr(node),
193 LuaSingleArgExpr::LiteralExpr(node) => LuaExpr::LiteralExpr(node),
194 }
195 }
196}
197
198#[derive(Debug, Clone, PartialEq, Eq, Hash)]
199pub struct LuaNameExpr {
200 syntax: LuaSyntaxNode,
201}
202
203impl LuaAstNode for LuaNameExpr {
204 fn syntax(&self) -> &LuaSyntaxNode {
205 &self.syntax
206 }
207
208 fn can_cast(kind: LuaSyntaxKind) -> bool
209 where
210 Self: Sized,
211 {
212 kind == LuaSyntaxKind::NameExpr
213 }
214
215 fn cast(syntax: LuaSyntaxNode) -> Option<Self>
216 where
217 Self: Sized,
218 {
219 if Self::can_cast(syntax.kind().into()) {
220 Some(Self { syntax })
221 } else {
222 None
223 }
224 }
225}
226
227impl LuaCommentOwner for LuaNameExpr {}
228
229impl LuaNameExpr {
230 pub fn get_name_token(&self) -> Option<LuaNameToken> {
231 self.token()
232 }
233
234 pub fn get_name_text(&self) -> Option<String> {
235 self.get_name_token()
236 .map(|it| it.get_name_text().to_string())
237 }
238}
239
240impl PathTrait for LuaNameExpr {}
241
242impl From<LuaNameExpr> for LuaVarExpr {
243 fn from(expr: LuaNameExpr) -> Self {
244 LuaVarExpr::NameExpr(expr)
245 }
246}
247
248#[derive(Debug, Clone, PartialEq, Eq, Hash)]
249pub struct LuaIndexExpr {
250 syntax: LuaSyntaxNode,
251}
252
253impl LuaAstNode for LuaIndexExpr {
254 fn syntax(&self) -> &LuaSyntaxNode {
255 &self.syntax
256 }
257
258 fn can_cast(kind: LuaSyntaxKind) -> bool
259 where
260 Self: Sized,
261 {
262 kind == LuaSyntaxKind::IndexExpr
263 }
264
265 fn cast(syntax: LuaSyntaxNode) -> Option<Self>
266 where
267 Self: Sized,
268 {
269 if Self::can_cast(syntax.kind().into()) {
270 Some(Self { syntax })
271 } else {
272 None
273 }
274 }
275}
276
277impl LuaIndexExpr {
278 pub fn get_prefix_expr(&self) -> Option<LuaExpr> {
279 self.child()
280 }
281
282 pub fn get_index_token(&self) -> Option<LuaIndexToken> {
283 self.token()
284 }
285
286 pub fn get_index_key(&self) -> Option<LuaIndexKey> {
287 let mut meet_left_bracket = false;
288 for child in self.syntax.children_with_tokens() {
289 if meet_left_bracket {
290 match child {
291 rowan::NodeOrToken::Node(node) => {
292 if LuaLiteralExpr::can_cast(node.kind().into()) {
293 let literal_expr = LuaLiteralExpr::cast(node.clone()).unwrap();
294 if let Some(literal_token) = literal_expr.get_literal() {
295 match literal_token {
296 LuaLiteralToken::String(token) => {
297 return Some(LuaIndexKey::String(token.clone()));
298 }
299 LuaLiteralToken::Number(token) => {
300 return Some(LuaIndexKey::Integer(token.clone()));
301 }
302 _ => {}
303 }
304 }
305 }
306
307 return Some(LuaIndexKey::Expr(LuaExpr::cast(node).unwrap()));
308 }
309 _ => return None,
310 }
311 } else if let Some(token) = child.as_token() {
312 if token.kind() == LuaTokenKind::TkLeftBracket.into() {
313 meet_left_bracket = true;
314 } else if token.kind() == LuaTokenKind::TkName.into() {
315 return Some(LuaIndexKey::Name(
316 LuaNameToken::cast(token.clone()).unwrap(),
317 ));
318 }
319 }
320 }
321
322 None
323 }
324
325 pub fn get_index_name_token(&self) -> Option<LuaSyntaxToken> {
326 let index_token = self.get_index_token()?;
327 index_token.syntax().next_token()
328 }
329
330 pub fn get_name_token(&self) -> Option<LuaNameToken> {
331 self.token()
332 }
333}
334
335impl PathTrait for LuaIndexExpr {}
336
337impl From<LuaIndexExpr> for LuaVarExpr {
338 fn from(expr: LuaIndexExpr) -> Self {
339 LuaVarExpr::IndexExpr(expr)
340 }
341}
342
343#[derive(Debug, Clone, PartialEq, Eq, Hash)]
344pub struct LuaCallExpr {
345 syntax: LuaSyntaxNode,
346}
347
348impl LuaAstNode for LuaCallExpr {
349 fn syntax(&self) -> &LuaSyntaxNode {
350 &self.syntax
351 }
352
353 fn can_cast(kind: LuaSyntaxKind) -> bool
354 where
355 Self: Sized,
356 {
357 kind == LuaSyntaxKind::CallExpr
358 || kind == LuaSyntaxKind::AssertCallExpr
359 || kind == LuaSyntaxKind::ErrorCallExpr
360 || kind == LuaSyntaxKind::RequireCallExpr
361 || kind == LuaSyntaxKind::TypeCallExpr
362 || kind == LuaSyntaxKind::SetmetatableCallExpr
363 }
364
365 fn cast(syntax: LuaSyntaxNode) -> Option<Self>
366 where
367 Self: Sized,
368 {
369 if Self::can_cast(syntax.kind().into()) {
370 Some(Self { syntax })
371 } else {
372 None
373 }
374 }
375}
376
377impl LuaCallExpr {
378 pub fn get_prefix_expr(&self) -> Option<LuaExpr> {
379 self.child()
380 }
381
382 pub fn get_args_list(&self) -> Option<LuaCallArgList> {
383 self.child()
384 }
385
386 pub fn get_args_count(&self) -> Option<usize> {
387 self.get_args_list().map(|it| it.get_args().count())
388 }
389
390 pub fn is_colon_call(&self) -> bool {
391 if let Some(index_token) = self.get_colon_token() {
392 return index_token.is_colon();
393 }
394 false
395 }
396
397 pub fn get_colon_token(&self) -> Option<LuaIndexToken> {
398 self.get_prefix_expr().and_then(|prefix| match prefix {
399 LuaExpr::IndexExpr(index_expr) => index_expr.get_index_token(),
400 _ => None,
401 })
402 }
403
404 pub fn is_require(&self) -> bool {
405 self.syntax().kind() == LuaSyntaxKind::RequireCallExpr.into()
406 }
407
408 pub fn is_error(&self) -> bool {
409 self.syntax().kind() == LuaSyntaxKind::ErrorCallExpr.into()
410 }
411
412 pub fn is_assert(&self) -> bool {
413 self.syntax().kind() == LuaSyntaxKind::AssertCallExpr.into()
414 }
415
416 pub fn is_type(&self) -> bool {
417 self.syntax().kind() == LuaSyntaxKind::TypeCallExpr.into()
418 }
419
420 pub fn is_setmetatable(&self) -> bool {
421 self.syntax().kind() == LuaSyntaxKind::SetmetatableCallExpr.into()
422 }
423}
424
425impl PathTrait for LuaCallExpr {}
426
427impl From<LuaCallExpr> for LuaExpr {
428 fn from(expr: LuaCallExpr) -> Self {
429 LuaExpr::CallExpr(expr)
430 }
431}
432
433#[derive(Debug, Clone, PartialEq, Eq, Hash)]
444pub struct LuaTableExpr {
445 syntax: LuaSyntaxNode,
446}
447
448impl LuaAstNode for LuaTableExpr {
449 fn syntax(&self) -> &LuaSyntaxNode {
450 &self.syntax
451 }
452
453 fn can_cast(kind: LuaSyntaxKind) -> bool
454 where
455 Self: Sized,
456 {
457 kind == LuaSyntaxKind::TableArrayExpr
458 || kind == LuaSyntaxKind::TableObjectExpr
459 || kind == LuaSyntaxKind::TableEmptyExpr
460 }
461
462 fn cast(syntax: LuaSyntaxNode) -> Option<Self>
463 where
464 Self: Sized,
465 {
466 if Self::can_cast(syntax.kind().into()) {
467 Some(Self { syntax })
468 } else {
469 None
470 }
471 }
472}
473
474impl LuaCommentOwner for LuaTableExpr {}
475
476impl LuaTableExpr {
477 pub fn is_empty(&self) -> bool {
478 self.syntax().kind() == LuaSyntaxKind::TableEmptyExpr.into()
479 }
480
481 pub fn is_array(&self) -> bool {
482 self.syntax().kind() == LuaSyntaxKind::TableArrayExpr.into()
483 }
484
485 pub fn is_object(&self) -> bool {
486 self.syntax().kind() == LuaSyntaxKind::TableObjectExpr.into()
487 }
488
489 pub fn get_fields(&self) -> LuaAstChildren<LuaTableField> {
490 self.children()
491 }
492}
493
494impl From<LuaTableExpr> for LuaSingleArgExpr {
495 fn from(expr: LuaTableExpr) -> Self {
496 LuaSingleArgExpr::TableExpr(expr)
497 }
498}
499
500#[derive(Debug, Clone, PartialEq, Eq, Hash)]
501pub struct LuaLiteralExpr {
502 syntax: LuaSyntaxNode,
503}
504
505impl LuaAstNode for LuaLiteralExpr {
506 fn syntax(&self) -> &LuaSyntaxNode {
507 &self.syntax
508 }
509
510 fn can_cast(kind: LuaSyntaxKind) -> bool
511 where
512 Self: Sized,
513 {
514 kind == LuaSyntaxKind::LiteralExpr
515 }
516
517 fn cast(syntax: LuaSyntaxNode) -> Option<Self>
518 where
519 Self: Sized,
520 {
521 if Self::can_cast(syntax.kind().into()) {
522 Some(Self { syntax })
523 } else {
524 None
525 }
526 }
527}
528
529impl LuaLiteralExpr {
530 pub fn get_literal(&self) -> Option<LuaLiteralToken> {
531 self.token()
532 }
533}
534
535impl From<LuaLiteralExpr> for LuaSingleArgExpr {
536 fn from(expr: LuaLiteralExpr) -> Self {
537 LuaSingleArgExpr::LiteralExpr(expr)
538 }
539}
540
541#[derive(Debug, Clone, PartialEq, Eq, Hash)]
542pub struct LuaBinaryExpr {
543 syntax: LuaSyntaxNode,
544}
545
546impl LuaAstNode for LuaBinaryExpr {
547 fn syntax(&self) -> &LuaSyntaxNode {
548 &self.syntax
549 }
550
551 fn can_cast(kind: LuaSyntaxKind) -> bool
552 where
553 Self: Sized,
554 {
555 kind == LuaSyntaxKind::BinaryExpr
556 }
557
558 fn cast(syntax: LuaSyntaxNode) -> Option<Self>
559 where
560 Self: Sized,
561 {
562 if Self::can_cast(syntax.kind().into()) {
563 Some(Self { syntax })
564 } else {
565 None
566 }
567 }
568}
569
570impl LuaBinaryExpr {
571 pub fn get_exprs(&self) -> Option<(LuaExpr, LuaExpr)> {
572 let exprs = self.children::<LuaExpr>().collect::<Vec<_>>();
573 if exprs.len() == 2 {
574 Some((exprs[0].clone(), exprs[1].clone()))
575 } else {
576 None
577 }
578 }
579
580 pub fn get_op_token(&self) -> Option<LuaBinaryOpToken> {
581 self.token()
582 }
583
584 pub fn get_left_expr(&self) -> Option<LuaExpr> {
585 self.child()
586 }
587}
588
589impl From<LuaBinaryExpr> for LuaExpr {
590 fn from(expr: LuaBinaryExpr) -> Self {
591 LuaExpr::BinaryExpr(expr)
592 }
593}
594
595#[derive(Debug, Clone, PartialEq, Eq, Hash)]
596pub struct LuaUnaryExpr {
597 syntax: LuaSyntaxNode,
598}
599
600impl LuaAstNode for LuaUnaryExpr {
601 fn syntax(&self) -> &LuaSyntaxNode {
602 &self.syntax
603 }
604
605 fn can_cast(kind: LuaSyntaxKind) -> bool
606 where
607 Self: Sized,
608 {
609 kind == LuaSyntaxKind::UnaryExpr
610 }
611
612 fn cast(syntax: LuaSyntaxNode) -> Option<Self>
613 where
614 Self: Sized,
615 {
616 if Self::can_cast(syntax.kind().into()) {
617 Some(Self { syntax })
618 } else {
619 None
620 }
621 }
622}
623
624impl LuaUnaryExpr {
625 pub fn get_expr(&self) -> Option<LuaExpr> {
626 self.child()
627 }
628
629 pub fn get_op_token(&self) -> Option<LuaUnaryOpToken> {
630 self.token()
631 }
632}
633
634impl From<LuaUnaryExpr> for LuaExpr {
635 fn from(expr: LuaUnaryExpr) -> Self {
636 LuaExpr::UnaryExpr(expr)
637 }
638}
639
640#[derive(Debug, Clone, PartialEq, Eq, Hash)]
641pub struct LuaClosureExpr {
642 syntax: LuaSyntaxNode,
643}
644
645impl LuaAstNode for LuaClosureExpr {
646 fn syntax(&self) -> &LuaSyntaxNode {
647 &self.syntax
648 }
649
650 fn can_cast(kind: LuaSyntaxKind) -> bool
651 where
652 Self: Sized,
653 {
654 kind == LuaSyntaxKind::ClosureExpr
655 }
656
657 fn cast(syntax: LuaSyntaxNode) -> Option<Self>
658 where
659 Self: Sized,
660 {
661 if Self::can_cast(syntax.kind().into()) {
662 Some(Self { syntax })
663 } else {
664 None
665 }
666 }
667}
668
669impl LuaClosureExpr {
670 pub fn get_block(&self) -> Option<LuaBlock> {
671 self.child()
672 }
673
674 pub fn get_params_list(&self) -> Option<LuaParamList> {
675 self.child()
676 }
677}
678
679impl From<LuaClosureExpr> for LuaExpr {
680 fn from(expr: LuaClosureExpr) -> Self {
681 LuaExpr::ClosureExpr(expr)
682 }
683}
684
685#[derive(Debug, Clone, PartialEq, Eq, Hash)]
686pub struct LuaParenExpr {
687 syntax: LuaSyntaxNode,
688}
689
690impl LuaAstNode for LuaParenExpr {
691 fn syntax(&self) -> &LuaSyntaxNode {
692 &self.syntax
693 }
694
695 fn can_cast(kind: LuaSyntaxKind) -> bool
696 where
697 Self: Sized,
698 {
699 kind == LuaSyntaxKind::ParenExpr
700 }
701
702 fn cast(syntax: LuaSyntaxNode) -> Option<Self>
703 where
704 Self: Sized,
705 {
706 if Self::can_cast(syntax.kind().into()) {
707 Some(Self { syntax })
708 } else {
709 None
710 }
711 }
712}
713
714impl LuaParenExpr {
715 pub fn get_expr(&self) -> Option<LuaExpr> {
716 self.child()
717 }
718}
719
720impl From<LuaParenExpr> for LuaExpr {
721 fn from(expr: LuaParenExpr) -> Self {
722 LuaExpr::ParenExpr(expr)
723 }
724}