1- use std:: str:: FromStr ;
1+ use std:: { collections :: HashSet , str:: FromStr } ;
22
33use emmylua_code_analysis:: {
44 LuaDeclId , LuaMemberId , LuaMemberInfo , LuaMemberKey , LuaSemanticDeclId , LuaType , LuaTypeDeclId ,
@@ -16,6 +16,7 @@ pub fn goto_def_definition(
1616 semantic_model : & SemanticModel ,
1717 property_owner : LuaSemanticDeclId ,
1818 trigger_token : & LuaSyntaxToken ,
19+ guard : & mut GotoDefGuard ,
1920) -> Option < GotoDefinitionResponse > {
2021 if let Some ( property) = semantic_model
2122 . get_db ( )
@@ -40,8 +41,16 @@ pub fn goto_def_definition(
4041 return Some ( GotoDefinitionResponse :: Scalar ( location) ) ;
4142 }
4243 LuaSemanticDeclId :: Member ( member_id) => {
43- if let Some ( property_owner) = find_member_origin_owner ( semantic_model, member_id) {
44- return goto_def_definition ( semantic_model, property_owner, trigger_token) ;
44+ if let Some ( origin_property_owner) = find_member_origin_owner ( semantic_model, member_id)
45+ {
46+ if guard. check ( & origin_property_owner) {
47+ return goto_def_definition (
48+ semantic_model,
49+ origin_property_owner,
50+ trigger_token,
51+ guard,
52+ ) ;
53+ }
4554 }
4655
4756 let member_key = semantic_model
@@ -233,3 +242,24 @@ fn get_member_location(
233242 let document = semantic_model. get_document_by_file_id ( member_id. file_id ) ?;
234243 document. to_lsp_location ( member_id. get_syntax_id ( ) . get_range ( ) )
235244}
245+
246+ #[ derive( Debug , Clone ) ]
247+ pub struct GotoDefGuard {
248+ ids : HashSet < LuaSemanticDeclId > ,
249+ }
250+
251+ impl GotoDefGuard {
252+ pub fn new ( first : LuaSemanticDeclId ) -> Self {
253+ Self {
254+ ids : HashSet :: from ( [ first] ) ,
255+ }
256+ }
257+
258+ pub fn check ( & mut self , id : & LuaSemanticDeclId ) -> bool {
259+ if self . ids . contains ( id) {
260+ return false ;
261+ }
262+ self . ids . insert ( id. clone ( ) ) ;
263+ true
264+ }
265+ }
0 commit comments