-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathSimplifyBoolExpr.ql
More file actions
107 lines (100 loc) · 3.46 KB
/
SimplifyBoolExpr.ql
File metadata and controls
107 lines (100 loc) · 3.46 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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
* @name Unnecessarily complex boolean expression
* @description Boolean expressions that are unnecessarily complicated hinder readability.
* @kind problem
* @problem.severity recommendation
* @precision low
* @id java/complex-boolean-expression
* @tags readability
*/
import java
class BoolCompare extends EqualityTest {
BoolCompare() { this.getAnOperand() instanceof BooleanLiteral }
predicate simplify(string pattern, string rewrite) {
exists(boolean b | b = this.getAnOperand().(BooleanLiteral).getBooleanValue() |
this instanceof ValueOrReferenceEqualsExpr and
b = true and
pattern = "A == true" and
rewrite = "A"
or
this instanceof ValueOrReferenceNotEqualsExpr and
b = false and
pattern = "A != false" and
rewrite = "A"
or
this instanceof ValueOrReferenceEqualsExpr and
b = false and
pattern = "A == false" and
rewrite = "!A"
or
this instanceof ValueOrReferenceNotEqualsExpr and
b = true and
pattern = "A != true" and
rewrite = "!A"
)
}
}
predicate conditionalWithBool(ConditionalExpr c, string pattern, string rewrite) {
exists(boolean truebranch |
c.getThen().(BooleanLiteral).getBooleanValue() = truebranch and
not c.getElse() instanceof BooleanLiteral and
not c.getElse().getType() instanceof NullType and
(
truebranch = true and pattern = "A ? true : B" and rewrite = "A || B"
or
truebranch = false and pattern = "A ? false : B" and rewrite = "!A && B"
)
)
or
exists(boolean falsebranch |
not c.getThen() instanceof BooleanLiteral and
not c.getThen().getType() instanceof NullType and
c.getElse().(BooleanLiteral).getBooleanValue() = falsebranch and
(
falsebranch = true and pattern = "A ? B : true" and rewrite = "!A || B"
or
falsebranch = false and pattern = "A ? B : false" and rewrite = "A && B"
)
)
or
exists(boolean truebranch, boolean falsebranch |
c.getThen().(BooleanLiteral).getBooleanValue() = truebranch and
c.getElse().(BooleanLiteral).getBooleanValue() = falsebranch and
(
truebranch = true and falsebranch = false and pattern = "A ? true : false" and rewrite = "A"
or
truebranch = false and falsebranch = true and pattern = "A ? false : true" and rewrite = "!A"
)
)
}
class ComparisonOrEquality extends BinaryExpr {
ComparisonOrEquality() { this instanceof ComparisonExpr or this instanceof EqualityTest }
predicate negate(string pattern, string rewrite) {
this instanceof EQExpr and pattern = "!(A == B)" and rewrite = "A != B"
or
this instanceof NEExpr and pattern = "!(A != B)" and rewrite = "A == B"
or
this instanceof LTExpr and pattern = "!(A < B)" and rewrite = "A >= B"
or
this instanceof GTExpr and pattern = "!(A > B)" and rewrite = "A <= B"
or
this instanceof LEExpr and pattern = "!(A <= B)" and rewrite = "A > B"
or
this instanceof GEExpr and pattern = "!(A >= B)" and rewrite = "A < B"
}
}
from Expr e, string pattern, string rewrite
where
e.getFile().isJavaSourceFile() and
(
e.(BoolCompare).simplify(pattern, rewrite)
or
conditionalWithBool(e, pattern, rewrite)
or
e.(LogNotExpr).getOperand().(ComparisonOrEquality).negate(pattern, rewrite)
or
e.(LogNotExpr).getOperand() instanceof LogNotExpr and
pattern = "!!A" and
rewrite = "A"
)
select e, "Expressions of the form \"" + pattern + "\" can be simplified to \"" + rewrite + "\"."