Skip to content

Commit 189f718

Browse files
committed
fix Tuple check_field
1 parent e23b361 commit 189f718

File tree

4 files changed

+59
-40
lines changed

4 files changed

+59
-40
lines changed

crates/emmylua_code_analysis/src/compilation/test/tuple_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,6 @@ mod tests {
4141
"#,
4242
);
4343
let ty = ws.expr_ty("A");
44-
assert_eq!(ws.humanize_type(ty), "36|826");
44+
assert_eq!(ws.humanize_type(ty), "(36|826)");
4545
}
4646
}

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
@@ -242,7 +242,7 @@ where
242242

243243
if display_types.len() == 1 {
244244
if has_function && has_nil {
245-
format!("({})?", type_str)
245+
format!("{}?", type_str)
246246
} else {
247247
format!("{}{}", type_str, if has_nil { "?" } else { "" })
248248
}

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

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -131,55 +131,54 @@ fn is_valid_prefix_type(typ: &LuaType) -> bool {
131131
}
132132
}
133133

134-
#[allow(dead_code)]
135-
fn is_valid_index_key(index_key: &LuaIndexKey) -> bool {
136-
match index_key {
137-
LuaIndexKey::String(_) | LuaIndexKey::Name(_) | LuaIndexKey::Integer(_) => true,
138-
_ => false,
139-
}
140-
}
141-
142134
fn is_valid_member(
143135
semantic_model: &SemanticModel,
144136
prefix_typ: &LuaType,
145137
index_expr: &LuaIndexExpr,
146138
index_key: &LuaIndexKey,
147139
code: DiagnosticCode,
148140
) -> Option<()> {
149-
// 如果类型是 Ref 的 enum, 那么需要检查变量是否为参数, 因为作为参数的 enum 本质上是 value 而不是 enum
150-
if enum_variable_is_param(
151-
semantic_model.get_db(),
152-
&mut semantic_model.get_config().borrow_mut(),
153-
index_expr,
154-
prefix_typ,
155-
)
156-
.is_some()
157-
{
158-
return None;
141+
match prefix_typ {
142+
LuaType::Global | LuaType::Userdata => return Some(()),
143+
LuaType::Array(typ) => {
144+
if typ.is_unknown() {
145+
return Some(());
146+
}
147+
}
148+
LuaType::Ref(_) => {
149+
// 如果类型是 Ref 的 enum, 那么需要检查变量是否为参数, 因为作为参数的 enum 本质上是 value 而不是 enum
150+
if check_enum_is_param(semantic_model, prefix_typ, index_expr).is_some() {
151+
return None;
152+
}
153+
}
154+
_ => {}
159155
}
160156

161157
// 检查 member_info
162158
let need_add_diagnostic =
163159
match semantic_model.get_semantic_info(index_expr.syntax().clone().into()) {
164-
Some(info) => info.semantic_decl.is_none() && info.typ.is_unknown(),
160+
Some(info) => {
161+
let need = info.semantic_decl.is_none() && info.typ.is_unknown();
162+
// TODO: 元组类型的检查或许需要独立出来
163+
if !need && matches!(code, DiagnosticCode::InjectField) {
164+
if let LuaType::Tuple(tuple) = prefix_typ {
165+
if tuple.is_infer_resolve() {
166+
return Some(());
167+
} else {
168+
// 元组类型禁止修改
169+
return None;
170+
}
171+
}
172+
}
173+
need
174+
}
165175
None => true,
166176
};
167177

168178
if !need_add_diagnostic {
169179
return Some(());
170180
}
171181

172-
match prefix_typ {
173-
LuaType::Global => return Some(()),
174-
LuaType::Userdata => return Some(()),
175-
LuaType::Array(typ) => {
176-
if typ.is_unknown() {
177-
return Some(());
178-
}
179-
}
180-
_ => {}
181-
}
182-
183182
let key_type = if let LuaIndexKey::Expr(expr) = index_key {
184183
match semantic_model.infer_expr(expr.clone()) {
185184
Ok(
@@ -235,8 +234,8 @@ fn is_valid_member(
235234
local field
236235
local a = Class[field]
237236
*/
238-
let key_type_set = get_key_types(&key_type);
239-
if key_type_set.is_empty() {
237+
let key_types = get_key_types(&key_type);
238+
if key_types.is_empty() {
240239
return None;
241240
}
242241

@@ -247,28 +246,28 @@ fn is_valid_member(
247246
match &info.key {
248247
LuaMemberKey::ExprType(typ) => {
249248
if typ.is_string() {
250-
if key_type_set
249+
if key_types
251250
.iter()
252251
.any(|typ| typ.is_string() || typ.is_str_tpl_ref())
253252
{
254253
return Some(());
255254
}
256255
} else if typ.is_integer() {
257-
if key_type_set.iter().any(|typ| typ.is_integer()) {
256+
if key_types.iter().any(|typ| typ.is_integer()) {
258257
return Some(());
259258
}
260259
}
261260
}
262261
LuaMemberKey::Name(_) => {
263-
if key_type_set
262+
if key_types
264263
.iter()
265264
.any(|typ| typ.is_string() || typ.is_str_tpl_ref())
266265
{
267266
return Some(());
268267
}
269268
}
270269
LuaMemberKey::Integer(_) => {
271-
if key_type_set.iter().any(|typ| typ.is_integer()) {
270+
if key_types.iter().any(|typ| typ.is_integer()) {
272271
return Some(());
273272
}
274273
}
@@ -281,7 +280,7 @@ fn is_valid_member(
281280
if let Some(decl) = semantic_model.get_db().get_type_index().get_type_decl(&id)
282281
{
283282
if decl.is_enum() {
284-
if key_type_set.iter().any(|typ| match typ {
283+
if key_types.iter().any(|typ| match typ {
285284
LuaType::Ref(key_id) | LuaType::Def(key_id) => id == *key_id,
286285
_ => false,
287286
}) {
@@ -433,3 +432,22 @@ fn is_in_conditional_statement<T: LuaAstNode>(node: &T) -> bool {
433432
}
434433
false
435434
}
435+
436+
fn check_enum_is_param(
437+
semantic_model: &SemanticModel,
438+
prefix_typ: &LuaType,
439+
index_expr: &LuaIndexExpr,
440+
) -> Option<()> {
441+
if enum_variable_is_param(
442+
semantic_model.get_db(),
443+
&mut semantic_model.get_config().borrow_mut(),
444+
index_expr,
445+
prefix_typ,
446+
)
447+
.is_some()
448+
{
449+
return Some(());
450+
}
451+
452+
None
453+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,8 @@ fn infer_member_by_index_table(
714714
let members = db
715715
.get_member_index()
716716
.get_members(&LuaMemberOwner::Element(table_range.clone()));
717-
if let Some(members) = members {
717+
if let Some(mut members) = members {
718+
members.sort_by(|a, b| a.get_key().cmp(&b.get_key()));
718719
let mut result_type = LuaType::Unknown;
719720
for member in members {
720721
let member_key_type = match member.get_key() {

0 commit comments

Comments
 (0)