Skip to content

Commit 65870c5

Browse files
committed
check_field 完善
1 parent 1daa739 commit 65870c5

File tree

3 files changed

+94
-2
lines changed

3 files changed

+94
-2
lines changed

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ fn is_valid_member(
143143

144144
match prefix_typ {
145145
LuaType::Global => return Some(()),
146+
LuaType::Userdata => return Some(()),
146147
LuaType::Array(typ) => {
147148
if typ.is_unknown() {
148149
return Some(());
@@ -233,6 +234,22 @@ fn is_valid_member(
233234
_ => {}
234235
}
235236
}
237+
if members.is_empty() {
238+
// 当没有任何成员信息且是 enum 类型时, 需要检查参数是否为自己
239+
if let LuaType::Ref(id) | LuaType::Def(id) = prefix_type {
240+
if let Some(decl) = semantic_model.get_db().get_type_index().get_type_decl(&id)
241+
{
242+
if decl.is_enum() {
243+
if key_type_set.iter().any(|typ| match typ {
244+
LuaType::Ref(key_id) | LuaType::Def(key_id) => id == *key_id,
245+
_ => false,
246+
}) {
247+
return Some(());
248+
}
249+
}
250+
}
251+
}
252+
}
236253
}
237254
}
238255

@@ -276,6 +293,9 @@ fn get_key_types(typ: &LuaType) -> HashSet<LuaType> {
276293
stack.push(t.clone());
277294
}
278295
}
296+
LuaType::Ref(_) => {
297+
type_set.insert(current_type);
298+
}
279299
_ => {}
280300
}
281301
}

crates/emmylua_code_analysis/src/diagnostic/test/undefined_field_test.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,4 +383,72 @@ mod test {
383383
"#
384384
));
385385
}
386+
387+
#[test]
388+
fn test_enum_3() {
389+
let mut ws = VirtualWorkspace::new();
390+
assert!(ws.check_code_for(
391+
DiagnosticCode::UndefinedField,
392+
r#"
393+
---@enum (key) PlayerAttr
394+
local PlayerAttr = {}
395+
396+
---@param key PlayerAttr
397+
local function add(key)
398+
local a = PlayerAttr[key]
399+
end
400+
"#
401+
));
402+
}
403+
404+
#[test]
405+
fn test_enum_alias() {
406+
let mut ws = VirtualWorkspace::new();
407+
assert!(ws.check_code_for(
408+
DiagnosticCode::UndefinedField,
409+
r#"
410+
---@enum EA
411+
A = {
412+
['GAME_INIT'] = "ET_GAME_INIT",
413+
}
414+
415+
---@enum EB
416+
B = {
417+
['GAME_PAUSE'] = "ET_GAME_PAUSE",
418+
}
419+
420+
---@alias EventName EA | EB
421+
422+
---@class Event
423+
local event = {}
424+
event.ET_GAME_INIT = {}
425+
event.ET_GAME_PAUSE = {}
426+
427+
428+
---@param name EventName
429+
local function test(name)
430+
local a = event[name]
431+
end
432+
"#
433+
));
434+
}
435+
436+
#[test]
437+
fn test_userdata() {
438+
let mut ws = VirtualWorkspace::new();
439+
assert!(ws.check_code_for(
440+
DiagnosticCode::UndefinedField,
441+
r#"
442+
---@type any
443+
local value
444+
local tp = type(value)
445+
446+
if tp == 'userdata' then
447+
---@cast value userdata
448+
if value['type'] then
449+
end
450+
end
451+
"#
452+
));
453+
}
386454
}

crates/emmylua_code_analysis/src/semantic/infer/infer_index.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,12 @@ fn get_all_member_key(
327327
LuaType::MultiLineUnion(types) => {
328328
for (typ, _) in types.get_unions() {
329329
let member_key: LuaMemberKey = match typ {
330-
LuaType::DocStringConst(s) => (*s).to_string().into(),
331-
LuaType::IntegerConst(i) => (*i).into(),
330+
LuaType::DocStringConst(s) | LuaType::StringConst(s) => (*s).to_string().into(),
331+
LuaType::DocIntegerConst(i) | LuaType::IntegerConst(i) => (*i).into(),
332+
LuaType::Ref(_) => {
333+
get_all_member_key(db, index_type_decl, typ, result);
334+
continue;
335+
}
332336
_ => continue,
333337
};
334338

0 commit comments

Comments
 (0)