@@ -10,7 +10,7 @@ use rowan::TextRange;
1010use smol_str:: SmolStr ;
1111
1212use crate :: {
13- db_index:: { LuaMemberKey , LuaSignatureId } ,
13+ db_index:: { r#type :: type_visit_trait :: TypeVisitTrait , LuaMemberKey , LuaSignatureId } ,
1414 DbIndex , InFiled , SemanticModel ,
1515} ;
1616
@@ -450,12 +450,50 @@ impl LuaType {
450450 }
451451}
452452
453+ impl TypeVisitTrait for LuaType {
454+ fn visit_type < F > ( & self , f : & mut F )
455+ where
456+ F : FnMut ( & LuaType ) ,
457+ {
458+ f ( self ) ;
459+ match self {
460+ LuaType :: Array ( base) => base. visit_type ( f) ,
461+ LuaType :: Tuple ( base) => base. visit_type ( f) ,
462+ LuaType :: DocFunction ( base) => base. visit_type ( f) ,
463+ LuaType :: Object ( base) => base. visit_type ( f) ,
464+ LuaType :: Union ( base) => base. visit_type ( f) ,
465+ LuaType :: Intersection ( base) => base. visit_type ( f) ,
466+ LuaType :: Generic ( base) => base. visit_type ( f) ,
467+ LuaType :: Variadic ( multi) => multi. visit_type ( f) ,
468+ LuaType :: TableGeneric ( params) => {
469+ for param in params. iter ( ) {
470+ param. visit_type ( f) ;
471+ }
472+ }
473+ LuaType :: MultiLineUnion ( inner) => inner. visit_type ( f) ,
474+ LuaType :: TypeGuard ( inner) => inner. visit_type ( f) ,
475+ _ => { }
476+ }
477+ }
478+ }
479+
453480#[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
454481pub struct LuaTupleType {
455482 types : Vec < LuaType > ,
456483 pub status : LuaTupleStatus ,
457484}
458485
486+ impl TypeVisitTrait for LuaTupleType {
487+ fn visit_type < F > ( & self , f : & mut F )
488+ where
489+ F : FnMut ( & LuaType ) ,
490+ {
491+ for ty in & self . types {
492+ ty. visit_type ( f) ;
493+ }
494+ }
495+ }
496+
459497#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
460498pub enum LuaTupleStatus {
461499 DocResolve ,
@@ -538,6 +576,20 @@ pub struct LuaFunctionType {
538576 ret : LuaType ,
539577}
540578
579+ impl TypeVisitTrait for LuaFunctionType {
580+ fn visit_type < F > ( & self , f : & mut F )
581+ where
582+ F : FnMut ( & LuaType ) ,
583+ {
584+ for ( _, t) in & self . params {
585+ if let Some ( t) = t {
586+ t. visit_type ( f) ;
587+ }
588+ }
589+ self . ret . visit_type ( f) ;
590+ }
591+ }
592+
541593impl LuaFunctionType {
542594 pub fn new (
543595 is_async : bool ,
@@ -628,6 +680,18 @@ impl LuaFunctionType {
628680 false
629681 }
630682 }
683+
684+ pub fn collect_generic_tpls ( & self , tpls : & mut HashSet < GenericTplId > ) {
685+ self . visit_type ( & mut |t| match t {
686+ LuaType :: TplRef ( generic_tpl) | LuaType :: ConstTplRef ( generic_tpl) => {
687+ tpls. insert ( generic_tpl. get_tpl_id ( ) ) ;
688+ }
689+ LuaType :: StrTplRef ( str_tpl) => {
690+ tpls. insert ( str_tpl. get_tpl_id ( ) ) ;
691+ }
692+ _ => { }
693+ } ) ;
694+ }
631695}
632696
633697impl From < LuaFunctionType > for LuaType {
@@ -649,6 +713,21 @@ pub struct LuaObjectType {
649713 index_access : Vec < ( LuaType , LuaType ) > ,
650714}
651715
716+ impl TypeVisitTrait for LuaObjectType {
717+ fn visit_type < F > ( & self , f : & mut F )
718+ where
719+ F : FnMut ( & LuaType ) ,
720+ {
721+ for t in self . fields . values ( ) {
722+ t. visit_type ( f) ;
723+ }
724+ for ( key, value_type) in & self . index_access {
725+ key. visit_type ( f) ;
726+ value_type. visit_type ( f) ;
727+ }
728+ }
729+ }
730+
652731impl LuaObjectType {
653732 pub fn new ( object_fields : Vec < ( LuaIndexAccessKey , LuaType ) > ) -> Self {
654733 let mut fields = HashMap :: new ( ) ;
@@ -757,6 +836,22 @@ pub enum LuaUnionType {
757836 Multi ( Vec < LuaType > ) ,
758837}
759838
839+ impl TypeVisitTrait for LuaUnionType {
840+ fn visit_type < F > ( & self , f : & mut F )
841+ where
842+ F : FnMut ( & LuaType ) ,
843+ {
844+ match self {
845+ LuaUnionType :: Nullable ( ty) => ty. visit_type ( f) ,
846+ LuaUnionType :: Multi ( types) => {
847+ for ty in types {
848+ ty. visit_type ( f) ;
849+ }
850+ }
851+ }
852+ }
853+ }
854+
760855impl LuaUnionType {
761856 pub fn from_set ( mut set : HashSet < LuaType > ) -> Self {
762857 if set. len ( ) == 2 && set. contains ( & LuaType :: Nil ) {
@@ -872,6 +967,17 @@ pub struct LuaIntersectionType {
872967 types : Vec < LuaType > ,
873968}
874969
970+ impl TypeVisitTrait for LuaIntersectionType {
971+ fn visit_type < F > ( & self , f : & mut F )
972+ where
973+ F : FnMut ( & LuaType ) ,
974+ {
975+ for ty in & self . types {
976+ ty. visit_type ( f) ;
977+ }
978+ }
979+ }
980+
875981impl LuaIntersectionType {
876982 pub fn new ( types : Vec < LuaType > ) -> Self {
877983 Self { types }
@@ -914,6 +1020,17 @@ pub struct LuaAliasCallType {
9141020 operand : Vec < LuaType > ,
9151021}
9161022
1023+ impl TypeVisitTrait for LuaAliasCallType {
1024+ fn visit_type < F > ( & self , f : & mut F )
1025+ where
1026+ F : FnMut ( & LuaType ) ,
1027+ {
1028+ for t in & self . operand {
1029+ t. visit_type ( f) ;
1030+ }
1031+ }
1032+ }
1033+
9171034impl LuaAliasCallType {
9181035 pub fn new ( call_kind : LuaAliasCallKind , operand : Vec < LuaType > ) -> Self {
9191036 Self { call_kind, operand }
@@ -938,6 +1055,17 @@ pub struct LuaGenericType {
9381055 params : Vec < LuaType > ,
9391056}
9401057
1058+ impl TypeVisitTrait for LuaGenericType {
1059+ fn visit_type < F > ( & self , f : & mut F )
1060+ where
1061+ F : FnMut ( & LuaType ) ,
1062+ {
1063+ for param in & self . params {
1064+ param. visit_type ( f) ;
1065+ }
1066+ }
1067+ }
1068+
9411069impl LuaGenericType {
9421070 pub fn new ( base : LuaTypeDeclId , params : Vec < LuaType > ) -> Self {
9431071 Self { base, params }
@@ -976,6 +1104,22 @@ pub enum VariadicType {
9761104 Base ( LuaType ) ,
9771105}
9781106
1107+ impl TypeVisitTrait for VariadicType {
1108+ fn visit_type < F > ( & self , f : & mut F )
1109+ where
1110+ F : FnMut ( & LuaType ) ,
1111+ {
1112+ match self {
1113+ VariadicType :: Multi ( types) => {
1114+ for ty in types {
1115+ ty. visit_type ( f) ;
1116+ }
1117+ }
1118+ VariadicType :: Base ( t) => t. visit_type ( f) ,
1119+ }
1120+ }
1121+ }
1122+
9791123impl VariadicType {
9801124 pub fn get_type ( & self , idx : usize ) -> Option < & LuaType > {
9811125 match self {
@@ -1105,6 +1249,15 @@ pub struct LuaInstanceType {
11051249 range : InFiled < TextRange > ,
11061250}
11071251
1252+ impl TypeVisitTrait for LuaInstanceType {
1253+ fn visit_type < F > ( & self , f : & mut F )
1254+ where
1255+ F : FnMut ( & LuaType ) ,
1256+ {
1257+ self . base . visit_type ( f) ;
1258+ }
1259+ }
1260+
11081261impl LuaInstanceType {
11091262 pub fn new ( base : LuaType , range : InFiled < TextRange > ) -> Self {
11101263 Self { base, range }
@@ -1202,6 +1355,17 @@ pub struct LuaMultiLineUnion {
12021355 unions : Vec < ( LuaType , Option < String > ) > ,
12031356}
12041357
1358+ impl TypeVisitTrait for LuaMultiLineUnion {
1359+ fn visit_type < F > ( & self , f : & mut F )
1360+ where
1361+ F : FnMut ( & LuaType ) ,
1362+ {
1363+ for ( t, _) in & self . unions {
1364+ t. visit_type ( f) ;
1365+ }
1366+ }
1367+ }
1368+
12051369impl LuaMultiLineUnion {
12061370 pub fn new ( unions : Vec < ( LuaType , Option < String > ) > ) -> Self {
12071371 Self { unions }
@@ -1231,6 +1395,15 @@ pub struct LuaArrayType {
12311395 len : LuaArrayLen ,
12321396}
12331397
1398+ impl TypeVisitTrait for LuaArrayType {
1399+ fn visit_type < F > ( & self , f : & mut F )
1400+ where
1401+ F : FnMut ( & LuaType ) ,
1402+ {
1403+ self . base . visit_type ( f) ;
1404+ }
1405+ }
1406+
12341407#[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
12351408pub enum LuaArrayLen {
12361409 None ,
0 commit comments