|
| 1 | +/** |
| 2 | + * Finds code which first creates a `Stream` for an array (or varargs arguments) just to |
| 3 | + * directly afterwards call `collect(Collectors.toList())` on it. Such code should be |
| 4 | + * simplified by using `java.util.Arrays.asList(...)` instead, especially because |
| 5 | + * `Collectors.toList()` makes no guarantees about the type of the created list, so there |
| 6 | + * is really no advantage of using it over `Arrays.asList`. |
| 7 | + * |
| 8 | + * @kind problem |
| 9 | + */ |
| 10 | + |
| 11 | +import java |
| 12 | + |
| 13 | +class StreamFromArrayMethod extends Method { |
| 14 | + StreamFromArrayMethod() { |
| 15 | + ( |
| 16 | + getDeclaringType().hasQualifiedName("java.util", "Arrays") |
| 17 | + // Only consider method which accepts object array (ignore primitive ones), and only |
| 18 | + // the one without start and end index |
| 19 | + and hasStringSignature("stream(T[])") |
| 20 | + ) |
| 21 | + or ( |
| 22 | + getDeclaringType().hasQualifiedName("java.util.stream", "Stream") |
| 23 | + // Only consider method which accepts an array (respectively varargs) |
| 24 | + and hasStringSignature("of(T[])") |
| 25 | + ) |
| 26 | + } |
| 27 | +} |
| 28 | + |
| 29 | +class StreamCollectMethod extends Method { |
| 30 | + StreamCollectMethod() { |
| 31 | + getDeclaringType().hasQualifiedName("java.util.stream", "Stream") |
| 32 | + and hasName("collect") |
| 33 | + and getNumberOfParameters() = 1 |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +class CollectorsToListMethod extends Method { |
| 38 | + CollectorsToListMethod() { |
| 39 | + getDeclaringType().hasQualifiedName("java.util.stream", "Collectors") |
| 40 | + and hasStringSignature("toList()") |
| 41 | + } |
| 42 | +} |
| 43 | + |
| 44 | +from MethodAccess streamCreationCall, MethodAccess collectCall |
| 45 | +where |
| 46 | + streamCreationCall.getMethod() instanceof StreamFromArrayMethod |
| 47 | + and streamCreationCall = collectCall.getQualifier() |
| 48 | + and collectCall.getMethod().getSourceDeclaration().getASourceOverriddenMethod*() instanceof StreamCollectMethod |
| 49 | + // Note: Don't cover `Stream.toList()` because that makes guarantees about the list, such as it being unmodifiable |
| 50 | + and collectCall.getArgument(0).(MethodAccess).getMethod() instanceof CollectorsToListMethod |
| 51 | +select collectCall, "Should use `Arrays.asList(...)` instead" |
0 commit comments