-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathCovariantCompareTo.ql
More file actions
55 lines (49 loc) · 1.81 KB
/
CovariantCompareTo.ql
File metadata and controls
55 lines (49 loc) · 1.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
* @name Overloaded compareTo
* @description Defining 'Comparable.compareTo', where the parameter of 'compareTo' is not of the
* appropriate type, overloads 'compareTo' instead of overriding it.
* @kind problem
* @problem.severity error
* @precision medium
* @id java/wrong-compareto-signature
* @tags reliability
* correctness
*/
import java
private predicate implementsComparable(RefType t, RefType param) {
exists(ParameterizedType pt |
t.getASupertype*() = pt and
pt.getSourceDeclaration().hasQualifiedName("java.lang", "Comparable") and
param = pt.getATypeArgument() and
not param instanceof Wildcard and
not param instanceof TypeVariable
)
}
private predicate mostSpecificComparableTypeArgument(RefType t, RefType param) {
implementsComparable(t, param) and
not implementsComparable(t, param.getASubtype+())
}
private predicate mostSpecificComparableTypeArgumentOrTypeObject(RefType t, RefType param) {
if mostSpecificComparableTypeArgument(t, _)
then mostSpecificComparableTypeArgument(t, param)
else param instanceof TypeObject
}
private predicate compareTo(RefType declaring, Method m, RefType param) {
m.hasName("compareTo") and
m.isPublic() and
m.getNumberOfParameters() = 1 and
m.fromSource() and
m.getAParamType() = param and
declaring = m.getDeclaringType() and
declaring.getASupertype*().getSourceDeclaration().hasQualifiedName("java.lang", "Comparable")
}
from Method m, Class t, Type actual, Type desired
where
compareTo(t, m, actual) and
mostSpecificComparableTypeArgumentOrTypeObject(t, desired) and
actual != desired and
not compareTo(t, _, desired) and
not actual instanceof TypeVariable
select m,
"The parameter of compareTo should have type '" + desired.getName() +
"' when implementing 'Comparable<" + desired.getName() + ">'."