emmylua_parser/syntax/node/lua/
path_trait.rs1use crate::LuaAstNode;
2
3use super::{LuaExpr, LuaIndexKey};
4
5pub trait PathTrait: LuaAstNode {
6 fn get_access_path(&self) -> Option<String> {
7 let mut paths = Vec::new();
8 let mut current_node = self.syntax().clone();
9 loop {
10 match LuaExpr::cast(current_node)? {
11 LuaExpr::NameExpr(name_expr) => {
12 let name = name_expr.get_name_text()?;
13 if paths.is_empty() {
14 return Some(name);
15 } else {
16 paths.push(name);
17 paths.reverse();
18 return Some(paths.join("."));
19 }
20 }
21 LuaExpr::CallExpr(call_expr) => {
22 let prefix_expr = call_expr.get_prefix_expr()?;
23 current_node = prefix_expr.syntax().clone();
24 }
25 LuaExpr::IndexExpr(index_expr) => {
26 match index_expr.get_index_key()? {
27 LuaIndexKey::String(s) => {
28 paths.push(s.get_value());
29 }
30 LuaIndexKey::Name(name) => {
31 paths.push(name.get_name_text().to_string());
32 }
33 LuaIndexKey::Integer(i) => {
34 paths.push(i.get_int_value().to_string());
35 }
36 LuaIndexKey::Expr(expr) => {
37 let text = format!("[{}]", expr.syntax().text());
38 paths.push(text);
39 }
40 LuaIndexKey::Idx(idx) => {
41 let text = format!("[{}]", idx);
42 paths.push(text);
43 }
44 }
45
46 current_node = index_expr.get_prefix_expr()?.syntax().clone();
47 }
48 _ => return None,
49 }
50 }
51 }
52
53 fn get_member_path(&self) -> Option<String> {
54 let mut paths = Vec::new();
55 let mut current_node = self.syntax().clone();
56 loop {
57 match LuaExpr::cast(current_node)? {
58 LuaExpr::NameExpr(_) => {
59 if paths.is_empty() {
60 return None;
61 } else {
62 paths.reverse();
63 return Some(paths.join("."));
64 }
65 }
66 LuaExpr::CallExpr(call_expr) => {
67 let prefix_expr = call_expr.get_prefix_expr()?;
68 current_node = prefix_expr.syntax().clone();
69 }
70 LuaExpr::IndexExpr(index_expr) => {
71 let path_parts = index_expr.get_index_key()?.get_path_part();
72 paths.push(path_parts);
73
74 current_node = index_expr.get_prefix_expr()?.syntax().clone();
75 }
76 _ => return None,
77 }
78 }
79 }
80}