Merge "add target_compatible_with stanza for host targets"
diff --git a/android/bazel.go b/android/bazel.go
index 8e2e350..5d1507c 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -235,6 +235,7 @@
// Configure modules in these directories to enable bp2build_available: true or false by default.
bp2buildDefaultConfig = Bp2BuildConfig{
+ "art/libartpalette": Bp2BuildDefaultTrueRecursively,
"art/libdexfile": Bp2BuildDefaultTrueRecursively,
"art/runtime": Bp2BuildDefaultTrueRecursively,
"art/tools": Bp2BuildDefaultTrue,
@@ -296,6 +297,9 @@
"external/google-benchmark": Bp2BuildDefaultTrueRecursively,
"external/googletest": Bp2BuildDefaultTrueRecursively,
"external/gwp_asan": Bp2BuildDefaultTrueRecursively,
+ "external/icu": Bp2BuildDefaultTrueRecursively,
+ "external/icu/android_icu4j": Bp2BuildDefaultFalse, // java rules incomplete
+ "external/icu/icu4j": Bp2BuildDefaultFalse, // java rules incomplete
"external/jemalloc_new": Bp2BuildDefaultTrueRecursively,
"external/jsoncpp": Bp2BuildDefaultTrueRecursively,
"external/libcap": Bp2BuildDefaultTrueRecursively,
@@ -481,14 +485,27 @@
"libdexfiled", // depends on unconverted modules: dexfile_operator_srcs, libartbased, libartpalette
// go deps:
- "apex-protos", // depends on soong_zip, a go binary
- "robolectric_tzdata", // depends on soong_zip, a go binary
- "robolectric-sqlite4java-native", // depends on soong_zip, a go binary
+ "apex-protos", // depends on soong_zip, a go binary
+ "generated_android_icu4j_src_files", "generated_android_icu4j_test_files", "icu4c_test_data", // depends on unconverted modules: soong_zip
"host_bionic_linker_asm", // depends on extract_linker, a go binary.
"host_bionic_linker_script", // depends on extract_linker, a go binary.
+ "robolectric-sqlite4java-native", // depends on soong_zip, a go binary
+ "robolectric_tzdata", // depends on soong_zip, a go binary
+
+ "android_icu4j_srcgen_binary", // Bazel build error: deps not allowed without srcs; move to runtime_deps
+ "core-icu4j-for-host", // Bazel build error: deps not allowed without srcs; move to runtime_deps
// java deps
- "bin2c_fastdeployagent", // depends on deployagent, a java binary
+ "android_icu4j_srcgen", // depends on unconverted modules: currysrc
+ "currysrc", // depends on unconverted modules: currysrc_org.eclipse, guavalib, jopt-simple-4.9
+ "bin2c_fastdeployagent", // depends on unconverted module: deployagent
+ "timezone-host", // depends on unconverted modules: art.module.api.annotations
+ "robolectric-sqlite4java-0.282", // depends on unconverted modules: robolectric-sqlite4java-import, robolectric-sqlite4java-native
+ "truth-prebuilt", // depends on unconverted modules: asm-7.0, guava
+ "truth-host-prebuilt", // depends on unconverted modules: truth-prebuilt
+
+ "generated_android_icu4j_resources", // depends on unconverted modules: android_icu4j_srcgen_binary, soong_zip
+ "generated_android_icu4j_test_resources", // depends on unconverted modules: android_icu4j_srcgen_binary, soong_zip
}
// Per-module denylist of cc_library modules to only generate the static
diff --git a/android/testing.go b/android/testing.go
index 8daf6b7..39864e1 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -781,19 +781,21 @@
return p
}
-func (b baseTestingComponent) maybeBuildParamsFromDescription(desc string) TestingBuildParams {
+func (b baseTestingComponent) maybeBuildParamsFromDescription(desc string) (TestingBuildParams, []string) {
+ var searchedDescriptions []string
for _, p := range b.provider.BuildParamsForTests() {
+ searchedDescriptions = append(searchedDescriptions, p.Description)
if strings.Contains(p.Description, desc) {
- return b.newTestingBuildParams(p)
+ return b.newTestingBuildParams(p), searchedDescriptions
}
}
- return TestingBuildParams{}
+ return TestingBuildParams{}, searchedDescriptions
}
func (b baseTestingComponent) buildParamsFromDescription(desc string) TestingBuildParams {
- p := b.maybeBuildParamsFromDescription(desc)
+ p, searchedDescriptions := b.maybeBuildParamsFromDescription(desc)
if p.Rule == nil {
- panic(fmt.Errorf("couldn't find description %q", desc))
+ panic(fmt.Errorf("couldn't find description %q\nall descriptions:\n%s", desc, strings.Join(searchedDescriptions, "\n")))
}
return p
}
@@ -860,7 +862,8 @@
// MaybeDescription finds a call to ctx.Build with BuildParams.Description set to a the given string. Returns an empty
// BuildParams if no rule is found.
func (b baseTestingComponent) MaybeDescription(desc string) TestingBuildParams {
- return b.maybeBuildParamsFromDescription(desc)
+ p, _ := b.maybeBuildParamsFromDescription(desc)
+ return p
}
// Description finds a call to ctx.Build with BuildParams.Description set to a the given string. Panics if no rule is
diff --git a/cc/bp2build.go b/cc/bp2build.go
index c5eab06..30c3c50 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -844,10 +844,8 @@
func bazelLabelForStaticModule(ctx android.BazelConversionPathContext, m blueprint.Module) string {
label := android.BazelModuleLabel(ctx, m)
- if aModule, ok := m.(android.Module); ok {
- if ctx.OtherModuleType(aModule) == "cc_library" && !android.GenerateCcLibraryStaticOnly(m.Name()) {
- label += "_bp2build_cc_library_static"
- }
+ if ccModule, ok := m.(*Module); ok && ccModule.typ() == fullLibrary && !android.GenerateCcLibraryStaticOnly(m.Name()) {
+ label += "_bp2build_cc_library_static"
}
return label
}
diff --git a/cc/cc.go b/cc/cc.go
index 31babc2..46e3b91 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1751,7 +1751,7 @@
// Returns true if Bazel was successfully used for the analysis of this module.
func (c *Module) maybeGenerateBazelActions(actx android.ModuleContext) bool {
var bazelModuleLabel string
- if actx.ModuleType() == "cc_library" && c.static() {
+ if c.typ() == fullLibrary && c.static() {
// cc_library is a special case in bp2build; two targets are generated -- one for each
// of the shared and static variants. The shared variant keeps the module name, but the
// static variant uses a different suffixed name.
@@ -1759,6 +1759,7 @@
} else {
bazelModuleLabel = c.GetBazelLabel(actx, c)
}
+
bazelActionsUsed := false
// Mixed builds mode is disabled for modules outside of device OS.
// TODO(b/200841190): Support non-device OS in mixed builds.
@@ -3466,17 +3467,23 @@
var _ snapshot.RelativeInstallPath = (*Module)(nil)
-// ConvertWithBp2build converts Module to Bazel for bp2build.
-func (c *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
- prebuilt := c.IsPrebuilt()
+type moduleType int
+
+const (
+ unknownType moduleType = iota
+ binary
+ object
+ fullLibrary
+ staticLibrary
+ sharedLibrary
+ headerLibrary
+)
+
+func (c *Module) typ() moduleType {
if c.Binary() {
- if !prebuilt {
- binaryBp2build(ctx, c, ctx.ModuleType())
- }
+ return binary
} else if c.Object() {
- if !prebuilt {
- objectBp2Build(ctx, c)
- }
+ return object
} else if c.CcLibrary() {
static := false
shared := false
@@ -3487,25 +3494,48 @@
static = library.MutatedProperties.BuildStatic
shared = library.MutatedProperties.BuildShared
}
-
if static && shared {
- if !prebuilt {
- libraryBp2Build(ctx, c)
- }
+ return fullLibrary
} else if !static && !shared {
- libraryHeadersBp2Build(ctx, c)
+ return headerLibrary
} else if static {
- if prebuilt {
- prebuiltLibraryStaticBp2Build(ctx, c)
- } else {
- sharedOrStaticLibraryBp2Build(ctx, c, true)
- }
- } else if shared {
- if prebuilt {
- prebuiltLibrarySharedBp2Build(ctx, c)
- } else {
- sharedOrStaticLibraryBp2Build(ctx, c, false)
- }
+ return staticLibrary
+ }
+ return sharedLibrary
+ }
+ return unknownType
+}
+
+// ConvertWithBp2build converts Module to Bazel for bp2build.
+func (c *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+ prebuilt := c.IsPrebuilt()
+ switch c.typ() {
+ case binary:
+ if !prebuilt {
+ binaryBp2build(ctx, c, ctx.ModuleType())
+ }
+ case object:
+ if !prebuilt {
+ objectBp2Build(ctx, c)
+ }
+ case fullLibrary:
+ if !prebuilt {
+ libraryBp2Build(ctx, c)
+ }
+ case headerLibrary:
+ libraryHeadersBp2Build(ctx, c)
+ case staticLibrary:
+
+ if prebuilt {
+ prebuiltLibraryStaticBp2Build(ctx, c)
+ } else {
+ sharedOrStaticLibraryBp2Build(ctx, c, true)
+ }
+ case sharedLibrary:
+ if prebuilt {
+ prebuiltLibrarySharedBp2Build(ctx, c)
+ } else {
+ sharedOrStaticLibraryBp2Build(ctx, c, false)
}
}
}
diff --git a/cc/config/global.go b/cc/config/global.go
index 5acc7f5..cf39d3c 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -95,6 +95,9 @@
// Nested and array designated initialization is nice to have.
"-Wno-c99-designator",
+ // Many old files still have GNU designator syntax.
+ "-Wno-gnu-designator",
+
// Warnings from clang-12
"-Wno-gnu-folding-constant",
diff --git a/java/app.go b/java/app.go
index 7ae73f7..9f2f99a 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1432,17 +1432,15 @@
}
type bazelAndroidAppAttributes struct {
- Srcs bazel.LabelListAttribute
+ *javaLibraryAttributes
Manifest bazel.Label
Custom_package *string
Resource_files bazel.LabelListAttribute
- Deps bazel.LabelListAttribute
}
// ConvertWithBp2build is used to convert android_app to Bazel.
func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
- //TODO(b/209577426): Support multiple arch variants
- srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Srcs, a.properties.Exclude_srcs))
+ libAttrs := a.convertLibraryAttrsBp2Build(ctx)
manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
@@ -1454,15 +1452,12 @@
resourceFiles.Includes = append(resourceFiles.Includes, files...)
}
- deps := bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, a.properties.Static_libs))
-
attrs := &bazelAndroidAppAttributes{
- Srcs: srcs,
- Manifest: android.BazelLabelForModuleSrcSingle(ctx, manifest),
+ libAttrs,
+ android.BazelLabelForModuleSrcSingle(ctx, manifest),
// TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES
- Custom_package: a.overridableAppProperties.Package_name,
- Resource_files: bazel.MakeLabelListAttribute(resourceFiles),
- Deps: deps,
+ a.overridableAppProperties.Package_name,
+ bazel.MakeLabelListAttribute(resourceFiles),
}
props := bazel.BazelTargetModuleProperties{Rule_class: "android_binary",
Bzl_load_location: "@rules_android//rules:rules.bzl"}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 7ad316f..f9dcfd6 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -334,7 +334,11 @@
// TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
FlagWithArg("--hide ", "SuperfluousPrefix").
- FlagWithArg("--hide ", "AnnotationExtraction")
+ FlagWithArg("--hide ", "AnnotationExtraction").
+ // (b/217545629)
+ FlagWithArg("--hide ", "ChangedThrows").
+ // (b/217552813)
+ FlagWithArg("--hide ", "ChangedAbstract")
}
}
diff --git a/java/java.go b/java/java.go
index 7a2a991..e55f045 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2011,6 +2011,7 @@
}
func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) *javaLibraryAttributes {
+ //TODO(b/209577426): Support multiple arch variants
srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs))
attrs := &javaLibraryAttributes{
Srcs: srcs,
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 90dc46b..03cf21e 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -370,10 +370,6 @@
}
}
-type nodeReceiver interface {
- newNode(node starlarkNode)
-}
-
// Information about the generated Starlark script.
type StarlarkScript struct {
mkFile string
@@ -389,10 +385,6 @@
nodeLocator func(pos mkparser.Pos) int
}
-func (ss *StarlarkScript) newNode(node starlarkNode) {
- ss.nodes = append(ss.nodes, node)
-}
-
// varAssignmentScope points to the last assignment for each variable
// in the current block. It is used during the parsing to chain
// the assignments to a variable together.
@@ -415,8 +407,6 @@
tracedVariables map[string]bool // variables to be traced in the generated script
variables map[string]variable
varAssignments *varAssignmentScope
- receiver nodeReceiver // receptacle for the generated starlarkNode's
- receiverStack []nodeReceiver
outputDir string
dependentModules map[string]*moduleInfo
soongNamespaces map[string]map[string]bool
@@ -503,20 +493,6 @@
ctx.varAssignments = ctx.varAssignments.outer
}
-func (ctx *parseContext) pushReceiver(rcv nodeReceiver) {
- ctx.receiverStack = append(ctx.receiverStack, ctx.receiver)
- ctx.receiver = rcv
-}
-
-func (ctx *parseContext) popReceiver() {
- last := len(ctx.receiverStack) - 1
- if last < 0 {
- panic(fmt.Errorf("popReceiver: receiver stack empty"))
- }
- ctx.receiver = ctx.receiverStack[last]
- ctx.receiverStack = ctx.receiverStack[0:last]
-}
-
func (ctx *parseContext) hasNodes() bool {
return ctx.currentNodeIndex < len(ctx.nodes)
}
@@ -537,11 +513,10 @@
ctx.currentNodeIndex--
}
-func (ctx *parseContext) handleAssignment(a *mkparser.Assignment) {
+func (ctx *parseContext) handleAssignment(a *mkparser.Assignment) []starlarkNode {
// Handle only simple variables
if !a.Name.Const() {
- ctx.errorf(a, "Only simple variables are handled")
- return
+ return []starlarkNode{ctx.newBadNode(a, "Only simple variables are handled")}
}
name := a.Name.Strings[0]
// The `override` directive
@@ -549,18 +524,16 @@
// is parsed as an assignment to a variable named `override FOO`.
// There are very few places where `override` is used, just flag it.
if strings.HasPrefix(name, "override ") {
- ctx.errorf(a, "cannot handle override directive")
+ return []starlarkNode{ctx.newBadNode(a, "cannot handle override directive")}
}
// Soong configuration
if strings.HasPrefix(name, soongNsPrefix) {
- ctx.handleSoongNsAssignment(strings.TrimPrefix(name, soongNsPrefix), a)
- return
+ return ctx.handleSoongNsAssignment(strings.TrimPrefix(name, soongNsPrefix), a)
}
lhs := ctx.addVariable(name)
if lhs == nil {
- ctx.errorf(a, "unknown variable %s", name)
- return
+ return []starlarkNode{ctx.newBadNode(a, "unknown variable %s", name)}
}
_, isTraced := ctx.tracedVariables[name]
asgn := &assignmentNode{lhs: lhs, mkValue: a.Value, isTraced: isTraced, location: ctx.errorLocation(a)}
@@ -568,8 +541,7 @@
// Try to divine variable type from the RHS
asgn.value = ctx.parseMakeString(a, a.Value)
if xBad, ok := asgn.value.(*badExpr); ok {
- ctx.wrapBadExpr(xBad)
- return
+ return []starlarkNode{&exprNode{xBad}}
}
inferred_type := asgn.value.typ()
if inferred_type != starlarkTypeUnknown {
@@ -577,9 +549,9 @@
}
}
if lhs.valueType() == starlarkTypeList {
- xConcat := ctx.buildConcatExpr(a)
- if xConcat == nil {
- return
+ xConcat, xBad := ctx.buildConcatExpr(a)
+ if xBad != nil {
+ return []starlarkNode{&exprNode{expr: xBad}}
}
switch len(xConcat.items) {
case 0:
@@ -592,8 +564,7 @@
} else {
asgn.value = ctx.parseMakeString(a, a.Value)
if xBad, ok := asgn.value.(*badExpr); ok {
- ctx.wrapBadExpr(xBad)
- return
+ return []starlarkNode{&exprNode{expr: xBad}}
}
}
@@ -614,14 +585,13 @@
panic(fmt.Errorf("unexpected assignment type %s", a.Type))
}
- ctx.receiver.newNode(asgn)
+ return []starlarkNode{asgn}
}
-func (ctx *parseContext) handleSoongNsAssignment(name string, asgn *mkparser.Assignment) {
+func (ctx *parseContext) handleSoongNsAssignment(name string, asgn *mkparser.Assignment) []starlarkNode {
val := ctx.parseMakeString(asgn, asgn.Value)
if xBad, ok := val.(*badExpr); ok {
- ctx.wrapBadExpr(xBad)
- return
+ return []starlarkNode{&exprNode{expr: xBad}}
}
// Unfortunately, Soong namespaces can be set up by directly setting corresponding Make
@@ -634,17 +604,18 @@
// $(call add_soong_config_namespace,foo)
s, ok := maybeString(val)
if !ok {
- ctx.errorf(asgn, "cannot handle variables in SOONG_CONFIG_NAMESPACES assignment, please use add_soong_config_namespace instead")
- return
+ return []starlarkNode{ctx.newBadNode(asgn, "cannot handle variables in SOONG_CONFIG_NAMESPACES assignment, please use add_soong_config_namespace instead")}
}
+ result := make([]starlarkNode, 0)
for _, ns := range strings.Fields(s) {
ctx.addSoongNamespace(ns)
- ctx.receiver.newNode(&exprNode{&callExpr{
+ result = append(result, &exprNode{&callExpr{
name: baseName + ".soong_config_namespace",
args: []starlarkExpr{&globalsExpr{}, &stringLiteralExpr{ns}},
returnType: starlarkTypeVoid,
}})
}
+ return result
} else {
// Upon seeing
// SOONG_CONFIG_x_y = v
@@ -664,45 +635,41 @@
continue
}
if namespaceName != "" {
- ctx.errorf(asgn, "ambiguous soong namespace (may be either `%s` or `%s`)", namespaceName, name[0:pos])
- return
+ return []starlarkNode{ctx.newBadNode(asgn, "ambiguous soong namespace (may be either `%s` or `%s`)", namespaceName, name[0:pos])}
}
namespaceName = name[0:pos]
varName = name[pos+1:]
}
if namespaceName == "" {
- ctx.errorf(asgn, "cannot figure out Soong namespace, please use add_soong_config_var_value macro instead")
- return
+ return []starlarkNode{ctx.newBadNode(asgn, "cannot figure out Soong namespace, please use add_soong_config_var_value macro instead")}
}
if varName == "" {
// Remember variables in this namespace
s, ok := maybeString(val)
if !ok {
- ctx.errorf(asgn, "cannot handle variables in SOONG_CONFIG_ assignment, please use add_soong_config_var_value instead")
- return
+ return []starlarkNode{ctx.newBadNode(asgn, "cannot handle variables in SOONG_CONFIG_ assignment, please use add_soong_config_var_value instead")}
}
ctx.updateSoongNamespace(asgn.Type != "+=", namespaceName, strings.Fields(s))
- return
+ return []starlarkNode{}
}
// Finally, handle assignment to a namespace variable
if !ctx.hasNamespaceVar(namespaceName, varName) {
- ctx.errorf(asgn, "no %s variable in %s namespace, please use add_soong_config_var_value instead", varName, namespaceName)
- return
+ return []starlarkNode{ctx.newBadNode(asgn, "no %s variable in %s namespace, please use add_soong_config_var_value instead", varName, namespaceName)}
}
fname := baseName + "." + soongConfigAssign
if asgn.Type == "+=" {
fname = baseName + "." + soongConfigAppend
}
- ctx.receiver.newNode(&exprNode{&callExpr{
+ return []starlarkNode{&exprNode{&callExpr{
name: fname,
args: []starlarkExpr{&globalsExpr{}, &stringLiteralExpr{namespaceName}, &stringLiteralExpr{varName}, val},
returnType: starlarkTypeVoid,
- }})
+ }}}
}
}
-func (ctx *parseContext) buildConcatExpr(a *mkparser.Assignment) *concatExpr {
+func (ctx *parseContext) buildConcatExpr(a *mkparser.Assignment) (*concatExpr, *badExpr) {
xConcat := &concatExpr{}
var xItemList *listExpr
addToItemList := func(x ...starlarkExpr) {
@@ -724,8 +691,7 @@
// expressions return individual elements.
switch x := ctx.parseMakeString(a, item).(type) {
case *badExpr:
- ctx.wrapBadExpr(x)
- return nil
+ return nil, x
case *stringLiteralExpr:
addToItemList(maybeConvertToStringList(x).(*listExpr).items...)
default:
@@ -749,7 +715,7 @@
if xItemList != nil {
xConcat.items = append(xConcat.items, xItemList)
}
- return xConcat
+ return xConcat, nil
}
func (ctx *parseContext) newDependentModule(path string, optional bool) *moduleInfo {
@@ -779,7 +745,7 @@
}
func (ctx *parseContext) handleSubConfig(
- v mkparser.Node, pathExpr starlarkExpr, loadAlways bool, processModule func(inheritedModule)) {
+ v mkparser.Node, pathExpr starlarkExpr, loadAlways bool, processModule func(inheritedModule) starlarkNode) []starlarkNode {
// In a simple case, the name of a module to inherit/include is known statically.
if path, ok := maybeString(pathExpr); ok {
@@ -788,18 +754,19 @@
moduleShouldExist := loadAlways && ctx.ifNestLevel == 0
if strings.Contains(path, "*") {
if paths, err := fs.Glob(ctx.script.sourceFS, path); err == nil {
+ result := make([]starlarkNode, 0)
for _, p := range paths {
mi := ctx.newDependentModule(p, !moduleShouldExist)
- processModule(inheritedStaticModule{mi, loadAlways})
+ result = append(result, processModule(inheritedStaticModule{mi, loadAlways}))
}
+ return result
} else {
- ctx.errorf(v, "cannot glob wildcard argument")
+ return []starlarkNode{ctx.newBadNode(v, "cannot glob wildcard argument")}
}
} else {
mi := ctx.newDependentModule(path, !moduleShouldExist)
- processModule(inheritedStaticModule{mi, loadAlways})
+ return []starlarkNode{processModule(inheritedStaticModule{mi, loadAlways})}
}
- return
}
// If module path references variables (e.g., $(v1)/foo/$(v2)/device-config.mk), find all the paths in the
@@ -819,8 +786,7 @@
var matchingPaths []string
varPath, ok := pathExpr.(*interpolateExpr)
if !ok {
- ctx.errorf(v, "inherit-product/include argument is too complex")
- return
+ return []starlarkNode{ctx.newBadNode(v, "inherit-product/include argument is too complex")}
}
pathPattern := []string{varPath.chunks[0]}
@@ -842,12 +808,11 @@
// Safeguard against $(call inherit-product,$(PRODUCT_PATH))
const maxMatchingFiles = 150
if len(matchingPaths) > maxMatchingFiles {
- ctx.errorf(v, "there are >%d files matching the pattern, please rewrite it", maxMatchingFiles)
- return
+ return []starlarkNode{ctx.newBadNode(v, "there are >%d files matching the pattern, please rewrite it", maxMatchingFiles)}
}
if len(matchingPaths) == 1 {
res := inheritedStaticModule{ctx.newDependentModule(matchingPaths[0], loadAlways && ctx.ifNestLevel == 0), loadAlways}
- processModule(res)
+ return []starlarkNode{processModule(res)}
} else {
needsWarning := pathPattern[0] == "" && len(ctx.includeTops) == 0
res := inheritedDynamicModule{*varPath, []*moduleInfo{}, loadAlways, ctx.errorLocation(v), needsWarning}
@@ -857,7 +822,7 @@
// by always loading the dynamic files as optional.
res.candidateModules = append(res.candidateModules, ctx.newDependentModule(p, true))
}
- processModule(res)
+ return []starlarkNode{processModule(res)}
}
}
@@ -885,25 +850,25 @@
return res
}
-func (ctx *parseContext) handleInheritModule(v mkparser.Node, args *mkparser.MakeString, loadAlways bool) {
+func (ctx *parseContext) handleInheritModule(v mkparser.Node, args *mkparser.MakeString, loadAlways bool) []starlarkNode {
args.TrimLeftSpaces()
args.TrimRightSpaces()
pathExpr := ctx.parseMakeString(v, args)
if _, ok := pathExpr.(*badExpr); ok {
- ctx.errorf(v, "Unable to parse argument to inherit")
+ return []starlarkNode{ctx.newBadNode(v, "Unable to parse argument to inherit")}
}
- ctx.handleSubConfig(v, pathExpr, loadAlways, func(im inheritedModule) {
- ctx.receiver.newNode(&inheritNode{im, loadAlways})
+ return ctx.handleSubConfig(v, pathExpr, loadAlways, func(im inheritedModule) starlarkNode {
+ return &inheritNode{im, loadAlways}
})
}
-func (ctx *parseContext) handleInclude(v mkparser.Node, pathExpr starlarkExpr, loadAlways bool) {
- ctx.handleSubConfig(v, pathExpr, loadAlways, func(im inheritedModule) {
- ctx.receiver.newNode(&includeNode{im, loadAlways})
+func (ctx *parseContext) handleInclude(v mkparser.Node, pathExpr starlarkExpr, loadAlways bool) []starlarkNode {
+ return ctx.handleSubConfig(v, pathExpr, loadAlways, func(im inheritedModule) starlarkNode {
+ return &includeNode{im, loadAlways}
})
}
-func (ctx *parseContext) handleVariable(v *mkparser.Variable) {
+func (ctx *parseContext) handleVariable(v *mkparser.Variable) []starlarkNode {
// Handle:
// $(call inherit-product,...)
// $(call inherit-product-if-exists,...)
@@ -918,67 +883,57 @@
if strings.HasPrefix(v.Name.Dump(), "call inherit-product,") {
args := v.Name.Clone()
args.ReplaceLiteral("call inherit-product,", "")
- ctx.handleInheritModule(v, args, true)
- return
+ return ctx.handleInheritModule(v, args, true)
}
if strings.HasPrefix(v.Name.Dump(), "call inherit-product-if-exists,") {
args := v.Name.Clone()
args.ReplaceLiteral("call inherit-product-if-exists,", "")
- ctx.handleInheritModule(v, args, false)
- return
+ return ctx.handleInheritModule(v, args, false)
}
- expr := ctx.parseReference(v, v.Name)
- switch x := expr.(type) {
- case *callExpr:
- ctx.receiver.newNode(&exprNode{expr})
- case *badExpr:
- ctx.wrapBadExpr(x)
- default:
- ctx.errorf(v, "cannot handle %s", v.Dump())
- }
+ return []starlarkNode{&exprNode{expr: ctx.parseReference(v, v.Name)}}
}
-func (ctx *parseContext) handleDefine(directive *mkparser.Directive) {
+func (ctx *parseContext) maybeHandleDefine(directive *mkparser.Directive) starlarkNode {
macro_name := strings.Fields(directive.Args.Strings[0])[0]
// Ignore the macros that we handle
_, ignored := ignoredDefines[macro_name]
_, known := knownFunctions[macro_name]
if !ignored && !known {
- ctx.errorf(directive, "define is not supported: %s", macro_name)
+ return ctx.newBadNode(directive, "define is not supported: %s", macro_name)
}
+ return nil
}
-func (ctx *parseContext) handleIfBlock(ifDirective *mkparser.Directive) {
- ssSwitch := &switchNode{}
- ctx.pushReceiver(ssSwitch)
- for ctx.processBranch(ifDirective); ctx.hasNodes() && ctx.fatalError == nil; {
+func (ctx *parseContext) handleIfBlock(ifDirective *mkparser.Directive) starlarkNode {
+ ssSwitch := &switchNode{
+ ssCases: []*switchCase{ctx.processBranch(ifDirective)},
+ }
+ for ctx.hasNodes() && ctx.fatalError == nil {
node := ctx.getNode()
switch x := node.(type) {
case *mkparser.Directive:
switch x.Name {
case "else", "elifdef", "elifndef", "elifeq", "elifneq":
- ctx.processBranch(x)
+ ssSwitch.ssCases = append(ssSwitch.ssCases, ctx.processBranch(x))
case "endif":
- ctx.popReceiver()
- ctx.receiver.newNode(ssSwitch)
- return
+ return ssSwitch
default:
- ctx.errorf(node, "unexpected directive %s", x.Name)
+ return ctx.newBadNode(node, "unexpected directive %s", x.Name)
}
default:
- ctx.errorf(ifDirective, "unexpected statement")
+ return ctx.newBadNode(ifDirective, "unexpected statement")
}
}
if ctx.fatalError == nil {
ctx.fatalError = fmt.Errorf("no matching endif for %s", ifDirective.Dump())
}
- ctx.popReceiver()
+ return ctx.newBadNode(ifDirective, "no matching endif for %s", ifDirective.Dump())
}
// processBranch processes a single branch (if/elseif/else) until the next directive
// on the same level.
-func (ctx *parseContext) processBranch(check *mkparser.Directive) {
- block := switchCase{gate: ctx.parseCondition(check)}
+func (ctx *parseContext) processBranch(check *mkparser.Directive) *switchCase {
+ block := &switchCase{gate: ctx.parseCondition(check)}
defer func() {
ctx.popVarAssignments()
ctx.ifNestLevel--
@@ -987,29 +942,26 @@
ctx.pushVarAssignments()
ctx.ifNestLevel++
- ctx.pushReceiver(&block)
for ctx.hasNodes() {
node := ctx.getNode()
if d, ok := node.(*mkparser.Directive); ok {
switch d.Name {
case "else", "elifdef", "elifndef", "elifeq", "elifneq", "endif":
- ctx.popReceiver()
- ctx.receiver.newNode(&block)
ctx.backNode()
- return
+ return block
}
}
- ctx.handleSimpleStatement(node)
+ block.nodes = append(block.nodes, ctx.handleSimpleStatement(node)...)
}
ctx.fatalError = fmt.Errorf("no matching endif for %s", check.Dump())
- ctx.popReceiver()
+ return block
}
func (ctx *parseContext) parseCondition(check *mkparser.Directive) starlarkNode {
switch check.Name {
case "ifdef", "ifndef", "elifdef", "elifndef":
if !check.Args.Const() {
- return &exprNode{expr: ctx.newBadExpr(check, "ifdef variable ref too complex: %s", check.Args.Dump())}
+ return ctx.newBadNode(check, "ifdef variable ref too complex: %s", check.Args.Dump())
}
v := NewVariableRefExpr(ctx.addVariable(check.Args.Strings[0]), false)
if strings.HasSuffix(check.Name, "ndef") {
@@ -1032,12 +984,16 @@
}
func (ctx *parseContext) newBadExpr(node mkparser.Node, text string, args ...interface{}) starlarkExpr {
- message := fmt.Sprintf(text, args...)
if ctx.errorLogger != nil {
ctx.errorLogger.NewError(ctx.errorLocation(node), node, text, args...)
}
ctx.script.hasErrors = true
- return &badExpr{errorLocation: ctx.errorLocation(node), message: message}
+ return &badExpr{errorLocation: ctx.errorLocation(node), message: fmt.Sprintf(text, args...)}
+}
+
+// records that the given node failed to be converted and includes an explanatory message
+func (ctx *parseContext) newBadNode(failedNode mkparser.Node, message string, args ...interface{}) starlarkNode {
+ return &exprNode{ctx.newBadExpr(failedNode, message, args...)}
}
func (ctx *parseContext) parseCompare(cond *mkparser.Directive) starlarkExpr {
@@ -1730,28 +1686,34 @@
// Handles the statements whose treatment is the same in all contexts: comment,
// assignment, variable (which is a macro call in reality) and all constructs that
// do not handle in any context ('define directive and any unrecognized stuff).
-func (ctx *parseContext) handleSimpleStatement(node mkparser.Node) {
+func (ctx *parseContext) handleSimpleStatement(node mkparser.Node) []starlarkNode {
+ var result []starlarkNode
switch x := node.(type) {
case *mkparser.Comment:
- ctx.maybeHandleAnnotation(x)
- ctx.insertComment("#" + x.Comment)
+ if n, handled := ctx.maybeHandleAnnotation(x); handled && n != nil {
+ result = []starlarkNode{n}
+ } else if !handled {
+ result = []starlarkNode{&commentNode{strings.TrimSpace("#" + x.Comment)}}
+ }
case *mkparser.Assignment:
- ctx.handleAssignment(x)
+ result = ctx.handleAssignment(x)
case *mkparser.Variable:
- ctx.handleVariable(x)
+ result = ctx.handleVariable(x)
case *mkparser.Directive:
switch x.Name {
case "define":
- ctx.handleDefine(x)
+ if res := ctx.maybeHandleDefine(x); res != nil {
+ result = []starlarkNode{res}
+ }
case "include", "-include":
- ctx.handleInclude(node, ctx.parseMakeString(node, x.Args), x.Name[0] != '-')
+ result = ctx.handleInclude(node, ctx.parseMakeString(node, x.Args), x.Name[0] != '-')
case "ifeq", "ifneq", "ifdef", "ifndef":
- ctx.handleIfBlock(x)
+ result = []starlarkNode{ctx.handleIfBlock(x)}
default:
- ctx.errorf(x, "unexpected directive %s", x.Name)
+ result = []starlarkNode{ctx.newBadNode(x, "unexpected directive %s", x.Name)}
}
default:
- ctx.errorf(x, "unsupported line %s", strings.ReplaceAll(x.Dump(), "\n", "\n#"))
+ result = []starlarkNode{ctx.newBadNode(x, "unsupported line %s", strings.ReplaceAll(x.Dump(), "\n", "\n#"))}
}
// Clear the includeTops after each non-comment statement
@@ -1760,12 +1722,17 @@
if _, wasComment := node.(*mkparser.Comment); !wasComment && len(ctx.includeTops) > 0 {
ctx.includeTops = []string{}
}
+
+ if result == nil {
+ result = []starlarkNode{}
+ }
+ return result
}
// Processes annotation. An annotation is a comment that starts with #RBC# and provides
// a conversion hint -- say, where to look for the dynamically calculated inherit/include
-// paths.
-func (ctx *parseContext) maybeHandleAnnotation(cnode *mkparser.Comment) {
+// paths. Returns true if the comment was a successfully-handled annotation.
+func (ctx *parseContext) maybeHandleAnnotation(cnode *mkparser.Comment) (starlarkNode, bool) {
maybeTrim := func(s, prefix string) (string, bool) {
if strings.HasPrefix(s, prefix) {
return strings.TrimSpace(strings.TrimPrefix(s, prefix)), true
@@ -1774,44 +1741,20 @@
}
annotation, ok := maybeTrim(cnode.Comment, annotationCommentPrefix)
if !ok {
- return
+ return nil, false
}
if p, ok := maybeTrim(annotation, "include_top"); ok {
// Don't allow duplicate include tops, because then we will generate
// invalid starlark code. (duplicate keys in the _entry dictionary)
for _, top := range ctx.includeTops {
if top == p {
- return
+ return nil, true
}
}
ctx.includeTops = append(ctx.includeTops, p)
- return
+ return nil, true
}
- ctx.errorf(cnode, "unsupported annotation %s", cnode.Comment)
-
-}
-
-func (ctx *parseContext) insertComment(s string) {
- ctx.receiver.newNode(&commentNode{strings.TrimSpace(s)})
-}
-
-func (ctx *parseContext) carryAsComment(failedNode mkparser.Node) {
- for _, line := range strings.Split(failedNode.Dump(), "\n") {
- ctx.insertComment("# " + line)
- }
-}
-
-// 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{}) {
- if ctx.errorLogger != nil {
- ctx.errorLogger.NewError(ctx.errorLocation(failedNode), failedNode, message, args...)
- }
- ctx.receiver.newNode(&exprNode{ctx.newBadExpr(failedNode, message, args...)})
- ctx.script.hasErrors = true
-}
-
-func (ctx *parseContext) wrapBadExpr(xBad *badExpr) {
- ctx.receiver.newNode(&exprNode{xBad})
+ return ctx.newBadNode(cnode, "unsupported annotation %s", cnode.Comment), true
}
func (ctx *parseContext) loadedModulePath(path string) string {
@@ -1926,6 +1869,7 @@
sourceFS: req.SourceFS,
makefileFinder: req.MakefileFinder,
nodeLocator: func(pos mkparser.Pos) int { return parser.Unpack(pos).Line },
+ nodes: make([]starlarkNode, 0),
}
ctx := newParseContext(starScript, nodes)
ctx.outputSuffix = req.OutputSuffix
@@ -1937,9 +1881,8 @@
ctx.tracedVariables[v] = true
}
}
- ctx.pushReceiver(starScript)
for ctx.hasNodes() && ctx.fatalError == nil {
- ctx.handleSimpleStatement(ctx.getNode())
+ starScript.nodes = append(starScript.nodes, ctx.handleSimpleStatement(ctx.getNode())...)
}
if ctx.fatalError != nil {
return nil, ctx.fatalError
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 376ee5e..c499398 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -1071,7 +1071,6 @@
def init(g, handle):
cfg = rblf.cfg(handle)
g["MY_PATH"] = "foo"
- #RBC# include_top vendor/foo1
rblf.inherit(handle, "vendor/foo1/cfg", _cfg_init)
`,
},
@@ -1083,6 +1082,7 @@
#RBC# include_top vendor/foo1
$(call inherit-product,$(MY_PATH)/cfg.mk)
#RBC# include_top vendor/foo1
+#RBC# include_top vendor/foo1
$(call inherit-product,$(MY_PATH)/cfg.mk)
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
@@ -1091,9 +1091,7 @@
def init(g, handle):
cfg = rblf.cfg(handle)
g["MY_PATH"] = "foo"
- #RBC# include_top vendor/foo1
rblf.inherit(handle, "vendor/foo1/cfg", _cfg_init)
- #RBC# include_top vendor/foo1
rblf.inherit(handle, "vendor/foo1/cfg", _cfg_init)
`,
},
@@ -1112,15 +1110,13 @@
$(call inherit-product,$(MY_VAR)/font.mk)
`,
- expected: `#RBC# include_top foo
-load("//build/make/core:product_config.rbc", "rblf")
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
load("//foo:font.star|init", _font_init = "init")
load("//bar:font.star|init", _font1_init = "init")
def init(g, handle):
cfg = rblf.cfg(handle)
rblf.inherit(handle, "foo/font", _font_init)
- #RBC# include_top foo
# There's some space and even this comment between the include_top and the inherit-product
rblf.inherit(handle, "foo/font", _font_init)
rblf.mkwarning("product.mk:11", "Including a path with a non-constant prefix, please convert this to a simple literal to generate cleaner starlark.")
@@ -1157,7 +1153,6 @@
def init(g, handle):
cfg = rblf.cfg(handle)
rblf.mk2rbc_error("product.mk:2", "cannot handle override directive")
- g["override FOO"] = ""
`,
},
{
diff --git a/mk2rbc/node.go b/mk2rbc/node.go
index dea4dc8..61aaf91 100644
--- a/mk2rbc/node.go
+++ b/mk2rbc/node.go
@@ -255,29 +255,17 @@
nodes []starlarkNode
}
-func (cb *switchCase) newNode(node starlarkNode) {
- cb.nodes = append(cb.nodes, node)
-}
-
func (cb *switchCase) emit(gctx *generationContext) {
cb.gate.emit(gctx)
gctx.indentLevel++
hasStatements := false
- emitNode := func(node starlarkNode) {
+ for _, node := range cb.nodes {
if _, ok := node.(*commentNode); !ok {
hasStatements = true
}
node.emit(gctx)
}
- if len(cb.nodes) > 0 {
- emitNode(cb.nodes[0])
- for _, node := range cb.nodes[1:] {
- emitNode(node)
- }
- if !hasStatements {
- gctx.emitPass()
- }
- } else {
+ if !hasStatements {
gctx.emitPass()
}
gctx.indentLevel--
@@ -288,22 +276,8 @@
ssCases []*switchCase
}
-func (ssw *switchNode) newNode(node starlarkNode) {
- switch br := node.(type) {
- case *switchCase:
- ssw.ssCases = append(ssw.ssCases, br)
- default:
- panic(fmt.Errorf("expected switchCase node, got %t", br))
- }
-}
-
func (ssw *switchNode) emit(gctx *generationContext) {
- if len(ssw.ssCases) == 0 {
- gctx.emitPass()
- } else {
- ssw.ssCases[0].emit(gctx)
- for _, ssCase := range ssw.ssCases[1:] {
- ssCase.emit(gctx)
- }
+ for _, ssCase := range ssw.ssCases {
+ ssCase.emit(gctx)
}
}