1- use emmylua_parser:: { LuaAstNode , LuaExpr , LuaVarExpr } ;
1+ use emmylua_parser:: { LuaAstNode , LuaTableExpr , LuaVarExpr } ;
22
33use crate :: {
4- infer_call_expr_func, infer_expr, infer_table_field_value_should_be, DbIndex , InferFailReason ,
5- InferGuard , LuaDocParamInfo , LuaDocReturnInfo , LuaInferCache , LuaType , SignatureReturnStatus ,
4+ infer_call_expr_func, infer_expr, infer_member_map, infer_table_should_be, DbIndex ,
5+ InferFailReason , InferGuard , LuaDocParamInfo , LuaDocReturnInfo , LuaFunctionType , LuaInferCache ,
6+ LuaMemberInfo , LuaSemanticDeclId , LuaSignatureId , LuaType , LuaTypeDeclId ,
7+ SignatureReturnStatus ,
68} ;
79
810use super :: {
@@ -177,19 +179,28 @@ pub fn try_resolve_closure_parent_params(
177179 if !signature. param_docs . is_empty ( ) {
178180 return Some ( true ) ;
179181 }
180-
182+ let self_type ;
181183 let member_type = match & closure_params. parent_ast {
182184 UnResolveParentAst :: LuaFuncStat ( func_stat) => {
183185 let func_name = func_stat. get_func_name ( ) ?;
184186 match func_name {
185187 LuaVarExpr :: IndexExpr ( index_expr) => {
186- infer_expr ( db, cache, LuaExpr :: IndexExpr ( index_expr) ) . ok ( ) ?
188+ let typ = infer_expr ( db, cache, index_expr. get_prefix_expr ( ) ?) . ok ( ) ?;
189+ self_type = Some ( typ. clone ( ) ) ;
190+
191+ find_best_function_type ( db, cache, & typ, & closure_params. signature_id )
187192 }
188- LuaVarExpr :: NameExpr ( _ ) => return Some ( true ) ,
193+ _ => return Some ( true ) ,
189194 }
190195 }
191196 UnResolveParentAst :: LuaTableField ( table_field) => {
192- infer_table_field_value_should_be ( db, cache, table_field. clone ( ) ) . ok ( ) ?
197+ let parnet_table_expr = table_field
198+ . get_parent :: < LuaTableExpr > ( )
199+ . ok_or ( InferFailReason :: None )
200+ . ok ( ) ?;
201+ let typ = infer_table_should_be ( db, cache, parnet_table_expr) . ok ( ) ?;
202+ self_type = Some ( typ. clone ( ) ) ;
203+ find_best_function_type ( db, cache, & typ, & closure_params. signature_id )
193204 }
194205 UnResolveParentAst :: LuaAssignStat ( assign) => {
195206 let ( vars, exprs) = assign. get_var_and_expr_list ( ) ;
@@ -198,20 +209,53 @@ pub fn try_resolve_closure_parent_params(
198209 . iter ( )
199210 . position ( |expr| expr. get_position ( ) == position) ?;
200211 let var = vars. get ( idx) ?;
201-
202212 match var {
203213 LuaVarExpr :: IndexExpr ( index_expr) => {
204- infer_expr ( db, cache, LuaExpr :: IndexExpr ( index_expr. clone ( ) ) ) . ok ( ) ?
214+ let typ = infer_expr ( db, cache, index_expr. get_prefix_expr ( ) ?) . ok ( ) ?;
215+ self_type = Some ( typ. clone ( ) ) ;
216+ find_best_function_type ( db, cache, & typ, & closure_params. signature_id )
205217 }
206- LuaVarExpr :: NameExpr ( _ ) => return Some ( true ) ,
218+ _ => return Some ( true ) ,
207219 }
208220 }
209221 } ;
210222
211- let LuaType :: DocFunction ( doc_func ) = member_type else {
223+ let Some ( member_type ) = member_type else {
212224 return Some ( true ) ;
213225 } ;
214226
227+ match & member_type {
228+ LuaType :: DocFunction ( doc_func) => {
229+ resolve_doc_function ( db, closure_params, doc_func, self_type)
230+ }
231+ LuaType :: Signature ( id) => {
232+ if id == & closure_params. signature_id {
233+ return Some ( true ) ;
234+ }
235+ let signature = db. get_signature_index ( ) . get ( id) ;
236+
237+ if let Some ( signature) = signature {
238+ let fake_doc_function = LuaFunctionType :: new (
239+ signature. is_async ,
240+ signature. is_colon_define ,
241+ signature. get_type_params ( ) ,
242+ signature. get_return_types ( ) ,
243+ ) ;
244+ resolve_doc_function ( db, closure_params, & fake_doc_function, self_type)
245+ } else {
246+ Some ( true )
247+ }
248+ }
249+ _ => Some ( true ) ,
250+ }
251+ }
252+
253+ fn resolve_doc_function (
254+ db : & mut DbIndex ,
255+ closure_params : & UnResolveParentClosureParams ,
256+ doc_func : & LuaFunctionType ,
257+ self_type : Option < LuaType > ,
258+ ) -> Option < bool > {
215259 let signature = db
216260 . get_signature_index_mut ( )
217261 . get_mut ( & closure_params. signature_id ) ?;
@@ -220,17 +264,30 @@ pub fn try_resolve_closure_parent_params(
220264 signature. is_async = true ;
221265 }
222266
223- let colon_define = signature. is_colon_define ;
224- let mut params = doc_func. get_params ( ) ;
225- if colon_define {
226- if params. len ( ) > 1 {
227- params = & params[ 1 ..] ;
228- } else {
229- params = & [ ] ;
267+ let mut doc_params = doc_func. get_params ( ) . to_vec ( ) ;
268+ // doc_func 是往上追溯的有效签名, signature 是未解析的签名
269+ match ( doc_func. is_colon_define ( ) , signature. is_colon_define ) {
270+ ( true , true ) | ( false , false ) => { }
271+ ( true , false ) => {
272+ // 原始签名是冒号定义, 但未解析的签名不是冒号定义, 即要插入第一个参数
273+ doc_params. insert ( 0 , ( "self" . to_string ( ) , Some ( LuaType :: SelfInfer ) ) ) ;
274+ }
275+ ( false , true ) => {
276+ // 原始签名不是冒号定义, 但未解析的签名是冒号定义, 即要删除第一个参数
277+ doc_params. remove ( 0 ) ;
278+ }
279+ }
280+ // 如果第一个参数是 self, 则需要将 self 的类型设置为 self_type
281+ if doc_params. get ( 0 ) . map_or ( false , |( _, typ) | match typ {
282+ Some ( LuaType :: SelfInfer ) => true ,
283+ _ => false ,
284+ } ) {
285+ if let Some ( self_type) = self_type {
286+ doc_params[ 0 ] . 1 = Some ( self_type) ;
230287 }
231288 }
232289
233- for ( index, param) in params . iter ( ) . enumerate ( ) {
290+ for ( index, param) in doc_params . iter ( ) . enumerate ( ) {
234291 let name = signature. params . get ( index) . unwrap_or ( & param. 0 ) ;
235292 signature. param_docs . insert (
236293 index,
@@ -259,3 +316,94 @@ pub fn try_resolve_closure_parent_params(
259316
260317 Some ( true )
261318}
319+
320+ fn get_owner_type_id ( db : & DbIndex , info : & LuaMemberInfo ) -> Option < LuaTypeDeclId > {
321+ match & info. property_owner_id {
322+ Some ( LuaSemanticDeclId :: Member ( member_id) ) => {
323+ if let Some ( owner) = db. get_member_index ( ) . get_current_owner ( member_id) {
324+ return owner. get_type_id ( ) . cloned ( ) ;
325+ }
326+ None
327+ }
328+ _ => None ,
329+ }
330+ }
331+
332+ fn find_best_function_type (
333+ db : & DbIndex ,
334+ cache : & mut LuaInferCache ,
335+ prefix_type : & LuaType ,
336+ signature_id : & LuaSignatureId ,
337+ ) -> Option < LuaType > {
338+ let member_info_map = infer_member_map ( db, & prefix_type) ?;
339+ let mut current_type_id = None ;
340+ // 如果找不到证明是重定义
341+ let target_infos = member_info_map. into_values ( ) . find ( |infos| {
342+ infos. iter ( ) . any ( |info| match & info. typ {
343+ LuaType :: Signature ( id) => {
344+ if id == signature_id {
345+ current_type_id = get_owner_type_id ( db, info) ;
346+ return true ;
347+ }
348+ false
349+ }
350+ _ => false ,
351+ } )
352+ } ) ?;
353+ // 找到第一个具有实际参数类型的签名
354+ target_infos. iter ( ) . find_map ( |info| {
355+ // 所有者类型一致, 但我们找的是父类型
356+ if get_owner_type_id ( db, info) == current_type_id {
357+ return None ;
358+ }
359+ let function_type =
360+ get_final_function_type ( db, cache, & info. typ ) . unwrap_or ( info. typ . clone ( ) ) ;
361+ let param_type_len = match & function_type {
362+ LuaType :: Signature ( id) => db
363+ . get_signature_index ( )
364+ . get ( & id)
365+ . map ( |sig| sig. param_docs . len ( ) )
366+ . unwrap_or ( 0 ) ,
367+ LuaType :: DocFunction ( doc_func) => doc_func
368+ . get_params ( )
369+ . iter ( )
370+ . filter ( |( _, typ) | typ. is_some ( ) )
371+ . count ( ) ,
372+ _ => 0 , // 跳过其他类型
373+ } ;
374+ if param_type_len > 0 {
375+ return Some ( function_type. clone ( ) ) ;
376+ }
377+ None
378+ } )
379+ }
380+
381+ fn get_final_function_type (
382+ db : & DbIndex ,
383+ cache : & mut LuaInferCache ,
384+ origin : & LuaType ,
385+ ) -> Option < LuaType > {
386+ match origin {
387+ LuaType :: Signature ( _) => Some ( origin. clone ( ) ) ,
388+ LuaType :: DocFunction ( _) => Some ( origin. clone ( ) ) ,
389+ LuaType :: Ref ( decl_id) => {
390+ let decl = db. get_type_index ( ) . get_type_decl ( decl_id) ?;
391+ if decl. is_alias ( ) {
392+ let origin_type = decl. get_alias_origin ( db, None ) ?;
393+ get_final_function_type ( db, cache, & origin_type)
394+ } else {
395+ Some ( origin. clone ( ) )
396+ }
397+ }
398+ LuaType :: Union ( union_types) => {
399+ for typ in union_types. get_types ( ) {
400+ let final_type = get_final_function_type ( db, cache, typ) ;
401+ if final_type. is_some ( ) {
402+ return final_type;
403+ }
404+ }
405+ None
406+ }
407+ _ => None ,
408+ }
409+ }
0 commit comments