Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Code Action: Generate toString()... #873

Merged
merged 3 commits into from
Apr 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,17 @@ The following settings are supported:
* `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`.
* `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`.
* `java.codeGeneration.hashCodeEquals.useInstanceof`: Use 'instanceof' to compare types when generating the hashCode and equals methods. Defaults to `false`.
* `java.codeGeneration.hashCodeEquals.useBlocks`: Use blocks in 'if' statements when generating the hashCode and equals methods. Defaults to `false`.
* `java.codeGeneration.hashCodeEquals.generateComments`: Generate method comments when generating the hashCode and equals methods. Defaults to `false`.
* `java.foldingRange.enabled`: Enable/disable smart folding range support. If disabled, it will use the default indentation-based folding range provided by VS Code.

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

Troubleshooting
===============
Expand Down
48 changes: 44 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -296,17 +296,57 @@
"default": false,
"scope": "window"
},
"java.codeGeneration.hashCodeEquals.useBlocks": {
"java.codeGeneration.useBlocks": {
"type": "boolean",
"description": "Use blocks in 'if' statements when generating the hashCode and equals methods.",
"description": "Use blocks in 'if' statements when generating the methods.",
"default": false,
"scope": "window"
},
"java.codeGeneration.hashCodeEquals.generateComments": {
"java.codeGeneration.generateComments": {
"type": "boolean",
"description": "Generate method comments when generating the hashCode and equals methods.",
"description": "Generate method comments when generating the methods.",
"default": false,
"scope": "window"
},
"java.codeGeneration.toString.template": {
"type": "string",
"description": "The template for generating the toString method.",
"default": "${object.className} [${member.name()}=${member.value}, ${otherMembers}]"
},
"java.codeGeneration.toString.codeStyle": {
"type": "string",
"enum": [
"STRING_CONCATENATION",
"STRING_BUILDER",
"STRING_BUILDER_CHAINED",
"STRING_FORMAT"
],
"enumDescriptions": [
"String concatenation",
"StringBuilder/StringBuffer",
"StringBuilder/StringBuffer - chained call",
"String.format/MessageFormat"
],
"description": "The code style for generating the toString method.",
"default": "STRING_CONCATENATION"
},
"java.codeGeneration.toString.skipNullValues": {
"type": "boolean",
"description": "Skip null values when generating the toString method.",
"default": false,
"scope": "window"
},
"java.codeGeneration.toString.listArrayContents": {
"type": "boolean",
"description": "List contents of arrays instead of using native toString().",
"default": true,
"scope": "window"
},
"java.codeGeneration.toString.limitElements": {
"type": "integer",
"description": "Limit number of items in arrays/collections/maps to list, if 0 then list all.",
"default": 0,
"scope": "window"
}
}
},
Expand Down
6 changes: 5 additions & 1 deletion src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export namespace Commands {
/**
* Generate hashCode() and equals().
*/
export const HASHCODE_EQUALS_PROMPT = 'java.action.hashCodeEqualsPrompt';
export const HASHCODE_EQUALS_PROMPT = 'java.action.hashCodeEqualsPrompt';
/**
* Open settings.json
*/
Expand All @@ -122,4 +122,8 @@ export namespace Commands {
* Choose type to import.
*/
export const CHOOSE_IMPORTS = "java.action.organizeImports.chooseImports";
/**
* Generate toString().
*/
export const GENERATE_TOSTRING_PROMPT = 'java.action.generateToStringPrompt';
}
3 changes: 2 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ export function activate(context: ExtensionContext): Promise<ExtensionAPI> {
classFileContentsSupport:true,
overrideMethodsPromptSupport:true,
hashCodeEqualsPromptSupport:true,
advancedOrganizeImportsSupport:true
advancedOrganizeImportsSupport:true,
generateToStringPromptSupport:true
},
triggerFiles: getTriggerFiles()
},
Expand Down
19 changes: 19 additions & 0 deletions src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,23 @@ export interface ImportCandidate {
export interface ImportSelection {
candidates: ImportCandidate[];
range: Range;
}

export interface CheckToStringResponse {
type: string;
fields: VariableField[];
exists: boolean;
}

export namespace CheckToStringStatusRequest {
export const type = new RequestType<CodeActionParams, CheckToStringResponse, void, void>('java/checkToStringStatus');
}

export interface GenerateToStringParams {
context: CodeActionParams;
fields: VariableField[];
}

export namespace GenerateToStringRequest {
export const type = new RequestType<GenerateToStringParams, WorkspaceEdit, void, void>('java/generateToString');
}
46 changes: 45 additions & 1 deletion src/sourceAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { CodeActionParams, LanguageClient } from 'vscode-languageclient';
import { Commands } from './commands';
import { applyWorkspaceEdit } from './extension';
import { ListOverridableMethodsRequest, AddOverridableMethodsRequest, CheckHashCodeEqualsStatusRequest, GenerateHashCodeEqualsRequest,
OrganizeImportsRequest, ImportCandidate, ImportSelection } from './protocol';
OrganizeImportsRequest, ImportCandidate, ImportSelection, GenerateToStringRequest, CheckToStringStatusRequest, VariableField } from './protocol';

export function registerCommands(languageClient: LanguageClient, context: ExtensionContext) {
registerOverrideMethodsCommand(languageClient, context);
registerHashCodeEqualsCommand(languageClient, context);
registerOrganizeImportsCommand(languageClient, context);
registerChooseImportCommand(context);
registerGenerateToStringCommand(languageClient, context);
}

function registerOverrideMethodsCommand(languageClient: LanguageClient, context: ExtensionContext): void {
Expand Down Expand Up @@ -158,3 +159,46 @@ function registerChooseImportCommand(context: ExtensionContext): void {
return chosen;
}));
}

function registerGenerateToStringCommand(languageClient: LanguageClient, context: ExtensionContext): void {
context.subscriptions.push(commands.registerCommand(Commands.GENERATE_TOSTRING_PROMPT, async (params: CodeActionParams) => {
const result = await languageClient.sendRequest(CheckToStringStatusRequest.type, params);
if (!result) {
return;
}

if (result.exists) {
const ans = await window.showInformationMessage(`Method 'toString()' already exists in the Class '${result.type}'. `
+ 'Do you want to replace the implementation?', 'Replace', 'Cancel');
if (ans !== 'Replace') {
return;
}
}

let fields: VariableField[] = [];
if (result.fields && result.fields.length) {
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 toString() method.'
});
if (!selectedFields) {
return;
}

fields = selectedFields.map((item) => item.originalField);
}

const workspaceEdit = await languageClient.sendRequest(GenerateToStringRequest.type, {
context: params,
fields,
});
applyWorkspaceEdit(workspaceEdit, languageClient);
}));
}
3 changes: 2 additions & 1 deletion test/extension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ suite('Java Language Extension', () => {
Commands.HASHCODE_EQUALS_PROMPT,
Commands.OPEN_JSON_SETTINGS,
Commands.ORGANIZE_IMPORTS,
Commands.CHOOSE_IMPORTS
Commands.CHOOSE_IMPORTS,
Commands.GENERATE_TOSTRING_PROMPT
];
let foundJavaCommands = commands.filter(function(value){
return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.');
Expand Down