|
1 | | -use std::collections::HashMap; |
| 1 | +use std::{collections::HashMap, sync::Arc}; |
2 | 2 |
|
3 | 3 | use crate::{ |
4 | 4 | humanize_type, semantic::member::infer_members, DbIndex, LuaMemberKey, LuaMemberOwner, |
@@ -39,72 +39,57 @@ pub fn check_ref_type_compact( |
39 | 39 |
|
40 | 40 | if type_decl.is_enum() { |
41 | 41 | match compact_type { |
42 | | - LuaType::Def(compact_id) => { |
43 | | - if source_id == compact_id { |
44 | | - return Ok(()); |
45 | | - } |
46 | | - } |
47 | | - LuaType::Ref(compact_id) => { |
| 42 | + LuaType::Def(compact_id) | LuaType::Ref(compact_id) => { |
48 | 43 | if source_id == compact_id { |
49 | 44 | return Ok(()); |
50 | 45 | } |
51 | 46 | } |
52 | 47 | _ => {} |
53 | 48 | }; |
54 | | - |
55 | | - let enum_member_owner = LuaMemberOwner::Type(source_id.clone()); |
56 | | - let enum_members = db |
57 | | - .get_member_index() |
58 | | - .get_members(&enum_member_owner) |
59 | | - .ok_or(TypeCheckFailReason::TypeNotMatch)?; |
60 | | - |
61 | | - let mut union_types = Vec::new(); |
62 | | - if type_decl.is_enum_key() { |
63 | | - for enum_member in enum_members { |
64 | | - let member_key = enum_member.get_key(); |
65 | | - let fake_type = match member_key { |
66 | | - LuaMemberKey::Name(name) => LuaType::DocStringConst(name.clone().into()), |
67 | | - LuaMemberKey::Integer(i) => LuaType::IntegerConst(i.clone()), |
68 | | - LuaMemberKey::None => continue, |
69 | | - LuaMemberKey::Expr(_) => continue, |
70 | | - }; |
71 | | - |
72 | | - union_types.push(fake_type); |
73 | | - } |
74 | | - } else { |
75 | | - for member in enum_members { |
76 | | - if let Some(type_cache) = |
77 | | - db.get_type_index().get_type_cache(&member.get_id().into()) |
78 | | - { |
79 | | - let member_fake_type = match type_cache.as_type() { |
80 | | - LuaType::StringConst(s) => &LuaType::DocStringConst(s.clone().into()), |
81 | | - LuaType::IntegerConst(i) => &LuaType::DocIntegerConst(i.clone()), |
82 | | - _ => &type_cache.as_type(), |
83 | | - }; |
84 | | - |
85 | | - union_types.push(member_fake_type.clone()); |
| 49 | + // 移除掉枚举类型本身 |
| 50 | + let mut compact_type = compact_type.clone(); |
| 51 | + match compact_type { |
| 52 | + LuaType::Union(union_types) => { |
| 53 | + let mut new_union_types = Vec::new(); |
| 54 | + let union_types = union_types.get_types(); |
| 55 | + for typ in union_types { |
| 56 | + if let LuaType::Def(compact_id) | LuaType::Ref(compact_id) = typ { |
| 57 | + if compact_id != source_id { |
| 58 | + new_union_types.push(typ.clone()); |
| 59 | + } |
| 60 | + continue; |
| 61 | + } |
| 62 | + new_union_types.push(typ.clone()); |
86 | 63 | } |
| 64 | + compact_type = LuaType::Union(Arc::new(LuaUnionType::new(new_union_types))); |
87 | 65 | } |
| 66 | + _ => {} |
88 | 67 | } |
89 | 68 |
|
90 | | - // 当 enum 的值全为整数常量时, 可能会用于位运算, 此时右值推断为整数 |
91 | | - if union_types |
92 | | - .iter() |
93 | | - .all(|t| matches!(t, LuaType::DocIntegerConst(_))) |
94 | | - { |
95 | | - match compact_type { |
96 | | - LuaType::Integer => { |
97 | | - return Ok(()); |
| 69 | + let Some(enum_fields) = type_decl.get_enum_field_type(db) else { |
| 70 | + return Err(TypeCheckFailReason::TypeNotMatch); |
| 71 | + }; |
| 72 | + |
| 73 | + if let LuaType::Union(union_types) = &enum_fields { |
| 74 | + // 当 enum 的值全为整数常量时, 可能会用于位运算, 此时右值推断为整数 |
| 75 | + if union_types |
| 76 | + .get_types() |
| 77 | + .iter() |
| 78 | + .all(|t| matches!(t, LuaType::DocIntegerConst(_))) |
| 79 | + { |
| 80 | + match compact_type { |
| 81 | + LuaType::Integer => { |
| 82 | + return Ok(()); |
| 83 | + } |
| 84 | + _ => {} |
98 | 85 | } |
99 | | - _ => {} |
100 | 86 | } |
101 | 87 | } |
102 | 88 |
|
103 | | - let fake_union_type = LuaType::Union(LuaUnionType::new(union_types).into()); |
104 | 89 | return check_general_type_compact( |
105 | 90 | db, |
106 | | - &fake_union_type, |
107 | | - compact_type, |
| 91 | + &enum_fields, |
| 92 | + &compact_type, |
108 | 93 | check_guard.next_level()?, |
109 | 94 | ); |
110 | 95 | } else { |
|
0 commit comments