1- use std:: { collections :: HashSet , str:: FromStr } ;
1+ use std:: str:: FromStr ;
22
33use emmylua_code_analysis:: {
44 LuaDeclId , LuaMemberId , LuaMemberInfo , LuaMemberKey , LuaSemanticDeclId , LuaType , LuaTypeDeclId ,
55 SemanticDeclLevel , SemanticModel ,
66} ;
77use emmylua_parser:: {
88 LuaAstNode , LuaAstToken , LuaCallExpr , LuaExpr , LuaIndexExpr , LuaStringToken , LuaSyntaxToken ,
9- LuaTableExpr ,
9+ LuaTableExpr , LuaTableField ,
1010} ;
11+ use itertools:: Itertools ;
1112use lsp_types:: { GotoDefinitionResponse , Location , Position , Range , Uri } ;
1213
13- use crate :: handlers:: hover:: find_member_origin_owner ;
14+ use crate :: handlers:: hover:: find_all_same_named_members ;
1415
1516pub fn goto_def_definition (
1617 semantic_model : & SemanticModel ,
1718 property_owner : LuaSemanticDeclId ,
1819 trigger_token : & LuaSyntaxToken ,
19- guard : & mut GotoDefGuard ,
2020) -> Option < GotoDefinitionResponse > {
2121 if let Some ( property) = semantic_model
2222 . get_db ( )
@@ -41,48 +41,59 @@ pub fn goto_def_definition(
4141 return Some ( GotoDefinitionResponse :: Scalar ( location) ) ;
4242 }
4343 LuaSemanticDeclId :: Member ( member_id) => {
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- }
54- }
55-
56- let member_key = semantic_model
57- . get_db ( )
58- . get_member_index ( )
59- . get_member ( & member_id) ?
60- . get_key ( ) ;
44+ let same_named_members = find_all_same_named_members (
45+ semantic_model,
46+ & Some ( LuaSemanticDeclId :: Member ( member_id) ) ,
47+ ) ?;
6148
6249 let mut locations: Vec < Location > = Vec :: new ( ) ;
6350
6451 // 添加原始成员的位置
65- if let Some ( location) = get_member_location ( semantic_model, & member_id) {
66- locations. push ( location) ;
52+ for member in same_named_members {
53+ match member {
54+ LuaSemanticDeclId :: Member ( member_id) => {
55+ if let Some ( location) = get_member_location ( semantic_model, & member_id) {
56+ locations. push ( location) ;
57+ }
58+ }
59+ _ => { }
60+ }
6761 }
6862
69- // 查找实体的定义, 例如在 ---@field 时声明, obj = {} 时实际定义
70- if let Some ( table_field_info) =
71- find_table_member_definition ( semantic_model, trigger_token, member_key)
63+ /* 对于实例的处理, 对于实例 obj
64+ ```lua
65+ ---@class T
66+ ---@field func fun(a: int)
67+ ---@field func fun(a: string)
68+
69+ ---@type T
70+ local obj = {
71+ func = function() end -- 点击`func`时需要寻找`T`的定义
72+ }
73+ obj:func(1) -- 点击`func`时, 不止需要寻找`T`的定义也需要寻找`obj`实例化时赋值的`func`
74+ ```
75+
76+ */
77+ if let Some ( table_field_infos) =
78+ find_table_member_definition ( semantic_model, trigger_token, & member_id)
7279 {
73- if let Some ( LuaSemanticDeclId :: Member ( table_member_id) ) =
74- table_field_info. property_owner_id
75- {
76- if let Some ( location) = get_member_location ( semantic_model, & table_member_id) {
77- if !locations. contains ( & location) {
80+ for table_field_info in table_field_infos {
81+ if let Some ( LuaSemanticDeclId :: Member ( table_member_id) ) =
82+ table_field_info. property_owner_id
83+ {
84+ if let Some ( location) =
85+ get_member_location ( semantic_model, & table_member_id)
86+ {
7887 locations. push ( location) ;
7988 }
8089 }
8190 }
8291 }
8392
8493 if !locations. is_empty ( ) {
85- return Some ( GotoDefinitionResponse :: Array ( locations) ) ;
94+ return Some ( GotoDefinitionResponse :: Array (
95+ locations. into_iter ( ) . unique ( ) . collect ( ) ,
96+ ) ) ;
8697 }
8798 }
8899 LuaSemanticDeclId :: TypeDecl ( type_decl_id) => {
@@ -191,28 +202,53 @@ pub fn goto_str_tpl_ref_definition(
191202pub fn find_table_member_definition (
192203 semantic_model : & SemanticModel ,
193204 trigger_token : & LuaSyntaxToken ,
194- member_key : & LuaMemberKey ,
195- ) -> Option < LuaMemberInfo > {
196- let index_expr = trigger_token. parent ( ) . and_then ( LuaIndexExpr :: cast) ?;
197- let prefix_expr = index_expr. get_prefix_expr ( ) ?;
205+ member_id : & LuaMemberId ,
206+ ) -> Option < Vec < LuaMemberInfo > > {
207+ let member_key = semantic_model
208+ . get_db ( )
209+ . get_member_index ( )
210+ . get_member ( & member_id) ?
211+ . get_key ( ) ;
212+ let parent = trigger_token. parent ( ) ?;
213+
214+ match parent {
215+ expr_node if LuaIndexExpr :: can_cast ( expr_node. kind ( ) . into ( ) ) => {
216+ let index_expr = LuaIndexExpr :: cast ( expr_node) ?;
217+ let prefix_expr = index_expr. get_prefix_expr ( ) ?;
198218
199- let decl = semantic_model. find_decl (
200- prefix_expr. syntax ( ) . clone ( ) . into ( ) ,
201- SemanticDeclLevel :: default ( ) ,
202- ) ;
219+ let decl = semantic_model. find_decl (
220+ prefix_expr. syntax ( ) . clone ( ) . into ( ) ,
221+ SemanticDeclLevel :: default ( ) ,
222+ ) ;
203223
204- if let Some ( LuaSemanticDeclId :: LuaDecl ( decl_id) ) = decl {
205- return find_member_in_table_decl ( semantic_model, & decl_id, member_key) ;
224+ if let Some ( LuaSemanticDeclId :: LuaDecl ( decl_id) ) = decl {
225+ return find_member_in_table_const ( semantic_model, & decl_id, member_key) ;
226+ }
227+ }
228+ table_field_node if LuaTableField :: can_cast ( table_field_node. kind ( ) . into ( ) ) => {
229+ let table_field = LuaTableField :: cast ( table_field_node) ?;
230+ let table_expr = table_field. get_parent :: < LuaTableExpr > ( ) ?;
231+ let typ = semantic_model. infer_table_should_be ( table_expr) ?;
232+ let member_infos = semantic_model. get_member_infos ( & typ) ?;
233+ return Some (
234+ member_infos
235+ . iter ( )
236+ . filter ( |m| m. key == * member_key)
237+ . cloned ( )
238+ . collect ( ) ,
239+ ) ;
240+ }
241+ _ => { }
206242 }
207243
208244 None
209245}
210246
211- fn find_member_in_table_decl (
247+ fn find_member_in_table_const (
212248 semantic_model : & SemanticModel ,
213249 decl_id : & LuaDeclId ,
214250 member_key : & LuaMemberKey ,
215- ) -> Option < LuaMemberInfo > {
251+ ) -> Option < Vec < LuaMemberInfo > > {
216252 let root = semantic_model
217253 . get_db ( )
218254 . get_vfs ( )
@@ -232,7 +268,13 @@ fn find_member_in_table_decl(
232268 . ok ( ) ?;
233269
234270 let member_infos = semantic_model. get_member_infos ( & typ) ?;
235- member_infos. iter ( ) . find ( |m| m. key == * member_key) . cloned ( )
271+ Some (
272+ member_infos
273+ . iter ( )
274+ . filter ( |m| m. key == * member_key)
275+ . cloned ( )
276+ . collect ( ) ,
277+ )
236278}
237279
238280fn get_member_location (
@@ -242,24 +284,3 @@ fn get_member_location(
242284 let document = semantic_model. get_document_by_file_id ( member_id. file_id ) ?;
243285 document. to_lsp_location ( member_id. get_syntax_id ( ) . get_range ( ) )
244286}
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