Recognize some unsupported functions
Some functions are called without the use of $(call), since $(call) is not necessary when the function doesn't take any arguments. mk2rbc thinks these function calls are local variables, and converts them as such. This leads to undefined variable errors when trying to load (before even executing) the starlark file. Hardcode a known function that should not be converted to a local variable. Bug: 226974242 Test: go test Change-Id: I5567a34fcc282b181a7e78ac3d5cc9b40bd025a2
This commit is contained in:
@@ -741,8 +741,8 @@ func (_ *badExpr) typ() starlarkType {
|
|||||||
return starlarkTypeUnknown
|
return starlarkTypeUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_ *badExpr) emitListVarCopy(_ *generationContext) {
|
func (b *badExpr) emitListVarCopy(gctx *generationContext) {
|
||||||
panic("implement me")
|
b.emit(gctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *badExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
|
func (b *badExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
|
||||||
|
@@ -130,6 +130,14 @@ var knownNodeFunctions = map[string]interface {
|
|||||||
"foreach": &foreachCallNodeParser{},
|
"foreach": &foreachCallNodeParser{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These look like variables, but are actually functions, and would give
|
||||||
|
// undefined variable errors if we converted them as variables. Instead,
|
||||||
|
// emit an error instead of converting them.
|
||||||
|
var unsupportedFunctions = map[string]bool{
|
||||||
|
"local-generated-sources-dir": true,
|
||||||
|
"local-intermediates-dir": true,
|
||||||
|
}
|
||||||
|
|
||||||
// These are functions that we don't implement conversions for, but
|
// These are functions that we don't implement conversions for, but
|
||||||
// we allow seeing their definitions in the product config files.
|
// we allow seeing their definitions in the product config files.
|
||||||
var ignoredDefines = map[string]bool{
|
var ignoredDefines = map[string]bool{
|
||||||
@@ -556,9 +564,6 @@ func (ctx *parseContext) handleAssignment(a *mkparser.Assignment) []starlarkNode
|
|||||||
if lhs.valueType() == starlarkTypeUnknown {
|
if lhs.valueType() == starlarkTypeUnknown {
|
||||||
// Try to divine variable type from the RHS
|
// Try to divine variable type from the RHS
|
||||||
asgn.value = ctx.parseMakeString(a, a.Value)
|
asgn.value = ctx.parseMakeString(a, a.Value)
|
||||||
if xBad, ok := asgn.value.(*badExpr); ok {
|
|
||||||
return []starlarkNode{&exprNode{xBad}}
|
|
||||||
}
|
|
||||||
inferred_type := asgn.value.typ()
|
inferred_type := asgn.value.typ()
|
||||||
if inferred_type != starlarkTypeUnknown {
|
if inferred_type != starlarkTypeUnknown {
|
||||||
lhs.setValueType(inferred_type)
|
lhs.setValueType(inferred_type)
|
||||||
@@ -567,21 +572,19 @@ func (ctx *parseContext) handleAssignment(a *mkparser.Assignment) []starlarkNode
|
|||||||
if lhs.valueType() == starlarkTypeList {
|
if lhs.valueType() == starlarkTypeList {
|
||||||
xConcat, xBad := ctx.buildConcatExpr(a)
|
xConcat, xBad := ctx.buildConcatExpr(a)
|
||||||
if xBad != nil {
|
if xBad != nil {
|
||||||
return []starlarkNode{&exprNode{expr: xBad}}
|
asgn.value = xBad
|
||||||
}
|
} else {
|
||||||
switch len(xConcat.items) {
|
switch len(xConcat.items) {
|
||||||
case 0:
|
case 0:
|
||||||
asgn.value = &listExpr{}
|
asgn.value = &listExpr{}
|
||||||
case 1:
|
case 1:
|
||||||
asgn.value = xConcat.items[0]
|
asgn.value = xConcat.items[0]
|
||||||
default:
|
default:
|
||||||
asgn.value = xConcat
|
asgn.value = xConcat
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
asgn.value = ctx.parseMakeString(a, a.Value)
|
asgn.value = ctx.parseMakeString(a, a.Value)
|
||||||
if xBad, ok := asgn.value.(*badExpr); ok {
|
|
||||||
return []starlarkNode{&exprNode{expr: xBad}}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if asgn.lhs.valueType() == starlarkTypeString &&
|
if asgn.lhs.valueType() == starlarkTypeString &&
|
||||||
@@ -1262,6 +1265,12 @@ func (ctx *parseContext) parseReference(node mkparser.Node, ref *mkparser.MakeSt
|
|||||||
return ctx.newBadExpr(node, "reference is too complex: %s", refDump)
|
return ctx.newBadExpr(node, "reference is too complex: %s", refDump)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name, _, ok := ctx.maybeParseFunctionCall(node, ref); ok {
|
||||||
|
if _, unsupported := unsupportedFunctions[name]; unsupported {
|
||||||
|
return ctx.newBadExpr(node, "%s is not supported", refDump)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If it is a single word, it can be a simple variable
|
// If it is a single word, it can be a simple variable
|
||||||
// reference or a function call
|
// reference or a function call
|
||||||
if len(words) == 1 && !isMakeControlFunc(refDump) && refDump != "shell" && refDump != "eval" {
|
if len(words) == 1 && !isMakeControlFunc(refDump) && refDump != "shell" && refDump != "eval" {
|
||||||
@@ -1309,9 +1318,8 @@ func (ctx *parseContext) parseReference(node mkparser.Node, ref *mkparser.MakeSt
|
|||||||
} else {
|
} else {
|
||||||
return ctx.newBadExpr(node, "cannot handle invoking %s", name)
|
return ctx.newBadExpr(node, "cannot handle invoking %s", name)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return ctx.newBadExpr(node, "cannot handle %s", refDump)
|
|
||||||
}
|
}
|
||||||
|
return ctx.newBadExpr(node, "cannot handle %s", refDump)
|
||||||
}
|
}
|
||||||
|
|
||||||
type simpleCallParser struct {
|
type simpleCallParser struct {
|
||||||
|
@@ -117,8 +117,8 @@ PRODUCT_NAME := $(call foo0)
|
|||||||
|
|
||||||
def init(g, handle):
|
def init(g, handle):
|
||||||
cfg = rblf.cfg(handle)
|
cfg = rblf.cfg(handle)
|
||||||
rblf.mk2rbc_error("product.mk:2", "cannot handle invoking foo1")
|
cfg["PRODUCT_NAME"] = rblf.mk2rbc_error("product.mk:2", "cannot handle invoking foo1")
|
||||||
rblf.mk2rbc_error("product.mk:3", "cannot handle invoking foo0")
|
cfg["PRODUCT_NAME"] = rblf.mk2rbc_error("product.mk:3", "cannot handle invoking foo0")
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -975,7 +975,7 @@ def init(g, handle):
|
|||||||
rblf.soong_config_namespace(g, "cvd")
|
rblf.soong_config_namespace(g, "cvd")
|
||||||
rblf.soong_config_set(g, "cvd", "launch_configs", "cvd_config_auto.json")
|
rblf.soong_config_set(g, "cvd", "launch_configs", "cvd_config_auto.json")
|
||||||
rblf.soong_config_append(g, "cvd", "grub_config", "grub.cfg")
|
rblf.soong_config_append(g, "cvd", "grub_config", "grub.cfg")
|
||||||
rblf.mk2rbc_error("product.mk:7", "SOONG_CONFIG_ variables cannot be referenced, use soong_config_get instead: SOONG_CONFIG_cvd_grub_config")
|
_x = rblf.mk2rbc_error("product.mk:7", "SOONG_CONFIG_ variables cannot be referenced, use soong_config_get instead: SOONG_CONFIG_cvd_grub_config")
|
||||||
`,
|
`,
|
||||||
}, {
|
}, {
|
||||||
desc: "soong namespace accesses",
|
desc: "soong namespace accesses",
|
||||||
@@ -1269,6 +1269,7 @@ def init(g, handle):
|
|||||||
in: `
|
in: `
|
||||||
ifeq (,$(call foobar))
|
ifeq (,$(call foobar))
|
||||||
endif
|
endif
|
||||||
|
my_sources := $(local-generated-sources-dir)
|
||||||
`,
|
`,
|
||||||
expected: `load("//build/make/core:product_config.rbc", "rblf")
|
expected: `load("//build/make/core:product_config.rbc", "rblf")
|
||||||
|
|
||||||
@@ -1276,6 +1277,7 @@ def init(g, handle):
|
|||||||
cfg = rblf.cfg(handle)
|
cfg = rblf.cfg(handle)
|
||||||
if rblf.mk2rbc_error("build/product.mk:2", "cannot handle invoking foobar"):
|
if rblf.mk2rbc_error("build/product.mk:2", "cannot handle invoking foobar"):
|
||||||
pass
|
pass
|
||||||
|
_my_sources = rblf.mk2rbc_error("build/product.mk:4", "local-generated-sources-dir is not supported")
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user