All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openrewrite.staticanalysis.ReplaceCollectionToArrayArgWithEmptyArray Maven / Gradle / Ivy

/*
 * Copyright 2024 the original author or authors.
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* https://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.openrewrite.staticanalysis; import org.openrewrite.*; import org.openrewrite.analysis.InvocationMatcher; import org.openrewrite.analysis.search.UsesInvocation; import org.openrewrite.internal.ListUtils; import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.JavaType; import org.openrewrite.java.tree.Space; import org.openrewrite.marker.Markers; import java.util.Collections; import static java.util.Objects.requireNonNull; public class ReplaceCollectionToArrayArgWithEmptyArray extends Recipe { @Override public String getDisplayName() { return "Use Empty Array for `Collection.toArray()`"; } @Override public String getDescription() { return "Changes new array creation with `Collection#toArray(T[])` to use an empty array argument, which is better for performance.\n" + "\n" + "According to the `Collection#toArray(T[])` documentation:\n" + "\n" + "> If the collection fits in the specified array, it is returned therein.\n" + "\n" + "However, although it's not intuitive, " + "allocating a right-sized array ahead of time to pass to the API appears to be [generally worse for performance](https://shipilev.net/blog/2016/arrays-wisdom-ancients/#_conclusion) " + "according to benchmarking and JVM developers due to a number of implementation details in both Java and the virtual machine.\n" + "\n" + "H2 achieved significant performance gains by [switching to empty arrays instead pre-sized ones](https://github.com/h2database/h2database/issues/311)."; } @Override public TreeVisitor getVisitor() { return Preconditions.check( new UsesInvocation<>(ReplaceCollectionToArrayArgWithEmptyArrayVisitor.COLLECTION_TO_ARRAY), new ReplaceCollectionToArrayArgWithEmptyArrayVisitor<>() ); } private static class ReplaceCollectionToArrayArgWithEmptyArrayVisitor

extends JavaIsoVisitor

{ private static final InvocationMatcher COLLECTION_TO_ARRAY = InvocationMatcher.fromMethodMatcher("java.util.Collection toArray(..)"); @Override public J.NewArray visitNewArray(J.NewArray newArray, P p) { if (COLLECTION_TO_ARRAY.advanced().isFirstArgument(getCursor()) && newArray.getDimensions().size() == 1) { J.NewArray newArrayZero = newArray.withDimensions(ListUtils.mapFirst(newArray.getDimensions(), d -> { if (d.getIndex() instanceof J.Literal && Integer.valueOf(0).equals(((J.Literal) d.getIndex()).getValue())) { return d; } return d.withIndex(new J.Literal( Tree.randomId(), Space.EMPTY, Markers.EMPTY, 0, "0", Collections.emptyList(), (JavaType.Primitive) requireNonNull(d.getIndex().getType()) )); })); return maybeAutoFormat(newArray, newArrayZero, p); } return super.visitNewArray(newArray, p); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy