Skip to content

Commit 445d977

Browse files
authored
Support changing from a constructor to a factory method in ChangeMethodTargetToStatic (#1804) (#7281)
1 parent deca4de commit 445d977

2 files changed

Lines changed: 185 additions & 5 deletions

File tree

rewrite-java-test/src/test/java/org/openrewrite/java/ChangeMethodTargetToStaticTest.java

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,129 @@ public void test() {
304304
);
305305
}
306306

307+
@Issue("https://github.com/openrewrite/rewrite/issues/1804")
308+
@Test
309+
void constructorToStaticMethod() {
310+
rewriteRun(
311+
spec -> spec.recipes(
312+
new ChangeMethodTargetToStatic("a.A <constructor>(String)", "b.B", "b.B", null, false),
313+
new ChangeMethodName("b.B A(String)", "foo", null, null)
314+
),
315+
java(
316+
"""
317+
package a;
318+
public class A {
319+
public A(String s) {}
320+
}
321+
"""
322+
),
323+
java(
324+
"""
325+
package b;
326+
public class B {
327+
public static B foo(String s) { return null; }
328+
}
329+
"""
330+
),
331+
java(
332+
"""
333+
import a.A;
334+
class C {
335+
public void test() {
336+
new A("hello");
337+
}
338+
}
339+
""",
340+
"""
341+
import b.B;
342+
343+
class C {
344+
public void test() {
345+
B.foo("hello");
346+
}
347+
}
348+
"""
349+
)
350+
);
351+
}
352+
353+
@Issue("https://github.com/openrewrite/rewrite/issues/1804")
354+
@Test
355+
void constructorToStaticMethodWithReturnType() {
356+
rewriteRun(
357+
spec -> spec.recipe(
358+
new ChangeMethodTargetToStatic("a.A <constructor>(String)", "b.B", "b.B", null, false)
359+
),
360+
java(
361+
"""
362+
package a;
363+
public class A {
364+
public A(String s) {}
365+
}
366+
"""
367+
),
368+
java(
369+
"""
370+
package b;
371+
public class B {
372+
public static B A(String s) { return null; }
373+
}
374+
"""
375+
),
376+
java(
377+
"""
378+
import a.A;
379+
class C {
380+
public void test() {
381+
new A("hello");
382+
}
383+
}
384+
""",
385+
"""
386+
import b.B;
387+
388+
class C {
389+
public void test() {
390+
B.A("hello");
391+
}
392+
}
393+
"""
394+
)
395+
);
396+
}
397+
398+
@Issue("https://github.com/openrewrite/rewrite/issues/1804")
399+
@Test
400+
void constructorWithAnonymousBodyNotChanged() {
401+
rewriteRun(
402+
spec -> spec.recipe(
403+
new ChangeMethodTargetToStatic("a.A <constructor>(String)", "b.B", "b.B", null, false)
404+
),
405+
java(
406+
"""
407+
package a;
408+
public class A {
409+
public A(String s) {}
410+
public void doSomething() {}
411+
}
412+
"""
413+
),
414+
java(
415+
"""
416+
import a.A;
417+
class C {
418+
public void test() {
419+
new A("hello") {
420+
@Override
421+
public void doSomething() {}
422+
};
423+
}
424+
}
425+
"""
426+
)
427+
);
428+
}
429+
307430
@Disabled
308431
@Issue("https://github.com/openrewrite/rewrite/issues/3085")
309432
@SuppressWarnings("ResultOfMethodCallIgnored")

rewrite-java/src/main/java/org/openrewrite/java/ChangeMethodTargetToStatic.java

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
9898
return matchUnknown ? visitor : Preconditions.check(new UsesMethod<>(methodPattern, matchOverrides), visitor);
9999
}
100100

101-
private class ChangeMethodTargetToStaticVisitor extends JavaIsoVisitor<ExecutionContext> {
101+
private class ChangeMethodTargetToStaticVisitor extends JavaVisitor<ExecutionContext> {
102102
private final MethodMatcher methodMatcher;
103103
private final boolean matchUnknownTypes;
104104
private final JavaType.FullyQualified classType = JavaType.ShallowClass.build(fullyQualifiedTargetTypeName);
@@ -136,8 +136,8 @@ private JavaType.Method transformMethodType(JavaType.Method methodType) {
136136
}
137137

138138
@Override
139-
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
140-
J.MethodInvocation m = super.visitMethodInvocation(method, ctx);
139+
public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
140+
J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx);
141141
Expression select = method.getSelect();
142142
if (!isAlreadyStaticCallOnTargetType(select, method) &&
143143
methodMatcher.matches(method, matchUnknownTypes)) {
@@ -170,8 +170,8 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu
170170
}
171171

172172
@Override
173-
public J.MemberReference visitMemberReference(J.MemberReference memberRef, ExecutionContext ctx) {
174-
J.MemberReference m = super.visitMemberReference(memberRef, ctx);
173+
public J visitMemberReference(J.MemberReference memberRef, ExecutionContext ctx) {
174+
J.MemberReference m = (J.MemberReference) super.visitMemberReference(memberRef, ctx);
175175
Expression containing = memberRef.getContaining();
176176
if (!isAlreadyStaticCallOnTargetType(containing, memberRef) &&
177177
methodMatcher.matches(memberRef)) {
@@ -195,5 +195,62 @@ public J.MemberReference visitMemberReference(J.MemberReference memberRef, Execu
195195
}
196196
return m;
197197
}
198+
199+
@Override
200+
public J visitNewClass(J.NewClass newClass, ExecutionContext ctx) {
201+
J.NewClass n = (J.NewClass) super.visitNewClass(newClass, ctx);
202+
if (n.getBody() != null || n.getEnclosing() != null) {
203+
return n;
204+
}
205+
if (methodMatcher.matches(n)) {
206+
String methodName;
207+
JavaType.Method transformedType = null;
208+
if (n.getConstructorType() != null) {
209+
methodName = n.getConstructorType().getConstructorName();
210+
if (methodName == null) {
211+
return n;
212+
}
213+
maybeRemoveImport(n.getConstructorType().getDeclaringType());
214+
transformedType = transformMethodType(n.getConstructorType())
215+
.withName(methodName);
216+
} else {
217+
return n;
218+
}
219+
220+
maybeAddImport(fullyQualifiedTargetTypeName, !matchUnknownTypes);
221+
222+
J.Identifier selectId = new J.Identifier(
223+
randomId(),
224+
n.getPrefix(),
225+
Markers.EMPTY,
226+
emptyList(),
227+
classType.getClassName(),
228+
classType,
229+
null
230+
);
231+
232+
J.Identifier nameId = new J.Identifier(
233+
randomId(),
234+
Space.EMPTY,
235+
Markers.EMPTY,
236+
emptyList(),
237+
methodName,
238+
transformedType,
239+
null
240+
);
241+
242+
return new J.MethodInvocation(
243+
randomId(),
244+
Space.EMPTY,
245+
Markers.EMPTY,
246+
JRightPadded.build(selectId),
247+
null,
248+
nameId,
249+
n.getPadding().getArguments(),
250+
transformedType
251+
);
252+
}
253+
return n;
254+
}
198255
}
199256
}

0 commit comments

Comments
 (0)