Skip to content

Commit 6ad40ae

Browse files
committed
update diagnostic MissingFields
1 parent b4e6d62 commit 6ad40ae

5 files changed

Lines changed: 76 additions & 18 deletions

File tree

crates/emmylua_code_analysis/src/db_index/type/humanize_type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ where
247247

248248
if display_types.len() == 1 {
249249
if has_function && has_nil {
250-
format!("{}?", type_str)
250+
format!("({})?", type_str)
251251
} else {
252252
format!("{}{}", type_str, if has_nil { "?" } else { "" })
253253
}

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,33 @@ fn check_table_expr(
2929
type_cache: &mut HashMap<LuaType, HashSet<String>>,
3030
) -> Option<()> {
3131
let db = context.db;
32-
let table_type = semantic_model.infer_table_should_be(expr.clone())?;
32+
33+
let table_type = match semantic_model.infer_table_should_be(expr.clone())? {
34+
LuaType::Union(union) => {
35+
let mut set = HashSet::new();
36+
for ty in union.get_types() {
37+
match ty {
38+
LuaType::Ref(_)
39+
| LuaType::Object(_)
40+
| LuaType::Generic(_)
41+
| LuaType::Intersection(_) => {
42+
set.insert(ty.clone());
43+
}
44+
LuaType::Table | LuaType::Userdata => {
45+
return Some(());
46+
}
47+
_ => {}
48+
}
49+
}
50+
match set.len() {
51+
1 => set.into_iter().next()?.clone(),
52+
_ => {
53+
return Some(());
54+
}
55+
}
56+
}
57+
table_type => table_type,
58+
};
3359

3460
let current_fields = expr
3561
.get_fields()

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,13 @@ pub fn check_file(context: &mut DiagnosticContext, semantic_model: &SemanticMode
7878
run_check::<local_const_reassign::LocalConstReassignChecker>(context, semantic_model);
7979
run_check::<discard_returns::DiscardReturnsChecker>(context, semantic_model);
8080
run_check::<await_in_sync::AwaitInSyncChecker>(context, semantic_model);
81+
run_check::<missing_fields::MissingFieldsChecker>(context, semantic_model);
8182
run_check::<param_type_check::ParamTypeCheckChecker>(context, semantic_model);
8283
run_check::<need_check_nil::NeedCheckNilChecker>(context, semantic_model);
8384
run_check::<code_style_check::CodeStyleCheckChecker>(context, semantic_model);
8485
run_check::<return_type_mismatch::ReturnTypeMismatch>(context, semantic_model);
8586
run_check::<undefined_doc_param::UndefinedDocParamChecker>(context, semantic_model);
8687
run_check::<redefined_local::RedefinedLocalChecker>(context, semantic_model);
87-
run_check::<missing_fields::MissingFieldsChecker>(context, semantic_model);
8888
run_check::<check_field::CheckFieldChecker>(context, semantic_model);
8989
run_check::<circle_doc_class::CircleDocClassChecker>(context, semantic_model);
9090
run_check::<incomplete_signature_doc::IncompleteSignatureDocChecker>(context, semantic_model);

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,4 +1253,28 @@ mod test {
12531253
"#
12541254
));
12551255
}
1256+
1257+
#[test]
1258+
fn test_generic_union_type() {
1259+
let mut ws = VirtualWorkspace::new();
1260+
ws.def(
1261+
r#"
1262+
---@class Params<T>
1263+
---@field next fun(value: T)
1264+
---@field error? fun(error: any)
1265+
1266+
---@generic T
1267+
---@param params fun(value: T) | Params<T>
1268+
function test(params)
1269+
end
1270+
1271+
"#,
1272+
);
1273+
assert!(!ws.check_code_for(
1274+
DiagnosticCode::ParamTypeNotMatch,
1275+
r#"
1276+
test({})
1277+
"#
1278+
));
1279+
}
12561280
}

crates/emmylua_code_analysis/src/semantic/type_check/generic_type.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ pub fn check_generic_type_compact(
1717
check_guard: TypeCheckGuard,
1818
) -> TypeCheckResult {
1919
// 不检查尚未实例化的泛型类
20-
if source_generic.contain_tpl() {
21-
return Ok(());
22-
}
20+
let is_tpl = source_generic.contain_tpl();
2321

2422
let source_base_id = source_generic.get_base_type_id();
2523
let type_decl = db
@@ -41,24 +39,34 @@ pub fn check_generic_type_compact(
4139
}
4240

4341
match compact_type {
44-
LuaType::Generic(compact_generic) => check_generic_type_compact_generic(
45-
db,
46-
source_generic,
47-
compact_generic,
48-
check_guard.next_level()?,
49-
),
42+
LuaType::Generic(compact_generic) => {
43+
if is_tpl {
44+
return Ok(());
45+
}
46+
check_generic_type_compact_generic(
47+
db,
48+
source_generic,
49+
compact_generic,
50+
check_guard.next_level()?,
51+
)
52+
}
5053
LuaType::TableConst(range) => check_generic_type_compact_table(
5154
db,
5255
source_generic,
5356
LuaMemberOwner::Element(range.clone()),
5457
check_guard.next_level()?,
5558
),
56-
LuaType::Ref(_) | LuaType::Def(_) => check_ref_type_compact(
57-
db,
58-
&source_generic.get_base_type_id(),
59-
compact_type,
60-
check_guard.next_level()?,
61-
),
59+
LuaType::Ref(_) | LuaType::Def(_) => {
60+
if is_tpl {
61+
return Ok(());
62+
}
63+
check_ref_type_compact(
64+
db,
65+
&source_generic.get_base_type_id(),
66+
compact_type,
67+
check_guard.next_level()?,
68+
)
69+
}
6270
_ => Err(TypeCheckFailReason::TypeNotMatch),
6371
}
6472
}

0 commit comments

Comments
 (0)