Skip to content

Commit 075cec4

Browse files
committed
Add simplifiable-call-with-array-arg-and-indices.ql
1 parent eef9e44 commit 075cec4

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* Finds calls with an array as argument which can possibly be simplified
3+
* by omitting indices or the array length argument because there is
4+
* a method overload which accepts only the array for convenience.
5+
*
6+
* For example:
7+
* ```java
8+
* out.write(array, 0, array.length)
9+
* // can be simplified:
10+
* out.write(array)
11+
* ```
12+
*
13+
* **Important:** Please verify that the alternative suggested by this
14+
* query behaves the same way. This query does not check the implementation
15+
* of the proposed alternative but only determines it based on its signature.
16+
*
17+
* @kind problem
18+
*/
19+
20+
import java
21+
22+
class ArrayLengthAccess extends FieldRead {
23+
ArrayLengthAccess() { getField() instanceof ArrayLengthField }
24+
}
25+
26+
from Variable array, Call call, Callable callee, Callable alternative
27+
where
28+
call.getCallee() = callee and
29+
// Either `method(array, array.length)` or `method(array, 0, array.length)`
30+
(
31+
call.getNumArgument() = 2 and
32+
call.getArgument(0) = array.getAnAccess() and
33+
call.getArgument(1).(ArrayLengthAccess).getQualifier() = array.getAnAccess()
34+
or
35+
call.getNumArgument() = 3 and
36+
call.getArgument(0) = array.getAnAccess() and
37+
call.getArgument(1).(IntegerLiteral).getIntValue() = 0 and
38+
call.getArgument(2).(ArrayLengthAccess).getQualifier() = array.getAnAccess()
39+
) and
40+
// Altnerative is available on same receiver
41+
(
42+
alternative.getDeclaringType() = callee.getDeclaringType().getASourceSupertype*() or
43+
alternative.getDeclaringType() = call.(MethodAccess).getReceiverType().getASourceSupertype*()
44+
) and
45+
// Alternative has same name and return type, and a single parameter of the same array type
46+
alternative.getName() = callee.getName() and
47+
alternative.getReturnType() = callee.getReturnType() and
48+
alternative.getNumberOfParameters() = 1 and
49+
alternative.getParameterType(0) = callee.getParameterType(0) and
50+
// And is same static or non-static as called callable
51+
(
52+
callee.isStatic() and alternative.isStatic()
53+
or
54+
not callee.isStatic() and not alternative.isStatic()
55+
) and
56+
// And is at least as visible as called callable
57+
(
58+
alternative.isPublic()
59+
or
60+
callee.isProtected() and alternative.isProtected()
61+
) and
62+
// Don't suggest infinite recursion by calling itself
63+
not (
64+
call.getEnclosingCallable() = alternative or
65+
call.getEnclosingCallable().(Method).getASourceOverriddenMethod*() = alternative
66+
)
67+
select call, "Could possibly instead call `" + alternative.getStringSignature() + "`"

0 commit comments

Comments
 (0)