@@ -13,14 +13,13 @@ use super::{
1313use crate :: GenericParam ;
1414use crate :: compilation:: analyzer:: doc:: tags:: report_orphan_tag;
1515use crate :: {
16- LuaTypeCache , LuaTypeDeclId ,
16+ DbIndex , LuaTypeCache , LuaTypeDeclId ,
1717 compilation:: analyzer:: common:: bind_type,
1818 db_index:: {
1919 LuaDeclId , LuaGenericParamInfo , LuaMemberId , LuaSemanticDeclId , LuaSignatureId , LuaType ,
2020 } ,
2121} ;
22- use std:: sync:: Arc ;
23- use std:: vec;
22+ use std:: { collections:: HashSet , sync:: Arc , vec} ;
2423
2524pub fn analyze_class ( analyzer : & mut DocAnalyzer , tag : LuaDocTagClass ) -> Option < ( ) > {
2625 let file_id = analyzer. file_id ;
@@ -159,7 +158,10 @@ pub fn analyze_alias(analyzer: &mut DocAnalyzer, tag: LuaDocTagAlias) -> Option<
159158 . append_generic_params ( scope_id, generic_params) ;
160159 }
161160
162- let origin_type = infer_type ( analyzer, tag. get_type ( ) ?) ;
161+ let mut origin_type = infer_type ( analyzer, tag. get_type ( ) ?) ;
162+ if alias_origin_reaches ( analyzer. db , & origin_type, & alias_decl_id) {
163+ origin_type = LuaType :: Any ;
164+ }
163165
164166 let alias = analyzer
165167 . db
@@ -173,6 +175,40 @@ pub fn analyze_alias(analyzer: &mut DocAnalyzer, tag: LuaDocTagAlias) -> Option<
173175 Some ( ( ) )
174176}
175177
178+ fn alias_origin_reaches ( db : & DbIndex , origin : & LuaType , target_id : & LuaTypeDeclId ) -> bool {
179+ // Collapse only pure alias chains. Structural recursive aliases can be
180+ // meaningful, but `A = B; B = A` has no useful declaration skeleton.
181+ let mut seen_aliases = HashSet :: new ( ) ;
182+ let mut current = alias_chain_ref ( origin) ;
183+
184+ while let Some ( ref_id) = current {
185+ if & ref_id == target_id {
186+ return true ;
187+ }
188+
189+ if !seen_aliases. insert ( ref_id. clone ( ) ) {
190+ return false ;
191+ }
192+
193+ current = db
194+ . get_type_index ( )
195+ . get_type_decl ( & ref_id)
196+ . filter ( |type_decl| type_decl. is_alias ( ) )
197+ . and_then ( |type_decl| type_decl. get_alias_ref ( ) )
198+ . and_then ( alias_chain_ref) ;
199+ }
200+
201+ false
202+ }
203+
204+ fn alias_chain_ref ( typ : & LuaType ) -> Option < LuaTypeDeclId > {
205+ match typ {
206+ LuaType :: Ref ( id) => Some ( id. clone ( ) ) ,
207+ LuaType :: Generic ( generic) => Some ( generic. get_base_type_id ( ) ) ,
208+ _ => None ,
209+ }
210+ }
211+
176212/// 分析属性定义
177213pub fn analyze_attribute ( analyzer : & mut DocAnalyzer , tag : LuaDocTagAttribute ) -> Option < ( ) > {
178214 let file_id = analyzer. file_id ;
0 commit comments