Skip to content

Commit b7ec207

Browse files
committed
Add queries for Objects.deepEquals
1 parent 3a63022 commit b7ec207

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Finds unnecessary usage of `Objects.deepEquals`. That method is mainly intended for
3+
* `Object[]` or multi-dimensional arrays. For all other cases this method is not
4+
* needed and there are other ways to check for equality, which also make the
5+
* intention clearer:
6+
* - If both arguments are primitive arrays, use one of the `Arrays.equals` methods,
7+
* such as `Arrays.equals(int[], int[])`
8+
* - If both arguments are one-dimensional arrays with component type other than `Object`,
9+
* use `Arrays.equals(Object[], Object[])`
10+
* - Otherwise use `Objects.equals(Object, Object)` if the arguments can be `null`,
11+
* or if not directly call `equals` on one of the arguments
12+
*
13+
* @kind problem
14+
*/
15+
16+
import java
17+
18+
class DeepEqualsMethod extends Method {
19+
DeepEqualsMethod() {
20+
getDeclaringType().hasQualifiedName("java.util", "Objects")
21+
and hasName("deepEquals")
22+
}
23+
}
24+
25+
from MethodAccess deepEqualsCall, Expr nonObjectArrayArg, Type argType
26+
where
27+
deepEqualsCall.getMethod() instanceof DeepEqualsMethod
28+
and nonObjectArrayArg = deepEqualsCall.getAnArgument()
29+
and argType = nonObjectArrayArg.getType()
30+
and not (
31+
argType instanceof TypeObject
32+
// Object[]
33+
or argType.(Array).getComponentType() instanceof TypeObject
34+
// Multi-dimensional array
35+
or argType.(Array).getComponentType() instanceof Array
36+
)
37+
select deepEqualsCall, "Unnecessary usage of `Objects.deepEquals` because $@ has neither type `Object` nor `Object[]`, nor is it a multi-dimensional array",
38+
nonObjectArrayArg, "this argument"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Similar to unnecessary-Objects-deepEquals-usage.ql
2+
3+
/**
4+
* Finds usage of `Object.deepEquals` where `Arrays.deepEquals` could be used instead.
5+
* Using `Arrays.deepEquals` makes the intention clearer and also provides slightly
6+
* more type-safety because it requires that its arguments are actually arrays.
7+
*
8+
* @kind problem
9+
*/
10+
11+
import java
12+
13+
class DeepEqualsMethod extends Method {
14+
DeepEqualsMethod() {
15+
getDeclaringType().hasQualifiedName("java.util", "Objects")
16+
and hasName("deepEquals")
17+
}
18+
}
19+
20+
/**
21+
* Type `Object[]`
22+
*/
23+
class ObjectArray extends Array {
24+
ObjectArray() {
25+
getComponentType() instanceof TypeObject
26+
}
27+
}
28+
29+
from MethodAccess deepEqualsCall
30+
where
31+
deepEqualsCall.getMethod() instanceof DeepEqualsMethod
32+
// Only cover the case where both arguments have type Object[]; other cases such as using String[]
33+
// are covered by unnecessary-Objects-deepEquals-usage.ql
34+
and deepEqualsCall.getArgument(0).getType() instanceof ObjectArray
35+
and deepEqualsCall.getArgument(1).getType() instanceof ObjectArray
36+
select deepEqualsCall, "Could use `Arrays.deepEquals` instead"

0 commit comments

Comments
 (0)