Skip to content

Commit 25c7cd4

Browse files
testforstephenfbricon
authored andcommitted
Enable move instance method and static member (#1027)
Signed-off-by: Jinbo Wang <jinbwan@microsoft.com>
1 parent da07c30 commit 25c7cd4

2 files changed

Lines changed: 117 additions & 3 deletions

File tree

src/protocol.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
import { RequestType, NotificationType, TextDocumentIdentifier, ExecuteCommandParams, CodeActionParams, WorkspaceEdit, FormattingOptions } from 'vscode-languageclient';
3+
import { RequestType, NotificationType, TextDocumentIdentifier, ExecuteCommandParams, CodeActionParams, WorkspaceEdit, FormattingOptions, WorkspaceSymbolParams, SymbolInformation } from 'vscode-languageclient';
44
import { Command, Range } from 'vscode';
55

66
/**
@@ -152,6 +152,7 @@ export interface VariableBinding {
152152
bindingKey: string;
153153
name: string;
154154
type: string;
155+
isField: boolean;
155156
}
156157

157158
export interface CheckHashCodeEqualsResponse {
@@ -320,6 +321,7 @@ export interface MoveParams {
320321
}
321322

322323
export interface MoveDestinationsResponse {
324+
errorMessage?: string;
323325
destinations: any[];
324326
}
325327

@@ -330,3 +332,13 @@ export namespace GetMoveDestinationsRequest {
330332
export namespace MoveRequest {
331333
export const type = new RequestType<MoveParams, RefactorWorkspaceEdit, void, void>('java/move');
332334
}
335+
336+
export interface SearchSymbolParams extends WorkspaceSymbolParams {
337+
projectName: string;
338+
maxResults?: number;
339+
sourceOnly?: boolean;
340+
}
341+
342+
export namespace SearchSymbols {
343+
export const type = new RequestType<SearchSymbolParams, SymbolInformation[], void, void>('java/searchSymbols');
344+
}

src/refactorAction.ts

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import { existsSync } from 'fs';
44
import * as path from 'path';
55
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';
77
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';
99

1010
export function registerCommands(languageClient: LanguageClient, context: ExtensionContext) {
1111
registerApplyRefactorCommand(languageClient, context);
@@ -82,6 +82,10 @@ function registerApplyRefactorCommand(languageClient: LanguageClient, context: E
8282
}
8383

8484
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);
8589
}
8690
}));
8791
}
@@ -244,3 +248,101 @@ async function saveEdit(edit: WorkspaceEdit) {
244248
await document.save();
245249
}
246250
}
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

Comments
 (0)