Skip to content

Commit fc86b67

Browse files
committed
优化member_info搜索
1 parent 466b92f commit fc86b67

File tree

9 files changed

+318
-168
lines changed

9 files changed

+318
-168
lines changed

crates/emmylua_code_analysis/src/diagnostic/checker/check_field.rs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -317,26 +317,41 @@ fn is_valid_member(
317317
}
318318
if members.is_empty() {
319319
// 当没有任何成员信息且是 enum 类型时, 需要检查参数是否为自己
320-
if let LuaType::Ref(id) | LuaType::Def(id) = prefix_type {
321-
if let Some(decl) = semantic_model.get_db().get_type_index().get_type_decl(&id)
322-
{
323-
if decl.is_enum() {
324-
if key_types.iter().any(|typ| match typ {
325-
LuaType::Ref(key_id) | LuaType::Def(key_id) => id == *key_id,
326-
_ => false,
327-
}) {
328-
return Some(());
329-
}
330-
}
331-
}
320+
if check_enum_self_reference(semantic_model, &prefix_type, &key_types).is_some() {
321+
return Some(());
332322
}
333323
}
324+
} else {
325+
if check_enum_self_reference(semantic_model, &prefix_type, &key_types).is_some() {
326+
return Some(());
327+
}
334328
}
335329
}
336330

337331
None
338332
}
339333

334+
/// 检查枚举类型的自引用
335+
fn check_enum_self_reference(
336+
semantic_model: &SemanticModel,
337+
prefix_type: &LuaType,
338+
key_types: &HashSet<LuaType>,
339+
) -> Option<()> {
340+
if let LuaType::Ref(id) | LuaType::Def(id) = prefix_type {
341+
if let Some(decl) = semantic_model.get_db().get_type_index().get_type_decl(&id) {
342+
if decl.is_enum() {
343+
if key_types.iter().any(|typ| match typ {
344+
LuaType::Ref(key_id) | LuaType::Def(key_id) => *id == *key_id,
345+
_ => false,
346+
}) {
347+
return Some(());
348+
}
349+
}
350+
}
351+
}
352+
None
353+
}
354+
340355
fn get_prefix_types(prefix_typ: &LuaType) -> HashSet<LuaType> {
341356
let mut type_set = HashSet::new();
342357
let mut stack = vec![prefix_typ.clone()];

crates/emmylua_code_analysis/src/semantic/infer/infer_call/infer_setmetatable.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ use emmylua_parser::{LuaAstNode, LuaCallExpr, LuaExpr, LuaIndexKey, LuaTableExpr
22

33
use crate::{
44
infer_expr,
5-
semantic::{infer::InferResult, member::find_members},
6-
DbIndex, InFiled, InferFailReason, LuaInferCache, LuaType,
5+
semantic::{
6+
infer::InferResult,
7+
member::{find_members, find_members_with_key},
8+
},
9+
DbIndex, InFiled, InferFailReason, LuaInferCache, LuaMemberKey, LuaType,
710
};
811

912
pub fn infer_setmetatable_call(
@@ -55,20 +58,19 @@ fn meta_type_contain_table(
5558
meta_type: LuaType,
5659
table_expr: LuaTableExpr,
5760
) -> Option<LuaType> {
58-
let meta_members = find_members(db, &meta_type)?;
61+
let meta_members =
62+
find_members_with_key(db, &meta_type, LuaMemberKey::Name("__index".into()), true)?;
5963
for member in meta_members {
60-
if member.key.get_name() == Some("__index") {
61-
let index_members = find_members(db, &member.typ)?;
62-
let table_type = infer_expr(db, cache, LuaExpr::TableExpr(table_expr.clone())).ok()?;
63-
let table_members = find_members(db, &table_type)?;
64-
// 如果 index_members 包含了 table_members 中的所有成员,则返回 meta_type
65-
if table_members.iter().all(|table_member| {
66-
index_members
67-
.iter()
68-
.any(|index_member| index_member.key.to_path() == table_member.key.to_path())
69-
}) {
70-
return Some(meta_type);
71-
}
64+
let index_members = find_members(db, &member.typ)?;
65+
let table_type = infer_expr(db, cache, LuaExpr::TableExpr(table_expr.clone())).ok()?;
66+
let table_members = find_members(db, &table_type)?;
67+
// 如果 index_members 包含了 table_members 中的所有成员,则返回 meta_type
68+
if table_members.iter().all(|table_member| {
69+
index_members
70+
.iter()
71+
.any(|index_member| index_member.key.to_path() == table_member.key.to_path())
72+
}) {
73+
return Some(meta_type);
7274
}
7375
}
7476
None

0 commit comments

Comments
 (0)