Skip to content

Commit 841f327

Browse files
committed
Add simplifiable-Stream-CharSequence-joining.ql
1 parent 0677ba8 commit 841f327

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* Finds conversion of an array or a `Collection<CharSequence>` to a `Stream`
3+
* just to join the elements to a single string. Such code can be simplified
4+
* by using `String.join`. For example:
5+
* ```java
6+
* List<String> words = ...;
7+
* String sentence = words.stream().collect(Collectors.joining(" "));
8+
*
9+
* // Can be simplified as
10+
* String sentence = String.join(" ", words);
11+
* ```
12+
*
13+
* @kind problem
14+
*/
15+
16+
import java
17+
18+
class CollectionStreamMethod extends Method {
19+
CollectionStreamMethod() {
20+
getDeclaringType().hasQualifiedName("java.util", "Collection") and
21+
hasStringSignature("stream()")
22+
}
23+
}
24+
25+
class ArrayAsStreamMethod extends Method {
26+
ArrayAsStreamMethod() {
27+
isStatic() and
28+
(
29+
getDeclaringType().hasQualifiedName("java.util", "Arrays") and
30+
hasName("stream")
31+
or
32+
getDeclaringType().hasQualifiedName("java.util.stream", "Stream") and
33+
hasName("of")
34+
)
35+
}
36+
}
37+
38+
class CollectMethod extends Method {
39+
CollectMethod() {
40+
getDeclaringType().hasQualifiedName("java.util.stream", "Stream") and
41+
hasName("collect")
42+
}
43+
}
44+
45+
class JoiningCollectorMethod extends Method {
46+
JoiningCollectorMethod() {
47+
getDeclaringType().hasQualifiedName("java.util.stream", "Collectors") and
48+
hasName("joining") and
49+
// Ignore variant with additional prefix and suffix arguments
50+
getNumberOfParameters() = [0, 1]
51+
}
52+
}
53+
54+
from
55+
Expr collectionExpr, MethodAccess charSeqStreamExpr, MethodAccess collectCall,
56+
MethodAccess joiningCall
57+
where
58+
(
59+
exists(MethodAccess collectionStreamCall | charSeqStreamExpr = collectionStreamCall |
60+
collectionStreamCall.getQualifier() = collectionExpr and
61+
collectionStreamCall.getMethod().getSourceDeclaration().getASourceOverriddenMethod*()
62+
instanceof CollectionStreamMethod
63+
)
64+
or
65+
exists(MethodAccess arrayStreamCall | charSeqStreamExpr = arrayStreamCall |
66+
arrayStreamCall.getArgument(0) = collectionExpr and
67+
arrayStreamCall.getMethod() instanceof ArrayAsStreamMethod
68+
)
69+
) and
70+
// Has type Stream<CharSequence>
71+
charSeqStreamExpr
72+
.getType()
73+
.(ParameterizedType)
74+
.getTypeArgument(0)
75+
.getErasure()
76+
.(RefType)
77+
.getASourceSupertype*()
78+
.hasQualifiedName("java.lang", "CharSequence") and
79+
// Calls `stream.collect(...)`
80+
collectCall.getQualifier() = charSeqStreamExpr and
81+
collectCall.getMethod().getSourceDeclaration().getASourceOverriddenMethod*() instanceof
82+
CollectMethod and
83+
// Calls `collect(Collectors.joining(...))`
84+
collectCall.getArgument(0) = joiningCall and
85+
joiningCall.getMethod().getSourceDeclaration().getASourceOverriddenMethod*() instanceof
86+
JoiningCollectorMethod
87+
select joiningCall, "Could instead use `String.join` to join elements of $@", collectionExpr,
88+
"this collection"

0 commit comments

Comments
 (0)