Skip to content

Commit f04a12b

Browse files
committed
Adding MigrateClassNewInstanceToGetDeclaredConstructorNewInstance recipe. Fixes #51
1 parent 509acab commit f04a12b

File tree

4 files changed

+145
-25
lines changed

4 files changed

+145
-25
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package org.openrewrite.java.migrate.lang;
2+
3+
import org.openrewrite.ExecutionContext;
4+
import org.openrewrite.Recipe;
5+
import org.openrewrite.internal.lang.Nullable;
6+
import org.openrewrite.java.ChangeMethodName;
7+
import org.openrewrite.java.JavaIsoVisitor;
8+
import org.openrewrite.java.MethodMatcher;
9+
import org.openrewrite.java.search.UsesMethod;
10+
import org.openrewrite.java.tree.J;
11+
import org.openrewrite.java.tree.JavaType;
12+
import org.openrewrite.java.tree.TypeUtils;
13+
14+
public class MigrateClassNewInstanceToGetDeclaredConstructorNewInstance extends Recipe {
15+
private static final MethodMatcher NEW_INSTANCE_MATCHER = new MethodMatcher("java.lang.Class newInstance()");
16+
@Override
17+
public String getDisplayName() {
18+
return "Use `Class#getDeclaredConstructor().newInstance()`";
19+
}
20+
21+
@Override
22+
public String getDescription() {
23+
return "`Class#newInstance()` was deprecated in Java 9.";
24+
}
25+
26+
@Override
27+
protected UsesMethod<ExecutionContext> getSingleSourceApplicableTest() {
28+
return new UsesMethod<>("java.lang.Class newInstance()");
29+
}
30+
31+
@Override
32+
protected NewInstanceToDeclaredConstructorVisitor getVisitor() {
33+
return new NewInstanceToDeclaredConstructorVisitor();
34+
}
35+
36+
private static class NewInstanceToDeclaredConstructorVisitor extends JavaIsoVisitor<ExecutionContext> {
37+
private final JavaType exType = JavaType.buildType("java.lang.Exception");
38+
private final JavaType thType = JavaType.buildType("java.lang.Throwable");
39+
private static final ChangeMethodName TO_DECLARED_CONS_NEW_INSTANCE = new ChangeMethodName("java.lang.Class newInstance()", "getDeclaredConstructor().newInstance", null);
40+
41+
@Override
42+
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext executionContext) {
43+
J.MethodInvocation mi = super.visitMethodInvocation(method, executionContext);
44+
if (NEW_INSTANCE_MATCHER.matches(mi)) {
45+
J.Try tri = getCursor().firstEnclosing(J.Try.class);
46+
J.MethodDeclaration md = getCursor().firstEnclosing(J.MethodDeclaration.class);
47+
if ((tri != null && tri.getCatches().stream().anyMatch(c -> isExceptionType(c.getParameter().getType())))
48+
|| (md != null && md.getThrows() != null && md.getThrows().stream().anyMatch(nt -> isExceptionType(nt.getType())))) {
49+
J.MethodInvocation modifiedMethodInvocation = (J.MethodInvocation)TO_DECLARED_CONS_NEW_INSTANCE.getVisitor().visit(mi,executionContext);
50+
if (modifiedMethodInvocation != null) {
51+
mi = modifiedMethodInvocation;
52+
}
53+
}
54+
}
55+
return mi;
56+
}
57+
58+
private boolean isExceptionType(@Nullable JavaType type) {
59+
return TypeUtils.isOfType(type,exType)
60+
|| TypeUtils.isOfType(type, thType);
61+
}
62+
}
63+
}

src/main/resources/META-INF/rewrite/java-lang-apis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ recipeList:
2727
- org.openrewrite.java.migrate.lang.MigrateRuntimeVersionSecurityToUpdate
2828
- org.openrewrite.java.migrate.lang.MigrateSecurityManagerMulticast
2929
- org.openrewrite.java.migrate.lang.MigrateClassLoaderDefineClass
30+
- org.openrewrite.java.migrate.lang.MigrateClassNewInstanceToGetDeclaredConstructorNewInstance
3031

3132
---
3233
type: specs.openrewrite.org/v1beta/recipe

src/test/kotlin/org/openrewrite/java/migrate/lang/JavaLangAPIsTest.kt

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -94,31 +94,6 @@ class JavaLangAPIsTest : JavaRecipeTest {
9494
"""
9595
)
9696

97-
@Disabled
98-
@Test
99-
fun classNewInstanceToGetDeclaredConstructorNewInstance() = assertChanged(
100-
before = """
101-
package com.abc;
102-
103-
class A {
104-
public void test() {
105-
Class<?> clazz = Class.forName("org.openrewrite.Test");
106-
clazz.newInstance();
107-
}
108-
}
109-
""",
110-
after = """
111-
package com.abc;
112-
113-
class A {
114-
public void test() {
115-
Class<?> clazz = Class.forName("org.openrewrite.Test");
116-
clazz.getDeclaredConstructor().newInstance();
117-
}
118-
}
119-
"""
120-
)
121-
12297
@Test
12398
fun runtimeVersionMajorToFeature() = assertChanged(
12499
before = """
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package org.openrewrite.java.migrate.lang
2+
3+
import org.junit.jupiter.api.Test
4+
import org.openrewrite.Recipe
5+
import org.openrewrite.java.JavaRecipeTest
6+
7+
@Suppress("deprecation")
8+
class MigrateClassNewInstanceToGetDeclaredConstructorNewInstanceTest : JavaRecipeTest {
9+
override val recipe: Recipe
10+
get() = MigrateClassNewInstanceToGetDeclaredConstructorNewInstance()
11+
12+
@Test
13+
fun doesNotThrowExceptionOrThrowable() = assertUnchanged(
14+
before = """
15+
package com.abc;
16+
17+
class A {
18+
public void test() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
19+
Class<?> clazz = Class.forName("org.openrewrite.Test");
20+
clazz.newInstance();
21+
}
22+
}
23+
"""
24+
)
25+
26+
@Test
27+
fun methodThrowsThrowable() = assertChanged(
28+
before = """
29+
package com.abc;
30+
31+
class A {
32+
public void test() throws Throwable {
33+
Class<?> clazz = Class.forName("org.openrewrite.Test");
34+
clazz.newInstance();
35+
}
36+
}
37+
""",
38+
after = """
39+
package com.abc;
40+
41+
class A {
42+
public void test() throws Throwable {
43+
Class<?> clazz = Class.forName("org.openrewrite.Test");
44+
clazz.getDeclaredConstructor().newInstance();
45+
}
46+
}
47+
"""
48+
)
49+
50+
@Test
51+
fun tryBlockCatchesException() = assertChanged(
52+
before = """
53+
package com.abc;
54+
55+
class A {
56+
public void test() {
57+
try {
58+
Class<?> clazz = Class.forName("org.openrewrite.Test");
59+
clazz.newInstance();
60+
} catch (Exception ex) {
61+
System.out.println(ex.getMessage());
62+
}
63+
}
64+
}
65+
""",
66+
after = """
67+
package com.abc;
68+
69+
class A {
70+
public void test() {
71+
try {
72+
Class<?> clazz = Class.forName("org.openrewrite.Test");
73+
clazz.getDeclaredConstructor().newInstance();
74+
} catch (Exception ex) {
75+
System.out.println(ex.getMessage());
76+
}
77+
}
78+
}
79+
"""
80+
)
81+
}

0 commit comments

Comments
 (0)