1+ use emmylua_parser:: {
2+ LuaAstNode , LuaClosureExpr , LuaCommentOwner , LuaDocTagParam , LuaDocTagReturn , LuaStat ,
3+ LuaTableField ,
4+ } ;
15use hashbrown:: HashSet ;
26use std:: sync:: Arc ;
37
48use crate :: {
5- DbIndex , LuaOperatorMetaMethod , LuaOperatorOwner , LuaTypeDeclId , LuaUnionType ,
9+ DbIndex , LuaOperatorMetaMethod , LuaOperatorOwner , LuaSignatureId , LuaTypeDeclId , LuaUnionType ,
610 db_index:: { LuaFunctionType , LuaType } ,
711 semantic:: {
812 generic:: { TypeSubstitutor , instantiate_type_generic} ,
@@ -91,9 +95,14 @@ fn collect_callable_overload_groups_inner(
9195 let Some ( signature) = db. get_signature_index ( ) . get ( sig_id) else {
9296 return Ok ( ( ) ) ;
9397 } ;
94- // 主签名描述了函数实现本身, 当它和 overload 同时可匹配时应作为同等匹配下的优先候选.
95- let mut overloads = vec ! [ signature. to_doc_func_type( ) ] ;
96- overloads. extend ( signature. overloads . iter ( ) . cloned ( ) ) ;
98+ let main_signature = signature. to_doc_func_type ( ) ;
99+ let mut overloads = signature. overloads . clone ( ) ;
100+ // 如果存在参数/返回值签名, 那么他的优先级在同等条件下是更高的
101+ if signature_has_declared_docs ( db, sig_id) {
102+ overloads. insert ( 0 , main_signature) ;
103+ } else {
104+ overloads. push ( main_signature) ;
105+ }
97106 groups. push ( overloads) ;
98107 }
99108 LuaType :: Instance ( instance) => {
@@ -136,7 +145,9 @@ fn push_call_operator_overload_group(
136145 } ;
137146
138147 // 同一个 owner 的 call operators 作为一个 overload group, 由调用方再做参数匹配.
139- let mut overloads = Vec :: new ( ) ;
148+ let mut declared_signatures = Vec :: new ( ) ;
149+ let mut doc_functions = Vec :: new ( ) ;
150+ let mut undeclared_signatures = Vec :: new ( ) ;
140151 for operator_id in operator_ids {
141152 let Some ( operator) = db. get_operator_index ( ) . get_operator ( operator_id) else {
142153 continue ;
@@ -148,22 +159,29 @@ fn push_call_operator_overload_group(
148159 }
149160
150161 match func_type {
151- LuaType :: DocFunction ( func) => overloads . push ( func) ,
162+ LuaType :: DocFunction ( func) => doc_functions . push ( func) ,
152163 LuaType :: Signature ( signature_id) => {
153164 let Some ( signature) = db. get_signature_index ( ) . get ( & signature_id) else {
154165 continue ;
155166 } ;
156167 // 未解析返回的 signature 不能安全转换成候选, 这里先跳过.
157168 if signature. is_resolve_return ( ) {
158- overloads. push ( signature. to_call_operator_func_type ( ) ) ;
169+ let function = signature. to_call_operator_func_type ( ) ;
170+ if signature_has_declared_docs ( db, & signature_id) {
171+ declared_signatures. push ( function) ;
172+ } else {
173+ undeclared_signatures. push ( function) ;
174+ }
159175 }
160176 }
161177 _ => { }
162178 }
163179 }
164180
165- if !overloads. is_empty ( ) {
166- groups. push ( overloads) ;
181+ declared_signatures. extend ( doc_functions) ;
182+ declared_signatures. extend ( undeclared_signatures) ;
183+ if !declared_signatures. is_empty ( ) {
184+ groups. push ( declared_signatures) ;
167185 }
168186}
169187
@@ -260,3 +278,35 @@ fn call_operator_self_for_type_id(
260278 visiting_aliases. remove ( type_id) ;
261279 has_call. then ( || ty. clone ( ) )
262280}
281+
282+ fn signature_has_declared_docs ( db : & DbIndex , signature_id : & LuaSignatureId ) -> bool {
283+ let Some ( tree) = db. get_vfs ( ) . get_syntax_tree ( & signature_id. get_file_id ( ) ) else {
284+ return false ;
285+ } ;
286+ let Some ( token) = tree
287+ . get_red_root ( )
288+ . token_at_offset ( signature_id. get_position ( ) )
289+ . right_biased ( )
290+ else {
291+ return false ;
292+ } ;
293+ let Some ( closure) = token
294+ . parent_ancestors ( )
295+ . find_map ( LuaClosureExpr :: cast)
296+ . filter ( |closure| closure. get_position ( ) == signature_id. get_position ( ) )
297+ else {
298+ return false ;
299+ } ;
300+ let comments = if let Some ( table_field) = closure. get_parent :: < LuaTableField > ( ) {
301+ table_field. get_comments ( )
302+ } else if let Some ( stat) = closure. ancestors :: < LuaStat > ( ) . next ( ) {
303+ stat. get_comments ( )
304+ } else {
305+ return false ;
306+ } ;
307+
308+ comments. into_iter ( ) . any ( |comment| {
309+ comment. children :: < LuaDocTagParam > ( ) . next ( ) . is_some ( )
310+ || comment. children :: < LuaDocTagReturn > ( ) . next ( ) . is_some ( )
311+ } )
312+ }
0 commit comments