11use emmylua_code_analysis:: {
22 DbIndex , GenericTpl , InferGuard , InferGuardRef , LuaAliasCallKind , LuaAliasCallType ,
3- LuaDeclLocation , LuaFunctionType , LuaMember , LuaMemberKey , LuaMemberOwner , LuaMultiLineUnion ,
4- LuaSemanticDeclId , LuaStringTplType , LuaType , LuaTypeCache , LuaTypeDeclId , LuaUnionType ,
5- RenderLevel , SemanticDeclLevel , TypeSubstitutor , build_call_constraint_context, get_real_type,
6- instantiate_type_generic, normalize_constraint_type,
3+ LuaDeclLocation , LuaFunctionType , LuaMemberKey , LuaMemberOwner , LuaMultiLineUnion ,
4+ LuaStringTplType , LuaType , LuaTypeCache , LuaTypeDeclId , LuaUnionType , RenderLevel ,
5+ filter_callable_overloads, get_real_type, normalize_constraint_type,
76} ;
87use emmylua_parser:: {
98 LuaAssignStat , LuaAst , LuaAstNode , LuaAstToken , LuaCallArgList , LuaCallExpr , LuaClosureExpr ,
@@ -12,7 +11,6 @@ use emmylua_parser::{
1211} ;
1312use itertools:: Itertools ;
1413use lsp_types:: { CompletionItem , Documentation } ;
15- use std:: sync:: Arc ;
1614
1715use crate :: handlers:: {
1816 completion:: {
@@ -325,236 +323,66 @@ fn infer_call_arg_list(
325323 token : LuaSyntaxToken ,
326324) -> Option < Vec < LuaType > > {
327325 let call_expr = call_arg_list. get_parent :: < LuaCallExpr > ( ) ?;
328- let mut param_idx = get_current_param_index ( & call_expr, & token) ?;
329- let call_expr_func = builder
330- . semantic_model
331- . infer_call_expr_func ( call_expr. clone ( ) , Some ( param_idx + 1 ) ) ?;
332- let colon_call = call_expr. is_colon_call ( ) ;
333- let colon_define = call_expr_func. is_colon_define ( ) ;
334- match ( colon_call, colon_define) {
335- ( true , true ) | ( false , false ) | ( false , true ) => { }
336- ( true , false ) => {
337- param_idx += 1 ;
338- }
339- }
340- let constraint_substitutor = build_call_constraint_context ( & builder. semantic_model , & call_expr)
341- . map ( |ctx| ctx. substitutor ) ;
342- let substitutor = constraint_substitutor. as_ref ( ) ;
343- let typ = call_expr_func
344- . get_params ( )
345- . get ( param_idx) ?
346- . 1
347- . clone ( )
348- . unwrap_or ( LuaType :: Unknown ) ;
349- let typ = resolve_param_type ( builder, typ, substitutor) ;
350- let mut types = Vec :: new ( ) ;
351- types. push ( typ) ;
352- push_function_overloads_param (
353- builder,
354- & call_expr,
355- call_expr_func. get_params ( ) ,
356- param_idx,
357- substitutor,
358- & mut types,
359- ) ;
360- Some ( types. into_iter ( ) . unique ( ) . collect ( ) ) // 需要去重
361- }
362-
363- fn resolve_param_type (
364- builder : & CompletionBuilder ,
365- mut typ : LuaType ,
366- substitutor : Option < & TypeSubstitutor > ,
367- ) -> LuaType {
368- let db = builder. semantic_model . get_db ( ) ;
369- if let Some ( substitutor) = substitutor {
370- typ = apply_substitutor_to_type ( db, typ, substitutor) ;
371- }
372- normalize_constraint_type ( db, typ)
373- }
374-
375- fn apply_substitutor_to_type ( db : & DbIndex , typ : LuaType , substitutor : & TypeSubstitutor ) -> LuaType {
376- if let LuaType :: Call ( alias_call) = & typ {
377- if alias_call. get_call_kind ( ) == LuaAliasCallKind :: KeyOf {
378- let operands = alias_call
379- . get_operands ( )
380- . iter ( )
381- . map ( |operand| instantiate_type_generic ( db, operand, substitutor) )
382- . collect :: < Vec < _ > > ( ) ;
383- return LuaType :: Call ( Arc :: new ( LuaAliasCallType :: new (
384- alias_call. get_call_kind ( ) ,
385- operands,
386- ) ) ) ;
387- }
388- }
389- if let Some ( alias_call) = rebuild_keyof_alias_call ( db, & typ, substitutor) {
390- return alias_call;
391- }
392- instantiate_type_generic ( db, & typ, substitutor)
393- }
394-
395- fn rebuild_keyof_alias_call (
396- db : & DbIndex ,
397- original_type : & LuaType ,
398- substitutor : & TypeSubstitutor ,
399- ) -> Option < LuaType > {
400- let tpl = match original_type {
401- LuaType :: TplRef ( tpl) => tpl,
402- _ => return None ,
403- } ;
404- let constraint = tpl. get_constraint ( ) ?;
405- let LuaType :: Call ( alias_call) = constraint else {
406- return None ;
407- } ;
408- if alias_call. get_call_kind ( ) != LuaAliasCallKind :: KeyOf {
409- return None ;
410- }
411-
412- let operands = alias_call
413- . get_operands ( )
414- . iter ( )
415- . map ( |operand| instantiate_type_generic ( db, operand, substitutor) )
416- . collect :: < Vec < _ > > ( ) ;
417- Some ( LuaType :: Call ( Arc :: new ( LuaAliasCallType :: new (
418- alias_call. get_call_kind ( ) ,
419- operands,
420- ) ) ) )
421- }
422-
423- fn push_function_overloads_param (
424- builder : & mut CompletionBuilder ,
425- call_expr : & LuaCallExpr ,
426- call_params : & [ ( String , Option < LuaType > ) ] ,
427- param_idx : usize ,
428- substitutor : Option < & TypeSubstitutor > ,
429- types : & mut Vec < LuaType > ,
430- ) -> Option < ( ) > {
431- let member_index = builder. semantic_model . get_db ( ) . get_member_index ( ) ;
326+ let param_idx = get_current_param_index ( & call_expr, & token) ?;
432327 let prefix_expr = call_expr. get_prefix_expr ( ) ?;
433- let semantic_decl = builder. semantic_model . find_decl (
434- prefix_expr. syntax ( ) . clone ( ) . into ( ) ,
435- SemanticDeclLevel :: default ( ) ,
436- ) ?;
437-
438- // 收集函数类型
439- let functions = match semantic_decl {
440- LuaSemanticDeclId :: Member ( member_id) => {
441- let member = member_index. get_member ( & member_id) ?;
442- let key = member. get_key ( ) . to_path ( ) ;
443- let owner = member_index. get_current_owner ( & member_id) ?;
444- let members = member_index. get_members ( owner) ?;
445- let functions = filter_function_members ( builder. semantic_model . get_db ( ) , members, key) ;
446- Some ( functions)
447- }
448- LuaSemanticDeclId :: LuaDecl ( decl_id) => {
449- let decl = builder
450- . semantic_model
451- . get_db ( )
452- . get_decl_index ( )
453- . get_decl ( & decl_id) ?;
328+ let prefix_type = builder. semantic_model . infer_expr ( prefix_expr) . ok ( ) ?;
329+ let call_arg_types = infer_call_arg_types ( builder, & call_expr, Some ( param_idx) ) ?;
330+ let call_expr_funcs = filter_callable_overloads (
331+ builder. semantic_model . get_db ( ) ,
332+ & mut builder. semantic_model . get_cache ( ) . borrow_mut ( ) ,
333+ & prefix_type,
334+ & call_arg_types,
335+ & call_expr,
336+ Some ( param_idx) ,
337+ true ,
338+ )
339+ . ok ( ) ?;
454340
455- let typ = builder
456- . semantic_model
457- . get_db ( )
458- . get_type_index ( )
459- . get_type_cache ( & decl_id. into ( ) )
460- . map ( |cache| cache. as_type ( ) . clone ( ) )
461- . unwrap_or ( LuaType :: Unknown ) ;
462- match typ {
463- LuaType :: Signature ( _) | LuaType :: DocFunction ( _) => Some ( vec ! [ typ. clone( ) ] ) ,
464- _ => {
465- let key = decl. get_name ( ) ;
466- let type_id = LuaTypeDeclId :: global ( decl. get_name ( ) ) ;
467- let members = member_index. get_members ( & LuaMemberOwner :: Type ( type_id) ) ?;
468- let functions = filter_function_members (
469- builder. semantic_model . get_db ( ) ,
470- members,
471- key. to_string ( ) ,
472- ) ;
473- Some ( functions)
474- }
475- }
476- }
477- _ => None ,
478- } ?;
479-
480- // 获取重载函数列表
481- let signature_index = builder. semantic_model . get_db ( ) . get_signature_index ( ) ;
482- let mut overloads = Vec :: new ( ) ;
483- for function in functions {
484- match function {
485- LuaType :: Signature ( signature_id) => {
486- if let Some ( signature) = signature_index. get ( & signature_id) {
487- overloads. extend ( signature. overloads . iter ( ) . cloned ( ) ) ;
488- }
489- }
490- LuaType :: DocFunction ( doc_function) => {
491- overloads. push ( doc_function) ;
341+ let mut types = Vec :: new ( ) ;
342+ for call_expr_func in call_expr_funcs {
343+ let mut param_idx = param_idx;
344+ let colon_call = call_expr. is_colon_call ( ) ;
345+ let colon_define = call_expr_func. is_colon_define ( ) ;
346+ match ( colon_call, colon_define) {
347+ ( true , true ) | ( false , false ) | ( false , true ) => { }
348+ ( true , false ) => {
349+ param_idx += 1 ;
492350 }
493- _ => { }
494351 }
495- }
496-
497- // 筛选匹配的参数类型并添加到结果中
498- for overload in overloads. iter ( ) {
499- let overload_params = overload. get_params ( ) ;
500-
501- // 检查前面的参数是否匹配
502- if !params_match_prefix ( call_params, overload_params, param_idx) {
503- continue ;
504- }
505-
506- // 添加匹配的参数类型
507- if let Some ( param_type) = overload_params. get ( param_idx) . and_then ( |p| p. 1 . clone ( ) ) {
508- let param_type = resolve_param_type ( builder, param_type, substitutor) ;
509- types. push ( param_type) ;
510- }
511- }
512352
513- /// 过滤出函数类型的成员
514- fn filter_function_members (
515- db : & DbIndex ,
516- members : Vec < & LuaMember > ,
517- key : String ,
518- ) -> Vec < LuaType > {
519- let mut result_members = vec ! [ ] ;
520- for member in members {
521- if member. get_key ( ) . to_path ( ) == key {
522- let member_type = db
523- . get_type_index ( )
524- . get_type_cache ( & member. get_id ( ) . into ( ) )
525- . unwrap_or ( & LuaTypeCache :: InferType ( LuaType :: Unknown ) ) ;
526- if let LuaType :: Signature ( _) | LuaType :: DocFunction ( _) = member_type. as_type ( ) {
527- result_members. push ( member_type. as_type ( ) . clone ( ) ) ;
528- }
529- }
353+ if let Some ( typ) = call_expr_func
354+ . get_params ( )
355+ . get ( param_idx)
356+ . and_then ( |param| param. 1 . clone ( ) )
357+ {
358+ types. push ( normalize_constraint_type (
359+ builder. semantic_model . get_db ( ) ,
360+ typ,
361+ ) ) ;
530362 }
531-
532- result_members
533363 }
534364
535- /// 判断前面的参数是否匹配
536- fn params_match_prefix (
537- call_params : & [ ( String , Option < LuaType > ) ] ,
538- overload_params : & [ ( String , Option < LuaType > ) ] ,
539- param_idx : usize ,
540- ) -> bool {
541- if param_idx == 0 {
542- return true ;
543- }
544-
545- for i in 0 ..param_idx {
546- if let ( Some ( call_param) , Some ( overload_param) ) =
547- ( call_params. get ( i) , overload_params. get ( i) )
548- && call_param. 1 != overload_param. 1
549- {
550- return false ;
551- }
552- }
553-
554- true
365+ if types. is_empty ( ) {
366+ None
367+ } else {
368+ Some ( types. into_iter ( ) . unique ( ) . collect ( ) )
555369 }
370+ }
556371
557- Some ( ( ) )
372+ fn infer_call_arg_types (
373+ builder : & CompletionBuilder ,
374+ call_expr : & LuaCallExpr ,
375+ arg_count : Option < usize > ,
376+ ) -> Option < Vec < LuaType > > {
377+ let args = call_expr. get_args_list ( ) ?. get_args ( ) . collect :: < Vec < _ > > ( ) ;
378+ Some (
379+ builder
380+ . semantic_model
381+ . infer_expr_list_types ( & args, arg_count)
382+ . into_iter ( )
383+ . map ( |( typ, _) | typ)
384+ . collect ( ) ,
385+ )
558386}
559387
560388fn add_multi_line_union_member_completion (
0 commit comments