Skip to content

Commit 61aa100

Browse files
testforstephenfbricon
authored andcommitted
Add Code Action: Generate toString()... (#873)
Signed-off-by: Jinbo Wang <[email protected]>
1 parent a249454 commit 61aa100

File tree

7 files changed

+124
-10
lines changed

7 files changed

+124
-10
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,17 @@ The following settings are supported:
9797
* `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`.
9898
* `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`.
9999
* `java.codeGeneration.hashCodeEquals.useInstanceof`: Use 'instanceof' to compare types when generating the hashCode and equals methods. Defaults to `false`.
100-
* `java.codeGeneration.hashCodeEquals.useBlocks`: Use blocks in 'if' statements when generating the hashCode and equals methods. Defaults to `false`.
101-
* `java.codeGeneration.hashCodeEquals.generateComments`: Generate method comments when generating the hashCode and equals methods. Defaults to `false`.
102100
* `java.foldingRange.enabled`: Enable/disable smart folding range support. If disabled, it will use the default indentation-based folding range provided by VS Code.
103101

104102
*New in 0.43.0:*
105103
* `java.maven.downloadSources`: Enable/disable eager download of Maven source artifacts.
104+
* `java.codeGeneration.useBlocks`: Use blocks in 'if' statements when generating the methods. Defaults to `false`.
105+
* `java.codeGeneration.generateComments`: Generate method comments when generating the methods. Defaults to `false`.
106+
* `java.codeGeneration.toString.template`: The template for generating the toString method. Defaults to `${object.className} [${member.name()}=${member.value}, ${otherMembers}]`.
107+
* `java.codeGeneration.toString.codeStyle`: The code style for generating the toString method. Defaults to `STRING_CONCATENATION`.
108+
* `java.codeGeneration.toString.skipNullValues`: Skip null values when generating the toString method. Defaults to `false`.
109+
* `java.codeGeneration.toString.listArrayContents`: List contents of arrays instead of using native toString(). Defaults to `true`.
110+
* `java.codeGeneration.toString.limitElements`: Limit number of items in arrays/collections/maps to list, if 0 then list all. Defaults to `0`.
106111

107112
Troubleshooting
108113
===============

package.json

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,17 +296,57 @@
296296
"default": false,
297297
"scope": "window"
298298
},
299-
"java.codeGeneration.hashCodeEquals.useBlocks": {
299+
"java.codeGeneration.useBlocks": {
300300
"type": "boolean",
301-
"description": "Use blocks in 'if' statements when generating the hashCode and equals methods.",
301+
"description": "Use blocks in 'if' statements when generating the methods.",
302302
"default": false,
303303
"scope": "window"
304304
},
305-
"java.codeGeneration.hashCodeEquals.generateComments": {
305+
"java.codeGeneration.generateComments": {
306306
"type": "boolean",
307-
"description": "Generate method comments when generating the hashCode and equals methods.",
307+
"description": "Generate method comments when generating the methods.",
308308
"default": false,
309309
"scope": "window"
310+
},
311+
"java.codeGeneration.toString.template": {
312+
"type": "string",
313+
"description": "The template for generating the toString method.",
314+
"default": "${object.className} [${member.name()}=${member.value}, ${otherMembers}]"
315+
},
316+
"java.codeGeneration.toString.codeStyle": {
317+
"type": "string",
318+
"enum": [
319+
"STRING_CONCATENATION",
320+
"STRING_BUILDER",
321+
"STRING_BUILDER_CHAINED",
322+
"STRING_FORMAT"
323+
],
324+
"enumDescriptions": [
325+
"String concatenation",
326+
"StringBuilder/StringBuffer",
327+
"StringBuilder/StringBuffer - chained call",
328+
"String.format/MessageFormat"
329+
],
330+
"description": "The code style for generating the toString method.",
331+
"default": "STRING_CONCATENATION"
332+
},
333+
"java.codeGeneration.toString.skipNullValues": {
334+
"type": "boolean",
335+
"description": "Skip null values when generating the toString method.",
336+
"default": false,
337+
"scope": "window"
338+
},
339+
"java.codeGeneration.toString.listArrayContents": {
340+
"type": "boolean",
341+
"description": "List contents of arrays instead of using native toString().",
342+
"default": true,
343+
"scope": "window"
344+
},
345+
"java.codeGeneration.toString.limitElements": {
346+
"type": "integer",
347+
"description": "Limit number of items in arrays/collections/maps to list, if 0 then list all.",
348+
"default": 0,
349+
"scope": "window"
310350
}
311351
}
312352
},

