Skip to content

Commit 067c093

Browse files
authored
Simplify Arrays.asList with new array argument (#633)
* Simplify `Arrays.asList` with a single array argument * Minimize implementation * Skip edge case
1 parent 3cf0d8a commit 067c093

File tree

4 files changed

+474
-3
lines changed

4 files changed

+474
-3
lines changed

.claude/settings.local.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
"permissions": {
33
"allow": [
44
"Bash(./gradlew:*)",
5+
"Bash(cat:*)",
56
"Bash(echo:*)",
67
"Bash(find:*)",
78
"Bash(gh:*)",
89
"Bash(git:*)",
910
"Bash(grep:*)",
11+
"Bash(javac:*)",
1012
"Bash(mv:*)",
1113
"Bash(npm test:*)",
1214
"Bash(rg:*)",
@@ -27,9 +29,8 @@
2729
"mcp__idea__open_file_in_editor",
2830
"mcp__idea__replace_selected_text",
2931
"mcp__idea__replace_specific_text",
30-
"mcp__idea__search_in_files_content",
31-
"Bash(./gradlew compileTestJava:*)"
32+
"mcp__idea__search_in_files_content"
3233
],
3334
"deny": []
3435
}
35-
}
36+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
* <p>
4+
* Licensed under the Moderne Source Available License (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* https://docs.moderne.io/licensing/moderne-source-available-license
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.openrewrite.staticanalysis;
17+
18+
import org.openrewrite.ExecutionContext;
19+
import org.openrewrite.Preconditions;
20+
import org.openrewrite.Recipe;
21+
import org.openrewrite.TreeVisitor;
22+
import org.openrewrite.java.JavaVisitor;
23+
import org.openrewrite.java.MethodMatcher;
24+
import org.openrewrite.java.search.UsesMethod;
25+
import org.openrewrite.java.tree.Expression;
26+
import org.openrewrite.java.tree.J;
27+
28+
import java.time.Duration;
29+
import java.util.Collections;
30+
import java.util.List;
31+
import java.util.Set;
32+
33+
public class SimplifyArraysAsList extends Recipe {
34+
private static final MethodMatcher ARRAYS_AS_LIST = new MethodMatcher("java.util.Arrays asList(..)");
35+
36+
@Override
37+
public String getDisplayName() {
38+
return "Simplify `Arrays.asList(..)` with varargs";
39+
}
40+
41+
@Override
42+
public String getDescription() {
43+
return "Simplifies `Arrays.asList()` method calls that use explicit array creation to use varargs instead. " +
44+
"For example, `Arrays.asList(new String[]{\"a\", \"b\", \"c\"})` becomes `Arrays.asList(\"a\", \"b\", \"c\")`.";
45+
}
46+
47+
@Override
48+
public Set<String> getTags() {
49+
return Collections.singleton("RSPEC-S3878");
50+
}
51+
52+
@Override
53+
public Duration getEstimatedEffortPerOccurrence() {
54+
return Duration.ofMinutes(2);
55+
}
56+
57+
@Override
58+
public TreeVisitor<?, ExecutionContext> getVisitor() {
59+
return Preconditions.check(new UsesMethod<>(ARRAYS_AS_LIST), new JavaVisitor<ExecutionContext>() {
60+
@Override
61+
public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
62+
J.MethodInvocation mi = (J.MethodInvocation) super.visitMethodInvocation(method, ctx);
63+
if (ARRAYS_AS_LIST.matches(mi) && mi.getArguments().size() == 1 &&
64+
mi.getArguments().get(0) instanceof J.NewArray) {
65+
J.NewArray newArray = (J.NewArray) mi.getArguments().get(0);
66+
List<Expression> elements = newArray.getInitializer();
67+
if (newArray.getDimensions().size() == 1 && elements != null &&
68+
// Skip transformation if there's exactly one null element to avoid ambiguity
69+
(elements.size() != 1 || !J.Literal.isLiteralValue(elements.get(0), null))) {
70+
return mi.withArguments(newArray.getInitializer());
71+
}
72+
}
73+
return mi;
74+
}
75+
});
76+
}
77+
}

src/main/resources/META-INF/rewrite/common-static-analysis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ recipeList:
7878
- org.openrewrite.staticanalysis.ReplaceClassIsInstanceWithInstanceof
7979
- org.openrewrite.staticanalysis.ReplaceLambdaWithMethodReference
8080
- org.openrewrite.staticanalysis.ReplaceStringBuilderWithString
81+
- org.openrewrite.staticanalysis.SimplifyArraysAsList
8182
- org.openrewrite.staticanalysis.SimplifyBooleanExpression
8283
- org.openrewrite.staticanalysis.SimplifyBooleanReturn
8384
# - org.openrewrite.staticanalysis.SimplifyTernaryRecipes

0 commit comments

Comments
 (0)