Skip to content

Commit d2f60e6

Browse files
committed
Add array-to-Stream-to-List.ql
1 parent 98cdeed commit d2f60e6

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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

Comments
 (0)