1- use std:: ops:: Deref ;
1+ use std:: { ops:: Deref , sync :: Arc } ;
22
33use emmylua_parser:: { LuaAstNode , LuaCallExpr , LuaExpr } ;
4+ use internment:: ArcIntern ;
5+ use smol_str:: SmolStr ;
46
57use crate :: {
68 db_index:: { DbIndex , LuaType } ,
79 semantic:: { infer:: InferFailReason , infer_expr, LuaInferCache } ,
8- LuaFunctionType ,
10+ GenericTpl , GenericTplId , LuaFunctionType , LuaGenericType ,
911} ;
1012
1113use super :: {
@@ -54,7 +56,9 @@ pub fn instantiate_func_generic(
5456 ) ?;
5557
5658 if func. contain_self ( ) {
57- infer_self_type ( db, cache, & call_expr, & mut substitutor) ?;
59+ if let Some ( self_type) = infer_self_type ( db, cache, & call_expr) {
60+ substitutor. add_self_type ( self_type) ;
61+ }
5862 }
5963
6064 if let LuaType :: DocFunction ( f) = instantiate_doc_function ( db, func, & substitutor) {
@@ -79,22 +83,46 @@ fn collect_arg_types(
7983 Ok ( arg_types)
8084}
8185
82- fn infer_self_type (
86+ pub fn build_self_type ( db : & DbIndex , self_type : & LuaType ) -> LuaType {
87+ match self_type {
88+ LuaType :: Def ( id) | LuaType :: Ref ( id) => {
89+ if let Some ( generic) = db. get_type_index ( ) . get_generic_params ( id) {
90+ let mut params = Vec :: new ( ) ;
91+ for ( i, ty) in generic. iter ( ) . enumerate ( ) {
92+ if let Some ( t) = & ty. 1 {
93+ params. push ( t. clone ( ) ) ;
94+ } else {
95+ params. push ( LuaType :: TplRef ( Arc :: new ( GenericTpl :: new (
96+ GenericTplId :: Type ( i as u32 ) ,
97+ ArcIntern :: new ( SmolStr :: from ( ty. 0 . clone ( ) ) ) ,
98+ ) ) ) ) ;
99+ }
100+ }
101+ let generic = LuaGenericType :: new ( id. clone ( ) , params) ;
102+ return LuaType :: Generic ( Arc :: new ( generic) ) ;
103+ }
104+ }
105+ _ => { }
106+ } ;
107+ self_type. clone ( )
108+ }
109+
110+ pub fn infer_self_type (
83111 db : & DbIndex ,
84112 cache : & mut LuaInferCache ,
85113 call_expr : & LuaCallExpr ,
86- substitutor : & mut TypeSubstitutor ,
87- ) -> Result < ( ) , InferFailReason > {
114+ ) -> Option < LuaType > {
88115 let prefix_expr = call_expr. get_prefix_expr ( ) ;
89116 if let Some ( prefix_expr) = prefix_expr {
90117 if let LuaExpr :: IndexExpr ( index) = prefix_expr {
91118 let self_expr = index. get_prefix_expr ( ) ;
92119 if let Some ( self_expr) = self_expr {
93- let self_type = infer_expr ( db, cache, self_expr. into ( ) ) ?;
94- substitutor. add_self_type ( self_type) ;
120+ let self_type = infer_expr ( db, cache, self_expr. into ( ) ) . ok ( ) ?;
121+ let self_type = build_self_type ( db, & self_type) ;
122+ return Some ( self_type) ;
95123 }
96124 }
97125 }
98126
99- Ok ( ( ) )
127+ None
100128}
0 commit comments