11use emmylua_code_analysis:: {
22 enum_variable_is_param, DbIndex , LuaMemberInfo , LuaSemanticDeclId , LuaType , LuaTypeDeclId ,
3+ SemanticModel ,
34} ;
45use emmylua_parser:: { LuaAstNode , LuaAstToken , LuaIndexExpr , LuaStringToken } ;
56
@@ -40,7 +41,11 @@ pub fn add_completion(builder: &mut CompletionBuilder) -> Option<()> {
4041 }
4142
4243 let member_info_map = builder. semantic_model . get_member_info_map ( & prefix_type) ?;
43- for ( _, member_infos) in member_info_map. iter ( ) {
44+ // 排序
45+ let mut sorted_entries: Vec < _ > = member_info_map. iter ( ) . collect ( ) ;
46+ sorted_entries. sort_unstable_by ( |( name1, _) , ( name2, _) | name1. cmp ( name2) ) ;
47+
48+ for ( _, member_infos) in sorted_entries {
4449 add_resolve_member_infos ( builder, & member_infos, completion_status) ;
4550 }
4651
@@ -53,11 +58,28 @@ fn add_resolve_member_infos(
5358 completion_status : CompletionTriggerStatus ,
5459) -> Option < ( ) > {
5560 if member_infos. len ( ) == 1 {
56- let overload_count = count_function_overloads (
57- builder. semantic_model . get_db ( ) ,
58- & member_infos. iter ( ) . map ( |info| info) . collect :: < Vec < _ > > ( ) ,
59- ) ;
6061 let member_info = & member_infos[ 0 ] ;
62+ let overload_count = match & member_info. typ {
63+ LuaType :: DocFunction ( _) => None ,
64+ LuaType :: Signature ( id) => {
65+ if let Some ( signature) = builder
66+ . semantic_model
67+ . get_db ( )
68+ . get_signature_index ( )
69+ . get ( & id)
70+ {
71+ let count = signature. overloads . len ( ) ;
72+ if count == 0 {
73+ None
74+ } else {
75+ Some ( count)
76+ }
77+ } else {
78+ None
79+ }
80+ }
81+ _ => None ,
82+ } ;
6183 add_member_completion (
6284 builder,
6385 member_info. clone ( ) ,
@@ -67,46 +89,12 @@ fn add_resolve_member_infos(
6789 return Some ( ( ) ) ;
6890 }
6991
70- let mut resolve_state = MemberResolveState :: All ;
71- if builder
72- . semantic_model
73- . get_db ( )
74- . get_emmyrc ( )
75- . strict
76- . meta_override_file_define
77- {
78- for member_info in member_infos {
79- match member_info. feature {
80- Some ( feature) => {
81- if feature. is_meta_decl ( ) {
82- resolve_state = MemberResolveState :: Meta ;
83- break ;
84- } else if feature. is_file_decl ( ) {
85- resolve_state = MemberResolveState :: FileDecl ;
86- }
87- }
88- None => { }
89- }
90- }
91- }
92-
93- // 屏蔽掉父类成员
94- let first_owner = get_owner_type_id ( builder. semantic_model . get_db ( ) , member_infos. first ( ) ?) ;
95- let member_infos: Vec < & LuaMemberInfo > = member_infos
96- . iter ( )
97- . filter ( |member_info| {
98- get_owner_type_id ( builder. semantic_model . get_db ( ) , member_info) == first_owner
99- } )
100- . collect ( ) ;
101-
102- // 当全为`DocFunction`时, 只取第一个作为补全项
103- let limit_doc_function = member_infos
104- . iter ( )
105- . all ( |info| matches ! ( info. typ, LuaType :: DocFunction ( _) ) ) ;
92+ let ( filtered_member_infos, overload_count) =
93+ filter_member_infos ( & builder. semantic_model , member_infos) ?;
10694
107- let overload_count = count_function_overloads ( builder. semantic_model . get_db ( ) , & member_infos ) ;
95+ let resolve_state = get_resolve_state ( builder. semantic_model . get_db ( ) , & filtered_member_infos ) ;
10896
109- for member_info in member_infos {
97+ for member_info in filtered_member_infos {
11098 match resolve_state {
11199 MemberResolveState :: All => {
112100 add_member_completion (
@@ -115,9 +103,6 @@ fn add_resolve_member_infos(
115103 completion_status,
116104 overload_count,
117105 ) ;
118- if limit_doc_function {
119- break ;
120- }
121106 }
122107 MemberResolveState :: Meta => {
123108 if let Some ( feature) = member_info. feature {
@@ -128,9 +113,6 @@ fn add_resolve_member_infos(
128113 completion_status,
129114 overload_count,
130115 ) ;
131- if limit_doc_function {
132- break ;
133- }
134116 }
135117 }
136118 }
@@ -143,9 +125,6 @@ fn add_resolve_member_infos(
143125 completion_status,
144126 overload_count,
145127 ) ;
146- if limit_doc_function {
147- break ;
148- }
149128 }
150129 }
151130 }
@@ -155,30 +134,105 @@ fn add_resolve_member_infos(
155134 Some ( ( ) )
156135}
157136
158- fn count_function_overloads ( db : & DbIndex , member_infos : & Vec < & LuaMemberInfo > ) -> Option < usize > {
159- let mut count = 0 ;
137+ /// 过滤成员信息,返回需要的成员列表和重载数量
138+ fn filter_member_infos < ' a > (
139+ semantic_model : & SemanticModel ,
140+ member_infos : & ' a Vec < LuaMemberInfo > ,
141+ ) -> Option < ( Vec < & ' a LuaMemberInfo > , Option < usize > ) > {
142+ if member_infos. is_empty ( ) {
143+ return None ;
144+ }
145+
146+ let mut file_decl_member: Option < & LuaMemberInfo > = None ;
147+ let mut member_with_owners: Vec < ( & LuaMemberInfo , Option < LuaTypeDeclId > ) > =
148+ Vec :: with_capacity ( member_infos. len ( ) ) ;
149+ let mut all_doc_function = true ;
150+ let mut overload_count = 0 ;
151+
152+ // 一次遍历收集所有信息
160153 for member_info in member_infos {
154+ let owner_id = get_owner_type_id ( semantic_model. get_db ( ) , member_info) ;
155+ member_with_owners. push ( ( member_info, owner_id. clone ( ) ) ) ;
156+
157+ // 寻找第一个 file_decl 作为参考,如果没有则使用第一个
158+ if file_decl_member. is_none ( ) {
159+ if let Some ( feature) = member_info. feature {
160+ if feature. is_file_decl ( ) {
161+ file_decl_member = Some ( member_info) ;
162+ }
163+ }
164+ }
165+
166+ // 检查是否全为 DocFunction,同时计算重载数量
161167 match & member_info. typ {
162168 LuaType :: DocFunction ( _) => {
163- count += 1 ;
169+ overload_count += 1 ;
164170 }
165171 LuaType :: Signature ( id) => {
166- count += 1 ;
167- if let Some ( signature) = db. get_signature_index ( ) . get ( & id) {
168- count += signature. overloads . len ( ) ;
172+ all_doc_function = false ;
173+ overload_count += 1 ;
174+ if let Some ( signature) = semantic_model. get_db ( ) . get_signature_index ( ) . get ( & id) {
175+ overload_count += signature. overloads . len ( ) ;
169176 }
170177 }
171- _ => { }
178+ _ => {
179+ all_doc_function = false ;
180+ }
172181 }
173182 }
174- if count >= 1 {
175- count -= 1 ;
176- }
177- if count == 0 {
178- None
183+
184+ // 确定最终使用的参考 owner
185+ let final_reference_owner = if let Some ( file_decl_member_info) = file_decl_member {
186+ // 与第一个成员进行类型检查, 确保子类成员的类型与父类成员的类型一致
187+ if let Some ( ( first_member, first_owner) ) = member_with_owners. first ( ) {
188+ let type_check_result =
189+ semantic_model. type_check ( & file_decl_member_info. typ , & first_member. typ ) ;
190+ if type_check_result. is_ok ( ) {
191+ get_owner_type_id ( semantic_model. get_db ( ) , file_decl_member_info)
192+ } else {
193+ first_owner. clone ( )
194+ }
195+ } else {
196+ get_owner_type_id ( semantic_model. get_db ( ) , file_decl_member_info)
197+ }
198+ } else {
199+ // 没有找到 file_decl,使用第一个成员作为参考
200+ member_with_owners
201+ . first ( )
202+ . map ( |( _, owner) | owner. clone ( ) )
203+ . flatten ( )
204+ } ;
205+
206+ // 过滤出相同 owner_type_id 的成员
207+ let mut filtered_member_infos: Vec < & LuaMemberInfo > = member_with_owners
208+ . into_iter ( )
209+ . filter_map ( |( member_info, owner_id) | {
210+ if owner_id == final_reference_owner {
211+ Some ( member_info)
212+ } else {
213+ None
214+ }
215+ } )
216+ . collect ( ) ;
217+
218+ // 处理重载计数
219+ let final_overload_count = if overload_count >= 1 {
220+ let count = overload_count - 1 ;
221+ if count == 0 {
222+ None
223+ } else {
224+ Some ( count)
225+ }
179226 } else {
180- Some ( count)
227+ None
228+ } ;
229+
230+ // 如果全为 DocFunction, 只保留第一个
231+ if all_doc_function && !filtered_member_infos. is_empty ( ) {
232+ filtered_member_infos. truncate ( 1 ) ;
181233 }
234+
235+ Some ( ( filtered_member_infos, final_overload_count) )
182236}
183237
184238enum MemberResolveState {
@@ -198,3 +252,23 @@ fn get_owner_type_id(db: &DbIndex, info: &LuaMemberInfo) -> Option<LuaTypeDeclId
198252 _ => None ,
199253 }
200254}
255+
256+ fn get_resolve_state ( db : & DbIndex , member_infos : & Vec < & LuaMemberInfo > ) -> MemberResolveState {
257+ let mut resolve_state = MemberResolveState :: All ;
258+ if db. get_emmyrc ( ) . strict . meta_override_file_define {
259+ for member_info in member_infos. iter ( ) {
260+ match member_info. feature {
261+ Some ( feature) => {
262+ if feature. is_meta_decl ( ) {
263+ resolve_state = MemberResolveState :: Meta ;
264+ break ;
265+ } else if feature. is_file_decl ( ) {
266+ resolve_state = MemberResolveState :: FileDecl ;
267+ }
268+ }
269+ None => { }
270+ }
271+ }
272+ }
273+ resolve_state
274+ }
0 commit comments