Skip to content

Commit 3377ec7

Browse files
committed
refactor member
1 parent 349ecfb commit 3377ec7

32 files changed

+874
-471
lines changed

crates/emmylua_code_analysis/src/compilation/analyzer/bind_type/mod.rs renamed to crates/emmylua_code_analysis/src/compilation/analyzer/common/bind_type.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
mod migrate_global_member;
2-
3-
use migrate_global_member::migrate_global_members_when_type_resolve;
1+
// use migrate_global_member::migrate_global_members_when_type_resolve;
42
use rowan::TextRange;
53

64
use crate::{
75
InFiled, LuaMemberId, LuaTypeCache, LuaTypeOwner,
6+
compilation::analyzer::common::migrate_global_member::migrate_global_members_when_type_resolve,
87
db_index::{DbIndex, LuaMemberOwner, LuaType, LuaTypeDeclId},
98
};
109

@@ -44,9 +43,12 @@ pub fn bind_type(
4443
}
4544
}
4645

47-
db.get_type_index_mut()
48-
.bind_type(type_owner.clone(), type_cache);
49-
migrate_global_members_when_type_resolve(db, type_owner);
46+
if db
47+
.get_type_index_mut()
48+
.bind_type(type_owner.clone(), type_cache)
49+
{
50+
migrate_global_members_when_type_resolve(db, type_owner);
51+
}
5052
} else {
5153
let decl_type = decl_type_cache?.as_type();
5254
merge_def_type(db, decl_type.clone(), type_cache.as_type().clone());
@@ -92,20 +94,17 @@ fn merge_def_type_with_table(
9294
}
9395

9496
pub fn add_member(db: &mut DbIndex, owner: LuaMemberOwner, member_id: LuaMemberId) -> Option<()> {
97+
let old_member_owner = db.get_member_index().get_current_owner(&member_id);
98+
if let Some(old_owner) = old_member_owner {
99+
if old_owner == &owner {
100+
return None; // Already exists
101+
}
102+
}
103+
95104
db.get_member_index_mut()
96105
.set_member_owner(owner.clone(), member_id.file_id, member_id);
97106
db.get_member_index_mut()
98107
.add_member_to_owner(owner.clone(), member_id);
99108

100109
Some(())
101110
}
102-
103-
fn get_owner_id(db: &DbIndex, type_owner: &LuaTypeOwner) -> Option<LuaMemberOwner> {
104-
let type_cache = db.get_type_index().get_type_cache(&type_owner)?;
105-
match type_cache.as_type() {
106-
LuaType::Ref(type_id) => Some(LuaMemberOwner::Type(type_id.clone())),
107-
LuaType::TableConst(id) => Some(LuaMemberOwner::Element(id.clone())),
108-
LuaType::Instance(inst) => Some(LuaMemberOwner::Element(inst.get_range().clone())),
109-
_ => None,
110-
}
111-
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
use std::vec;
2+
3+
use emmylua_parser::{LuaAstNode, LuaExpr, LuaIndexExpr, LuaIndexKey, LuaNameExpr};
4+
5+
use crate::{DbIndex, FileId, GlobalId, LuaDeclId, LuaMemberOwner, LuaType};
6+
7+
// todo
8+
9+
pub fn get_name_expr_member_owner(
10+
db: &DbIndex,
11+
file_id: FileId,
12+
name_expr: &LuaNameExpr,
13+
) -> Option<LuaMemberOwner> {
14+
let decl_id = LuaDeclId::new(file_id, name_expr.get_position());
15+
if let Some(owner) = get_decl_member_owner(&db, &decl_id) {
16+
return Some(owner);
17+
}
18+
19+
let decl_tree = db.get_decl_index().get_decl_tree(&file_id)?;
20+
let name = name_expr.get_name_text()?;
21+
let prev_decl = decl_tree.find_local_decl(&name, name_expr.get_position())?;
22+
23+
if !prev_decl.is_implicit_self() {
24+
return get_decl_member_owner(db, &prev_decl.get_id())
25+
}
26+
27+
let root = name_expr.get_root();
28+
let syntax_id = prev_decl.get_syntax_id();
29+
let token = syntax_id.to_token_from_root(&root)?;
30+
let index_expr = LuaIndexExpr::cast(token.parent()?)?;
31+
let LuaExpr::NameExpr(prefix_name_expr) = index_expr.get_prefix_expr()? else {
32+
return None;
33+
};
34+
35+
get_name_expr_member_owner(db, file_id, &prefix_name_expr)
36+
}
37+
38+
pub fn get_decl_member_owner(db: &DbIndex, decl_id: &LuaDeclId) -> Option<LuaMemberOwner> {
39+
if let Some(type_cache) = db.get_type_index().get_type_cache(&decl_id.clone().into()) {
40+
let decl_type = type_cache.as_type();
41+
match decl_type {
42+
LuaType::Def(type_id) => {
43+
return Some(LuaMemberOwner::Type(type_id.clone()));
44+
}
45+
LuaType::GlobalTable(global_id) => {
46+
return Some(LuaMemberOwner::GlobalId(GlobalId(global_id.clone())));
47+
}
48+
LuaType::TableConst(table_const) => {
49+
return Some(LuaMemberOwner::Element(table_const.clone()));
50+
}
51+
LuaType::Instance(inst) => {
52+
return Some(LuaMemberOwner::Element(inst.get_range().clone()))
53+
}
54+
_ => return None,
55+
}
56+
}
57+
58+
let decl = db.get_decl_index().get_decl(decl_id)?;
59+
60+
if decl.is_global() {
61+
return Some(LuaMemberOwner::GlobalId(GlobalId::new(decl.get_name())));
62+
}
63+
64+
None
65+
// Some(LuaMemberOwner::LocalDeclId(decl_id.clone()))
66+
}
67+
68+
pub fn get_global_path(
69+
db: &DbIndex,
70+
file_id: FileId,
71+
index_expr: &LuaIndexExpr,
72+
) -> Option<GlobalId> {
73+
let mut prefix_expr = index_expr.get_prefix_expr()?;
74+
let mut paths = vec![index_expr.clone()];
75+
loop {
76+
match &prefix_expr {
77+
LuaExpr::NameExpr(name_expr) => {
78+
let owner_id = get_name_expr_member_owner(db, file_id, &name_expr)?;
79+
match owner_id {
80+
LuaMemberOwner::GlobalId(global_id) => {
81+
let base_name = global_id.get_name();
82+
match paths.len() {
83+
0 => return Some(GlobalId::new(base_name)),
84+
1 => {
85+
if let Some(name) = to_path_name(&paths[0]) {
86+
return Some(GlobalId::new(&format!("{}.{}", base_name, name)));
87+
} else {
88+
return None;
89+
}
90+
}
91+
_ => {
92+
let mut path = base_name.to_string();
93+
for path_expr in paths.iter().rev() {
94+
if let Some(name) = to_path_name(path_expr) {
95+
// general this path is not too long
96+
path.push_str(&format!(".{}", name));
97+
}
98+
}
99+
return Some(GlobalId::new(&path));
100+
}
101+
}
102+
}
103+
_ => return None,
104+
};
105+
}
106+
LuaExpr::IndexExpr(index_expr) => {
107+
paths.push(index_expr.clone());
108+
prefix_expr = index_expr.get_prefix_expr()?;
109+
}
110+
_ => return None,
111+
}
112+
}
113+
}
114+
115+
fn to_path_name(index_expr: &LuaIndexExpr) -> Option<String> {
116+
match index_expr.get_index_key()? {
117+
LuaIndexKey::String(s) => {
118+
return Some(s.get_value());
119+
}
120+
LuaIndexKey::Name(name) => {
121+
return Some(name.get_name_text().to_string());
122+
}
123+
LuaIndexKey::Integer(i) => {
124+
return Some(i.get_int_value().to_string());
125+
}
126+
LuaIndexKey::Idx(idx) => {
127+
let text = format!("[{}]", idx);
128+
return Some(text);
129+
}
130+
_ => return None,
131+
}
132+
}

crates/emmylua_code_analysis/src/compilation/analyzer/bind_type/migrate_global_member.rs renamed to crates/emmylua_code_analysis/src/compilation/analyzer/common/migrate_global_member.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use crate::{DbIndex, GlobalId, LuaDeclId, LuaMemberId, LuaMemberOwner, LuaTypeOwner};
2-
3-
use super::get_owner_id;
1+
use crate::{
2+
DbIndex, GlobalId, LuaDeclId, LuaMemberId, LuaMemberOwner, LuaTypeOwner,
3+
compilation::analyzer::common::{add_member, get_owner_id},
4+
};
45

56
pub fn migrate_global_members_when_type_resolve(
67
db: &mut DbIndex,
@@ -30,28 +31,27 @@ fn migrate_global_member_to_decl(db: &mut DbIndex, decl_id: LuaDeclId) -> Option
3031
let global_id = GlobalId::new(name.into());
3132
let members = db
3233
.get_member_index()
33-
.get_members(&LuaMemberOwner::GlobalPath(global_id))?
34+
.get_members(&LuaMemberOwner::GlobalId(global_id))?
3435
.iter()
3536
.map(|member| member.get_id())
3637
.collect::<Vec<_>>();
3738

38-
let member_index = db.get_member_index_mut();
3939
for member_id in members {
40-
member_index.set_member_owner(owner_id.clone(), member_id.file_id, member_id);
41-
member_index.add_member_to_owner(owner_id.clone(), member_id);
40+
add_member(db, owner_id.clone(), member_id);
4241
}
4342

4443
Some(())
4544
}
4645

4746
fn migrate_global_member_to_member(db: &mut DbIndex, member_id: LuaMemberId) -> Option<()> {
48-
let member = db.get_member_index().get_member(&member_id)?;
49-
let global_id = member.get_global_id()?;
47+
let global_id = db
48+
.get_member_index()
49+
.get_member_global_id(&member_id)?;
5050
let owner_id = get_owner_id(db, &member_id.clone().into())?;
5151

5252
let members = db
5353
.get_member_index()
54-
.get_members(&LuaMemberOwner::GlobalPath(global_id.clone()))?
54+
.get_members(&LuaMemberOwner::GlobalId(global_id.clone()))?
5555
.iter()
5656
.map(|member| member.get_id())
5757
.collect::<Vec<_>>();
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
mod bind_type;
2+
mod member;
3+
mod migrate_global_member;
4+
5+
pub use bind_type::{add_member, bind_type};
6+
pub use member::*;
7+
8+
use crate::{DbIndex, GlobalId, LuaMemberOwner, LuaType, LuaTypeOwner};
9+
10+
11+
fn get_owner_id(db: &DbIndex, type_owner: &LuaTypeOwner) -> Option<LuaMemberOwner> {
12+
let type_cache = db.get_type_index().get_type_cache(&type_owner)?;
13+
match type_cache.as_type() {
14+
LuaType::Ref(type_id) => Some(LuaMemberOwner::Type(type_id.clone())),
15+
LuaType::TableConst(id) => Some(LuaMemberOwner::Element(id.clone())),
16+
LuaType::Instance(inst) => Some(LuaMemberOwner::Element(inst.get_range().clone())),
17+
LuaType::GlobalTable(inst) => Some(LuaMemberOwner::GlobalId(GlobalId(inst.clone()))),
18+
_ => None,
19+
}
20+
}

0 commit comments

Comments
 (0)