1717
1818import java .util .List ;
1919
20+ import org .eclipse .core .runtime .NullProgressMonitor ;
2021import org .eclipse .jdt .core .ICompilationUnit ;
2122import org .eclipse .jdt .core .IJavaProject ;
2223import org .eclipse .jdt .core .IPackageFragment ;
2324import org .eclipse .jdt .core .IPackageFragmentRoot ;
2425import org .eclipse .jdt .core .JavaModelException ;
26+ import org .eclipse .jdt .internal .corext .codemanipulation .CodeGenerationSettings ;
27+ import org .eclipse .jdt .internal .corext .util .JavaModelUtil ;
2528import org .eclipse .jdt .ls .core .internal .CodeActionUtil ;
2629import org .eclipse .jdt .ls .core .internal .JavaClientConnection ;
2730import org .eclipse .jdt .ls .core .internal .JavaCodeActionKind ;
3033import org .eclipse .lsp4j .CodeAction ;
3134import org .eclipse .lsp4j .CodeActionParams ;
3235import org .eclipse .lsp4j .Command ;
33- import org .eclipse .lsp4j .WorkspaceEdit ;
3436import org .eclipse .lsp4j .jsonrpc .messages .Either ;
37+ import org .eclipse .text .edits .TextEdit ;
3538import org .junit .Assert ;
3639import org .junit .Before ;
3740import org .junit .Test ;
@@ -61,12 +64,13 @@ public void setup() throws Exception {
6164 @ Test
6265 public void testGenerateConstructorsEnabled () throws JavaModelException {
6366 //@formatter:off
64- ICompilationUnit unit = fPackageP .createCompilationUnit ("A.java" , "package p;\r \n " +
65- "\r \n " +
66- "public class A {\r \n " +
67- " String name;\r \n " +
68- "}"
69- , true , null );
67+ ICompilationUnit unit = fPackageP .createCompilationUnit ("A.java" , """
68+ package p;
69+
70+ public class A {
71+ String name;
72+ }
73+ """ , true , null );
7074 //@formatter:on
7175 CodeActionParams params = CodeActionUtil .constructCodeActionParams (unit , "String name" );
7276 List <Either <Command , CodeAction >> codeActions = server .codeAction (params ).join ();
@@ -81,12 +85,13 @@ public void testGenerateConstructorsEnabled() throws JavaModelException {
8185 @ Test
8286 public void testGenerateConstructorsQuickAssist () throws JavaModelException {
8387 //@formatter:off
84- ICompilationUnit unit = fPackageP .createCompilationUnit ("A.java" , "package p;\r \n " +
85- "\r \n " +
86- "public class A {\r \n " +
87- " String name;\r \n " +
88- "}"
89- , true , null );
88+ ICompilationUnit unit = fPackageP .createCompilationUnit ("A.java" , """
89+ package p;
90+
91+ public class A {
92+ String name;
93+ }
94+ """ , true , null );
9095 //@formatter:on
9196 // test for field declaration
9297 CodeActionParams params = CodeActionUtil .constructCodeActionParams (unit , "String name" );
@@ -106,52 +111,60 @@ public void testGenerateConstructorsQuickAssist() throws JavaModelException {
106111 @ Test
107112 public void testGenerateConstructorsQuickAssistWithAllStaticFields () throws JavaModelException {
108113 //@formatter:off
109- ICompilationUnit unit = fPackageP .createCompilationUnit ("A.java" , "package p;\r \n " +
110- "\r \n " +
111- "public class A {\r \n " +
112- " static String name;\r \n " +
113- "}"
114- , true , null );
114+ ICompilationUnit unit = fPackageP .createCompilationUnit ("A.java" , """
115+ package p;
116+
117+ public class A {
118+ static String name;
119+ }
120+ """ , true , null );
115121 //@formatter:on
116122 // test for field declaration
117123 CodeActionParams params = CodeActionUtil .constructCodeActionParams (unit , "static String name" );
118124 List <Either <Command , CodeAction >> codeActions = server .codeAction (params ).join ();
119125 Assert .assertNotNull (codeActions );
120- Either <Command , CodeAction > constructorAction = CodeActionHandlerTest .findAction (codeActions , JavaCodeActionKind .SOURCE_GENERATE_CONSTRUCTORS );
121- Assert .assertNull (constructorAction );
126+ Either <Command , CodeAction > quickAssistActions = CodeActionHandlerTest .findAction (codeActions , JavaCodeActionKind .QUICK_ASSIST );
127+ Assert .assertNotNull (quickAssistActions );
128+ Assert .assertFalse ("Generate constructors quick assist should not be available for a static field" ,
129+ CodeActionHandlerTest .commandExists (List .of (quickAssistActions ), SourceAssistProcessor .COMMAND_ID_ACTION_GENERATECONSTRUCTORSPROMPT ));
122130 // test for type declaration
123131 params = CodeActionUtil .constructCodeActionParams (unit , "class A" );
124132 codeActions = server .codeAction (params ).join ();
125133 Assert .assertNotNull (codeActions );
126- constructorAction = CodeActionHandlerTest .findAction (codeActions , JavaCodeActionKind .SOURCE_GENERATE_CONSTRUCTORS );
127- Assert .assertNull (constructorAction );
134+ Either <Command , CodeAction > constructorAction = CodeActionHandlerTest .findAction (codeActions , JavaCodeActionKind .SOURCE_GENERATE_CONSTRUCTORS );
135+ // constructor should not refer to static fields
136+ Assert .assertNotNull (constructorAction );
137+
128138 }
129139
130140 @ Test
131- public void testGenerateConstructorsDisabled_emptyFields () throws JavaModelException {
141+ public void testGenerateConstructors_emptyFields () throws JavaModelException {
132142 //@formatter:off
133- ICompilationUnit unit = fPackageP .createCompilationUnit ("A.java" , "package p;\r \n " +
134- "\r \n " +
135- "public class A {\r \n " +
136- "}"
137- , true , null );
143+ ICompilationUnit unit = fPackageP .createCompilationUnit ("A.java" , """
144+ package p;
145+
146+ public class A {
147+ }
148+ """ , true , null );
138149 //@formatter:on
139150 CodeActionParams params = CodeActionUtil .constructCodeActionParams (unit , "class A" );
140151 List <Either <Command , CodeAction >> codeActions = server .codeAction (params ).join ();
141152 Assert .assertNotNull (codeActions );
142153 Either <Command , CodeAction > constructorAction = CodeActionHandlerTest .findAction (codeActions , JavaCodeActionKind .SOURCE_GENERATE_CONSTRUCTORS );
143- Assert .assertNull (constructorAction );
154+ Assert .assertNotNull (constructorAction );
155+
144156 }
145157
146158 @ Test
147159 public void testGenerateConstructorsDisabled_interface () throws JavaModelException {
148160 //@formatter:off
149- ICompilationUnit unit = fPackageP .createCompilationUnit ("A.java" , "package p;\r \n " +
150- "\r \n " +
151- "public interface A {\r \n " +
152- " public final String name = \" test\" ;\r \n " +
153- "}"
154- , true , null );
161+ ICompilationUnit unit = fPackageP .createCompilationUnit ("A.java" , """
162+ package p;
163+
164+ public interface A {
165+ final String name = "test";
166+ }
167+ """ , true , null );
155168 //@formatter:on
156169 CodeActionParams params = CodeActionUtil .constructCodeActionParams (unit , "String name" );
157170 List <Either <Command , CodeAction >> codeActions = server .codeAction (params ).join ();
@@ -162,22 +175,72 @@ public void testGenerateConstructorsDisabled_interface() throws JavaModelExcepti
162175 @ Test
163176 public void testGenerateConstructorsDisabled_anonymous () throws JavaModelException {
164177 //@formatter:off
165- ICompilationUnit unit = fPackageP .createCompilationUnit ("A.java" , "package p;\r \n " +
166- "\r \n " +
167- "public class A {\r \n " +
168- " public Runnable getRunnable() {\r \n " +
169- " return new Runnable() {\r \n " +
170- " @Override\r \n " +
171- " public void run() {\r \n " +
172- " }\r \n " +
173- " };\r \n " +
174- " }\r \n " +
175- "}"
176- , true , null );
178+ ICompilationUnit unit = fPackageP .createCompilationUnit ("A.java" , """
179+ package p;
180+
181+ public class A {
182+ public Runnable getRunnable() {
183+ return new Runnable() {
184+ @Override
185+ public void run() {
186+ }
187+ };
188+ }
189+ }
190+ """ , true , null );
177191 //@formatter:on
178192 CodeActionParams params = CodeActionUtil .constructCodeActionParams (unit , "run()" );
179193 List <Either <Command , CodeAction >> codeActions = server .codeAction (params ).join ();
180194 Assert .assertNotNull (codeActions );
181195 Assert .assertFalse ("The operation is not applicable to anonymous" , CodeActionHandlerTest .containsKind (codeActions , JavaCodeActionKind .SOURCE_GENERATE_CONSTRUCTORS ));
182196 }
197+
198+ @ Test
199+ public void testGenerateConstructorsWithSuperDelegation () throws Exception {
200+ fPackageP .createCompilationUnit ("A.java" , """
201+ package p;
202+
203+ public class A {
204+ public A() {
205+ }
206+ public A(String a) {
207+ }
208+ }
209+ """ , true , null );
210+ ICompilationUnit unitB = fPackageP .createCompilationUnit ("B.java" , """
211+ package p;
212+
213+ public class B extends A {
214+ }
215+ """ , true , null );
216+ // Verify the code action is available
217+ CodeActionParams params = CodeActionUtil .constructCodeActionParams (unitB , "class B" );
218+ List <Either <Command , CodeAction >> codeActions = server .codeAction (params ).join ();
219+ Assert .assertNotNull (codeActions );
220+ Either <Command , CodeAction > constructorAction = CodeActionHandlerTest .findAction (codeActions , JavaCodeActionKind .SOURCE_GENERATE_CONSTRUCTORS );
221+ Assert .assertNotNull ("Generate constructors action should be available" , constructorAction );
222+
223+ // Verify quick assist is also available
224+ List <Either <Command , CodeAction >> quickAssistActions = CodeActionHandlerTest .findActions (codeActions , JavaCodeActionKind .QUICK_ASSIST );
225+ Assert .assertTrue ("Quick assist should be available" , CodeActionHandlerTest .commandExists (quickAssistActions , SourceAssistProcessor .COMMAND_ID_ACTION_GENERATECONSTRUCTORSPROMPT ));
226+
227+ // Generate constructors using the handler and verify they delegate to super
228+ GenerateConstructorsHandler .CheckConstructorsResponse response = GenerateConstructorsHandler .checkConstructorsStatus (params );
229+ Assert .assertNotNull (response .constructors );
230+ Assert .assertEquals ("Should have 2 constructors from superclass" , 2 , response .constructors .length );
231+ Assert .assertNotNull (response .fields );
232+ Assert .assertEquals ("Should have no fields" , 0 , response .fields .length );
233+
234+ CodeGenerationSettings settings = new CodeGenerationSettings ();
235+ settings .createComments = false ;
236+ TextEdit edit = GenerateConstructorsHandler .generateConstructors (unitB .findPrimaryType (), response .constructors , response .fields , settings , null , new NullProgressMonitor ());
237+ Assert .assertNotNull (edit );
238+ JavaModelUtil .applyEdit (unitB , edit , true , null );
239+
240+ // Verify the generated constructors delegate to super
241+ String actual = unitB .getSource ();
242+ Assert .assertTrue ("Should contain B() constructor\n " + actual , actual .contains ("public B() {" ));
243+ Assert .assertTrue ("Should contain B(String a) constructor\n " + actual , actual .contains ("public B(String a) {" ));
244+ Assert .assertTrue ("Should contain super(a) call\n " + actual , actual .contains ("super(a);" ));
245+ }
183246}
0 commit comments