Skip to content

Commit 0d81470

Browse files
testforstephenfbricon
authored andcommitted
Enable code action: Generate Delegate Methods... (#930)
Signed-off-by: Jinbo Wang <jinbwan@microsoft.com>
1 parent 1012a56 commit 0d81470

5 files changed

Lines changed: 96 additions & 1 deletion

File tree

src/commands.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,8 @@ export namespace Commands {
134134
* Generate Constructors.
135135
*/
136136
export const GENERATE_CONSTRUCTORS_PROMPT = 'java.action.generateConstructorsPrompt';
137+
/**
138+
* Generate Delegate Methods.
139+
*/
140+
export const GENERATE_DELEGATE_METHODS_PROMPT = 'java.action.generateDelegateMethodsPrompt';
137141
}

src/extension.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export function activate(context: ExtensionContext): Promise<ExtensionAPI> {
7171
generateToStringPromptSupport: true,
7272
advancedGenerateAccessorsSupport: true,
7373
generateConstructorsPromptSupport: true,
74+
generateDelegateMethodsPromptSupport: true,
7475
},
7576
triggerFiles: getTriggerFiles()
7677
},

src/protocol.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,30 @@ export interface GenerateConstructorsParams {
251251
export namespace GenerateConstructorsRequest {
252252
export const type = new RequestType<GenerateConstructorsParams, WorkspaceEdit, void, void>('java/generateConstructors');
253253
}
254+
255+
export interface DelegateField {
256+
field: VariableBinding;
257+
delegateMethods: MethodBinding[];
258+
}
259+
260+
export interface CheckDelegateMethodsResponse {
261+
delegateFields: DelegateField[];
262+
}
263+
264+
export namespace CheckDelegateMethodsStatusRequest {
265+
export const type = new RequestType<CodeActionParams, CheckDelegateMethodsResponse, void, void>('java/checkDelegateMethodsStatus');
266+
}
267+
268+
export interface DelegateEntry {
269+
field: VariableBinding;
270+
delegateMethod: MethodBinding;
271+
}
272+
273+
export interface GenerateDelegateMethodsParams {
274+
context: CodeActionParams;
275+
delegateEntries: DelegateEntry[];
276+
}
277+
278+
export namespace GenerateDelegateMethodsRequest {
279+
export const type = new RequestType<GenerateDelegateMethodsParams, WorkspaceEdit, void, void>('java/generateDelegateMethods');
280+
}

src/sourceAction.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ 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, GenerateToStringRequest, CheckToStringStatusRequest, VariableBinding, ResolveUnimplementedAccessorsRequest, GenerateAccessorsRequest, CheckConstructorStatusRequest, GenerateConstructorsRequest } from './protocol';
8+
OrganizeImportsRequest, ImportCandidate, ImportSelection, GenerateToStringRequest, CheckToStringStatusRequest, VariableBinding, ResolveUnimplementedAccessorsRequest, GenerateAccessorsRequest, CheckConstructorStatusRequest, GenerateConstructorsRequest, CheckDelegateMethodsStatusRequest, GenerateDelegateMethodsRequest } from './protocol';
99

1010
export function registerCommands(languageClient: LanguageClient, context: ExtensionContext) {
1111
registerOverrideMethodsCommand(languageClient, context);
@@ -15,6 +15,7 @@ export function registerCommands(languageClient: LanguageClient, context: Extens
1515
registerGenerateToStringCommand(languageClient, context);
1616
registerGenerateAccessorsCommand(languageClient, context);
1717
registerGenerateConstructorsCommand(languageClient, context);
18+
registerGenerateDelegateMethodsCommand(languageClient, context);
1819
}
1920

2021
function registerOverrideMethodsCommand(languageClient: LanguageClient, context: ExtensionContext): void {
@@ -295,3 +296,64 @@ function registerGenerateConstructorsCommand(languageClient: LanguageClient, con
295296
applyWorkspaceEdit(workspaceEdit, languageClient);
296297
}));
297298
}
299+
300+
function registerGenerateDelegateMethodsCommand(languageClient: LanguageClient, context: ExtensionContext): void {
301+
context.subscriptions.push(commands.registerCommand(Commands.GENERATE_DELEGATE_METHODS_PROMPT, async (params: CodeActionParams) => {
302+
const status = await languageClient.sendRequest(CheckDelegateMethodsStatusRequest.type, params);
303+
if (!status || !status.delegateFields || !status.delegateFields.length) {
304+
window.showWarningMessage("All delegatable methods are already implemented.");
305+
return;
306+
}
307+
308+
let selectedDelegateField = status.delegateFields[0];
309+
if (status.delegateFields.length > 1) {
310+
const fieldItems = status.delegateFields.map((delegateField) => {
311+
return {
312+
label: `${delegateField.field.name}: ${delegateField.field.type}`,
313+
originalField: delegateField,
314+
};
315+
});
316+
const selectedFieldItem = await window.showQuickPick(fieldItems, {
317+
placeHolder: 'Select target to generate delegates for.',
318+
});
319+
if (!selectedFieldItem) {
320+
return;
321+
}
322+
323+
selectedDelegateField = selectedFieldItem.originalField;
324+
}
325+
326+
let delegateEntryItems = selectedDelegateField.delegateMethods.map(delegateMethod => {
327+
return {
328+
label: `${selectedDelegateField.field.name}.${delegateMethod.name}(${delegateMethod.parameters.join(',')})`,
329+
originalField: selectedDelegateField.field,
330+
originalMethod: delegateMethod,
331+
}
332+
});
333+
334+
if (!delegateEntryItems.length) {
335+
window.showWarningMessage("All delegatable methods are already implemented.");
336+
return;
337+
}
338+
339+
const selectedDelegateEntryItems = await window.showQuickPick(delegateEntryItems, {
340+
canPickMany: true,
341+
placeHolder: 'Select methods to generate delegates for.',
342+
});
343+
if (!selectedDelegateEntryItems || !selectedDelegateEntryItems.length) {
344+
return;
345+
}
346+
347+
const delegateEntries = selectedDelegateEntryItems.map(item => {
348+
return {
349+
field: item.originalField,
350+
delegateMethod: item.originalMethod,
351+
};
352+
});
353+
const workspaceEdit = await languageClient.sendRequest(GenerateDelegateMethodsRequest.type, {
354+
context: params,
355+
delegateEntries,
356+
});
357+
applyWorkspaceEdit(workspaceEdit, languageClient);
358+
}));
359+
}

test/extension.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ suite('Java Language Extension', () => {
4949
Commands.GENERATE_TOSTRING_PROMPT,
5050
Commands.GENERATE_ACCESSORS_PROMPT,
5151
Commands.GENERATE_CONSTRUCTORS_PROMPT,
52+
Commands.GENERATE_DELEGATE_METHODS_PROMPT,
5253
];
5354
const foundJavaCommands = commands.filter(function(value) {
5455
return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.');

0 commit comments

Comments
 (0)