Skip to content

Commit 6eb922b

Browse files
committed
update
1 parent a026c68 commit 6eb922b

File tree

5 files changed

+131
-22
lines changed

5 files changed

+131
-22
lines changed

crates/emmylua_code_analysis/src/compilation/analyzer/common/member.rs

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use emmylua_parser::{LuaAstNode, LuaExpr, LuaIndexExpr, LuaNameExpr};
1+
use std::vec;
2+
3+
use emmylua_parser::{LuaAstNode, LuaExpr, LuaIndexExpr, LuaIndexKey, LuaNameExpr};
24

35
use crate::{DbIndex, FileId, GlobalId, LuaDeclId, LuaMemberOwner, LuaType};
46

@@ -17,7 +19,7 @@ pub fn get_name_expr_member_owner(
1719
let prev_decl = decl_tree.find_local_decl(&name, name_expr.get_position())?;
1820

1921
if !prev_decl.is_implicit_self() {
20-
return Some(LuaMemberOwner::DeclId(prev_decl.get_id()));
22+
return Some(LuaMemberOwner::LocalDeclId(prev_decl.get_id()));
2123
}
2224

2325
let root = name_expr.get_root();
@@ -39,10 +41,10 @@ pub fn get_decl_member_owner(db: &DbIndex, decl_id: &LuaDeclId) -> Option<LuaMem
3941
return Some(LuaMemberOwner::Type(type_id.clone()));
4042
}
4143
LuaType::GlobalTable(global_id) => {
42-
return Some(LuaMemberOwner::Global(GlobalId(global_id.clone())));
44+
return Some(LuaMemberOwner::GlobalId(GlobalId(global_id.clone())));
4345
}
4446
LuaType::LocalDecl(decl_id) => {
45-
return Some(LuaMemberOwner::DeclId(decl_id.clone()));
47+
return Some(LuaMemberOwner::LocalDeclId(decl_id.clone()));
4648
}
4749
LuaType::TableConst(table_const) => {
4850
return Some(LuaMemberOwner::Element(table_const.clone()));
@@ -54,8 +56,74 @@ pub fn get_decl_member_owner(db: &DbIndex, decl_id: &LuaDeclId) -> Option<LuaMem
5456
let decl = db.get_decl_index().get_decl(decl_id)?;
5557

5658
if decl.is_global() {
57-
return Some(LuaMemberOwner::Global(GlobalId::new(decl.get_name())));
59+
return Some(LuaMemberOwner::GlobalId(GlobalId::new(decl.get_name())));
5860
}
5961

60-
Some(LuaMemberOwner::DeclId(decl_id.clone()))
62+
Some(LuaMemberOwner::LocalDeclId(decl_id.clone()))
63+
}
64+
65+
pub fn get_global_path(
66+
db: &DbIndex,
67+
file_id: FileId,
68+
index_expr: &LuaIndexExpr,
69+
) -> Option<GlobalId> {
70+
let mut prefix_expr = index_expr.get_prefix_expr()?;
71+
let mut paths = vec![index_expr.clone()];
72+
loop {
73+
match &prefix_expr {
74+
LuaExpr::NameExpr(name_expr) => {
75+
let owner_id = get_name_expr_member_owner(db, file_id, &name_expr)?;
76+
match owner_id {
77+
LuaMemberOwner::GlobalId(global_id) => {
78+
let base_name = global_id.get_name();
79+
match paths.len() {
80+
0 => return Some(GlobalId::new(base_name)),
81+
1 => {
82+
if let Some(name) = to_path_name(&paths[0]) {
83+
return Some(GlobalId::new(&format!("{}.{}", base_name, name)));
84+
} else {
85+
return None;
86+
}
87+
}
88+
_ => {
89+
let mut path = base_name.to_string();
90+
for path_expr in paths.iter().rev() {
91+
if let Some(name) = to_path_name(path_expr) {
92+
// general this path is not too long
93+
path.push_str(&format!(".{}", name));
94+
}
95+
}
96+
return Some(GlobalId::new(&path));
97+
}
98+
}
99+
}
100+
_ => return None,
101+
};
102+
}
103+
LuaExpr::IndexExpr(index_expr) => {
104+
paths.push(index_expr.clone());
105+
prefix_expr = index_expr.get_prefix_expr()?;
106+
}
107+
_ => return None,
108+
}
109+
}
110+
}
111+
112+
fn to_path_name(index_expr: &LuaIndexExpr) -> Option<String> {
113+
match index_expr.get_index_key()? {
114+
LuaIndexKey::String(s) => {
115+
return Some(s.get_value());
116+
}
117+
LuaIndexKey::Name(name) => {
118+
return Some(name.get_name_text().to_string());
119+
}
120+
LuaIndexKey::Integer(i) => {
121+
return Some(i.get_int_value().to_string());
122+
}
123+
LuaIndexKey::Idx(idx) => {
124+
let text = format!("[{}]", idx);
125+
return Some(text);
126+
}
127+
_ => return None,
128+
}
61129
}

