Skip to content

Commit d8cc49d

Browse files
testforstephenfbricon
authored andcommitted
Enable generate hashCode and equals source action (#814)
Signed-off-by: Jinbo Wang <[email protected]>
1 parent ca29cb2 commit d8cc49d

File tree

7 files changed

+110
-3
lines changed

7 files changed

+110
-3
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,10 @@ The following settings are supported:
9393
* `java.completion.guessMethodArguments` : When set to true, method arguments are guessed when a method is selected from as list of code assist proposals.
9494
* `java.completion.enabled` : Enable/disable code completion support.
9595
* `java.configuration.checkProjectSettingsExclusions`: Checks if the extension-generated project settings files (`.project`, `.classpath`, `.factorypath`, `.settings/`) should be excluded from the file explorer. Defaults to `true`.
96-
96+
* `java.codeGeneration.hashCodeEquals.useJava7Objects`: Use Objects.hash and Objects.equals when generating the hashCode and equals methods. This setting only applies to Java 7 and higher. Defaults to `false`.
97+
* `java.codeGeneration.hashCodeEquals.useInstanceof`: Use 'instanceof' to compare types when generating the hashCode and equals methods. Defaults to `false`.
98+
* `java.codeGeneration.hashCodeEquals.useBlocks`: Use blocks in 'if' statements when generating the hashCode and equals methods. Defaults to `false`.
99+
* `java.codeGeneration.hashCodeEquals.generateComments`: Generate method comments when generating the hashCode and equals methods. Defaults to `false`.
97100

98101
Troubleshooting
99102
===============

package.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,30 @@
271271
"description": "Enable/disable automatic block formatting when typing `;`, `<enter>` or `}`",
272272
"default": true,
273273
"scope": "window"
274+
},
275+
"java.codeGeneration.hashCodeEquals.useJava7Objects": {
276+
"type": "boolean",
277+
"description": "Use Objects.hash and Objects.equals when generating the hashCode and equals methods. This setting only applies to Java 7 and higher.",
278+
"default": false,
279+
"scope": "window"
280+
},
281+
"java.codeGeneration.hashCodeEquals.useInstanceof": {
282+
"type": "boolean",
283+
"description": "Use 'instanceof' to compare types when generating the hashCode and equals methods.",
284+
"default": false,
285+
"scope": "window"
286+
},
287+
"java.codeGeneration.hashCodeEquals.useBlocks": {
288+
"type": "boolean",
289+
"description": "Use blocks in 'if' statements when generating the hashCode and equals methods.",
290+
"default": false,
291+
"scope": "window"
292+
},
293+
"java.codeGeneration.hashCodeEquals.generateComments": {
294+
"type": "boolean",
295+
"description": "Generate method comments when generating the hashCode and equals methods.",
296+
"default": false,
297+
"scope": "window"
274298
}
275299
}
276300
},

src/commands.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,8 @@ export namespace Commands {
106106
* Override or implements the methods from the supertypes.
107107
*/
108108
export const OVERRIDE_METHODS_PROMPT = 'java.action.overrideMethodsPrompt';
109+
/**
110+
* Generate hashCode() and equals().
111+
*/
112+
export const HASHCODE_EQUALS_PROMPT = 'java.action.hashCodeEqualsPrompt';
109113
}

src/extension.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ export function activate(context: ExtensionContext): Promise<ExtensionAPI> {
7474
extendedClientCapabilities:{
7575
progressReportProvider: getJavaConfiguration().get('progressReports.enabled'),
7676
classFileContentsSupport:true,
77-
overrideMethodsPromptSupport:true
77+
overrideMethodsPromptSupport:true,
78+
hashCodeEqualsPromptSupport:true
7879
},
7980
triggerFiles: getTriggerFiles()
8081
},

