Skip to content

Commit 9ae0aad

Browse files
committed
QL: suggest replacing 'this instanceof ...' in constructor with non-extending subtypes
1 parent fbb58f1 commit 9ae0aad

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* @name Suggest using non-extending subtype relationships.
3+
* @description Non-extending subtypes ("instanceof extensions") are generally preferrable to instanceof expressions in characteristic predicates.
4+
* @kind problem
5+
* @problem.severity warning
6+
* @id ql/suggest-instanceof-extension
7+
* @tags maintainability
8+
* @precision medium
9+
*/
10+
11+
import ql
12+
13+
InstanceOf instanceofInCharPred(Class c) {
14+
result = c.getCharPred().getBody()
15+
or
16+
exists(Conjunction conj |
17+
conj = c.getCharPred().getBody() and
18+
result = conj.getAnOperand()
19+
)
20+
}
21+
22+
predicate instanceofThisInCharPred(Class c, TypeExpr type) {
23+
exists(InstanceOf instanceOf |
24+
instanceOf = instanceofInCharPred(c) and
25+
instanceOf.getExpr() instanceof ThisAccess and
26+
type = instanceOf.getType()
27+
)
28+
}
29+
30+
predicate classWithInstanceofThis(Class c, TypeExpr type) {
31+
instanceofThisInCharPred(c, type) and
32+
exists(ClassPredicate classPred |
33+
classPred = c.getAClassPredicate() and
34+
exists(MemberCall call, InlineCast cast |
35+
call.getEnclosingPredicate() = classPred and
36+
cast = call.getBase() and
37+
cast.getBase() instanceof ThisAccess and
38+
cast.getTypeExpr().getResolvedType() = type.getResolvedType()
39+
)
40+
)
41+
}
42+
43+
from Class c, TypeExpr type, string message
44+
where
45+
classWithInstanceofThis(c, type) and
46+
message = "consider defining $@ as non-extending subtype of $@"
47+
select c, message, c, c.getName(), type, type.getResolvedType().getName()

0 commit comments

Comments
 (0)