@@ -12,9 +12,7 @@ use itertools::Itertools;
12
12
use lsp_types:: { GotoDefinitionResponse , Location , Position , Range , Uri } ;
13
13
14
14
use 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} ,
18
16
hover:: { find_all_same_named_members, find_member_origin_owner} ,
19
17
} ;
20
18
@@ -24,6 +22,7 @@ pub fn goto_def_definition(
24
22
property_owner : LuaSemanticDeclId ,
25
23
trigger_token : & LuaSyntaxToken ,
26
24
) -> Option < GotoDefinitionResponse > {
25
+ // 首先检查属性源位置
27
26
if let Some ( property) = semantic_model
28
27
. get_db ( )
29
28
. get_property_index ( )
@@ -35,154 +34,191 @@ pub fn goto_def_definition(
35
34
}
36
35
}
37
36
}
37
+
38
+ // 根据不同的语义声明类型处理
38
39
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 (
41
70
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
+ }
56
80
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) ) ;
59
102
}
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
+ }
65
104
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)
104
160
{
105
161
locations. push ( location) ;
162
+ continue ;
106
163
}
107
164
}
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
+ {
110
169
locations. push ( location) ;
170
+ continue ;
111
171
}
112
172
}
113
173
_ => { }
114
174
}
115
175
}
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 ) ;
118
178
}
119
179
}
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) ;
130
183
}
131
184
}
185
+ _ => { }
186
+ }
187
+ }
188
+ }
132
189
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)
145
201
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
149
215
{
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) ;
160
218
}
161
219
}
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) ) ;
182
220
}
183
- _ => { }
184
221
}
185
- None
186
222
}
187
223
188
224
fn goto_source_location ( source : & str ) -> Option < Location > {
0 commit comments