Generate runtime conversion diagnostics
Instead of inserting a comment with error description into the generated code, generate a call to a function that will print out a conversion error when executed. Do not print generic "partially converted" message anymore. Remove --verbose and --no_warnings options. Bug: 204062171 Test: internal Change-Id: Ib126e16dc76f49635e4939e670922f2561781049
This commit is contained in:
@@ -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 {
|
||||||
|
@@ -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(")")
|
||||||
@@ -414,7 +412,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
|
||||||
}
|
}
|
||||||
@@ -607,8 +605,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) {
|
||||||
@@ -617,15 +615,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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -157,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
|
||||||
@@ -249,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)
|
||||||
@@ -307,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
|
||||||
@@ -371,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) {
|
||||||
@@ -561,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)
|
||||||
@@ -1024,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 {
|
||||||
@@ -1545,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 {
|
||||||
@@ -1622,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()
|
||||||
}
|
}
|
||||||
@@ -1660,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
|
||||||
|
@@ -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")
|
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -859,9 +850,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",
|
||||||
@@ -1048,15 +1037,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 $@ $*")
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1064,14 +1049,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
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1142,13 +1140,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)
|
||||||
|
@@ -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(":")
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user