Loading mk2rbc/expr.go +15 −11 Original line number Original line Diff line number Diff line Loading @@ -240,22 +240,21 @@ func (eq *eqExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same } } func (eq *eqExpr) emit(gctx *generationContext) { func (eq *eqExpr) emit(gctx *generationContext) { // Are we checking that a variable is empty? emitSimple := func(expr starlarkExpr) { var varRef *variableRefExpr if s, ok := maybeString(eq.left); ok && s == "" { varRef, ok = eq.right.(*variableRefExpr) } else if s, ok := maybeString(eq.right); ok && s == "" { varRef, ok = eq.left.(*variableRefExpr) } if varRef != nil { // Yes. if eq.isEq { if eq.isEq { gctx.write("not ") gctx.write("not ") } } varRef.emit(gctx) expr.emit(gctx) return } } // 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 } // General case // General case eq.left.emit(gctx) eq.left.emit(gctx) if eq.isEq { if eq.isEq { Loading Loading @@ -578,3 +577,8 @@ func maybeConvertToStringList(expr starlarkExpr) starlarkExpr { } } return expr return expr } } func isEmptyString(expr starlarkExpr) bool { x, ok := expr.(*stringLiteralExpr) return ok && x.literal == "" } mk2rbc/mk2rbc.go +40 −32 Original line number Original line Diff line number Diff line Loading @@ -938,14 +938,14 @@ func (ctx *parseContext) parseCheckFunctionCallResult(directive *mkparser.Direct func (ctx *parseContext) parseCompareFilterFuncResult(cond *mkparser.Directive, func (ctx *parseContext) parseCompareFilterFuncResult(cond *mkparser.Directive, filterFuncCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { filterFuncCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { // We handle: // We handle: // * ifeq/ifneq (,$(filter v1 v2 ..., $(VAR)) becomes if VAR not in/in ["v1", "v2", ...] // * ifeq/ifneq (,$(filter v1 v2 ..., EXPR) becomes if EXPR not in/in ["v1", "v2", ...] // * ifeq/ifneq (,$(filter $(VAR), v1 v2 ...) becomes if VAR not in/in ["v1", "v2", ...] // * ifeq/ifneq (,$(filter EXPR, v1 v2 ...) becomes if EXPR not in/in ["v1", "v2", ...] // * ifeq/ifneq ($(VAR),$(filter $(VAR), v1 v2 ...) becomes if VAR in/not in ["v1", "v2"] // * ifeq/ifneq ($(VAR),$(filter $(VAR), v1 v2 ...) becomes if VAR in/not in ["v1", "v2"] // TODO(Asmundak): check the last case works for filter-out, too. // TODO(Asmundak): check the last case works for filter-out, too. xPattern := filterFuncCall.args[0] xPattern := filterFuncCall.args[0] xText := filterFuncCall.args[1] xText := filterFuncCall.args[1] var xInList *stringLiteralExpr var xInList *stringLiteralExpr var xVar starlarkExpr var expr starlarkExpr var ok bool var ok bool switch x := xValue.(type) { switch x := xValue.(type) { case *stringLiteralExpr: case *stringLiteralExpr: Loading @@ -955,34 +955,42 @@ func (ctx *parseContext) parseCompareFilterFuncResult(cond *mkparser.Directive, // Either pattern or text should be const, and the // Either pattern or text should be const, and the // non-const one should be varRefExpr // non-const one should be varRefExpr if xInList, ok = xPattern.(*stringLiteralExpr); ok { if xInList, ok = xPattern.(*stringLiteralExpr); ok { xVar = xText expr = xText } else if xInList, ok = xText.(*stringLiteralExpr); ok { } else if xInList, ok = xText.(*stringLiteralExpr); ok { xVar = xPattern expr = xPattern } else { return &callExpr{ object: nil, name: filterFuncCall.name, args: filterFuncCall.args, returnType: starlarkTypeBool, } } } case *variableRefExpr: case *variableRefExpr: if v, ok := xPattern.(*variableRefExpr); ok { if v, ok := xPattern.(*variableRefExpr); ok { if xInList, ok = xText.(*stringLiteralExpr); ok && v.ref.name() == x.ref.name() { if xInList, ok = xText.(*stringLiteralExpr); ok && v.ref.name() == x.ref.name() { // ifeq/ifneq ($(VAR),$(filter $(VAR), v1 v2 ...), flip negate, // ifeq/ifneq ($(VAR),$(filter $(VAR), v1 v2 ...), flip negate, // it's the opposite to what is done when comparing to empty. // it's the opposite to what is done when comparing to empty. xVar = xPattern expr = xPattern negate = !negate negate = !negate } } } } } } if xVar != nil && xInList != nil { if expr != nil && xInList != nil { if _, ok := xVar.(*variableRefExpr); ok { slExpr := newStringListExpr(strings.Fields(xInList.literal)) slExpr := newStringListExpr(strings.Fields(xInList.literal)) // Generate simpler code for the common cases: // Generate simpler code for the common cases: if xVar.typ() == starlarkTypeList { if expr.typ() == starlarkTypeList { if len(slExpr.items) == 1 { if len(slExpr.items) == 1 { // Checking that a string belongs to list // Checking that a string belongs to list return &inExpr{isNot: negate, list: xVar, expr: slExpr.items[0]} return &inExpr{isNot: negate, list: expr, expr: slExpr.items[0]} } else { } else { // TODO(asmundak): // TODO(asmundak): panic("TBD") panic("TBD") } } } } else if len(slExpr.items) == 1 { return &inExpr{isNot: negate, list: newStringListExpr(strings.Fields(xInList.literal)), expr: xVar} return &eqExpr{left: expr, right: slExpr.items[0], isEq: !negate} } else { return &inExpr{isNot: negate, list: newStringListExpr(strings.Fields(xInList.literal)), expr: expr} } } } } return ctx.newBadExpr(cond, "filter arguments are too complex: %s", cond.Dump()) return ctx.newBadExpr(cond, "filter arguments are too complex: %s", cond.Dump()) Loading @@ -990,7 +998,7 @@ func (ctx *parseContext) parseCompareFilterFuncResult(cond *mkparser.Directive, func (ctx *parseContext) parseCompareWildcardFuncResult(directive *mkparser.Directive, func (ctx *parseContext) parseCompareWildcardFuncResult(directive *mkparser.Directive, xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { if x, ok := xValue.(*stringLiteralExpr); !ok || x.literal != "" { if !isEmptyString(xValue) { return ctx.newBadExpr(directive, "wildcard result can be compared only to empty: %s", xValue) return ctx.newBadExpr(directive, "wildcard result can be compared only to empty: %s", xValue) } } callFunc := wildcardExistsPhony callFunc := wildcardExistsPhony Loading @@ -1006,9 +1014,7 @@ func (ctx *parseContext) parseCompareWildcardFuncResult(directive *mkparser.Dire func (ctx *parseContext) parseCheckFindstringFuncResult(directive *mkparser.Directive, func (ctx *parseContext) parseCheckFindstringFuncResult(directive *mkparser.Directive, xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { if x, ok := xValue.(*stringLiteralExpr); !ok || x.literal != "" { if isEmptyString(xValue) { return ctx.newBadExpr(directive, "findstring result can be compared only to empty: %s", xValue) } return &eqExpr{ return &eqExpr{ left: &callExpr{ left: &callExpr{ object: xCall.args[1], object: xCall.args[1], Loading @@ -1020,6 +1026,8 @@ func (ctx *parseContext) parseCheckFindstringFuncResult(directive *mkparser.Dire isEq: !negate, isEq: !negate, } } } } return ctx.newBadExpr(directive, "findstring result can be compared only to empty: %s", xValue) } func (ctx *parseContext) parseCompareStripFuncResult(directive *mkparser.Directive, func (ctx *parseContext) parseCompareStripFuncResult(directive *mkparser.Directive, xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { Loading mk2rbc/mk2rbc_test.go +22 −3 Original line number Original line Diff line number Diff line Loading @@ -342,6 +342,8 @@ ifneq (,$(filter plaf,$(PLATFORM_LIST))) endif endif ifeq ($(TARGET_BUILD_VARIANT), $(filter $(TARGET_BUILD_VARIANT), userdebug eng)) ifeq ($(TARGET_BUILD_VARIANT), $(filter $(TARGET_BUILD_VARIANT), userdebug eng)) endif endif ifneq (,$(filter true, $(v1)$(v2))) endif `, `, expected: `load("//build/make/core:product_config.rbc", "rblf") expected: `load("//build/make/core:product_config.rbc", "rblf") Loading @@ -349,12 +351,14 @@ def init(g, handle): cfg = rblf.cfg(handle) cfg = rblf.cfg(handle) if g["TARGET_BUILD_VARIANT"] not in ["userdebug", "eng"]: if g["TARGET_BUILD_VARIANT"] not in ["userdebug", "eng"]: pass pass if g["TARGET_BUILD_VARIANT"] in ["userdebug"]: if g["TARGET_BUILD_VARIANT"] == "userdebug": pass pass if "plaf" in g.get("PLATFORM_LIST", []): if "plaf" in g.get("PLATFORM_LIST", []): pass pass if g["TARGET_BUILD_VARIANT"] in ["userdebug", "eng"]: if g["TARGET_BUILD_VARIANT"] in ["userdebug", "eng"]: pass pass if "%s%s" % (_v1, _v2) == "true": pass `, `, }, }, { { Loading Loading @@ -385,7 +389,22 @@ endif def init(g, handle): def init(g, handle): cfg = rblf.cfg(handle) cfg = rblf.cfg(handle) if g["TARGET_PRODUCT"] not in ["yukawa_gms", "yukawa_sei510_gms"]: if g["TARGET_PRODUCT"] not in ["yukawa_gms", "yukawa_sei510_gms"]: if g["TARGET_PRODUCT"] in ["yukawa_gms"]: if g["TARGET_PRODUCT"] == "yukawa_gms": pass `, }, { desc: "filter $(V1), $(V2)", mkname: "product.mk", in: ` ifneq (, $(filter $(PRODUCT_LIST), $(TARGET_PRODUCT))) endif `, expected: `load("//build/make/core:product_config.rbc", "rblf") def init(g, handle): cfg = rblf.cfg(handle) if rblf.filter(g.get("PRODUCT_LIST", ""), g["TARGET_PRODUCT"]): pass pass `, `, }, }, Loading Loading @@ -779,7 +798,7 @@ endif def init(g, handle): def init(g, handle): cfg = rblf.cfg(handle) cfg = rblf.cfg(handle) if rblf.mkstrip(g.get("TARGET_VENDOR", "")) != "": if rblf.mkstrip(g.get("TARGET_VENDOR", "")): pass pass `, `, }, }, Loading Loading
mk2rbc/expr.go +15 −11 Original line number Original line Diff line number Diff line Loading @@ -240,22 +240,21 @@ func (eq *eqExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same } } func (eq *eqExpr) emit(gctx *generationContext) { func (eq *eqExpr) emit(gctx *generationContext) { // Are we checking that a variable is empty? emitSimple := func(expr starlarkExpr) { var varRef *variableRefExpr if s, ok := maybeString(eq.left); ok && s == "" { varRef, ok = eq.right.(*variableRefExpr) } else if s, ok := maybeString(eq.right); ok && s == "" { varRef, ok = eq.left.(*variableRefExpr) } if varRef != nil { // Yes. if eq.isEq { if eq.isEq { gctx.write("not ") gctx.write("not ") } } varRef.emit(gctx) expr.emit(gctx) return } } // 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 } // General case // General case eq.left.emit(gctx) eq.left.emit(gctx) if eq.isEq { if eq.isEq { Loading Loading @@ -578,3 +577,8 @@ func maybeConvertToStringList(expr starlarkExpr) starlarkExpr { } } return expr return expr } } func isEmptyString(expr starlarkExpr) bool { x, ok := expr.(*stringLiteralExpr) return ok && x.literal == "" }
mk2rbc/mk2rbc.go +40 −32 Original line number Original line Diff line number Diff line Loading @@ -938,14 +938,14 @@ func (ctx *parseContext) parseCheckFunctionCallResult(directive *mkparser.Direct func (ctx *parseContext) parseCompareFilterFuncResult(cond *mkparser.Directive, func (ctx *parseContext) parseCompareFilterFuncResult(cond *mkparser.Directive, filterFuncCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { filterFuncCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { // We handle: // We handle: // * ifeq/ifneq (,$(filter v1 v2 ..., $(VAR)) becomes if VAR not in/in ["v1", "v2", ...] // * ifeq/ifneq (,$(filter v1 v2 ..., EXPR) becomes if EXPR not in/in ["v1", "v2", ...] // * ifeq/ifneq (,$(filter $(VAR), v1 v2 ...) becomes if VAR not in/in ["v1", "v2", ...] // * ifeq/ifneq (,$(filter EXPR, v1 v2 ...) becomes if EXPR not in/in ["v1", "v2", ...] // * ifeq/ifneq ($(VAR),$(filter $(VAR), v1 v2 ...) becomes if VAR in/not in ["v1", "v2"] // * ifeq/ifneq ($(VAR),$(filter $(VAR), v1 v2 ...) becomes if VAR in/not in ["v1", "v2"] // TODO(Asmundak): check the last case works for filter-out, too. // TODO(Asmundak): check the last case works for filter-out, too. xPattern := filterFuncCall.args[0] xPattern := filterFuncCall.args[0] xText := filterFuncCall.args[1] xText := filterFuncCall.args[1] var xInList *stringLiteralExpr var xInList *stringLiteralExpr var xVar starlarkExpr var expr starlarkExpr var ok bool var ok bool switch x := xValue.(type) { switch x := xValue.(type) { case *stringLiteralExpr: case *stringLiteralExpr: Loading @@ -955,34 +955,42 @@ func (ctx *parseContext) parseCompareFilterFuncResult(cond *mkparser.Directive, // Either pattern or text should be const, and the // Either pattern or text should be const, and the // non-const one should be varRefExpr // non-const one should be varRefExpr if xInList, ok = xPattern.(*stringLiteralExpr); ok { if xInList, ok = xPattern.(*stringLiteralExpr); ok { xVar = xText expr = xText } else if xInList, ok = xText.(*stringLiteralExpr); ok { } else if xInList, ok = xText.(*stringLiteralExpr); ok { xVar = xPattern expr = xPattern } else { return &callExpr{ object: nil, name: filterFuncCall.name, args: filterFuncCall.args, returnType: starlarkTypeBool, } } } case *variableRefExpr: case *variableRefExpr: if v, ok := xPattern.(*variableRefExpr); ok { if v, ok := xPattern.(*variableRefExpr); ok { if xInList, ok = xText.(*stringLiteralExpr); ok && v.ref.name() == x.ref.name() { if xInList, ok = xText.(*stringLiteralExpr); ok && v.ref.name() == x.ref.name() { // ifeq/ifneq ($(VAR),$(filter $(VAR), v1 v2 ...), flip negate, // ifeq/ifneq ($(VAR),$(filter $(VAR), v1 v2 ...), flip negate, // it's the opposite to what is done when comparing to empty. // it's the opposite to what is done when comparing to empty. xVar = xPattern expr = xPattern negate = !negate negate = !negate } } } } } } if xVar != nil && xInList != nil { if expr != nil && xInList != nil { if _, ok := xVar.(*variableRefExpr); ok { slExpr := newStringListExpr(strings.Fields(xInList.literal)) slExpr := newStringListExpr(strings.Fields(xInList.literal)) // Generate simpler code for the common cases: // Generate simpler code for the common cases: if xVar.typ() == starlarkTypeList { if expr.typ() == starlarkTypeList { if len(slExpr.items) == 1 { if len(slExpr.items) == 1 { // Checking that a string belongs to list // Checking that a string belongs to list return &inExpr{isNot: negate, list: xVar, expr: slExpr.items[0]} return &inExpr{isNot: negate, list: expr, expr: slExpr.items[0]} } else { } else { // TODO(asmundak): // TODO(asmundak): panic("TBD") panic("TBD") } } } } else if len(slExpr.items) == 1 { return &inExpr{isNot: negate, list: newStringListExpr(strings.Fields(xInList.literal)), expr: xVar} return &eqExpr{left: expr, right: slExpr.items[0], isEq: !negate} } else { return &inExpr{isNot: negate, list: newStringListExpr(strings.Fields(xInList.literal)), expr: expr} } } } } return ctx.newBadExpr(cond, "filter arguments are too complex: %s", cond.Dump()) return ctx.newBadExpr(cond, "filter arguments are too complex: %s", cond.Dump()) Loading @@ -990,7 +998,7 @@ func (ctx *parseContext) parseCompareFilterFuncResult(cond *mkparser.Directive, func (ctx *parseContext) parseCompareWildcardFuncResult(directive *mkparser.Directive, func (ctx *parseContext) parseCompareWildcardFuncResult(directive *mkparser.Directive, xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { if x, ok := xValue.(*stringLiteralExpr); !ok || x.literal != "" { if !isEmptyString(xValue) { return ctx.newBadExpr(directive, "wildcard result can be compared only to empty: %s", xValue) return ctx.newBadExpr(directive, "wildcard result can be compared only to empty: %s", xValue) } } callFunc := wildcardExistsPhony callFunc := wildcardExistsPhony Loading @@ -1006,9 +1014,7 @@ func (ctx *parseContext) parseCompareWildcardFuncResult(directive *mkparser.Dire func (ctx *parseContext) parseCheckFindstringFuncResult(directive *mkparser.Directive, func (ctx *parseContext) parseCheckFindstringFuncResult(directive *mkparser.Directive, xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { if x, ok := xValue.(*stringLiteralExpr); !ok || x.literal != "" { if isEmptyString(xValue) { return ctx.newBadExpr(directive, "findstring result can be compared only to empty: %s", xValue) } return &eqExpr{ return &eqExpr{ left: &callExpr{ left: &callExpr{ object: xCall.args[1], object: xCall.args[1], Loading @@ -1020,6 +1026,8 @@ func (ctx *parseContext) parseCheckFindstringFuncResult(directive *mkparser.Dire isEq: !negate, isEq: !negate, } } } } return ctx.newBadExpr(directive, "findstring result can be compared only to empty: %s", xValue) } func (ctx *parseContext) parseCompareStripFuncResult(directive *mkparser.Directive, func (ctx *parseContext) parseCompareStripFuncResult(directive *mkparser.Directive, xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { Loading
mk2rbc/mk2rbc_test.go +22 −3 Original line number Original line Diff line number Diff line Loading @@ -342,6 +342,8 @@ ifneq (,$(filter plaf,$(PLATFORM_LIST))) endif endif ifeq ($(TARGET_BUILD_VARIANT), $(filter $(TARGET_BUILD_VARIANT), userdebug eng)) ifeq ($(TARGET_BUILD_VARIANT), $(filter $(TARGET_BUILD_VARIANT), userdebug eng)) endif endif ifneq (,$(filter true, $(v1)$(v2))) endif `, `, expected: `load("//build/make/core:product_config.rbc", "rblf") expected: `load("//build/make/core:product_config.rbc", "rblf") Loading @@ -349,12 +351,14 @@ def init(g, handle): cfg = rblf.cfg(handle) cfg = rblf.cfg(handle) if g["TARGET_BUILD_VARIANT"] not in ["userdebug", "eng"]: if g["TARGET_BUILD_VARIANT"] not in ["userdebug", "eng"]: pass pass if g["TARGET_BUILD_VARIANT"] in ["userdebug"]: if g["TARGET_BUILD_VARIANT"] == "userdebug": pass pass if "plaf" in g.get("PLATFORM_LIST", []): if "plaf" in g.get("PLATFORM_LIST", []): pass pass if g["TARGET_BUILD_VARIANT"] in ["userdebug", "eng"]: if g["TARGET_BUILD_VARIANT"] in ["userdebug", "eng"]: pass pass if "%s%s" % (_v1, _v2) == "true": pass `, `, }, }, { { Loading Loading @@ -385,7 +389,22 @@ endif def init(g, handle): def init(g, handle): cfg = rblf.cfg(handle) cfg = rblf.cfg(handle) if g["TARGET_PRODUCT"] not in ["yukawa_gms", "yukawa_sei510_gms"]: if g["TARGET_PRODUCT"] not in ["yukawa_gms", "yukawa_sei510_gms"]: if g["TARGET_PRODUCT"] in ["yukawa_gms"]: if g["TARGET_PRODUCT"] == "yukawa_gms": pass `, }, { desc: "filter $(V1), $(V2)", mkname: "product.mk", in: ` ifneq (, $(filter $(PRODUCT_LIST), $(TARGET_PRODUCT))) endif `, expected: `load("//build/make/core:product_config.rbc", "rblf") def init(g, handle): cfg = rblf.cfg(handle) if rblf.filter(g.get("PRODUCT_LIST", ""), g["TARGET_PRODUCT"]): pass pass `, `, }, }, Loading Loading @@ -779,7 +798,7 @@ endif def init(g, handle): def init(g, handle): cfg = rblf.cfg(handle) cfg = rblf.cfg(handle) if rblf.mkstrip(g.get("TARGET_VENDOR", "")) != "": if rblf.mkstrip(g.get("TARGET_VENDOR", "")): pass pass `, `, }, }, Loading