crates/emmylua_code_analysis/src/compilation/analyzer/common/mod.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,5 @@ mod bind_type;
22
mod member;
33

44
pub use bind_type::{add_member, bind_type};
5-
use emmylua_parser::LuaIndexExpr;
65
pub use member::*;
76

8-
use crate::{DbIndex, GlobalId};
9-
10-
pub fn get_global_path(_: &DbIndex, _: &LuaIndexExpr) -> Option<GlobalId> {
11-
None
12-
}

crates/emmylua_code_analysis/src/compilation/analyzer/member/members.rs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use emmylua_parser::{
2-
LuaAssignStat, LuaAstNode, LuaExpr, LuaFuncStat, LuaIndexKey, LuaLocalStat, LuaTableField,
3-
LuaVarExpr,
2+
LuaAssignStat, LuaAstNode, LuaExpr, LuaFuncStat, LuaIndexKey, LuaLocalStat, LuaTableExpr,
3+
LuaTableField, LuaVarExpr,
44
};
55

66
use crate::{
7-
LuaDeclId, LuaMember, LuaMemberFeature, LuaMemberId, LuaMemberKey, LuaMemberOwner, LuaType,
7+
InFiled, LuaDeclId, LuaMember, LuaMemberFeature, LuaMemberId, LuaMemberKey, LuaMemberOwner,
8+
LuaType,
89
compilation::analyzer::{
910
common::{get_global_path, get_name_expr_member_owner},
1011
member::MemberAnalyzer,
@@ -18,8 +19,12 @@ pub fn analyze_local_stat(analyzer: &mut MemberAnalyzer, local_stat: LuaLocalSta
1819
let local_name = local_name_list.get(i)?;
1920
let local_expr = local_expr_list.get(i)?;
2021
if let LuaExpr::TableExpr(table_expr) = local_expr {
22+
analyzer
23+
.visited_table_expr
24+
.insert(table_expr.get_syntax_id());
25+
2126
let decl_id = LuaDeclId::new(analyzer.file_id, local_name.get_position());
22-
let owner = LuaMemberOwner::DeclId(decl_id);
27+
let owner = LuaMemberOwner::LocalDeclId(decl_id);
2328
if table_expr.is_object() {
2429
for table_field in table_expr.get_fields() {
2530
if let Some(field_key) = table_field.get_field_key() {
@@ -64,14 +69,14 @@ pub fn analyze_assign_stat(
6469
}
6570
LuaExpr::IndexExpr(prefix_index_expr) => {
6671
if let Some(global_id) =
67-
get_global_path(&analyzer.db, &prefix_index_expr)
72+
get_global_path(&analyzer.db, analyzer.file_id, &prefix_index_expr)
6873
{
6974
if let Some(field_key) = index_expr.get_index_key() {
7075
let member_id = LuaMemberId::new(
7176
index_expr.get_syntax_id(),
7277
analyzer.file_id,
7378
);
74-
let owner = LuaMemberOwner::Global(global_id);
79+
let owner = LuaMemberOwner::GlobalId(global_id);
7580
add_field_member(analyzer, owner, field_key, member_id);
7681
}
7782
}
@@ -84,6 +89,10 @@ pub fn analyze_assign_stat(
8489
if let Some(owner) =
8590
get_name_expr_member_owner(&analyzer.db, analyzer.file_id, &name_expr)
8691
{
92+
analyzer
93+
.visited_table_expr
94+
.insert(table_expr.get_syntax_id());
95+
8796
if table_expr.is_object() {
8897
for table_field in table_expr.get_fields() {
8998
if let Some(field_key) = table_field.get_field_key() {
@@ -134,6 +143,10 @@ pub fn analyze_table_field(
134143
return None;
135144
};
136145

146+
analyzer
147+
.visited_table_expr
148+
.insert(table_value.get_syntax_id());
149+
137150
let member_id = LuaMemberId::new(table_field.get_syntax_id(), analyzer.file_id);
138151
let doc_type = analyzer
139152
.db
@@ -196,3 +209,29 @@ fn add_field_member(
196209

197210
Some(())
198211
}
212+
213+
pub fn analyze_table_expr(analyzer: &mut MemberAnalyzer, table_expr: LuaTableExpr) -> Option<()> {
214+
let in_filed = InFiled::new(analyzer.file_id, table_expr.get_range().clone());
215+
let owner_id = LuaMemberOwner::Element(in_filed);
216+
if analyzer
217+
.visited_table_expr
218+
.contains(&table_expr.get_syntax_id())
219+
{
220+
return Some(());
221+
}
222+
223+
analyzer
224+
.visited_table_expr
225+
.insert(table_expr.get_syntax_id());
226+
227+
if table_expr.is_object() {
228+
for field in table_expr.get_fields() {
229+
if let Some(field_key) = field.get_field_key() {
230+
let member_id = LuaMemberId::new(field.get_syntax_id(), analyzer.file_id);
231+
add_field_member(analyzer, owner_id.clone(), field_key, member_id);
232+
}
233+
}
234+
}
235+
236+
Some(())
237+
}

crates/emmylua_code_analysis/src/compilation/analyzer/member/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
mod members;
22

3-
use emmylua_parser::{LuaAst, LuaAstNode};
3+
use std::collections::HashSet;
4+
5+
use emmylua_parser::{LuaAst, LuaAstNode, LuaSyntaxId};
46

57
use crate::{
68
DbIndex, FileId, Profile,
79
compilation::analyzer::{
810
AnalysisPipeline, AnalyzeContext,
911
member::members::{
10-
analyze_assign_stat, analyze_func_stat, analyze_local_stat, analyze_table_field,
12+
analyze_assign_stat, analyze_func_stat, analyze_local_stat, analyze_table_expr,
13+
analyze_table_field,
1114
},
1215
},
1316
};
@@ -38,6 +41,9 @@ impl AnalysisPipeline for MemberAnalysisPipeline {
3841
LuaAst::LuaTableField(table_field) => {
3942
analyze_table_field(&mut analyzer, table_field);
4043
}
44+
LuaAst::LuaTableExpr(table_expr) => {
45+
analyze_table_expr(&mut analyzer, table_expr);
46+
}
4147
_ => {}
4248
}
4349
}
@@ -51,6 +57,7 @@ struct MemberAnalyzer<'a> {
5157
#[allow(unused)]
5258
context: &'a mut AnalyzeContext,
5359
is_meta: bool,
60+
visited_table_expr: HashSet<LuaSyntaxId>,
5461
}
5562

5663
impl<'a> MemberAnalyzer<'a> {
@@ -64,6 +71,7 @@ impl<'a> MemberAnalyzer<'a> {
6471
file_id,
6572
context,
6673
is_meta,
74+
visited_table_expr: HashSet::new(),
6775
}
6876
}
6977
}

crates/emmylua_code_analysis/src/db_index/member/lua_member_owner.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use crate::{GlobalId, InFiled, LuaDeclId, LuaTypeDeclId};
66
pub enum LuaMemberOwner {
77
Type(LuaTypeDeclId),
88
Element(InFiled<TextRange>),
9-
DeclId(LuaDeclId),
10-
Global(GlobalId),
9+
LocalDeclId(LuaDeclId),
10+
GlobalId(GlobalId),
1111
}
1212

1313
impl From<LuaTypeDeclId> for LuaMemberOwner {

0 commit comments

Comments
 (0)