@@ -29,12 +29,15 @@ pub fn hover_function_type(
2929) {
3030 match typ {
3131 LuaType :: Function => builder. set_type_description ( format ! ( "function {}()" , func_name) ) ,
32- LuaType :: DocFunction ( lua_func) => builder. set_type_description ( hover_doc_function_type (
33- db,
34- & lua_func,
35- function_member,
36- func_name,
37- ) ) ,
32+ LuaType :: DocFunction ( lua_func) => {
33+ // 泛型时会将`Signature`转为`DocFunction`
34+ builder. set_type_description ( hover_doc_function_type (
35+ db,
36+ & lua_func,
37+ function_member,
38+ func_name,
39+ ) )
40+ }
3841 LuaType :: Signature ( signature_id) => hover_signature_type (
3942 builder,
4043 db,
@@ -50,41 +53,64 @@ pub fn hover_function_type(
5053 }
5154}
5255
53- # [ allow ( unused ) ]
56+ // 泛型时会将`Signature`转为`DocFunction`, 我们必须处理这种情况
5457fn hover_doc_function_type (
5558 db : & DbIndex ,
5659 lua_func : & LuaFunctionType ,
5760 owner_member : Option < & LuaMember > ,
5861 func_name : & str ,
5962) -> String {
60- let async_prev = if lua_func. is_async ( ) { "async " } else { "" } ;
61- let mut type_prev = "function " ;
63+ dbg ! ( & lua_func) ;
64+ let async_label = if lua_func. is_async ( ) { "async " } else { "" } ;
65+ let mut type_label = "function " ;
6266 // 有可能来源于类. 例如: `local add = class.add`, `add()`应被视为类方法
63- let full_func_name = if let Some ( owner_member) = owner_member {
67+ let full_name = if let Some ( owner_member) = owner_member {
6468 let mut name = String :: new ( ) ;
6569 let parent_owner = owner_member. get_owner ( ) ;
66- if let LuaMemberOwner :: Type ( ty) = & parent_owner {
70+ if let LuaMemberOwner :: Type ( ty) = & parent_owner. clone ( ) {
6771 name. push_str ( ty. get_simple_name ( ) ) ;
6872 if owner_member. is_field ( ) . is_some ( ) {
69- type_prev = "(field) " ;
73+ type_label = "(field) " ;
7074 }
7175 }
7276 match owner_member. get_decl_type ( ) {
7377 LuaType :: DocFunction ( func) => {
7478 if func. is_colon_define ( )
7579 || func. get_params ( ) . first ( ) . and_then ( |param| {
76- param. 1 . as_ref ( ) . map ( |ty| {
77- param . 0 == "self"
78- && humanize_type ( db , ty , RenderLevel :: Normal ) == "self"
79- } )
80+ param
81+ . 1
82+ . as_ref ( )
83+ . map ( |ty| param . 0 == "self" && ty . is_self_infer ( ) )
8084 } ) == Some ( true )
8185 {
82- type_prev = "(method) " ;
86+ type_label = "(method) " ;
8387 name. push_str ( ":" ) ;
8488 } else {
8589 name. push_str ( "." ) ;
8690 }
8791 }
92+ LuaType :: Signature ( signature_id) => {
93+ let signature = db. get_signature_index ( ) . get ( & signature_id) ;
94+ if let Some ( signature) = signature {
95+ if signature. is_colon_define
96+ || signature // @field 定义的`docfunction`会被视为`signature`, 因此这里也需要匹配以转换为`method`
97+ . get_type_params ( )
98+ . first ( )
99+ . and_then ( |param| {
100+ param
101+ . 1
102+ . as_ref ( )
103+ . map ( |ty| param. 0 == "self" && ty. is_self_infer ( ) )
104+ } )
105+ . is_some ( )
106+ {
107+ type_label = "(method) " ;
108+ name. push_str ( ":" ) ;
109+ } else {
110+ name. push_str ( "." ) ;
111+ }
112+ }
113+ }
88114 _ => { }
89115 }
90116 if let LuaMemberKey :: Name ( n) = owner_member. get_key ( ) {
@@ -104,7 +130,7 @@ fn hover_doc_function_type(
104130 if index == 0
105131 && param. 1 . is_some ( )
106132 && name == "self"
107- && humanize_type ( db , param. 1 . as_ref ( ) . unwrap ( ) , RenderLevel :: Normal ) == "self"
133+ && param. 1 . as_ref ( ) . unwrap ( ) . is_self_infer ( )
108134 {
109135 "" . to_string ( )
110136 } else if let Some ( ty) = & param. 1 {
@@ -117,34 +143,21 @@ fn hover_doc_function_type(
117143 . collect :: < Vec < _ > > ( )
118144 . join ( ", " ) ;
119145
120- let rets = lua_func. get_ret ( ) ;
121-
122- let mut result = String :: new ( ) ;
123- result. push_str ( type_prev) ;
124- result. push_str ( async_prev) ;
125- result. push_str ( & full_func_name) ;
126- result. push_str ( "(" ) ;
127- result. push_str ( params. as_str ( ) ) ;
128- result. push_str ( ")" ) ;
129-
130- if !rets. is_empty ( ) {
131- result. push_str ( " -> " ) ;
132- if rets. len ( ) > 1 {
133- result. push_str ( "(" ) ;
134- }
135- result. push_str (
136- & rets
137- . iter ( )
138- . map ( |ty| humanize_type ( db, ty, RenderLevel :: Normal ) )
139- . collect :: < Vec < _ > > ( )
140- . join ( ", " ) ,
141- ) ;
142- if rets. len ( ) > 1 {
143- result. push_str ( ")" ) ;
146+ let rets = {
147+ let rets = lua_func. get_ret ( ) ;
148+ if rets. is_empty ( ) {
149+ "" . to_string ( )
150+ } else {
151+ format ! (
152+ " -> {}" ,
153+ rets. iter( )
154+ . map( |ty| humanize_type( db, ty, RenderLevel :: Simple ) )
155+ . collect:: <Vec <_>>( )
156+ . join( ", " )
157+ )
144158 }
145- }
146-
147- result
159+ } ;
160+ format_function_type ( type_label, async_label, full_name, params, rets)
148161}
149162
150163fn hover_signature_type (
@@ -155,6 +168,7 @@ fn hover_signature_type(
155168 func_name : & str ,
156169) -> Option < ( ) > {
157170 let signature = db. get_signature_index ( ) . get ( & signature_id) ?;
171+ let call_signature = builder. get_call_signature ( ) ;
158172
159173 let mut type_label = "function " ;
160174 // 有可能来源于类. 例如: `local add = class.add`, `add()`应被视为类定义的内容
@@ -198,24 +212,20 @@ fn hover_signature_type(
198212 . collect :: < Vec < _ > > ( )
199213 . join ( ", " ) ;
200214 let rets = get_signature_rets_string ( db, signature, builder. is_completion , None ) ;
201- let mut result = String :: new ( ) ;
202- if type_label. starts_with ( "function" ) {
203- result. push_str ( async_label) ;
204- result. push_str ( type_label) ;
205- } else {
206- result. push_str ( type_label) ;
207- result. push_str ( async_label) ;
215+ let result = format_function_type ( type_label, async_label, full_name. clone ( ) , params, rets) ;
216+ // 由于 @field 定义的`docfunction`会被视为`signature`, 因此这里额外处理
217+ if let Some ( call_signature) = & call_signature {
218+ if call_signature. get_params ( ) == signature. get_type_params ( ) {
219+ // 如果具有完全匹配的签名, 那么将其设置为当前签名, 且不显示重载
220+ builder. set_type_description ( result) ;
221+ builder. signature_overload = None ;
222+ return Some ( ( ) ) ;
223+ }
208224 }
209- result. push_str ( & full_name) ;
210- result. push_str ( "(" ) ;
211- result. push_str ( params. as_str ( ) ) ;
212- result. push_str ( ")" ) ;
213- result. push_str ( rets. as_str ( ) ) ;
214225 result
215226 } ;
216227 // 构建所有重载
217228 let overloads: Vec < String > = {
218- let call_signature = builder. get_call_signature ( ) ;
219229 let mut overloads = Vec :: new ( ) ;
220230 for ( _, overload) in signature. overloads . iter ( ) . enumerate ( ) {
221231 let async_label = if overload. is_async ( ) { "async " } else { "" } ;
@@ -234,20 +244,8 @@ fn hover_signature_type(
234244 . join ( ", " ) ;
235245 let rets =
236246 get_signature_rets_string ( db, signature, builder. is_completion , Some ( overload) ) ;
237-
238- let mut result = String :: new ( ) ;
239- if type_label. starts_with ( "function" ) {
240- result. push_str ( async_label) ;
241- result. push_str ( type_label) ;
242- } else {
243- result. push_str ( type_label) ;
244- result. push_str ( async_label) ;
245- }
246- result. push_str ( & full_name) ;
247- result. push_str ( "(" ) ;
248- result. push_str ( params. as_str ( ) ) ;
249- result. push_str ( ")" ) ;
250- result. push_str ( rets. as_str ( ) ) ;
247+ let result =
248+ format_function_type ( type_label, async_label, full_name. clone ( ) , params, rets) ;
251249
252250 if let Some ( call_signature) = & call_signature {
253251 if * call_signature == * * overload {
@@ -298,13 +296,17 @@ fn get_signature_rets_string(
298296 overload_rets_string
299297 } else {
300298 let rets = & signature. return_docs ;
301- format ! (
302- " -> {}" ,
303- rets. iter( )
304- . map( |ret| humanize_type( db, & ret. type_ref, RenderLevel :: Simple ) )
305- . collect:: <Vec <_>>( )
306- . join( ", " )
307- )
299+ if rets. is_empty ( ) {
300+ "" . to_string ( )
301+ } else {
302+ format ! (
303+ " -> {}" ,
304+ rets. iter( )
305+ . map( |ret| humanize_type( db, & ret. type_ref, RenderLevel :: Simple ) )
306+ . collect:: <Vec <_>>( )
307+ . join( ", " )
308+ )
309+ }
308310 } ;
309311 result. push_str ( rets. as_str ( ) ) ;
310312 } else {
@@ -351,3 +353,18 @@ fn get_signature_rets_string(
351353 } ;
352354 result
353355}
356+
357+ fn format_function_type (
358+ type_label : & str ,
359+ async_label : & str ,
360+ full_name : String ,
361+ params : String ,
362+ rets : String ,
363+ ) -> String {
364+ let prefix = if type_label. starts_with ( "function" ) {
365+ format ! ( "{}{}" , async_label, type_label)
366+ } else {
367+ format ! ( "{}{}" , type_label, async_label)
368+ } ;
369+ format ! ( "{}{}({}){}" , prefix, full_name, params, rets)
370+ }
0 commit comments