@@ -4,6 +4,15 @@ local JdtlsClient = require('java-core.ls.clients.jdtls-client')
4
4
local List = require (' java-core.utils.list' )
5
5
local ui = require (' java.utils.ui' )
6
6
7
+ local refactor_edit_request_needed_actions = {
8
+ ' convertVariableToField' ,
9
+ ' extractConstant' ,
10
+ ' extractField' ,
11
+ ' extractMethod' ,
12
+ ' extractVariable' ,
13
+ ' extractVariableAllOccurrence' ,
14
+ }
15
+
7
16
local selections_needed_refactoring_commands = {
8
17
' convertVariableToField' ,
9
18
' extractConstant' ,
@@ -13,7 +22,7 @@ local selections_needed_refactoring_commands = {
13
22
' extractVariableAllOccurrence' ,
14
23
}
15
24
16
- local available_commands = {
25
+ local available_actions = {
17
26
' assignField' ,
18
27
' assignVariable' ,
19
28
-- 'changeSignature',
@@ -27,6 +36,10 @@ local available_commands = {
27
36
' extractVariableAllOccurrence' ,
28
37
' introduceParameter' ,
29
38
' invertVariable' ,
39
+ ' moveFile' ,
40
+ ' moveInstanceMethod' ,
41
+ ' moveStaticMember' ,
42
+ ' moveType' ,
30
43
}
31
44
32
45
--- @class java-refactor.RefactorCommands
@@ -39,43 +52,210 @@ function RefactorCommands:_init(client)
39
52
end
40
53
41
54
--- Run refactor command
42
- --- @param refactor_type jdtls.CodeActionCommand
43
- --- @param params lsp.CodeActionParams
44
- function RefactorCommands :refactor (refactor_type , params )
45
- if not vim .tbl_contains (available_commands , refactor_type ) then
55
+ --- @param action_name jdtls.CodeActionCommand
56
+ --- @param action_context lsp.CodeActionParams
57
+ --- @param action_info lsp.LSPAny
58
+ function RefactorCommands :refactor (action_name , action_context , action_info )
59
+ if not vim .tbl_contains (available_actions , action_name ) then
46
60
notify .error (
47
- string.format (' Refactoring command "%s" is not supported' , refactor_type )
61
+ string.format (' Refactoring command "%s" is not supported' , action_name )
48
62
)
49
63
return
50
64
end
51
65
52
- params = params or RefactorCommands .make_action_params ()
53
- local formatting_options = RefactorCommands .make_formatting_options ()
54
- local selections
66
+ if vim .tbl_contains (refactor_edit_request_needed_actions , action_name ) then
67
+ local formatting_options = RefactorCommands .make_formatting_options ()
68
+ local selections
69
+
70
+ if
71
+ vim .tbl_contains (selections_needed_refactoring_commands , action_name )
72
+ then
73
+ selections = self :get_selections (action_name , action_context )
74
+ end
75
+
76
+ local changes = self .jdtls_client :java_get_refactor_edit (
77
+ action_name ,
78
+ action_context ,
79
+ formatting_options ,
80
+ selections ,
81
+ vim .api .nvim_get_current_buf ()
82
+ )
83
+
84
+ if not changes then
85
+ notify .warn (' No edits suggested for action' )
86
+ return
87
+ end
88
+
89
+ vim .lsp .util .apply_workspace_edit (changes .edit , ' utf-8' )
55
90
56
- if selections_needed_refactoring_commands then
57
- selections = self :get_selections (refactor_type , params )
91
+ RefactorCommands .run_lsp_client_command (
92
+ changes .command .command ,
93
+ changes .command .arguments
94
+ )
95
+ elseif action_name == ' moveType' then
96
+ self :move_type (
97
+ action_context ,
98
+ action_info --[[ @as jdtls.CodeActionMoveTypeCommandInfo]]
99
+ )
100
+ elseif action_name == ' moveStaticMember' then
101
+ self :move_static_member (
102
+ action_context ,
103
+ action_info --[[ @as jdtls.CodeActionMoveTypeCommandInfo]]
104
+ )
105
+ end
106
+ end
107
+
108
+ --- @param action_context lsp.CodeActionParams
109
+ --- @param action_info jdtls.CodeActionMoveTypeCommandInfo
110
+ function RefactorCommands :move_static_member (action_context , action_info )
111
+ local exclude = List :new ()
112
+
113
+ if action_info .enclosingTypeName then
114
+ exclude :push (action_info .enclosingTypeName )
115
+ if
116
+ action_info .memberType == 55
117
+ or action_info .memberType == 71
118
+ or action_info .memberType == 81
119
+ then
120
+ exclude :push (
121
+ action_info .enclosingTypeName .. ' .' .. action_info .displayName
122
+ )
123
+ end
58
124
end
59
125
60
- local changes = self .jdtls_client :java_get_refactor_edit (
61
- refactor_type ,
62
- params ,
63
- formatting_options ,
64
- selections ,
65
- vim .api .nvim_get_current_buf ()
126
+ local project_name = action_info and action_info .projectName or nil
127
+ local member_name = action_info
128
+ and action_info .displayName
129
+ and action_info .displayName
130
+ or ' '
131
+
132
+ local selected_class = self :select_target_class (
133
+ string.format (' Select the new class for the static member %s.' , member_name ),
134
+ project_name ,
135
+ exclude
66
136
)
67
137
68
- if not changes then
69
- notify .warn (' No edits suggested for action' )
138
+ if not selected_class then
70
139
return
71
140
end
72
141
142
+ local changes = self .jdtls_client :java_move ({
143
+ moveKind = ' moveStaticMember' ,
144
+ sourceUris = { action_context .textDocument .uri },
145
+ params = action_context ,
146
+ destination = selected_class ,
147
+ })
148
+
73
149
vim .lsp .util .apply_workspace_edit (changes .edit , ' utf-8' )
74
150
75
- RefactorCommands .run_lsp_client_command (
76
- changes .command .command ,
77
- changes .command .arguments
151
+ if changes .command then
152
+ RefactorCommands .run_lsp_client_command (
153
+ changes .command .command ,
154
+ changes .command .arguments
155
+ )
156
+ end
157
+ end
158
+
159
+ --- @param action_context lsp.CodeActionParams
160
+ --- @param action_info jdtls.CodeActionMoveTypeCommandInfo
161
+ function RefactorCommands :move_type (action_context , action_info )
162
+ if not action_info or not action_info .supportedDestinationKinds then
163
+ return
164
+ end
165
+
166
+ local selected_destination_kind = ui .select (
167
+ ' What would you like to do?' ,
168
+ action_info .supportedDestinationKinds ,
169
+ function (kind )
170
+ if kind == ' newFile' then
171
+ return string.format (
172
+ ' Move type "%s" to new file' ,
173
+ action_info .displayName
174
+ )
175
+ else
176
+ return string.format (
177
+ ' Move type "%s" to another class' ,
178
+ action_info .displayName
179
+ )
180
+ end
181
+ end
78
182
)
183
+
184
+ if not selected_destination_kind then
185
+ return
186
+ end
187
+
188
+ --- @type jdtls.RefactorWorkspaceEdit
189
+ local changes
190
+
191
+ if selected_destination_kind == ' newFile' then
192
+ changes = self .jdtls_client :java_move ({
193
+ moveKind = ' moveTypeToNewFile' ,
194
+ sourceUris = { action_context .textDocument .uri },
195
+ params = action_context ,
196
+ })
197
+ else
198
+ local exclude = List :new ()
199
+
200
+ if action_info .enclosingTypeName then
201
+ exclude :push (action_info .enclosingTypeName )
202
+ exclude :push (
203
+ action_info .enclosingTypeName .. ' :' .. action_info .displayName
204
+ )
205
+ end
206
+
207
+ local selected_class = self :select_target_class (
208
+ string.format (
209
+ ' Select the new class for the type %s.' ,
210
+ action_info .displayName
211
+ ),
212
+ action_info .projectName ,
213
+ exclude
214
+ )
215
+
216
+ if not selected_class then
217
+ return
218
+ end
219
+
220
+ changes = self .jdtls_client :java_move ({
221
+ moveKind = ' moveStaticMember' ,
222
+ sourceUris = { action_context .textDocument .uri },
223
+ params = action_context ,
224
+ destination = selected_class ,
225
+ })
226
+ end
227
+
228
+ vim .lsp .util .apply_workspace_edit (changes .edit , ' utf-8' )
229
+
230
+ if changes .command then
231
+ RefactorCommands .run_lsp_client_command (
232
+ changes .command .command ,
233
+ changes .command .arguments
234
+ )
235
+ end
236
+ end
237
+
238
+ --- @param prompt string
239
+ --- @param project_name string
240
+ --- @param exclude string[]
241
+ function RefactorCommands :select_target_class (prompt , project_name , exclude )
242
+ local classes = self .jdtls_client :java_search_symbols ({
243
+ query = ' *' ,
244
+ projectName = project_name ,
245
+ sourceOnly = true ,
246
+ })
247
+
248
+ --- @type lsp.SymbolInformation[]
249
+ local filtered_classes = List :new (classes ):filter (function (cls )
250
+ local type_name = cls .containerName .. ' .' .. cls .name
251
+ return not vim .tbl_contains (exclude , type_name )
252
+ end )
253
+
254
+ local selected = ui .select (prompt , filtered_classes , function (cls )
255
+ return cls .containerName .. ' .' .. cls .name
256
+ end )
257
+
258
+ return selected
79
259
end
80
260
81
261
--- @private
@@ -92,21 +272,6 @@ function RefactorCommands.run_lsp_client_command(command_name, arguments)
92
272
command (arguments )
93
273
end
94
274
95
- --- Returns action params
96
- --- @private
97
- --- @return lsp.CodeActionParams
98
- function RefactorCommands .make_action_params ()
99
- --- @type lsp.CodeActionParams
100
- local params = vim .lsp .util .make_range_params (0 )
101
-
102
- --- @type lsp.CodeActionContext
103
- local context = { diagnostics = vim .lsp .diagnostic .get_line_diagnostics (0 ) }
104
-
105
- params .context = context
106
-
107
- return params
108
- end
109
-
110
275
--- @private
111
276
--- @return lsp.FormattingOptions
112
277
function RefactorCommands .make_formatting_options ()
@@ -154,4 +319,11 @@ function RefactorCommands:get_selections(refactor_type, params)
154
319
return selections
155
320
end
156
321
322
+ --- @class jdtls.CodeActionMoveTypeCommandInfo
323
+ --- @field displayName string
324
+ --- @field enclosingTypeName string
325
+ --- @field memberType number
326
+ --- @field projectName string
327
+ --- @field supportedDestinationKinds string[]
328
+
157
329
return RefactorCommands
0 commit comments