src/protocol.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,30 @@ export interface AddOverridableMethodParams {
147147

148148
export namespace AddOverridableMethodsRequest {
149149
export const type = new RequestType<AddOverridableMethodParams, WorkspaceEdit, void, void>('java/addOverridableMethods');
150+
}
151+
152+
export interface VariableField {
153+
bindingKey: string;
154+
name: string;
155+
type: string;
156+
}
157+
158+
export interface CheckHashCodeEqualsResponse {
159+
type: string;
160+
fields: VariableField[];
161+
existingMethods: string[];
162+
}
163+
164+
export namespace CheckHashCodeEqualsStatusRequest {
165+
export const type = new RequestType<CodeActionParams, CheckHashCodeEqualsResponse, void, void>('java/checkHashCodeEqualsStatus');
166+
}
167+
168+
export interface GenerateHashCodeEqualsParams {
169+
context: CodeActionParams;
170+
fields: VariableField[];
171+
regenerate: boolean;
172+
}
173+
174+
export namespace GenerateHashCodeEqualsRequest {
175+
export const type = new RequestType<GenerateHashCodeEqualsParams, WorkspaceEdit, void, void>('java/generateHashCodeEquals');
150176
}

src/sourceAction.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ import { commands, window } from 'vscode';
44
import { CodeActionParams, LanguageClient } from 'vscode-languageclient';
55
import { Commands } from './commands';
66
import { applyWorkspaceEdit } from './extension';
7-
import { ListOverridableMethodsRequest, AddOverridableMethodsRequest } from './protocol';
7+
import { ListOverridableMethodsRequest, AddOverridableMethodsRequest, CheckHashCodeEqualsStatusRequest, GenerateHashCodeEqualsRequest } from './protocol';
88

99
export function registerCommands(languageClient: LanguageClient) {
10+
registerOverrideMethodsCommand(languageClient);
11+
registerHashCodeEqualsCommand(languageClient);
12+
}
13+
14+
function registerOverrideMethodsCommand(languageClient: LanguageClient): void {
1015
commands.registerCommand(Commands.OVERRIDE_METHODS_PROMPT, async (params: CodeActionParams) => {
1116
const result = await languageClient.sendRequest(ListOverridableMethodsRequest.type, params);
1217
if (!result || !result.methods || !result.methods.length) {
@@ -52,3 +57,46 @@ export function registerCommands(languageClient: LanguageClient) {
5257
applyWorkspaceEdit(workspaceEdit, languageClient);
5358
});
5459
}
60+
61+
function registerHashCodeEqualsCommand(languageClient: LanguageClient): void {
62+
commands.registerCommand(Commands.HASHCODE_EQUALS_PROMPT, async (params: CodeActionParams) => {
63+
const result = await languageClient.sendRequest(CheckHashCodeEqualsStatusRequest.type, params);
64+
if (!result || !result.fields || !result.fields.length) {
65+
window.showErrorMessage(`The operation is not applicable to the type ${result.type}.`);
66+
return;
67+
}
68+
69+
let regenerate = false;
70+
if (result.existingMethods && result.existingMethods.length) {
71+
const ans = await window.showInformationMessage(`Methods ${result.existingMethods.join(' and ')} already ${result.existingMethods.length === 1 ? 'exists' : 'exist'} in the Class '${result.type}'. `
72+
+ 'Do you want to regenerate the implementation?', 'Regenerate', 'Cancel');
73+
if (ans !== 'Regenerate') {
74+
return;
75+
}
76+
77+
regenerate = true;
78+
}
79+
80+
const fieldItems = result.fields.map((field) => {
81+
return {
82+
label: `${field.name}: ${field.type}`,
83+
picked: true,
84+
originalField: field
85+
};
86+
});
87+
const selectedFields = await window.showQuickPick(fieldItems, {
88+
canPickMany: true,
89+
placeHolder: 'Select the fields to include in the hashCode() and equals() methods.'
90+
});
91+
if (!selectedFields.length) {
92+
return;
93+
}
94+
95+
const workspaceEdit = await languageClient.sendRequest(GenerateHashCodeEqualsRequest.type, {
96+
context: params,
97+
fields: selectedFields.map((item) => item.originalField),
98+
regenerate
99+
});
100+
applyWorkspaceEdit(workspaceEdit, languageClient);
101+
});
102+
}

test/extension.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ suite('Java Language Extension', () => {
4242
Commands.REMOVE_FROM_SOURCEPATH,
4343
Commands.LIST_SOURCEPATHS,
4444
Commands.OVERRIDE_METHODS_PROMPT,
45+
Commands.HASHCODE_EQUALS_PROMPT
4546
];
4647
let foundJavaCommands = commands.filter(function(value){
4748
return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.');

0 commit comments

Comments
 (0)