Convert firstword/lastword to starlark functions instead of index operators

firstword/lastword need to be able to give an empty string when
the input is empty, which the indexing operator can't do.

Bug: 226974242
Test: go test
Change-Id: I44162a258297b32ec27e7acfb1fa06223391dcc6
This commit is contained in:
Cole Faust
2022-04-27 17:49:35 -07:00
parent a59059f3a1
commit 5a13aaf112
2 changed files with 8 additions and 29 deletions

View File

@@ -86,7 +86,7 @@ var knownFunctions = map[string]interface {
"find-copy-subdir-files": &simpleCallParser{name: baseName + ".find_and_copy", returnType: starlarkTypeList}, "find-copy-subdir-files": &simpleCallParser{name: baseName + ".find_and_copy", returnType: starlarkTypeList},
"filter": &simpleCallParser{name: baseName + ".filter", returnType: starlarkTypeList}, "filter": &simpleCallParser{name: baseName + ".filter", returnType: starlarkTypeList},
"filter-out": &simpleCallParser{name: baseName + ".filter_out", returnType: starlarkTypeList}, "filter-out": &simpleCallParser{name: baseName + ".filter_out", returnType: starlarkTypeList},
"firstword": &firstOrLastwordCallParser{isLastWord: false}, "firstword": &simpleCallParser{name: baseName + ".first_word", returnType: starlarkTypeString},
"foreach": &foreachCallParser{}, "foreach": &foreachCallParser{},
"if": &ifCallParser{}, "if": &ifCallParser{},
"info": &makeControlFuncParser{name: baseName + ".mkinfo"}, "info": &makeControlFuncParser{name: baseName + ".mkinfo"},
@@ -97,7 +97,7 @@ var knownFunctions = map[string]interface {
"is-product-in-list": &isProductInListCallParser{}, "is-product-in-list": &isProductInListCallParser{},
"is-vendor-board-platform": &isVendorBoardPlatformCallParser{}, "is-vendor-board-platform": &isVendorBoardPlatformCallParser{},
"is-vendor-board-qcom": &isVendorBoardQcomCallParser{}, "is-vendor-board-qcom": &isVendorBoardQcomCallParser{},
"lastword": &firstOrLastwordCallParser{isLastWord: true}, "lastword": &simpleCallParser{name: baseName + ".last_word", returnType: starlarkTypeString},
"notdir": &simpleCallParser{name: baseName + ".notdir", returnType: starlarkTypeString}, "notdir": &simpleCallParser{name: baseName + ".notdir", returnType: starlarkTypeString},
"math_max": &mathMaxOrMinCallParser{function: "max"}, "math_max": &mathMaxOrMinCallParser{function: "max"},
"math_min": &mathMaxOrMinCallParser{function: "min"}, "math_min": &mathMaxOrMinCallParser{function: "min"},
@@ -459,6 +459,7 @@ func newParseContext(ss *StarlarkScript, nodes []mkparser.Node) *parseContext {
predefined := []struct{ name, value string }{ predefined := []struct{ name, value string }{
{"SRC_TARGET_DIR", filepath.Join("build", "make", "target")}, {"SRC_TARGET_DIR", filepath.Join("build", "make", "target")},
{"LOCAL_PATH", filepath.Dir(ss.mkFile)}, {"LOCAL_PATH", filepath.Dir(ss.mkFile)},
{"MAKEFILE_LIST", ss.mkFile},
{"TOPDIR", ""}, // TOPDIR is just set to an empty string in cleanbuild.mk and core.mk {"TOPDIR", ""}, // TOPDIR is just set to an empty string in cleanbuild.mk and core.mk
// TODO(asmundak): maybe read it from build/make/core/envsetup.mk? // TODO(asmundak): maybe read it from build/make/core/envsetup.mk?
{"TARGET_COPY_OUT_SYSTEM", "system"}, {"TARGET_COPY_OUT_SYSTEM", "system"},
@@ -1662,28 +1663,6 @@ func (p *wordCallParser) parse(ctx *parseContext, node mkparser.Node, args *mkpa
return &indexExpr{array, &intLiteralExpr{int(index - 1)}} return &indexExpr{array, &intLiteralExpr{int(index - 1)}}
} }
type firstOrLastwordCallParser struct {
isLastWord bool
}
func (p *firstOrLastwordCallParser) parse(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString) starlarkExpr {
arg := ctx.parseMakeString(node, args)
if bad, ok := arg.(*badExpr); ok {
return bad
}
index := &intLiteralExpr{0}
if p.isLastWord {
if v, ok := arg.(*variableRefExpr); ok && v.ref.name() == "MAKEFILE_LIST" {
return &stringLiteralExpr{ctx.script.mkFile}
}
index.literal = -1
}
if arg.typ() == starlarkTypeList {
return &indexExpr{arg, index}
}
return &indexExpr{&callExpr{object: arg, name: "split", returnType: starlarkTypeList}, index}
}
func parseIntegerArguments(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString, expectedArgs int) ([]starlarkExpr, error) { func parseIntegerArguments(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString, expectedArgs int) ([]starlarkExpr, error) {
parsedArgs := make([]starlarkExpr, 0) parsedArgs := make([]starlarkExpr, 0)
for _, arg := range args.Split(",") { for _, arg := range args.Split(",") {

View File

@@ -833,11 +833,11 @@ def init(g, handle):
cfg["PRODUCT_NAME"] = ((g.get("TARGET_BOARD_PLATFORM", "")).replace(".", " ")).split()[0] cfg["PRODUCT_NAME"] = ((g.get("TARGET_BOARD_PLATFORM", "")).replace(".", " ")).split()[0]
rblf.mkinfo("product.mk", rblf.mkpatsubst("%.pub", "%s%%" % cfg["PRODUCT_NAME"], g.get("PRODUCT_ADB_KEYS", ""))) rblf.mkinfo("product.mk", rblf.mkpatsubst("%.pub", "%s%%" % cfg["PRODUCT_NAME"], g.get("PRODUCT_ADB_KEYS", "")))
rblf.mkinfo("product.mk", "$(dir foo/bar): %s" % rblf.dir("foo/bar")) rblf.mkinfo("product.mk", "$(dir foo/bar): %s" % rblf.dir("foo/bar"))
rblf.mkinfo("product.mk", cfg["PRODUCT_COPY_FILES"][0]) rblf.mkinfo("product.mk", rblf.first_word(cfg["PRODUCT_COPY_FILES"]))
rblf.mkinfo("product.mk", cfg["PRODUCT_COPY_FILES"][-1]) rblf.mkinfo("product.mk", rblf.last_word(cfg["PRODUCT_COPY_FILES"]))
rblf.mkinfo("product.mk", rblf.dir("product.mk")) rblf.mkinfo("product.mk", rblf.dir(rblf.last_word("product.mk")))
rblf.mkinfo("product.mk", rblf.dir(cfg["PRODUCT_COPY_FILES"][-1])) rblf.mkinfo("product.mk", rblf.dir(rblf.last_word(cfg["PRODUCT_COPY_FILES"])))
rblf.mkinfo("product.mk", rblf.dir((_foobar).split()[-1])) rblf.mkinfo("product.mk", rblf.dir(rblf.last_word(_foobar)))
rblf.mkinfo("product.mk", rblf.abspath("foo/bar")) rblf.mkinfo("product.mk", rblf.abspath("foo/bar"))
rblf.mkinfo("product.mk", rblf.notdir("foo/bar")) rblf.mkinfo("product.mk", rblf.notdir("foo/bar"))
rblf.soong_config_namespace(g, "snsconfig") rblf.soong_config_namespace(g, "snsconfig")