Simplify equality expressions when comparing to "true"
If a boolean type is compared to a string literal with
the value "true", it should just output that boolean
type unchanged (or prefixed with "not" if ifneq).
Fixes: 206637085
Test: go test
Change-Id: I0c116bb68b96d21ba3783c01fc4ca524aaa04143
diff --git a/mk2rbc/expr.go b/mk2rbc/expr.go
index 8279d2e..0c5bc40 100644
--- a/mk2rbc/expr.go
+++ b/mk2rbc/expr.go
@@ -224,9 +224,9 @@
s.expr.emit(ctx)
ctx.write("))")
case starlarkTypeBool:
- ctx.write("((")
+ ctx.write(`("true" if (`)
s.expr.emit(ctx)
- ctx.write(`) ? "true" : "")`)
+ ctx.write(`) else "")`)
case starlarkTypeVoid:
ctx.write(`""`)
default:
@@ -285,20 +285,33 @@
}
func (eq *eqExpr) emit(gctx *generationContext) {
- emitSimple := func(expr starlarkExpr) {
- if eq.isEq {
- gctx.write("not ")
- }
- expr.emit(gctx)
+ var stringOperand string
+ var otherOperand starlarkExpr
+ if s, ok := maybeString(eq.left); ok {
+ stringOperand = s
+ otherOperand = eq.right
+ } else if s, ok := maybeString(eq.right); ok {
+ stringOperand = s
+ otherOperand = eq.left
}
- // Are we checking that a variable is empty?
- if isEmptyString(eq.left) {
- emitSimple(eq.right)
- return
- } else if isEmptyString(eq.right) {
- emitSimple(eq.left)
- return
+ // If we've identified one of the operands as being a string literal, check
+ // for some special cases we can do to simplify the resulting expression.
+ if otherOperand != nil {
+ if stringOperand == "" {
+ if eq.isEq {
+ gctx.write("not ")
+ }
+ otherOperand.emit(gctx)
+ return
+ }
+ if stringOperand == "true" && otherOperand.typ() == starlarkTypeBool {
+ if !eq.isEq {
+ gctx.write("not ")
+ }
+ otherOperand.emit(gctx)
+ return
+ }
}
if eq.left.typ() != eq.right.typ() {