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
This commit is contained in:
Cole Faust
2021-11-16 14:52:12 -08:00
parent 2b244217a2
commit f1f44d3d21
2 changed files with 43 additions and 14 deletions

View File

@@ -224,9 +224,9 @@ func (s *toStringExpr) emit(ctx *generationContext) {
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) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same
}
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() {