src/commands.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export namespace Commands {
109109
/**
110110
* Generate hashCode() and equals().
111111
*/
112-
export const HASHCODE_EQUALS_PROMPT = 'java.action.hashCodeEqualsPrompt';
112+
export const HASHCODE_EQUALS_PROMPT = 'java.action.hashCodeEqualsPrompt';
113113
/**
114114
* Open settings.json
115115
*/
@@ -122,4 +122,8 @@ export namespace Commands {
122122
* Choose type to import.
123123
*/
124124
export const CHOOSE_IMPORTS = "java.action.organizeImports.chooseImports";
125+
/**
126+
* Generate toString().
127+
*/
128+
export const GENERATE_TOSTRING_PROMPT = 'java.action.generateToStringPrompt';
125129
}

src/extension.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ export function activate(context: ExtensionContext): Promise<ExtensionAPI> {
6565
classFileContentsSupport:true,
6666
overrideMethodsPromptSupport:true,
6767
hashCodeEqualsPromptSupport:true,
68-
advancedOrganizeImportsSupport:true
68+
advancedOrganizeImportsSupport:true,
69+
generateToStringPromptSupport:true
6970
},
7071
triggerFiles: getTriggerFiles()
7172
},

src/protocol.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,23 @@ export interface ImportCandidate {
187187
export interface ImportSelection {
188188
candidates: ImportCandidate[];
189189
range: Range;
190+
}
191+
192+
export interface CheckToStringResponse {
193+
type: string;
194+
fields: VariableField[];
195+
exists: boolean;
196+
}
197+
198+
export namespace CheckToStringStatusRequest {
199+
export const type = new RequestType<CodeActionParams, CheckToStringResponse, void, void>('java/checkToStringStatus');
200+
}
201+
202+
export interface GenerateToStringParams {
203+
context: CodeActionParams;
204+
fields: VariableField[];
205+
}
206+
207+
export namespace GenerateToStringRequest {
208+
export const type = new RequestType<GenerateToStringParams, WorkspaceEdit, void, void>('java/generateToString');
190209
}

src/sourceAction.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import { CodeActionParams, LanguageClient } from 'vscode-languageclient';
55
import { Commands } from './commands';
66
import { applyWorkspaceEdit } from './extension';
77
import { ListOverridableMethodsRequest, AddOverridableMethodsRequest, CheckHashCodeEqualsStatusRequest, GenerateHashCodeEqualsRequest,
8-
OrganizeImportsRequest, ImportCandidate, ImportSelection } from './protocol';
8+
OrganizeImportsRequest, ImportCandidate, ImportSelection, GenerateToStringRequest, CheckToStringStatusRequest, VariableField } from './protocol';
99

1010
export function registerCommands(languageClient: LanguageClient, context: ExtensionContext) {
1111
registerOverrideMethodsCommand(languageClient, context);
1212
registerHashCodeEqualsCommand(languageClient, context);
1313
registerOrganizeImportsCommand(languageClient, context);
1414
registerChooseImportCommand(context);
15+
registerGenerateToStringCommand(languageClient, context);
1516
}
1617

1718
function registerOverrideMethodsCommand(languageClient: LanguageClient, context: ExtensionContext): void {
@@ -158,3 +159,46 @@ function registerChooseImportCommand(context: ExtensionContext): void {
158159
return chosen;
159160
}));
160161
}
162+
163+
function registerGenerateToStringCommand(languageClient: LanguageClient, context: ExtensionContext): void {
164+
context.subscriptions.push(commands.registerCommand(Commands.GENERATE_TOSTRING_PROMPT, async (params: CodeActionParams) => {
165+
const result = await languageClient.sendRequest(CheckToStringStatusRequest.type, params);
166+
if (!result) {
167+
return;
168+
}
169+
170+
if (result.exists) {
171+
const ans = await window.showInformationMessage(`Method 'toString()' already exists in the Class '${result.type}'. `
172+
+ 'Do you want to replace the implementation?', 'Replace', 'Cancel');
173+
if (ans !== 'Replace') {
174+
return;
175+
}
176+
}
177+
178+
let fields: VariableField[] = [];
179+
if (result.fields && result.fields.length) {
180+
const fieldItems = result.fields.map((field) => {
181+
return {
182+
label: `${field.name}: ${field.type}`,
183+
picked: true,
184+
originalField: field
185+
};
186+
});
187+
const selectedFields = await window.showQuickPick(fieldItems, {
188+
canPickMany: true,
189+
placeHolder: 'Select the fields to include in the toString() method.'
190+
});
191+
if (!selectedFields) {
192+
return;
193+
}
194+
195+
fields = selectedFields.map((item) => item.originalField);
196+
}
197+
198+
const workspaceEdit = await languageClient.sendRequest(GenerateToStringRequest.type, {
199+
context: params,
200+
fields,
201+
});
202+
applyWorkspaceEdit(workspaceEdit, languageClient);
203+
}));
204+
}

test/extension.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ suite('Java Language Extension', () => {
4545
Commands.HASHCODE_EQUALS_PROMPT,
4646
Commands.OPEN_JSON_SETTINGS,
4747
Commands.ORGANIZE_IMPORTS,
48-
Commands.CHOOSE_IMPORTS
48+
Commands.CHOOSE_IMPORTS,
49+
Commands.GENERATE_TOSTRING_PROMPT
4950
];
5051
let foundJavaCommands = commands.filter(function(value){
5152
return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.');

0 commit comments

Comments
 (0)