@@ -12,9 +12,7 @@ use itertools::Itertools;
1212use lsp_types:: { GotoDefinitionResponse , Location , Position , Range , Uri } ;
1313
1414use crate :: handlers:: {
15- definition:: goto_function:: {
16- find_call_expr_origin_for_decl, find_call_match_function_for_member,
17- } ,
15+ definition:: goto_function:: { find_function_call_origin, find_matching_function_definitions} ,
1816 hover:: { find_all_same_named_members, find_member_origin_owner} ,
1917} ;
2018
@@ -24,6 +22,7 @@ pub fn goto_def_definition(
2422 property_owner : LuaSemanticDeclId ,
2523 trigger_token : & LuaSyntaxToken ,
2624) -> Option < GotoDefinitionResponse > {
25+ // 首先检查属性源位置
2726 if let Some ( property) = semantic_model
2827 . get_db ( )
2928 . get_property_index ( )
@@ -35,154 +34,191 @@ pub fn goto_def_definition(
3534 }
3635 }
3736 }
37+
38+ // 根据不同的语义声明类型处理
3839 match property_owner {
39- LuaSemanticDeclId :: LuaDecl ( decl_id) => {
40- if let Some ( match_semantic_decl) = find_call_expr_origin_for_decl (
40+ LuaSemanticDeclId :: LuaDecl ( decl_id) => handle_decl_definition (
41+ semantic_model,
42+ compilation,
43+ trigger_token,
44+ & property_owner,
45+ & decl_id,
46+ ) ,
47+ LuaSemanticDeclId :: Member ( member_id) => {
48+ handle_member_definition ( semantic_model, compilation, trigger_token, & member_id)
49+ }
50+ LuaSemanticDeclId :: TypeDecl ( type_decl_id) => {
51+ handle_type_decl_definition ( semantic_model, & type_decl_id)
52+ }
53+ _ => None ,
54+ }
55+ }
56+
57+ fn handle_decl_definition (
58+ semantic_model : & SemanticModel ,
59+ compilation : & LuaCompilation ,
60+ trigger_token : & LuaSyntaxToken ,
61+ property_owner : & LuaSemanticDeclId ,
62+ decl_id : & LuaDeclId ,
63+ ) -> Option < GotoDefinitionResponse > {
64+ // 尝试查找函数调用的原始定义
65+ if let Some ( match_semantic_decl) =
66+ find_function_call_origin ( semantic_model, compilation, trigger_token, property_owner)
67+ {
68+ if let LuaSemanticDeclId :: LuaDecl ( matched_decl_id) = match_semantic_decl {
69+ return Some ( GotoDefinitionResponse :: Scalar ( get_decl_location (
4170 semantic_model,
42- compilation,
43- trigger_token,
44- & property_owner,
45- ) {
46- match match_semantic_decl {
47- LuaSemanticDeclId :: LuaDecl ( decl_id) => {
48- return Some ( GotoDefinitionResponse :: Scalar ( get_decl_location (
49- semantic_model,
50- & decl_id,
51- ) ?) ) ;
52- }
53- _ => { }
54- } ;
55- }
71+ & matched_decl_id,
72+ ) ?) ) ;
73+ }
74+ }
75+
76+ // 返回声明的位置
77+ let location = get_decl_location ( semantic_model, decl_id) ?;
78+ Some ( GotoDefinitionResponse :: Scalar ( location) )
79+ }
5680
57- let location = get_decl_location ( semantic_model, & decl_id) ?;
58- return Some ( GotoDefinitionResponse :: Scalar ( location) ) ;
81+ fn handle_member_definition (
82+ semantic_model : & SemanticModel ,
83+ compilation : & LuaCompilation ,
84+ trigger_token : & LuaSyntaxToken ,
85+ member_id : & LuaMemberId ,
86+ ) -> Option < GotoDefinitionResponse > {
87+ let same_named_members =
88+ find_all_same_named_members ( semantic_model, & Some ( LuaSemanticDeclId :: Member ( * member_id) ) ) ?;
89+
90+ let mut locations: Vec < Location > = Vec :: new ( ) ;
91+
92+ // 尝试寻找函数调用时最匹配的定义
93+ if let Some ( match_members) = find_matching_function_definitions (
94+ semantic_model,
95+ compilation,
96+ trigger_token,
97+ & same_named_members,
98+ ) {
99+ process_matched_members ( semantic_model, compilation, & match_members, & mut locations) ;
100+ if !locations. is_empty ( ) {
101+ return Some ( GotoDefinitionResponse :: Array ( locations) ) ;
59102 }
60- LuaSemanticDeclId :: Member ( member_id) => {
61- let same_named_members = find_all_same_named_members (
62- semantic_model,
63- & Some ( LuaSemanticDeclId :: Member ( member_id) ) ,
64- ) ?;
103+ }
65104
66- let mut locations: Vec < Location > = Vec :: new ( ) ;
67- // 如果是函数调用, 则尝试寻找最匹配的定义
68- if let Some ( match_members) = find_call_match_function_for_member (
69- semantic_model,
70- compilation,
71- trigger_token,
72- & same_named_members,
73- ) {
74- for member in match_members {
75- match member {
76- LuaSemanticDeclId :: Member ( member_id) => {
77- if should_trace_member ( semantic_model, & member_id) . unwrap_or ( false ) {
78- // 尝试搜索这个成员最原始的定义
79- match find_member_origin_owner (
80- compilation,
81- semantic_model,
82- member_id,
83- ) {
84- Some ( LuaSemanticDeclId :: Member ( member_id) ) => {
85- if let Some ( location) =
86- get_member_location ( semantic_model, & member_id)
87- {
88- locations. push ( location) ;
89- continue ;
90- }
91- }
92- Some ( LuaSemanticDeclId :: LuaDecl ( decl_id) ) => {
93- if let Some ( location) =
94- get_decl_location ( semantic_model, & decl_id)
95- {
96- locations. push ( location) ;
97- continue ;
98- }
99- }
100- _ => { }
101- }
102- }
103- if let Some ( location) = get_member_location ( semantic_model, & member_id)
105+ // 添加原始成员的位置
106+ for member in same_named_members {
107+ if let LuaSemanticDeclId :: Member ( member_id) = member {
108+ if let Some ( location) = get_member_location ( semantic_model, & member_id) {
109+ locations. push ( location) ;
110+ }
111+ }
112+ }
113+
114+ // 处理实例表成员
115+ add_instance_table_member_locations ( semantic_model, trigger_token, member_id, & mut locations) ;
116+
117+ if !locations. is_empty ( ) {
118+ Some ( GotoDefinitionResponse :: Array (
119+ locations. into_iter ( ) . unique ( ) . collect ( ) ,
120+ ) )
121+ } else {
122+ None
123+ }
124+ }
125+
126+ fn handle_type_decl_definition (
127+ semantic_model : & SemanticModel ,
128+ type_decl_id : & LuaTypeDeclId ,
129+ ) -> Option < GotoDefinitionResponse > {
130+ let type_decl = semantic_model
131+ . get_db ( )
132+ . get_type_index ( )
133+ . get_type_decl ( type_decl_id) ?;
134+
135+ let mut locations: Vec < Location > = Vec :: new ( ) ;
136+ for lua_location in type_decl. get_locations ( ) {
137+ let document = semantic_model. get_document_by_file_id ( lua_location. file_id ) ?;
138+ let location = document. to_lsp_location ( lua_location. range ) ?;
139+ locations. push ( location) ;
140+ }
141+
142+ Some ( GotoDefinitionResponse :: Array ( locations) )
143+ }
144+
145+ fn process_matched_members (
146+ semantic_model : & SemanticModel ,
147+ compilation : & LuaCompilation ,
148+ match_members : & [ LuaSemanticDeclId ] ,
149+ locations : & mut Vec < Location > ,
150+ ) {
151+ for member in match_members {
152+ match member {
153+ LuaSemanticDeclId :: Member ( member_id) => {
154+ if should_trace_member ( semantic_model, member_id) . unwrap_or ( false ) {
155+ // 尝试搜索这个成员最原始的定义
156+ match find_member_origin_owner ( compilation, semantic_model, * member_id) {
157+ Some ( LuaSemanticDeclId :: Member ( origin_member_id) ) => {
158+ if let Some ( location) =
159+ get_member_location ( semantic_model, & origin_member_id)
104160 {
105161 locations. push ( location) ;
162+ continue ;
106163 }
107164 }
108- LuaSemanticDeclId :: LuaDecl ( decl_id) => {
109- if let Some ( location) = get_decl_location ( semantic_model, & decl_id) {
165+ Some ( LuaSemanticDeclId :: LuaDecl ( origin_decl_id) ) => {
166+ if let Some ( location) =
167+ get_decl_location ( semantic_model, & origin_decl_id)
168+ {
110169 locations. push ( location) ;
170+ continue ;
111171 }
112172 }
113173 _ => { }
114174 }
115175 }
116- if !locations . is_empty ( ) {
117- return Some ( GotoDefinitionResponse :: Array ( locations) ) ;
176+ if let Some ( location ) = get_member_location ( semantic_model , member_id ) {
177+ locations. push ( location ) ;
118178 }
119179 }
120-
121- // 添加原始成员的位置
122- for member in same_named_members {
123- match member {
124- LuaSemanticDeclId :: Member ( member_id) => {
125- if let Some ( location) = get_member_location ( semantic_model, & member_id) {
126- locations. push ( location) ;
127- }
128- }
129- _ => { }
180+ LuaSemanticDeclId :: LuaDecl ( decl_id) => {
181+ if let Some ( location) = get_decl_location ( semantic_model, decl_id) {
182+ locations. push ( location) ;
130183 }
131184 }
185+ _ => { }
186+ }
187+ }
188+ }
132189
133- /* 对于实例的处理, 对于实例 obj
134- ```lua
135- ---@class T
136- ---@field func fun(a: int)
137- ---@field func fun(a: string)
138-
139- ---@type T
140- local obj = {
141- func = function() end -- 点击`func`时需要寻找`T`的定义
142- }
143- obj:func(1) -- 点击`func`时, 不止需要寻找`T`的定义也需要寻找`obj`实例化时赋值的`func`
144- ```
190+ fn add_instance_table_member_locations (
191+ semantic_model : & SemanticModel ,
192+ trigger_token : & LuaSyntaxToken ,
193+ member_id : & LuaMemberId ,
194+ locations : & mut Vec < Location > ,
195+ ) {
196+ /* 对于实例的处理, 对于实例 obj
197+ ```lua
198+ ---@class T
199+ ---@field func fun(a: int)
200+ ---@field func fun(a: string)
145201
146- */
147- if let Some ( table_field_infos) =
148- find_instance_table_member ( semantic_model, trigger_token, & member_id)
202+ ---@type T
203+ local obj = {
204+ func = function() end -- 点击`func`时需要寻找`T`的定义
205+ }
206+ obj:func(1) -- 点击`func`时, 不止需要寻找`T`的定义也需要寻找`obj`实例化时赋值的`func`
207+ ```
208+ */
209+ if let Some ( table_field_infos) =
210+ find_instance_table_member ( semantic_model, trigger_token, member_id)
211+ {
212+ for table_field_info in table_field_infos {
213+ if let Some ( LuaSemanticDeclId :: Member ( table_member_id) ) =
214+ table_field_info. property_owner_id
149215 {
150- for table_field_info in table_field_infos {
151- if let Some ( LuaSemanticDeclId :: Member ( table_member_id) ) =
152- table_field_info. property_owner_id
153- {
154- if let Some ( location) =
155- get_member_location ( semantic_model, & table_member_id)
156- {
157- locations. push ( location) ;
158- }
159- }
216+ if let Some ( location) = get_member_location ( semantic_model, & table_member_id) {
217+ locations. push ( location) ;
160218 }
161219 }
162-
163- if !locations. is_empty ( ) {
164- return Some ( GotoDefinitionResponse :: Array (
165- locations. into_iter ( ) . unique ( ) . collect ( ) ,
166- ) ) ;
167- }
168- }
169- LuaSemanticDeclId :: TypeDecl ( type_decl_id) => {
170- let type_decl = semantic_model
171- . get_db ( )
172- . get_type_index ( )
173- . get_type_decl ( & type_decl_id) ?;
174- let mut locations: Vec < Location > = Vec :: new ( ) ;
175- for lua_location in type_decl. get_locations ( ) {
176- let document = semantic_model. get_document_by_file_id ( lua_location. file_id ) ?;
177- let location = document. to_lsp_location ( lua_location. range ) ?;
178- locations. push ( location) ;
179- }
180-
181- return Some ( GotoDefinitionResponse :: Array ( locations) ) ;
182220 }
183- _ => { }
184221 }
185- None
186222}
187223
188224fn goto_source_location ( source : & str ) -> Option < Location > {
0 commit comments