-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathMissedTernaryOpportunity.ql
More file actions
76 lines (70 loc) · 2.04 KB
/
MissedTernaryOpportunity.ql
File metadata and controls
76 lines (70 loc) · 2.04 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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
* @name Missed ternary opportunity
* @description An 'if' statement where both branches either
* (a) return or (b) write to the same variable
* can often be expressed more clearly using the '?' operator.
* @kind problem
* @problem.severity recommendation
* @precision low
* @id java/missed-ternary-operator
* @tags maintainability
* language-features
*/
import java
predicate complicatedBranch(Stmt branch) {
any(ConditionalExpr ce).getParent*() = branch or
count(MethodCall a | a.getParent*() = branch) > 1
}
predicate complicatedCondition(Expr cond) {
exists(Expr e | e = cond.getAChildExpr*() |
e instanceof AndLogicalExpr or
e instanceof OrLogicalExpr
)
}
predicate toCompare(Expr left, Expr right) {
exists(IfStmt is, AssignExpr at, AssignExpr ae |
at.getParent() = is.getThen() and
ae.getParent() = is.getElse()
|
left = at.getDest() and right = ae.getDest()
or
left = at.getDest().(VarAccess).getQualifier() and
right = ae.getDest().(VarAccess).getQualifier()
)
}
predicate sameVariable(VarAccess left, VarAccess right) {
toCompare(left, right) and
left.getVariable() = right.getVariable() and
(
exists(Expr q1, Expr q2 |
left.getQualifier() = q1 and
sameVariable(q1, q2) and
right.getQualifier() = q2
)
or
left.isLocal() and right.isLocal()
)
}
from IfStmt is, string what
where
(
is.getThen() instanceof ReturnStmt and
is.getElse() instanceof ReturnStmt and
what = "return"
or
exists(AssignExpr at, AssignExpr ae |
at.getParent() = is.getThen() and
ae.getParent() = is.getElse() and
sameVariable(at.getDest(), ae.getDest()) and
what = "write to the same variable"
)
) and
// Exclusions.
not (
exists(IfStmt other | is = other.getElse()) or
complicatedCondition(is.getCondition()) or
complicatedBranch(is.getThen()) or
complicatedBranch(is.getElse())
)
select is,
"Both branches of this 'if' statement " + what + " - consider using '?' to express intent better."