Merge changes from topics "dist_for_goals", "mk2star"

* changes:
  Generate runtime conversion diagnostics
  Convert dist-for-goals.
This commit is contained in:
Treehugger Robot
2021-11-18 22:04:52 +00:00
committed by Gerrit Code Review
6 changed files with 126 additions and 146 deletions

View File

@@ -46,8 +46,6 @@ var (
dryRun = flag.Bool("dry_run", false, "dry run") dryRun = flag.Bool("dry_run", false, "dry run")
recurse = flag.Bool("convert_dependents", false, "convert all dependent files") recurse = flag.Bool("convert_dependents", false, "convert all dependent files")
mode = flag.String("mode", "", `"backup" to back up existing files, "write" to overwrite them`) mode = flag.String("mode", "", `"backup" to back up existing files, "write" to overwrite them`)
noWarn = flag.Bool("no_warnings", false, "don't warn about partially failed conversions")
verbose = flag.Bool("v", false, "print summary")
errstat = flag.Bool("error_stat", false, "print error statistics") errstat = flag.Bool("error_stat", false, "print error statistics")
traceVar = flag.String("trace", "", "comma-separated list of variables to trace") traceVar = flag.String("trace", "", "comma-separated list of variables to trace")
// TODO(asmundak): this option is for debugging // TODO(asmundak): this option is for debugging
@@ -75,7 +73,6 @@ func init() {
flagAlias("root", "d") flagAlias("root", "d")
flagAlias("dry_run", "n") flagAlias("dry_run", "n")
flagAlias("convert_dependents", "r") flagAlias("convert_dependents", "r")
flagAlias("no_warnings", "w")
flagAlias("error_stat", "e") flagAlias("error_stat", "e")
} }
@@ -207,9 +204,9 @@ func main() {
} }
} }
printStats()
if *errstat { if *errstat {
errorLogger.printStatistics() errorLogger.printStatistics()
printStats()
} }
if !ok { if !ok {
os.Exit(1) os.Exit(1)
@@ -329,17 +326,16 @@ func convertOne(mkFile string) (ok bool) {
}() }()
mk2starRequest := mk2rbc.Request{ mk2starRequest := mk2rbc.Request{
MkFile: mkFile, MkFile: mkFile,
Reader: nil, Reader: nil,
RootDir: *rootDir, RootDir: *rootDir,
OutputDir: *outputTop, OutputDir: *outputTop,
OutputSuffix: *suffix, OutputSuffix: *suffix,
TracedVariables: tracedVariables, TracedVariables: tracedVariables,
TraceCalls: *traceCalls, TraceCalls: *traceCalls,
WarnPartialSuccess: !*noWarn, SourceFS: os.DirFS(*rootDir),
SourceFS: os.DirFS(*rootDir), MakefileFinder: makefileFinder,
MakefileFinder: makefileFinder, ErrorLogger: errorLogger,
ErrorLogger: errorLogger,
} }
ss, err := mk2rbc.Convert(mk2starRequest) ss, err := mk2rbc.Convert(mk2starRequest)
if err != nil { if err != nil {
@@ -417,9 +413,6 @@ func writeGenerated(path string, contents string) error {
func printStats() { func printStats() {
var sortedFiles []string var sortedFiles []string
if *noWarn && !*verbose {
return
}
for p := range converted { for p := range converted {
sortedFiles = append(sortedFiles, p) sortedFiles = append(sortedFiles, p)
} }
@@ -435,27 +428,22 @@ func printStats() {
nOk++ nOk++
} }
} }
if !*noWarn { if nPartial > 0 {
if nPartial > 0 { fmt.Fprintf(os.Stderr, "Conversion was partially successful for:\n")
fmt.Fprintf(os.Stderr, "Conversion was partially successful for:\n") for _, f := range sortedFiles {
for _, f := range sortedFiles { if ss := converted[f]; ss != nil && ss.HasErrors() {
if ss := converted[f]; ss != nil && ss.HasErrors() { fmt.Fprintln(os.Stderr, " ", f)
fmt.Fprintln(os.Stderr, " ", f)
}
}
}
if nFailed > 0 {
fmt.Fprintf(os.Stderr, "Conversion failed for files:\n")
for _, f := range sortedFiles {
if converted[f] == nil {
fmt.Fprintln(os.Stderr, " ", f)
}
} }
} }
} }
if *verbose && (nPartial > 0 || nFailed > 0) {
fmt.Fprintln(os.Stderr, "Succeeded: ", nOk, " Partial: ", nPartial, " Failed: ", nFailed) if nFailed > 0 {
fmt.Fprintf(os.Stderr, "Conversion failed for files:\n")
for _, f := range sortedFiles {
if converted[f] == nil {
fmt.Fprintln(os.Stderr, " ", f)
}
}
} }
} }
@@ -468,8 +456,8 @@ type errorSink struct {
data map[string]datum data map[string]datum
} }
func (ebt errorSink) NewError(sourceFile string, sourceLine int, node parser.Node, message string, args ...interface{}) { func (ebt errorSink) NewError(el mk2rbc.ErrorLocation, node parser.Node, message string, args ...interface{}) {
fmt.Fprintf(os.Stderr, "%s:%d ", sourceFile, sourceLine) fmt.Fprint(os.Stderr, el, ": ")
fmt.Fprintf(os.Stderr, message, args...) fmt.Fprintf(os.Stderr, message, args...)
fmt.Fprintln(os.Stderr) fmt.Fprintln(os.Stderr)
if !*errstat { if !*errstat {

View File

@@ -18,8 +18,6 @@ import (
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
mkparser "android/soong/androidmk/parser"
) )
// Represents an expression in the Starlark code. An expression has // Represents an expression in the Starlark code. An expression has
@@ -106,7 +104,7 @@ func (xi *interpolateExpr) emit(gctx *generationContext) {
format += "%s" + strings.ReplaceAll(chunk, "%", "%%") format += "%s" + strings.ReplaceAll(chunk, "%", "%%")
} }
gctx.writef("%q %% ", format) gctx.writef("%q %% ", format)
emitarg := func(arg starlarkExpr) { emitArg := func(arg starlarkExpr) {
if arg.typ() == starlarkTypeList { if arg.typ() == starlarkTypeList {
gctx.write(`" ".join(`) gctx.write(`" ".join(`)
arg.emit(gctx) arg.emit(gctx)
@@ -116,12 +114,12 @@ func (xi *interpolateExpr) emit(gctx *generationContext) {
} }
} }
if len(xi.args) == 1 { if len(xi.args) == 1 {
emitarg(xi.args[0]) emitArg(xi.args[0])
} else { } else {
sep := "(" sep := "("
for _, arg := range xi.args { for _, arg := range xi.args {
gctx.write(sep) gctx.write(sep)
emitarg(arg) emitArg(arg)
sep = ", " sep = ", "
} }
gctx.write(")") gctx.write(")")
@@ -427,7 +425,7 @@ func newStringListExpr(items []string) *listExpr {
return &v return &v
} }
// concatExpr generates epxr1 + expr2 + ... + exprN in Starlark. // concatExpr generates expr1 + expr2 + ... + exprN in Starlark.
type concatExpr struct { type concatExpr struct {
items []starlarkExpr items []starlarkExpr
} }
@@ -620,8 +618,8 @@ func (cx *callExpr) emitListVarCopy(gctx *generationContext) {
} }
type badExpr struct { type badExpr struct {
node mkparser.Node errorLocation ErrorLocation
message string message string
} }
func (b *badExpr) eval(_ map[string]starlarkExpr) (res starlarkExpr, same bool) { func (b *badExpr) eval(_ map[string]starlarkExpr) (res starlarkExpr, same bool) {
@@ -630,15 +628,15 @@ func (b *badExpr) eval(_ map[string]starlarkExpr) (res starlarkExpr, same bool)
return return
} }
func (b *badExpr) emit(_ *generationContext) { func (b *badExpr) emit(gctx *generationContext) {
panic("implement me") gctx.emitConversionError(b.errorLocation, b.message)
} }
func (_ *badExpr) typ() starlarkType { func (_ *badExpr) typ() starlarkType {
return starlarkTypeUnknown return starlarkTypeUnknown
} }
func (b *badExpr) emitListVarCopy(gctx *generationContext) { func (_ *badExpr) emitListVarCopy(_ *generationContext) {
panic("implement me") panic("implement me")
} }

View File

@@ -102,6 +102,7 @@ var knownFunctions = map[string]struct {
"addsuffix": {baseName + ".addsuffix", starlarkTypeList, hiddenArgNone}, "addsuffix": {baseName + ".addsuffix", starlarkTypeList, hiddenArgNone},
"copy-files": {baseName + ".copy_files", starlarkTypeList, hiddenArgNone}, "copy-files": {baseName + ".copy_files", starlarkTypeList, hiddenArgNone},
"dir": {baseName + ".dir", starlarkTypeList, hiddenArgNone}, "dir": {baseName + ".dir", starlarkTypeList, hiddenArgNone},
"dist-for-goals": {baseName + ".mkdist_for_goals", starlarkTypeVoid, hiddenArgGlobal},
"enforce-product-packages-exist": {baseName + ".enforce_product_packages_exist", starlarkTypeVoid, hiddenArgNone}, "enforce-product-packages-exist": {baseName + ".enforce_product_packages_exist", starlarkTypeVoid, hiddenArgNone},
"error": {baseName + ".mkerror", starlarkTypeVoid, hiddenArgNone}, "error": {baseName + ".mkerror", starlarkTypeVoid, hiddenArgNone},
"findstring": {"!findstring", starlarkTypeInt, hiddenArgNone}, "findstring": {"!findstring", starlarkTypeInt, hiddenArgNone},
@@ -156,23 +157,31 @@ var builtinFuncRex = regexp.MustCompile(
// Conversion request parameters // Conversion request parameters
type Request struct { type Request struct {
MkFile string // file to convert MkFile string // file to convert
Reader io.Reader // if set, read input from this stream instead Reader io.Reader // if set, read input from this stream instead
RootDir string // root directory path used to resolve included files RootDir string // root directory path used to resolve included files
OutputSuffix string // generated Starlark files suffix OutputSuffix string // generated Starlark files suffix
OutputDir string // if set, root of the output hierarchy OutputDir string // if set, root of the output hierarchy
ErrorLogger ErrorLogger ErrorLogger ErrorLogger
TracedVariables []string // trace assignment to these variables TracedVariables []string // trace assignment to these variables
TraceCalls bool TraceCalls bool
WarnPartialSuccess bool SourceFS fs.FS
SourceFS fs.FS MakefileFinder MakefileFinder
MakefileFinder MakefileFinder
} }
// ErrorLogger prints errors and gathers error statistics. // ErrorLogger prints errors and gathers error statistics.
// Its NewError function is called on every error encountered during the conversion. // Its NewError function is called on every error encountered during the conversion.
type ErrorLogger interface { type ErrorLogger interface {
NewError(sourceFile string, sourceLine int, node mkparser.Node, text string, args ...interface{}) NewError(el ErrorLocation, node mkparser.Node, text string, args ...interface{})
}
type ErrorLocation struct {
MkFile string
MkLine int
}
func (el ErrorLocation) String() string {
return fmt.Sprintf("%s:%d", el.MkFile, el.MkLine)
} }
// Derives module name for a given file. It is base name // Derives module name for a given file. It is base name
@@ -248,10 +257,6 @@ func (gctx *generationContext) emit() string {
node.emit(gctx) node.emit(gctx)
} }
if ss.hasErrors && ss.warnPartialSuccess {
gctx.newLine()
gctx.writef("%s(%q, %q)", cfnWarning, filepath.Base(ss.mkFile), "partially successful conversion")
}
if gctx.starScript.traceCalls { if gctx.starScript.traceCalls {
gctx.newLine() gctx.newLine()
gctx.writef(`print("<%s")`, gctx.starScript.mkFile) gctx.writef(`print("<%s")`, gctx.starScript.mkFile)
@@ -306,6 +311,10 @@ func (gctx *generationContext) newLine() {
gctx.writef("%*s", 2*gctx.indentLevel, "") gctx.writef("%*s", 2*gctx.indentLevel, "")
} }
func (gctx *generationContext) emitConversionError(el ErrorLocation, message string) {
gctx.writef(`rblf.mk2rbc_error("%s", %q)`, el, message)
}
type knownVariable struct { type knownVariable struct {
name string name string
class varClass class varClass
@@ -370,18 +379,17 @@ type nodeReceiver interface {
// Information about the generated Starlark script. // Information about the generated Starlark script.
type StarlarkScript struct { type StarlarkScript struct {
mkFile string mkFile string
moduleName string moduleName string
mkPos scanner.Position mkPos scanner.Position
nodes []starlarkNode nodes []starlarkNode
inherited []*moduleInfo inherited []*moduleInfo
hasErrors bool hasErrors bool
topDir string topDir string
traceCalls bool // print enter/exit each init function traceCalls bool // print enter/exit each init function
warnPartialSuccess bool sourceFS fs.FS
sourceFS fs.FS makefileFinder MakefileFinder
makefileFinder MakefileFinder nodeLocator func(pos mkparser.Pos) int
nodeLocator func(pos mkparser.Pos) int
} }
func (ss *StarlarkScript) newNode(node starlarkNode) { func (ss *StarlarkScript) newNode(node starlarkNode) {
@@ -560,7 +568,7 @@ func (ctx *parseContext) handleAssignment(a *mkparser.Assignment) {
return return
} }
_, isTraced := ctx.tracedVariables[name] _, isTraced := ctx.tracedVariables[name]
asgn := &assignmentNode{lhs: lhs, mkValue: a.Value, isTraced: isTraced} asgn := &assignmentNode{lhs: lhs, mkValue: a.Value, isTraced: isTraced, location: ctx.errorLocation(a)}
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)
@@ -1023,10 +1031,10 @@ func (ctx *parseContext) parseCondition(check *mkparser.Directive) starlarkNode
func (ctx *parseContext) newBadExpr(node mkparser.Node, text string, args ...interface{}) starlarkExpr { func (ctx *parseContext) newBadExpr(node mkparser.Node, text string, args ...interface{}) starlarkExpr {
message := fmt.Sprintf(text, args...) message := fmt.Sprintf(text, args...)
if ctx.errorLogger != nil { if ctx.errorLogger != nil {
ctx.errorLogger.NewError(ctx.script.mkFile, ctx.script.nodeLocator(node.Pos()), node, text, args...) ctx.errorLogger.NewError(ctx.errorLocation(node), node, text, args...)
} }
ctx.script.hasErrors = true ctx.script.hasErrors = true
return &badExpr{node, message} return &badExpr{errorLocation: ctx.errorLocation(node), message: message}
} }
func (ctx *parseContext) parseCompare(cond *mkparser.Directive) starlarkExpr { func (ctx *parseContext) parseCompare(cond *mkparser.Directive) starlarkExpr {
@@ -1544,18 +1552,14 @@ func (ctx *parseContext) carryAsComment(failedNode mkparser.Node) {
// records that the given node failed to be converted and includes an explanatory message // records that the given node failed to be converted and includes an explanatory message
func (ctx *parseContext) errorf(failedNode mkparser.Node, message string, args ...interface{}) { func (ctx *parseContext) errorf(failedNode mkparser.Node, message string, args ...interface{}) {
if ctx.errorLogger != nil { if ctx.errorLogger != nil {
ctx.errorLogger.NewError(ctx.script.mkFile, ctx.script.nodeLocator(failedNode.Pos()), failedNode, message, args...) ctx.errorLogger.NewError(ctx.errorLocation(failedNode), failedNode, message, args...)
} }
message = fmt.Sprintf(message, args...) ctx.receiver.newNode(&exprNode{ctx.newBadExpr(failedNode, message, args...)})
ctx.insertComment(fmt.Sprintf("# MK2RBC TRANSLATION ERROR: %s", message))
ctx.carryAsComment(failedNode)
ctx.script.hasErrors = true ctx.script.hasErrors = true
} }
func (ctx *parseContext) wrapBadExpr(xBad *badExpr) { func (ctx *parseContext) wrapBadExpr(xBad *badExpr) {
ctx.insertComment(fmt.Sprintf("# MK2RBC TRANSLATION ERROR: %s", xBad.message)) ctx.receiver.newNode(&exprNode{xBad})
ctx.carryAsComment(xBad.node)
} }
func (ctx *parseContext) loadedModulePath(path string) string { func (ctx *parseContext) loadedModulePath(path string) string {
@@ -1621,6 +1625,10 @@ func (ctx *parseContext) hasNamespaceVar(namespaceName string, varName string) b
return ok return ok
} }
func (ctx *parseContext) errorLocation(node mkparser.Node) ErrorLocation {
return ErrorLocation{ctx.script.mkFile, ctx.script.nodeLocator(node.Pos())}
}
func (ss *StarlarkScript) String() string { func (ss *StarlarkScript) String() string {
return NewGenerateContext(ss).emit() return NewGenerateContext(ss).emit()
} }
@@ -1659,14 +1667,13 @@ func Convert(req Request) (*StarlarkScript, error) {
return nil, fmt.Errorf("bad makefile %s", req.MkFile) return nil, fmt.Errorf("bad makefile %s", req.MkFile)
} }
starScript := &StarlarkScript{ starScript := &StarlarkScript{
moduleName: moduleNameForFile(req.MkFile), moduleName: moduleNameForFile(req.MkFile),
mkFile: req.MkFile, mkFile: req.MkFile,
topDir: req.RootDir, topDir: req.RootDir,
traceCalls: req.TraceCalls, traceCalls: req.TraceCalls,
warnPartialSuccess: req.WarnPartialSuccess, sourceFS: req.SourceFS,
sourceFS: req.SourceFS, makefileFinder: req.MakefileFinder,
makefileFinder: req.MakefileFinder, nodeLocator: func(pos mkparser.Pos) int { return parser.Unpack(pos).Line },
nodeLocator: func(pos mkparser.Pos) int { return parser.Unpack(pos).Line },
} }
ctx := newParseContext(starScript, nodes) ctx := newParseContext(starScript, nodes)
ctx.outputSuffix = req.OutputSuffix ctx.outputSuffix = req.OutputSuffix

View File

@@ -105,15 +105,12 @@ def init(g, handle):
PRODUCT_NAME := $(call foo1, bar) PRODUCT_NAME := $(call foo1, bar)
PRODUCT_NAME := $(call foo0) PRODUCT_NAME := $(call foo0)
`, `,
expected: `# MK2RBC TRANSLATION ERROR: cannot handle invoking foo1 expected: `load("//build/make/core:product_config.rbc", "rblf")
# PRODUCT_NAME := $(call foo1, bar)
# MK2RBC TRANSLATION ERROR: cannot handle invoking foo0
# PRODUCT_NAME := $(call foo0)
load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle): def init(g, handle):
cfg = rblf.cfg(handle) cfg = rblf.cfg(handle)
rblf.warning("product.mk", "partially successful conversion") rblf.mk2rbc_error("product.mk:2", "cannot handle invoking foo1")
rblf.mk2rbc_error("product.mk:3", "cannot handle invoking foo0")
`, `,
}, },
{ {
@@ -207,15 +204,11 @@ define some-macro
$(info foo) $(info foo)
endef endef
`, `,
expected: `# MK2RBC TRANSLATION ERROR: define is not supported: some-macro expected: `load("//build/make/core:product_config.rbc", "rblf")
# define some-macro
# $(info foo)
# endef
load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle): def init(g, handle):
cfg = rblf.cfg(handle) cfg = rblf.cfg(handle)
rblf.warning("product.mk", "partially successful conversion") rblf.mk2rbc_error("product.mk:2", "define is not supported: some-macro")
`, `,
}, },
{ {
@@ -282,9 +275,7 @@ def init(g, handle):
# Comment # Comment
pass pass
else: else:
# MK2RBC TRANSLATION ERROR: cannot set predefined variable TARGET_COPY_OUT_RECOVERY to "foo", its value should be "recovery" rblf.mk2rbc_error("product.mk:5", "cannot set predefined variable TARGET_COPY_OUT_RECOVERY to \"foo\", its value should be \"recovery\"")
pass
rblf.warning("product.mk", "partially successful conversion")
`, `,
}, },
{ {
@@ -704,6 +695,7 @@ $(call enforce-product-packages-exist,)
$(call enforce-product-packages-exist, foo) $(call enforce-product-packages-exist, foo)
$(call require-artifacts-in-path, foo, bar) $(call require-artifacts-in-path, foo, bar)
$(call require-artifacts-in-path-relaxed, foo, bar) $(call require-artifacts-in-path-relaxed, foo, bar)
$(call dist-for-goals, goal, from:to)
`, `,
expected: `load("//build/make/core:product_config.rbc", "rblf") expected: `load("//build/make/core:product_config.rbc", "rblf")
@@ -713,6 +705,7 @@ def init(g, handle):
rblf.enforce_product_packages_exist("foo") rblf.enforce_product_packages_exist("foo")
rblf.require_artifacts_in_path("foo", "bar") rblf.require_artifacts_in_path("foo", "bar")
rblf.require_artifacts_in_path_relaxed("foo", "bar") rblf.require_artifacts_in_path_relaxed("foo", "bar")
rblf.mkdist_for_goals(g, "goal", "from:to")
`, `,
}, },
{ {
@@ -872,9 +865,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")
# MK2RBC TRANSLATION ERROR: SOONG_CONFIG_ variables cannot be referenced, use soong_config_get instead: SOONG_CONFIG_cvd_grub_config rblf.mk2rbc_error("product.mk:7", "SOONG_CONFIG_ variables cannot be referenced, use soong_config_get instead: SOONG_CONFIG_cvd_grub_config")
# x := $(SOONG_CONFIG_cvd_grub_config)
rblf.warning("product.mk", "partially successful conversion")
`, `,
}, { }, {
desc: "soong namespace accesses", desc: "soong namespace accesses",
@@ -1061,15 +1052,11 @@ def init(g, handle):
in: ` in: `
foo: foo.c foo: foo.c
gcc -o $@ $*`, gcc -o $@ $*`,
expected: `# MK2RBC TRANSLATION ERROR: unsupported line rule: foo: foo.c expected: `load("//build/make/core:product_config.rbc", "rblf")
#gcc -o $@ $*
# rule: foo: foo.c
# gcc -o $@ $*
load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle): def init(g, handle):
cfg = rblf.cfg(handle) cfg = rblf.cfg(handle)
rblf.warning("product.mk", "partially successful conversion") rblf.mk2rbc_error("product.mk:2", "unsupported line rule: foo: foo.c\n#gcc -o $@ $*")
`, `,
}, },
{ {
@@ -1077,14 +1064,27 @@ def init(g, handle):
mkname: "product.mk", mkname: "product.mk",
in: ` in: `
override FOO:=`, override FOO:=`,
expected: `# MK2RBC TRANSLATION ERROR: cannot handle override directive expected: `load("//build/make/core:product_config.rbc", "rblf")
# override FOO :=
load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle): def init(g, handle):
cfg = rblf.cfg(handle) cfg = rblf.cfg(handle)
rblf.mk2rbc_error("product.mk:2", "cannot handle override directive")
g["override FOO"] = "" g["override FOO"] = ""
rblf.warning("product.mk", "partially successful conversion") `,
},
{
desc: "Bad expression",
mkname: "build/product.mk",
in: `
ifeq (,$(call foobar))
endif
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle):
cfg = rblf.cfg(handle)
if rblf.mk2rbc_error("build/product.mk:2", "cannot handle invoking foobar"):
pass
`, `,
}, },
} }
@@ -1156,13 +1156,12 @@ func TestGood(t *testing.T) {
t.Run(test.desc, t.Run(test.desc,
func(t *testing.T) { func(t *testing.T) {
ss, err := Convert(Request{ ss, err := Convert(Request{
MkFile: test.mkname, MkFile: test.mkname,
Reader: bytes.NewBufferString(test.in), Reader: bytes.NewBufferString(test.in),
RootDir: ".", RootDir: ".",
OutputSuffix: ".star", OutputSuffix: ".star",
WarnPartialSuccess: true, SourceFS: fs,
SourceFS: fs, MakefileFinder: &testMakefileFinder{fs: fs},
MakefileFinder: &testMakefileFinder{fs: fs},
}) })
if err != nil { if err != nil {
t.Error(err) t.Error(err)

View File

@@ -183,6 +183,7 @@ type assignmentNode struct {
value starlarkExpr value starlarkExpr
mkValue *mkparser.MakeString mkValue *mkparser.MakeString
flavor assignmentFlavor flavor assignmentFlavor
location ErrorLocation
isTraced bool isTraced bool
previous *assignmentNode previous *assignmentNode
} }
@@ -223,18 +224,6 @@ func (in *ifNode) emit(gctx *generationContext) {
} }
gctx.newLine() gctx.newLine()
if bad, ok := in.expr.(*badExpr); ok {
gctx.write("# MK2STAR ERROR converting:")
gctx.newLine()
gctx.writef("# %s", bad.node.Dump())
gctx.newLine()
gctx.writef("# %s", bad.message)
gctx.newLine()
// The init function emits a warning if the conversion was not
// fullly successful, so here we (arbitrarily) take the false path.
gctx.writef("%sFalse:", ifElif)
return
}
gctx.write(ifElif) gctx.write(ifElif)
in.expr.emit(gctx) in.expr.emit(gctx)
gctx.write(":") gctx.write(":")

View File

@@ -228,10 +228,9 @@ func (pv predefinedVariable) emitSet(gctx *generationContext, asgn *assignmentNo
if actualValue == expectedValue { if actualValue == expectedValue {
return return
} }
gctx.writef("# MK2RBC TRANSLATION ERROR: cannot set predefined variable %s to %q, its value should be %q", gctx.emitConversionError(asgn.location,
pv.name(), actualValue, expectedValue) fmt.Sprintf("cannot set predefined variable %s to %q, its value should be %q",
gctx.newLine() pv.name(), actualValue, expectedValue))
gctx.write("pass")
gctx.starScript.hasErrors = true gctx.starScript.hasErrors = true
return return
} }