Support complicated variable references

Bug: 226974242
Test: go test
Change-Id: Iaec16f5c498e7c75c9ee5d53d3499efadfba16bc
This commit is contained in:
Cole Faust 2022-04-28 14:29:57 -07:00
parent 85f8fa2c20
commit 1323877b7e
4 changed files with 55 additions and 3 deletions

View file

@ -234,10 +234,10 @@ func (ms *MakeString) splitNFunc(n int, splitFunc func(s string, n int) []string
if n != 0 { if n != 0 {
split := splitFunc(s, n) split := splitFunc(s, n)
if n != -1 { if n != -1 {
if len(split) > n { if len(split) > n || len(split) == 0 {
panic("oops!") panic("oops!")
} else { } else {
n -= len(split) n -= len(split) - 1
} }
} }
curMs.appendString(split[0]) curMs.appendString(split[0])

View file

@ -75,6 +75,16 @@ var splitNTestCases = []struct {
genMakeString(""), genMakeString(""),
}, },
}, },
{
// "x$(var1)y bar"
in: genMakeString("x", "var1", "y bar"),
sep: " ",
n: 2,
expected: []*MakeString{
genMakeString("x", "var1", "y"),
genMakeString("bar"),
},
},
} }
func TestMakeStringSplitN(t *testing.T) { func TestMakeStringSplitN(t *testing.T) {

View file

@ -1270,7 +1270,28 @@ func (ctx *parseContext) parseReference(node mkparser.Node, ref *mkparser.MakeSt
// Handle only the case where the first (or only) word is constant // Handle only the case where the first (or only) word is constant
words := ref.SplitN(" ", 2) words := ref.SplitN(" ", 2)
if !words[0].Const() { if !words[0].Const() {
return ctx.newBadExpr(node, "reference is too complex: %s", refDump) if len(words) == 1 {
expr := ctx.parseMakeString(node, ref)
return &callExpr{
object: &identifierExpr{"cfg"},
name: "get",
args: []starlarkExpr{
expr,
&callExpr{
object: &identifierExpr{"g"},
name: "get",
args: []starlarkExpr{
expr,
&stringLiteralExpr{literal: ""},
},
returnType: starlarkTypeUnknown,
},
},
returnType: starlarkTypeUnknown,
}
} else {
return ctx.newBadExpr(node, "reference is too complex: %s", refDump)
}
} }
if name, _, ok := ctx.maybeParseFunctionCall(node, ref); ok { if name, _, ok := ctx.maybeParseFunctionCall(node, ref); ok {

View file

@ -1597,6 +1597,27 @@ MY_VAR := foo
def init(g, handle): def init(g, handle):
cfg = rblf.cfg(handle) cfg = rblf.cfg(handle)
g["MY_VAR"] = "foo" g["MY_VAR"] = "foo"
`,
},
{
desc: "Complicated variable references",
mkname: "product.mk",
in: `
MY_VAR := foo
MY_VAR_2 := MY_VAR
MY_VAR_3 := $($(MY_VAR_2))
MY_VAR_4 := $(foo bar)
MY_VAR_5 := $($(MY_VAR_2) bar)
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle):
cfg = rblf.cfg(handle)
g["MY_VAR"] = "foo"
g["MY_VAR_2"] = "MY_VAR"
g["MY_VAR_3"] = (cfg).get(g["MY_VAR_2"], (g).get(g["MY_VAR_2"], ""))
g["MY_VAR_4"] = rblf.mk2rbc_error("product.mk:5", "cannot handle invoking foo")
g["MY_VAR_5"] = rblf.mk2rbc_error("product.mk:6", "reference is too complex: $(MY_VAR_2) bar")
`, `,
}, },
} }