Skip to content

Commit

Permalink
Enable 'Generate hashCode and equals...' source action
Browse files Browse the repository at this point in the history
Signed-off-by: Jinbo Wang <[email protected]>
  • Loading branch information
testforstephen committed Feb 27, 2019
1 parent 7ac9a33 commit 82c041e
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,8 @@ export namespace Commands {
* Override or implements the methods from the supertypes.
*/
export const OVERRIDE_METHODS_PROMPT = 'java.action.overrideMethodsPrompt';
/**
* Generate hashCode() and equals().
*/
export const HASHCODE_EQUALS_PROMPT = 'java.action.hashCodeEqualsPrompt';
}
3 changes: 2 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ export function activate(context: ExtensionContext): Promise<ExtensionAPI> {
extendedClientCapabilities:{
progressReportProvider: getJavaConfiguration().get('progressReports.enabled'),
classFileContentsSupport:true,
overrideMethodsPromptSupport:true
overrideMethodsPromptSupport:true,
hashCodeEqualsPromptSupport:true
},
triggerFiles: getTriggerFiles()
},
Expand Down
28 changes: 28 additions & 0 deletions src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,32 @@ export interface AddOverridableMethodParams {

export namespace AddOverridableMethodsRequest {
export const type = new RequestType<AddOverridableMethodParams, WorkspaceEdit, void, void>('java/addOverridableMethods');
}

export interface VariableField {
bindingKey: string;
name: string;
type: string;
}

export interface CheckHashCodeEqualsResponse {
type: string;
fields: VariableField[];
foundHashCode: boolean;
foundEquals: boolean;
settings: any;
}

export namespace CheckHashCodeEqualsStatusRequest {
export const type = new RequestType<CodeActionParams, CheckHashCodeEqualsResponse, void, void>('java/checkHashCodeEqualsStatus');
}

export interface GenerateHashCodeEqualsParams {
context: CodeActionParams;
fields: VariableField[];
settings: any;
}

export namespace GenerateHashCodeEqualsRequest {
export const type = new RequestType<GenerateHashCodeEqualsParams, WorkspaceEdit, void, void>('java/generateHashCodeEquals');
}
73 changes: 72 additions & 1 deletion src/sourceAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import { commands, window } from 'vscode';
import { CodeActionParams, LanguageClient } from 'vscode-languageclient';
import { Commands } from './commands';
import { applyWorkspaceEdit } from './extension';
import { ListOverridableMethodsRequest, AddOverridableMethodsRequest } from './protocol';
import { ListOverridableMethodsRequest, AddOverridableMethodsRequest, CheckHashCodeEqualsStatusRequest, GenerateHashCodeEqualsRequest } from './protocol';

export function registerCommands(languageClient: LanguageClient) {
registerOverrideMethodsCommand(languageClient);
registerHashCodeEqualsCommand(languageClient);
}

function registerOverrideMethodsCommand(languageClient: LanguageClient): void {
commands.registerCommand(Commands.OVERRIDE_METHODS_PROMPT, async (params: CodeActionParams) => {
const result = await languageClient.sendRequest(ListOverridableMethodsRequest.type, params);
if (!result || !result.methods || !result.methods.length) {
Expand Down Expand Up @@ -52,3 +57,69 @@ export function registerCommands(languageClient: LanguageClient) {
applyWorkspaceEdit(workspaceEdit, languageClient);
});
}

function registerHashCodeEqualsCommand(languageClient: LanguageClient): void {
commands.registerCommand(Commands.HASHCODE_EQUALS_PROMPT, async (params: CodeActionParams) => {
const result = await languageClient.sendRequest(CheckHashCodeEqualsStatusRequest.type, params);
if (!result || !result.fields || !result.fields.length) {
window.showErrorMessage(`The operation is not applicable to the type ${result.type}.`);
return;
}

if (result.foundHashCode || result.foundEquals) {
const methods = [];
if (result.foundHashCode) {
methods.push('\'int hashCode()\'');
}

if (result.foundEquals) {
methods.push('\'boolean equals(Object)\'');
}

const ans = await window.showInformationMessage(`Methods ${methods.join(' and ')} already exist in the Class '${result.type}'. `
+ 'Do you want to regenerate the implementation?', 'YES', 'NO');
if (ans !== 'YES') {
return;
}

result.settings.regenerate = true;
}

if (result.settings && result.settings.useJ7HashEquals !== undefined) {
const template = await window.showQuickPick([
'Use Objects.hash and Objects.equals methods (Java 7 or higher)',
'Default template'
], {
placeHolder: 'Select the template to generate the hashCode and equals methods.'
});

if (!template) {
return;
} else {
result.settings.useJ7HashEquals = (template !== 'Default template');
}
}

const fieldItems = result.fields.map((field) => {
return {
label: `${field.name}: ${field.type}`,
picked: true,
originalField: field
};
});
const selectedFields = await window.showQuickPick(fieldItems, {
canPickMany: true,
placeHolder: 'Select the fields to include in the hashCode() and equals() methods.'
});
if (!selectedFields.length) {
return;
}

const workspaceEdit = await languageClient.sendRequest(GenerateHashCodeEqualsRequest.type, {
context: params,
fields: selectedFields.map((item) => item.originalField),
settings: result.settings
});
applyWorkspaceEdit(workspaceEdit, languageClient);
});
}
1 change: 1 addition & 0 deletions test/extension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ suite('Java Language Extension', () => {
Commands.REMOVE_FROM_SOURCEPATH,
Commands.LIST_SOURCEPATHS,
Commands.OVERRIDE_METHODS_PROMPT,
Commands.HASHCODE_EQUALS_PROMPT
];
let foundJavaCommands = commands.filter(function(value){
return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.');
Expand Down

0 comments on commit 82c041e

Please sign in to comment.