Skip to content

Commit e93092c

Browse files
testforstephenfbricon
authored andcommitted
Enable Source Action: Generate Constructors
Signed-off-by: Jinbo Wang <jinbwan@microsoft.com>
1 parent 8437dba commit e93092c

5 files changed

Lines changed: 94 additions & 8 deletions

File tree

src/commands.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,8 @@ export namespace Commands {
130130
* Generate Getters and Setters.
131131
*/
132132
export const GENERATE_ACCESSORS_PROMPT = 'java.action.generateAccessorsPrompt';
133+
/**
134+
* Generate Constructors.
135+
*/
136+
export const GENERATE_CONSTRUCTORS_PROMPT = 'java.action.generateConstructorsPrompt';
133137
}

src/extension.ts

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

src/protocol.ts

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,15 +148,15 @@ export namespace AddOverridableMethodsRequest {
148148
export const type = new RequestType<AddOverridableMethodParams, WorkspaceEdit, void, void>('java/addOverridableMethods');
149149
}
150150

151-
export interface VariableField {
151+
export interface VariableBinding {
152152
bindingKey: string;
153153
name: string;
154154
type: string;
155155
}
156156

157157
export interface CheckHashCodeEqualsResponse {
158158
type: string;
159-
fields: VariableField[];
159+
fields: VariableBinding[];
160160
existingMethods: string[];
161161
}
162162

@@ -166,7 +166,7 @@ export namespace CheckHashCodeEqualsStatusRequest {
166166

167167
export interface GenerateHashCodeEqualsParams {
168168
context: CodeActionParams;
169-
fields: VariableField[];
169+
fields: VariableBinding[];
170170
regenerate: boolean;
171171
}
172172

@@ -190,7 +190,7 @@ export interface ImportSelection {
190190

191191
export interface CheckToStringResponse {
192192
type: string;
193-
fields: VariableField[];
193+
fields: VariableBinding[];
194194
exists: boolean;
195195
}
196196

@@ -200,7 +200,7 @@ export namespace CheckToStringStatusRequest {
200200

201201
export interface GenerateToStringParams {
202202
context: CodeActionParams;
203-
fields: VariableField[];
203+
fields: VariableBinding[];
204204
}
205205

206206
export namespace GenerateToStringRequest {
@@ -226,3 +226,28 @@ export interface GenerateAccessorsParams {
226226
export namespace GenerateAccessorsRequest {
227227
export const type = new RequestType<GenerateAccessorsParams, WorkspaceEdit, void, void>('java/generateAccessors');
228228
}
229+
230+
export interface MethodBinding {
231+
bindingKey: string;
232+
name: string;
233+
parameters: string[];
234+
}
235+
236+
export interface CheckConstructorsResponse {
237+
constructors: MethodBinding[];
238+
fields: VariableBinding[];
239+
}
240+
241+
export namespace CheckConstructorStatusRequest {
242+
export const type = new RequestType<CodeActionParams, CheckConstructorsResponse, void, void>('java/checkConstructorsStatus');
243+
}
244+
245+
export interface GenerateConstructorsParams {
246+
context: CodeActionParams;
247+
constructors: MethodBinding[];
248+
fields: VariableBinding[];
249+
}
250+
251+
export namespace GenerateConstructorsRequest {
252+
export const type = new RequestType<GenerateConstructorsParams, WorkspaceEdit, void, void>('java/generateConstructors');
253+
}

src/sourceAction.ts

Lines changed: 57 additions & 2 deletions
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, VariableField, ResolveUnimplementedAccessorsRequest, GenerateAccessorsRequest } from './protocol';
8+
OrganizeImportsRequest, ImportCandidate, ImportSelection, GenerateToStringRequest, CheckToStringStatusRequest, VariableBinding, ResolveUnimplementedAccessorsRequest, GenerateAccessorsRequest, CheckConstructorStatusRequest, GenerateConstructorsRequest } from './protocol';
99

1010
export function registerCommands(languageClient: LanguageClient, context: ExtensionContext) {
1111
registerOverrideMethodsCommand(languageClient, context);
@@ -14,6 +14,7 @@ export function registerCommands(languageClient: LanguageClient, context: Extens
1414
registerChooseImportCommand(context);
1515
registerGenerateToStringCommand(languageClient, context);
1616
registerGenerateAccessorsCommand(languageClient, context);
17+
registerGenerateConstructorsCommand(languageClient, context);
1718
}
1819

1920
function registerOverrideMethodsCommand(languageClient: LanguageClient, context: ExtensionContext): void {
@@ -176,7 +177,7 @@ function registerGenerateToStringCommand(languageClient: LanguageClient, context
176177
}
177178
}
178179

179-
let fields: VariableField[] = [];
180+
let fields: VariableBinding[] = [];
180181
if (result.fields && result.fields.length) {
181182
const fieldItems = result.fields.map((field) => {
182183
return {
@@ -240,3 +241,57 @@ function registerGenerateAccessorsCommand(languageClient: LanguageClient, contex
240241
applyWorkspaceEdit(workspaceEdit, languageClient);
241242
}));
242243
}
244+
245+
function registerGenerateConstructorsCommand(languageClient: LanguageClient, context: ExtensionContext): void {
246+
context.subscriptions.push(commands.registerCommand(Commands.GENERATE_CONSTRUCTORS_PROMPT, async (params: CodeActionParams) => {
247+
const status = await languageClient.sendRequest(CheckConstructorStatusRequest.type, params);
248+
if (!status || !status.constructors || !status.constructors.length) {
249+
return;
250+
}
251+
252+
let selectedConstructors = status.constructors;
253+
let selectedFields = [];
254+
if (status.constructors.length > 1) {
255+
const constructorItems = status.constructors.map((constructor) => {
256+
return {
257+
label: `${constructor.name}(${constructor.parameters.join(',')})`,
258+
originalConstructor: constructor,
259+
};
260+
});
261+
const selectedConstructorItems = await window.showQuickPick(constructorItems, {
262+
canPickMany: true,
263+
placeHolder: 'Select super class constructor(s).',
264+
});
265+
if (!selectedConstructorItems || !selectedConstructorItems.length) {
266+
return;
267+
}
268+
269+
selectedConstructors = selectedConstructorItems.map(item => item.originalConstructor);
270+
}
271+
272+
if (status.fields.length) {
273+
const fieldItems = status.fields.map((field) => {
274+
return {
275+
label: `${field.name}: ${field.type}`,
276+
originalField: field,
277+
};
278+
});
279+
const selectedFieldItems = await window.showQuickPick(fieldItems, {
280+
canPickMany: true,
281+
placeHolder: 'Select fields to initialize by constructor(s).',
282+
});
283+
if (!selectedFieldItems) {
284+
return;
285+
}
286+
287+
selectedFields = selectedFieldItems.map(item => item.originalField);
288+
}
289+
290+
const workspaceEdit = await languageClient.sendRequest(GenerateConstructorsRequest.type, {
291+
context: params,
292+
constructors: selectedConstructors,
293+
fields: selectedFields,
294+
});
295+
applyWorkspaceEdit(workspaceEdit, languageClient);
296+
}));
297+
}

test/extension.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ suite('Java Language Extension', () => {
4747
Commands.ORGANIZE_IMPORTS,
4848
Commands.CHOOSE_IMPORTS,
4949
Commands.GENERATE_TOSTRING_PROMPT,
50-
Commands.GENERATE_ACCESSORS_PROMPT
50+
Commands.GENERATE_ACCESSORS_PROMPT,
51+
Commands.GENERATE_CONSTRUCTORS_PROMPT,
5152
];
5253
const foundJavaCommands = commands.filter(function(value) {
5354
return JAVA_COMMANDS.indexOf(value)>=0 || value.startsWith('java.');

0 commit comments

Comments
 (0)