|
3 | 3 | import { existsSync } from 'fs'; |
4 | 4 | import * as path from 'path'; |
5 | 5 | import { commands, ExtensionContext, Position, TextDocument, Uri, window, workspace } from 'vscode'; |
6 | | -import { FormattingOptions, LanguageClient, WorkspaceEdit, CreateFile, RenameFile, DeleteFile, TextDocumentEdit } from 'vscode-languageclient'; |
| 6 | +import { FormattingOptions, LanguageClient, WorkspaceEdit, CreateFile, RenameFile, DeleteFile, TextDocumentEdit, CodeActionParams } from 'vscode-languageclient'; |
7 | 7 | import { Commands as javaCommands } from './commands'; |
8 | | -import { GetRefactorEditRequest, MoveRequest, RefactorWorkspaceEdit, RenamePosition, GetMoveDestinationsRequest } from './protocol'; |
| 8 | +import { GetRefactorEditRequest, MoveRequest, RefactorWorkspaceEdit, RenamePosition, GetMoveDestinationsRequest, SearchSymbols } from './protocol'; |
9 | 9 |
|
10 | 10 | export function registerCommands(languageClient: LanguageClient, context: ExtensionContext) { |
11 | 11 | registerApplyRefactorCommand(languageClient, context); |
@@ -82,6 +82,10 @@ function registerApplyRefactorCommand(languageClient: LanguageClient, context: E |
82 | 82 | } |
83 | 83 |
|
84 | 84 | await moveFile(languageClient, [Uri.parse(commandInfo.uri)]); |
| 85 | + } else if (command === 'moveInstanceMethod') { |
| 86 | + await moveInstanceMethod(languageClient, params, commandInfo); |
| 87 | + } else if (command === 'moveStaticMember') { |
| 88 | + await moveStaticMember(languageClient, params, commandInfo); |
85 | 89 | } |
86 | 90 | })); |
87 | 91 | } |
@@ -244,3 +248,101 @@ async function saveEdit(edit: WorkspaceEdit) { |
244 | 248 | await document.save(); |
245 | 249 | } |
246 | 250 | } |
| 251 | + |
| 252 | +async function moveInstanceMethod(languageClient: LanguageClient, params: CodeActionParams, commandInfo: any) { |
| 253 | + const moveDestinations = await languageClient.sendRequest(GetMoveDestinationsRequest.type, { |
| 254 | + moveKind: 'moveInstanceMethod', |
| 255 | + sourceUris: [ params.textDocument.uri ], |
| 256 | + params |
| 257 | + }); |
| 258 | + if (moveDestinations && moveDestinations.errorMessage) { |
| 259 | + window.showErrorMessage(moveDestinations.errorMessage); |
| 260 | + return; |
| 261 | + } |
| 262 | + |
| 263 | + if (!moveDestinations || !moveDestinations.destinations || !moveDestinations.destinations.length) { |
| 264 | + window.showErrorMessage("Cannot find possible class targets to move the selected method to."); |
| 265 | + return; |
| 266 | + } |
| 267 | + |
| 268 | + const destinationNodeItems = moveDestinations.destinations.map((destination) => { |
| 269 | + return { |
| 270 | + label: `${destination.type} ${destination.name}`, |
| 271 | + description: destination.isField ? "Field" : "Method Parameter", |
| 272 | + destination, |
| 273 | + }; |
| 274 | + }); |
| 275 | + const methodName = commandInfo && commandInfo.displayName ? commandInfo.displayName : ''; |
| 276 | + const selected = await window.showQuickPick(destinationNodeItems, { |
| 277 | + placeHolder: `Select the new class for the instance method ${methodName}.`, |
| 278 | + }); |
| 279 | + if (!selected) { |
| 280 | + return; |
| 281 | + } |
| 282 | + |
| 283 | + const refactorEdit: RefactorWorkspaceEdit = await languageClient.sendRequest(MoveRequest.type, { |
| 284 | + moveKind: 'moveInstanceMethod', |
| 285 | + sourceUris: [ params.textDocument.uri ], |
| 286 | + params, |
| 287 | + destination: selected.destination, |
| 288 | + }); |
| 289 | + await applyRefactorEdit(languageClient, refactorEdit); |
| 290 | +} |
| 291 | + |
| 292 | +async function moveStaticMember(languageClient: LanguageClient, params: CodeActionParams, commandInfo: any) { |
| 293 | + const memberName = commandInfo && commandInfo.displayName ? commandInfo.displayName : ''; |
| 294 | + const exclude: Set<string> = new Set(); |
| 295 | + if (commandInfo.enclosingTypeName) { |
| 296 | + exclude.add(commandInfo.enclosingTypeName); |
| 297 | + // 55: Type, 71: Enum, 81: AnnotationType |
| 298 | + if (commandInfo.memberType === 55 || commandInfo.memeberType === 71 |
| 299 | + || commandInfo.memberType === 81) { |
| 300 | + exclude.add(`${commandInfo.enclosingTypeName}.${commandInfo.displayName}`); |
| 301 | + } |
| 302 | + } |
| 303 | + const picked = await window.showQuickPick( |
| 304 | + languageClient.sendRequest(SearchSymbols.type, { |
| 305 | + query: '*', |
| 306 | + projectName: commandInfo ? commandInfo.projectName : null, |
| 307 | + sourceOnly: true, |
| 308 | + }).then(types => { |
| 309 | + if (types && types.length) { |
| 310 | + return types.filter((type) => { |
| 311 | + const typeName = type.containerName ? `${type.containerName}.${type.name}` : type.name; |
| 312 | + return !exclude.has(typeName); |
| 313 | + }).sort((a, b) => { |
| 314 | + if (a.name < b.name) { |
| 315 | + return -1; |
| 316 | + } else if (a.name > b.name) { |
| 317 | + return 1; |
| 318 | + } |
| 319 | + return 0; |
| 320 | + }).map((symbol => { |
| 321 | + return { |
| 322 | + label: symbol.name, |
| 323 | + description: symbol.containerName, |
| 324 | + symbolNode: symbol, |
| 325 | + }; |
| 326 | + })); |
| 327 | + } else { |
| 328 | + return [{ |
| 329 | + label: 'No result found', |
| 330 | + alwaysShow: true, |
| 331 | + description: '', |
| 332 | + symbolNode: null, |
| 333 | + }]; |
| 334 | + } |
| 335 | + }), { |
| 336 | + placeHolder: `Select the new class for the static member ${memberName}.` |
| 337 | + }); |
| 338 | + |
| 339 | + if (picked && picked.symbolNode) { |
| 340 | + const refactorEdit: RefactorWorkspaceEdit = await languageClient.sendRequest(MoveRequest.type, { |
| 341 | + moveKind: 'moveStaticMember', |
| 342 | + sourceUris: [ params.textDocument.uri ], |
| 343 | + params, |
| 344 | + destination: picked.symbolNode, |
| 345 | + }); |
| 346 | + await applyRefactorEdit(languageClient, refactorEdit); |
| 347 | + } |
| 348 | +} |
0 commit comments