@@ -4,6 +4,15 @@ local JdtlsClient = require('java-core.ls.clients.jdtls-client')
44local List = require (' java-core.utils.list' )
55local ui = require (' java.utils.ui' )
66
7+ local refactor_edit_request_needed_actions = {
8+ ' convertVariableToField' ,
9+ ' extractConstant' ,
10+ ' extractField' ,
11+ ' extractMethod' ,
12+ ' extractVariable' ,
13+ ' extractVariableAllOccurrence' ,
14+ }
15+
716local selections_needed_refactoring_commands = {
817 ' convertVariableToField' ,
918 ' extractConstant' ,
@@ -13,7 +22,7 @@ local selections_needed_refactoring_commands = {
1322 ' extractVariableAllOccurrence' ,
1423}
1524
16- local available_commands = {
25+ local available_actions = {
1726 ' assignField' ,
1827 ' assignVariable' ,
1928 -- 'changeSignature',
@@ -27,6 +36,10 @@ local available_commands = {
2736 ' extractVariableAllOccurrence' ,
2837 ' introduceParameter' ,
2938 ' invertVariable' ,
39+ ' moveFile' ,
40+ ' moveInstanceMethod' ,
41+ ' moveStaticMember' ,
42+ ' moveType' ,
3043}
3144
3245--- @class java-refactor.RefactorCommands
@@ -39,43 +52,210 @@ function RefactorCommands:_init(client)
3952end
4053
4154--- 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
4660 notify .error (
47- string.format (' Refactoring command "%s" is not supported' , refactor_type )
61+ string.format (' Refactoring command "%s" is not supported' , action_name )
4862 )
4963 return
5064 end
5165
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' )
5590
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
58124 end
59125
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
66136 )
67137
68- if not changes then
69- notify .warn (' No edits suggested for action' )
138+ if not selected_class then
70139 return
71140 end
72141
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+
73149 vim .lsp .util .apply_workspace_edit (changes .edit , ' utf-8' )
74150
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
78182 )
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
79259end
80260
81261--- @private
@@ -92,21 +272,6 @@ function RefactorCommands.run_lsp_client_command(command_name, arguments)
92272 command (arguments )
93273end
94274
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-
110275--- @private
111276--- @return lsp.FormattingOptions
112277function RefactorCommands .make_formatting_options ()
@@ -154,4 +319,11 @@ function RefactorCommands:get_selections(refactor_type, params)
154319 return selections
155320end
156321
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+
157329return RefactorCommands
0 commit comments