Skip to content

Commit fd116f2

Browse files
committed
C#: Re-factor the implementation to use the designated predicates for left/right and branches instead of relying on magic constants.
1 parent 964adaa commit fd116f2

1 file changed

Lines changed: 53 additions & 20 deletions

File tree

‎csharp/ql/src/Language Abuse/SimplifyBoolExpr.ql‎

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,46 +13,79 @@
1313
import csharp
1414

1515
/**
16-
* Holds if expression `expr` has Boolean `value` at child `child`.
17-
* No other child nodes are boolean literals.
16+
* Holds if the left operand of a binary operation is a Boolean literal with the specified value
17+
* and the right operand is not a Boolean literal.
1818
*/
19-
predicate literalChild(Expr expr, int child, boolean value) {
20-
value = expr.getChild(child).(BoolLiteral).getBoolValue() and
21-
forall(int c | c != child | not expr.getChild(c) instanceof BoolLiteral)
19+
predicate binaryLiteralLeft(BinaryOperation op, boolean value) {
20+
value = op.getLeftOperand().(BoolLiteral).getBoolValue() and
21+
not op.getRightOperand() instanceof BoolLiteral
2222
}
2323

2424
/**
25-
* Expression `expr` has Boolean `value1` at child `child1`, and boolean `value2` at `child2`.
26-
* No other child nodes are boolean literals.
25+
* Holds if the right operand of a binary operation is a Boolean literal with the specified value
26+
* and the left operand is not a Boolean literal.
2727
*/
28-
predicate literalChildren(Expr expr, int child1, boolean value1, int child2, boolean value2) {
29-
value1 = expr.getChild(child1).(BoolLiteral).getBoolValue() and
30-
value2 = expr.getChild(child2).(BoolLiteral).getBoolValue() and
31-
forall(int c | c != child1 and c != child2 | not expr.getChild(c) instanceof BoolLiteral)
28+
predicate binaryLiteralRight(BinaryOperation op, boolean value) {
29+
value = op.getRightOperand().(BoolLiteral).getBoolValue() and
30+
not op.getLeftOperand() instanceof BoolLiteral
31+
}
32+
33+
/**
34+
* Holds if the 'then' branch of a conditional expression is a Boolean literal with the specified value
35+
* and the 'condition' or 'else' branch are not Boolean literals.
36+
*/
37+
predicate conditionalThenLiteral(ConditionalExpr cond, boolean value) {
38+
value = cond.getThen().(BoolLiteral).getBoolValue() and
39+
not cond.getCondition() instanceof BoolLiteral and
40+
not cond.getElse() instanceof BoolLiteral
41+
}
42+
43+
/**
44+
* Holds if the 'else' branch of a conditional expression is a Boolean literal with the specified value
45+
* and the 'condition' or 'then' branch are not Boolean literals.
46+
*/
47+
predicate conditionalElseLiteral(ConditionalExpr cond, boolean value) {
48+
value = cond.getElse().(BoolLiteral).getBoolValue() and
49+
not cond.getCondition() instanceof BoolLiteral and
50+
not cond.getThen() instanceof BoolLiteral
51+
}
52+
53+
/**
54+
* Holds if both the 'then' and 'else' branches of a conditional expression are Boolean literals with the specified values
55+
* and the 'condition' branch is not a Boolean literal.
56+
*/
57+
predicate conditionalThenAndElseLiteral(ConditionalExpr cond, boolean thenValue, boolean elseValue) {
58+
thenValue = cond.getThen().(BoolLiteral).getBoolValue() and
59+
elseValue = cond.getElse().(BoolLiteral).getBoolValue() and
60+
not cond.getCondition() instanceof BoolLiteral
3261
}
3362

3463
predicate rewriteBinaryExpr(BinaryOperation op, boolean value, string oldPattern) {
35-
literalChild(op, 0, value) and oldPattern = value + " " + op.getOperator() + " A"
64+
binaryLiteralLeft(op, value) and oldPattern = value + " " + op.getOperator() + " A"
3665
or
37-
literalChild(op, 1, value) and oldPattern = "A " + op.getOperator() + " " + value
66+
binaryLiteralRight(op, value) and oldPattern = "A " + op.getOperator() + " " + value
3867
}
3968

4069
predicate rewriteConditionalExpr(ConditionalExpr cond, string oldPattern, string newPattern) {
41-
literalChild(cond, 1, false) and oldPattern = "A ? false : B" and newPattern = "!A && B"
70+
conditionalThenLiteral(cond, false) and oldPattern = "A ? false : B" and newPattern = "!A && B"
4271
or
43-
literalChild(cond, 1, true) and oldPattern = "A ? true : B" and newPattern = "A || B"
72+
conditionalThenLiteral(cond, true) and oldPattern = "A ? true : B" and newPattern = "A || B"
4473
or
45-
literalChild(cond, 2, false) and oldPattern = "A ? B : false" and newPattern = "A && B"
74+
conditionalElseLiteral(cond, false) and oldPattern = "A ? B : false" and newPattern = "A && B"
4675
or
47-
literalChild(cond, 2, true) and oldPattern = "A ? B : true" and newPattern = "!A || B"
76+
conditionalElseLiteral(cond, true) and oldPattern = "A ? B : true" and newPattern = "!A || B"
4877
or
49-
exists(boolean b | literalChildren(cond, 1, b, 2, b) |
78+
exists(boolean b | conditionalThenAndElseLiteral(cond, b, b) |
5079
oldPattern = "A ? " + b + " : " + b and newPattern = b.toString()
5180
)
5281
or
53-
literalChildren(cond, 1, true, 2, false) and oldPattern = "A ? true : false" and newPattern = "A"
82+
conditionalThenAndElseLiteral(cond, true, false) and
83+
oldPattern = "A ? true : false" and
84+
newPattern = "A"
5485
or
55-
literalChildren(cond, 1, false, 2, true) and oldPattern = "A ? false : true" and newPattern = "!A"
86+
conditionalThenAndElseLiteral(cond, false, true) and
87+
oldPattern = "A ? false : true" and
88+
newPattern = "!A"
5689
}
5790

5891
predicate negatedOperators(string op, string negated) {

0 commit comments

Comments
 (0)