Skip to content

Enable code action: Generate Delegate Methods... #930

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

Merged
merged 3 commits into from
May 23, 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
4 changes: 4 additions & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,8 @@ export namespace Commands {
* Generate Constructors.
*/
export const GENERATE_CONSTRUCTORS_PROMPT = 'java.action.generateConstructorsPrompt';
/**
* Generate Delegate Methods.
*/
export const GENERATE_DELEGATE_METHODS_PROMPT = 'java.action.generateDelegateMethodsPrompt';
}
1 change: 1 addition & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export function activate(context: ExtensionContext): Promise<ExtensionAPI> {
generateToStringPromptSupport: true,
advancedGenerateAccessorsSupport: true,
generateConstructorsPromptSupport: true,
generateDelegateMethodsPromptSupport: true,
},
triggerFiles: getTriggerFiles()
},
Expand Down
27 changes: 27 additions & 0 deletions src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,30 @@ export interface GenerateConstructorsParams {
export namespace GenerateConstructorsRequest {
export const type = new RequestType<GenerateConstructorsParams, WorkspaceEdit, void, void>('java/generateConstructors');
}

export interface DelegateField {
field: VariableBinding;
delegateMethods: MethodBinding[];
}

export interface CheckDelegateMethodsResponse {
delegateFields: DelegateField[];
}

export namespace CheckDelegateMethodsStatusRequest {
export const type = new RequestType<CodeActionParams, CheckDelegateMethodsResponse, void, void>('java/checkDelegateMethodsStatus');
}

export interface DelegateEntry {
field: VariableBinding;
delegateMethod: MethodBinding;
}

export interface GenerateDelegateMethodsParams {
context: CodeActionParams;
delegateEntries: DelegateEntry[];
}

export namespace GenerateDelegateMethodsRequest {
export const type = new RequestType<GenerateDelegateMethodsParams, WorkspaceEdit, void, void>('java/generateDelegateMethods');
}
64 changes: 63 additions & 1 deletion src/sourceAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { CodeActionParams, LanguageClient } from 'vscode-languageclient';
import { Commands } from './commands';
import { applyWorkspaceEdit } from './extension';
import { ListOverridableMethodsRequest, AddOverridableMethodsRequest, CheckHashCodeEqualsStatusRequest, GenerateHashCodeEqualsRequest,
OrganizeImportsRequest, ImportCandidate, ImportSelection, GenerateToStringRequest, CheckToStringStatusRequest, VariableBinding, ResolveUnimplementedAccessorsRequest, GenerateAccessorsRequest, CheckConstructorStatusRequest, GenerateConstructorsRequest } from './protocol';
OrganizeImportsRequest, ImportCandidate, ImportSelection, GenerateToStringRequest, CheckToStringStatusRequest, VariableBinding, ResolveUnimplementedAccessorsRequest, GenerateAccessorsRequest, CheckConstructorStatusRequest, GenerateConstructorsRequest, CheckDelegateMethodsStatusRequest, GenerateDelegateMethodsRequest } from './protocol';

export function registerCommands(languageClient: LanguageClient, context: ExtensionContext) {
registerOverrideMethodsCommand(languageClient, context);
Expand All @@ -15,6 +15,7 @@ export function registerCommands(languageClient: LanguageClient, context: Extens
registerGenerateToStringCommand(languageClient, context);
registerGenerateAccessorsCommand(languageClient, context);
registerGenerateConstructorsCommand(languageClient, context);
registerGenerateDelegateMethodsCommand(languageClient, context);
}

function registerOverrideMethodsCommand(languageClient: LanguageClient, context: ExtensionContext): void {
Expand Down Expand Up @@ -295,3 +296,64 @@ function registerGenerateConstructorsCommand(languageClient: LanguageClient, con
applyWorkspaceEdit(workspaceEdit, languageClient);
}));
}

function registerGenerateDelegateMethodsCommand(languageClient: LanguageClient, context: ExtensionContext): void {
context.subscriptions.push(commands.registerCommand(Commands.GENERATE_DELEGATE_METHODS_PROMPT, async (params: CodeActionParams) => {
const status = await languageClient.sendRequest(CheckDelegateMethodsStatusRequest.type, params);
if (!status || !status.delegateFields || !status.delegateFields.length) {
window.showWarningMessage("All delegatable methods are already implemented.");
return;
}

let selectedDelegateField = status.delegateFields[0];
if (status.delegateFields.length > 1) {
const fieldItems = status.delegateFields.map((delegateField) => {
return {
label: `${delegateField.field.name}: ${delegateField.field.type}`,
originalField: delegateField,
};
});
const selectedFieldItem = await window.showQuickPick(fieldItems, {
placeHolder: 'Select target to generate delegates for.',
});
if (!selectedFieldItem) {
return;
}

selectedDelegateField = selectedFieldItem.originalField;
}

let delegateEntryItems = selectedDelegateField.delegateMethods.map(delegateMethod => {
return {
label: `${selectedDelegateField.field.name}.${delegateMethod.name}(${delegateMethod.parameters.join(',')})`,
originalField: selectedDelegateField.field,
originalMethod: delegateMethod,
}
});

if (!delegateEntryItems.length) {
window.showWarningMessage("All delegatable methods are already implemented.");
return;
}

const selectedDelegateEntryItems = await window.showQuickPick(delegateEntryItems, {
canPickMany: true,
placeHolder: 'Select methods to generate delegates for.',
});
if (!selectedDelegateEntryItems || !selectedDelegateEntryItems.length) {
return;
}

const delegateEntries = selectedDelegateEntryItems.map(item => {
return {
field: item.originalField,
delegateMethod: item.originalMethod,
};
});
const workspaceEdit = await languageClient.sendRequest(GenerateDelegateMethodsRequest.type, {
context: params,
delegateEntries,
});
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 @@ -49,6 +49,7 @@ suite('Java Language Extension', () => {
Commands.GENERATE_TOSTRING_PROMPT,
Commands.GENERATE_ACCESSORS_PROMPT,
Commands.GENERATE_CONSTRUCTORS_PROMPT,
Commands.GENERATE_DELEGATE_METHODS_PROMPT,
];
const foundJavaCommands = commands.filter(function(value) {
return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.');
Expand Down