Loading mk2rbc/expr.go +30 −0 Original line number Diff line number Diff line Loading @@ -728,6 +728,36 @@ func (f *foreachExpr) transform(transformer func(expr starlarkExpr) starlarkExpr } } type binaryOpExpr struct { left, right starlarkExpr op string returnType starlarkType } func (b *binaryOpExpr) emit(gctx *generationContext) { b.left.emit(gctx) gctx.write(" " + b.op + " ") b.right.emit(gctx) } func (b *binaryOpExpr) typ() starlarkType { return b.returnType } func (b *binaryOpExpr) emitListVarCopy(gctx *generationContext) { b.emit(gctx) } func (b *binaryOpExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr { b.left = b.left.transform(transformer) b.right = b.right.transform(transformer) if replacement := transformer(b); replacement != nil { return replacement } else { return b } } type badExpr struct { errorLocation ErrorLocation message string Loading mk2rbc/mk2rbc.go +91 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,11 @@ var knownFunctions = map[string]interface { "is-vendor-board-qcom": &isVendorBoardQcomCallParser{}, "lastword": &firstOrLastwordCallParser{isLastWord: true}, "notdir": &simpleCallParser{name: baseName + ".notdir", returnType: starlarkTypeString, addGlobals: false}, "math_max": &mathMaxOrMinCallParser{function: "max"}, "math_min": &mathMaxOrMinCallParser{function: "min"}, "math_gt_or_eq": &mathComparisonCallParser{op: ">="}, "math_gt": &mathComparisonCallParser{op: ">"}, "math_lt": &mathComparisonCallParser{op: "<"}, "my-dir": &myDirCallParser{}, "patsubst": &substCallParser{fname: "patsubst"}, "product-copy-files-by-pattern": &simpleCallParser{name: baseName + ".product_copy_files_by_pattern", returnType: starlarkTypeList, addGlobals: false}, Loading Loading @@ -1068,6 +1073,23 @@ func (ctx *parseContext) parseCompare(cond *mkparser.Directive) starlarkExpr { case *eqExpr: typedExpr.isEq = !typedExpr.isEq return typedExpr case *binaryOpExpr: switch typedExpr.op { case ">": typedExpr.op = "<=" return typedExpr case "<": typedExpr.op = ">=" return typedExpr case ">=": typedExpr.op = "<" return typedExpr case "<=": typedExpr.op = ">" return typedExpr default: return ¬Expr{expr: expr} } default: return ¬Expr{expr: expr} } Loading @@ -1090,6 +1112,13 @@ func (ctx *parseContext) parseCompare(cond *mkparser.Directive) starlarkExpr { return otherOperand } } if intOperand, err := strconv.Atoi(strings.TrimSpace(stringOperand)); err == nil && otherOperand.typ() == starlarkTypeInt { return &eqExpr{ left: otherOperand, right: &intLiteralExpr{literal: intOperand}, isEq: isEq, } } } return &eqExpr{left: xLeft, right: xRight, isEq: isEq} Loading Loading @@ -1625,6 +1654,68 @@ func (p *firstOrLastwordCallParser) parse(ctx *parseContext, node mkparser.Node, return &indexExpr{&callExpr{object: arg, name: "split", returnType: starlarkTypeList}, index} } func parseIntegerArguments(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString, expectedArgs int) ([]starlarkExpr, error) { parsedArgs := make([]starlarkExpr, 0) for _, arg := range args.Split(",") { expr := ctx.parseMakeString(node, arg) if expr.typ() == starlarkTypeList { return nil, fmt.Errorf("argument to math argument has type list, which cannot be converted to int") } if s, ok := maybeString(expr); ok { intVal, err := strconv.Atoi(strings.TrimSpace(s)) if err != nil { return nil, err } expr = &intLiteralExpr{literal: intVal} } else if expr.typ() != starlarkTypeInt { expr = &callExpr{ name: "int", args: []starlarkExpr{expr}, returnType: starlarkTypeInt, } } parsedArgs = append(parsedArgs, expr) } if len(parsedArgs) != expectedArgs { return nil, fmt.Errorf("function should have %d arguments", expectedArgs) } return parsedArgs, nil } type mathComparisonCallParser struct { op string } func (p *mathComparisonCallParser) parse(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString) starlarkExpr { parsedArgs, err := parseIntegerArguments(ctx, node, args, 2) if err != nil { return ctx.newBadExpr(node, err.Error()) } return &binaryOpExpr{ left: parsedArgs[0], right: parsedArgs[1], op: p.op, returnType: starlarkTypeBool, } } type mathMaxOrMinCallParser struct { function string } func (p *mathMaxOrMinCallParser) parse(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString) starlarkExpr { parsedArgs, err := parseIntegerArguments(ctx, node, args, 2) if err != nil { return ctx.newBadExpr(node, err.Error()) } return &callExpr{ object: nil, name: p.function, args: parsedArgs, returnType: starlarkTypeInt, } } func (ctx *parseContext) parseMakeString(node mkparser.Node, mk *mkparser.MakeString) starlarkExpr { if mk.Const() { return &stringLiteralExpr{mk.Dump()} Loading mk2rbc/mk2rbc_test.go +57 −0 Original line number Diff line number Diff line Loading @@ -1279,6 +1279,63 @@ def init(g, handle): g["NATIVE_BRIDGE_PRODUCT_PACKAGES"] = "libnative_bridge_vdso.native_bridge native_bridge_guest_app_process.native_bridge native_bridge_guest_linker.native_bridge" g["NATIVE_BRIDGE_MODIFIED_GUEST_LIBS"] = "libaaudio libamidi libandroid libandroid_runtime" g["NATIVE_BRIDGE_PRODUCT_PACKAGES"] += " " + " ".join(rblf.addsuffix(".native_bridge", g.get("NATIVE_BRIDGE_ORIG_GUEST_LIBS", ""))) `, }, { desc: "Math functions", mkname: "product.mk", in: ` # Test the math functions defined in build/make/common/math.mk ifeq ($(call math_max,2,5),5) endif ifeq ($(call math_min,2,5),2) endif ifeq ($(call math_gt_or_eq,2,5),true) endif ifeq ($(call math_gt,2,5),true) endif ifeq ($(call math_lt,2,5),true) endif ifeq ($(call math_gt_or_eq,2,5),) endif ifeq ($(call math_gt,2,5),) endif ifeq ($(call math_lt,2,5),) endif ifeq ($(call math_gt_or_eq,$(MY_VAR), 5),true) endif ifeq ($(call math_gt_or_eq,$(MY_VAR),$(MY_OTHER_VAR)),true) endif ifeq ($(call math_gt_or_eq,100$(MY_VAR),10),true) endif `, expected: `# Test the math functions defined in build/make/common/math.mk load("//build/make/core:product_config.rbc", "rblf") def init(g, handle): cfg = rblf.cfg(handle) if max(2, 5) == 5: pass if min(2, 5) == 2: pass if 2 >= 5: pass if 2 > 5: pass if 2 < 5: pass if 2 < 5: pass if 2 <= 5: pass if 2 >= 5: pass if int(g.get("MY_VAR", "")) >= 5: pass if int(g.get("MY_VAR", "")) >= int(g.get("MY_OTHER_VAR", "")): pass if int("100%s" % g.get("MY_VAR", "")) >= 10: pass `, }, } Loading Loading
mk2rbc/expr.go +30 −0 Original line number Diff line number Diff line Loading @@ -728,6 +728,36 @@ func (f *foreachExpr) transform(transformer func(expr starlarkExpr) starlarkExpr } } type binaryOpExpr struct { left, right starlarkExpr op string returnType starlarkType } func (b *binaryOpExpr) emit(gctx *generationContext) { b.left.emit(gctx) gctx.write(" " + b.op + " ") b.right.emit(gctx) } func (b *binaryOpExpr) typ() starlarkType { return b.returnType } func (b *binaryOpExpr) emitListVarCopy(gctx *generationContext) { b.emit(gctx) } func (b *binaryOpExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr { b.left = b.left.transform(transformer) b.right = b.right.transform(transformer) if replacement := transformer(b); replacement != nil { return replacement } else { return b } } type badExpr struct { errorLocation ErrorLocation message string Loading
mk2rbc/mk2rbc.go +91 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,11 @@ var knownFunctions = map[string]interface { "is-vendor-board-qcom": &isVendorBoardQcomCallParser{}, "lastword": &firstOrLastwordCallParser{isLastWord: true}, "notdir": &simpleCallParser{name: baseName + ".notdir", returnType: starlarkTypeString, addGlobals: false}, "math_max": &mathMaxOrMinCallParser{function: "max"}, "math_min": &mathMaxOrMinCallParser{function: "min"}, "math_gt_or_eq": &mathComparisonCallParser{op: ">="}, "math_gt": &mathComparisonCallParser{op: ">"}, "math_lt": &mathComparisonCallParser{op: "<"}, "my-dir": &myDirCallParser{}, "patsubst": &substCallParser{fname: "patsubst"}, "product-copy-files-by-pattern": &simpleCallParser{name: baseName + ".product_copy_files_by_pattern", returnType: starlarkTypeList, addGlobals: false}, Loading Loading @@ -1068,6 +1073,23 @@ func (ctx *parseContext) parseCompare(cond *mkparser.Directive) starlarkExpr { case *eqExpr: typedExpr.isEq = !typedExpr.isEq return typedExpr case *binaryOpExpr: switch typedExpr.op { case ">": typedExpr.op = "<=" return typedExpr case "<": typedExpr.op = ">=" return typedExpr case ">=": typedExpr.op = "<" return typedExpr case "<=": typedExpr.op = ">" return typedExpr default: return ¬Expr{expr: expr} } default: return ¬Expr{expr: expr} } Loading @@ -1090,6 +1112,13 @@ func (ctx *parseContext) parseCompare(cond *mkparser.Directive) starlarkExpr { return otherOperand } } if intOperand, err := strconv.Atoi(strings.TrimSpace(stringOperand)); err == nil && otherOperand.typ() == starlarkTypeInt { return &eqExpr{ left: otherOperand, right: &intLiteralExpr{literal: intOperand}, isEq: isEq, } } } return &eqExpr{left: xLeft, right: xRight, isEq: isEq} Loading Loading @@ -1625,6 +1654,68 @@ func (p *firstOrLastwordCallParser) parse(ctx *parseContext, node mkparser.Node, return &indexExpr{&callExpr{object: arg, name: "split", returnType: starlarkTypeList}, index} } func parseIntegerArguments(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString, expectedArgs int) ([]starlarkExpr, error) { parsedArgs := make([]starlarkExpr, 0) for _, arg := range args.Split(",") { expr := ctx.parseMakeString(node, arg) if expr.typ() == starlarkTypeList { return nil, fmt.Errorf("argument to math argument has type list, which cannot be converted to int") } if s, ok := maybeString(expr); ok { intVal, err := strconv.Atoi(strings.TrimSpace(s)) if err != nil { return nil, err } expr = &intLiteralExpr{literal: intVal} } else if expr.typ() != starlarkTypeInt { expr = &callExpr{ name: "int", args: []starlarkExpr{expr}, returnType: starlarkTypeInt, } } parsedArgs = append(parsedArgs, expr) } if len(parsedArgs) != expectedArgs { return nil, fmt.Errorf("function should have %d arguments", expectedArgs) } return parsedArgs, nil } type mathComparisonCallParser struct { op string } func (p *mathComparisonCallParser) parse(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString) starlarkExpr { parsedArgs, err := parseIntegerArguments(ctx, node, args, 2) if err != nil { return ctx.newBadExpr(node, err.Error()) } return &binaryOpExpr{ left: parsedArgs[0], right: parsedArgs[1], op: p.op, returnType: starlarkTypeBool, } } type mathMaxOrMinCallParser struct { function string } func (p *mathMaxOrMinCallParser) parse(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString) starlarkExpr { parsedArgs, err := parseIntegerArguments(ctx, node, args, 2) if err != nil { return ctx.newBadExpr(node, err.Error()) } return &callExpr{ object: nil, name: p.function, args: parsedArgs, returnType: starlarkTypeInt, } } func (ctx *parseContext) parseMakeString(node mkparser.Node, mk *mkparser.MakeString) starlarkExpr { if mk.Const() { return &stringLiteralExpr{mk.Dump()} Loading
mk2rbc/mk2rbc_test.go +57 −0 Original line number Diff line number Diff line Loading @@ -1279,6 +1279,63 @@ def init(g, handle): g["NATIVE_BRIDGE_PRODUCT_PACKAGES"] = "libnative_bridge_vdso.native_bridge native_bridge_guest_app_process.native_bridge native_bridge_guest_linker.native_bridge" g["NATIVE_BRIDGE_MODIFIED_GUEST_LIBS"] = "libaaudio libamidi libandroid libandroid_runtime" g["NATIVE_BRIDGE_PRODUCT_PACKAGES"] += " " + " ".join(rblf.addsuffix(".native_bridge", g.get("NATIVE_BRIDGE_ORIG_GUEST_LIBS", ""))) `, }, { desc: "Math functions", mkname: "product.mk", in: ` # Test the math functions defined in build/make/common/math.mk ifeq ($(call math_max,2,5),5) endif ifeq ($(call math_min,2,5),2) endif ifeq ($(call math_gt_or_eq,2,5),true) endif ifeq ($(call math_gt,2,5),true) endif ifeq ($(call math_lt,2,5),true) endif ifeq ($(call math_gt_or_eq,2,5),) endif ifeq ($(call math_gt,2,5),) endif ifeq ($(call math_lt,2,5),) endif ifeq ($(call math_gt_or_eq,$(MY_VAR), 5),true) endif ifeq ($(call math_gt_or_eq,$(MY_VAR),$(MY_OTHER_VAR)),true) endif ifeq ($(call math_gt_or_eq,100$(MY_VAR),10),true) endif `, expected: `# Test the math functions defined in build/make/common/math.mk load("//build/make/core:product_config.rbc", "rblf") def init(g, handle): cfg = rblf.cfg(handle) if max(2, 5) == 5: pass if min(2, 5) == 2: pass if 2 >= 5: pass if 2 > 5: pass if 2 < 5: pass if 2 < 5: pass if 2 <= 5: pass if 2 >= 5: pass if int(g.get("MY_VAR", "")) >= 5: pass if int(g.get("MY_VAR", "")) >= int(g.get("MY_OTHER_VAR", "")): pass if int("100%s" % g.get("MY_VAR", "")) >= 10: pass `, }, } Loading