Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc46bc1e authored by Liz Kammer's avatar Liz Kammer
Browse files

Refactor BazelTargetModule

This eliminates the need to remove quotes, delete attributes, and
re-checking that name has correct prefix. Additionally, this allows
assignment directly to the BazelTargetModuleProperties struct, which
allows defaulting unused fields and clarity of which field is being set.

Test: go test soong tests
Test: ran ./build/bazel/scripts/milestone-2/demo.sh
Change-Id: Ia9bfcce76234c793a4ddd5f29a661150f83341c9
parent ece45440
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -57,9 +57,9 @@ func FilegroupBp2Build(ctx TopDownMutatorContext) {
		Srcs: BazelLabelForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs),
	}

	props := bazel.NewBazelTargetModuleProperties(fg.Name(), "filegroup", "")
	props := bazel.BazelTargetModuleProperties{Rule_class: "filegroup"}

	ctx.CreateBazelTargetModule(BazelFileGroupFactory, props, attrs)
	ctx.CreateBazelTargetModule(BazelFileGroupFactory, fg.Name(), props, attrs)
}

type fileGroupProperties struct {
+23 −4
Original line number Diff line number Diff line
@@ -507,13 +507,17 @@ type Module interface {
type BazelTargetModule interface {
	Module

	BazelTargetModuleProperties() *bazel.BazelTargetModuleProperties
	bazelTargetModuleProperties() *bazel.BazelTargetModuleProperties
	SetBazelTargetModuleProperties(props bazel.BazelTargetModuleProperties)

	RuleClass() string
	BzlLoadLocation() string
}

// InitBazelTargetModule is a wrapper function that decorates BazelTargetModule
// with property structs containing metadata for bp2build conversion.
func InitBazelTargetModule(module BazelTargetModule) {
	module.AddProperties(module.BazelTargetModuleProperties())
	module.AddProperties(module.bazelTargetModuleProperties())
	InitAndroidModule(module)
}

@@ -524,11 +528,26 @@ type BazelTargetModuleBase struct {
	Properties bazel.BazelTargetModuleProperties
}

// BazelTargetModuleProperties getter.
func (btmb *BazelTargetModuleBase) BazelTargetModuleProperties() *bazel.BazelTargetModuleProperties {
// bazelTargetModuleProperties getter.
func (btmb *BazelTargetModuleBase) bazelTargetModuleProperties() *bazel.BazelTargetModuleProperties {
	return &btmb.Properties
}

// SetBazelTargetModuleProperties setter for BazelTargetModuleProperties
func (btmb *BazelTargetModuleBase) SetBazelTargetModuleProperties(props bazel.BazelTargetModuleProperties) {
	btmb.Properties = props
}

// RuleClass returns the rule class for this Bazel target
func (b *BazelTargetModuleBase) RuleClass() string {
	return b.bazelTargetModuleProperties().Rule_class
}

// BzlLoadLocation returns the rule class for this Bazel target
func (b *BazelTargetModuleBase) BzlLoadLocation() string {
	return b.bazelTargetModuleProperties().Bzl_load_location
}

// Qualified id for a module
type qualifiedModuleName struct {
	// The package (i.e. directory) in which the module is defined, without trailing /
+14 −6
Original line number Diff line number Diff line
@@ -283,7 +283,7 @@ type TopDownMutatorContext interface {
	// factory method, just like in CreateModule, but also requires
	// BazelTargetModuleProperties containing additional metadata for the
	// bp2build codegenerator.
	CreateBazelTargetModule(ModuleFactory, bazel.BazelTargetModuleProperties, interface{}) BazelTargetModule
	CreateBazelTargetModule(ModuleFactory, string, bazel.BazelTargetModuleProperties, interface{}) BazelTargetModule
}

type topDownMutatorContext struct {
@@ -513,17 +513,25 @@ func registerDepsMutatorBp2Build(ctx RegisterMutatorsContext) {

func (t *topDownMutatorContext) CreateBazelTargetModule(
	factory ModuleFactory,
	name string,
	bazelProps bazel.BazelTargetModuleProperties,
	attrs interface{}) BazelTargetModule {
	if !strings.HasPrefix(*bazelProps.Name, bazel.BazelTargetModuleNamePrefix) {
	if strings.HasPrefix(name, bazel.BazelTargetModuleNamePrefix) {
		panic(fmt.Errorf(
			"bp2build error: the bazel target module name must start with '%s': %s",
			"The %s name prefix is added automatically, do not set it manually: %s",
			bazel.BazelTargetModuleNamePrefix,
			*bazelProps.Name,
		))
			name))
	}
	name = bazel.BazelTargetModuleNamePrefix + name
	nameProp := struct {
		Name *string
	}{
		Name: &name,
	}

	return t.CreateModule(factory, &bazelProps, attrs).(BazelTargetModule)
	b := t.CreateModule(factory, &nameProp, attrs).(BazelTargetModule)
	b.SetBazelTargetModuleProperties(bazelProps)
	return b
}

func (t *topDownMutatorContext) AppendProperties(props ...interface{}) {
+2 −24
Original line number Diff line number Diff line
@@ -14,11 +14,6 @@

package bazel

import (
	"fmt"
	"strings"
)

type bazelModuleProperties struct {
	// The label of the Bazel target replacing this Soong module.
	Label string
@@ -37,32 +32,15 @@ type Properties struct {
// BazelTargetModuleProperties contain properties and metadata used for
// Blueprint to BUILD file conversion.
type BazelTargetModuleProperties struct {
	Name *string

	// The Bazel rule class for this target.
	Rule_class string
	Rule_class string `blueprint:"mutated"`

	// The target label for the bzl file containing the definition of the rule class.
	Bzl_load_location string
	Bzl_load_location string `blueprint:"mutated"`
}

const BazelTargetModuleNamePrefix = "__bp2build__"

func NewBazelTargetModuleProperties(name string, ruleClass string, bzlLoadLocation string) BazelTargetModuleProperties {
	if strings.HasPrefix(name, BazelTargetModuleNamePrefix) {
		panic(fmt.Errorf(
			"The %s name prefix is added automatically, do not set it manually: %s",
			BazelTargetModuleNamePrefix,
			name))
	}
	name = BazelTargetModuleNamePrefix + name
	return BazelTargetModuleProperties{
		Name:              &name,
		Rule_class:        ruleClass,
		Bzl_load_location: bzlLoadLocation,
	}
}

// Label is used to represent a Bazel compatible Label. Also stores the original bp text to support
// string replacement.
type Label struct {
+7 −30
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ import (
	"android/soong/bazel"
	"fmt"
	"reflect"
	"strconv"
	"strings"

	"github.com/google/blueprint"
@@ -178,13 +177,14 @@ func GenerateBazelTargets(ctx CodegenContext) (map[string]BazelTargets, CodegenM

		switch ctx.Mode() {
		case Bp2Build:
			if _, ok := m.(android.BazelTargetModule); !ok {
			if b, ok := m.(android.BazelTargetModule); !ok {
				// Only include regular Soong modules (non-BazelTargetModules) into the total count.
				totalModuleCount += 1
				return
			}
			t = generateBazelTarget(bpCtx, m)
			} else {
				t = generateBazelTarget(bpCtx, m, b)
				ruleClassCount[t.ruleClass] += 1
			}
		case QueryView:
			// Blocklist certain module types from being generated.
			if canonicalizeModuleType(bpCtx.ModuleType(m)) == "package" {
@@ -208,36 +208,13 @@ func GenerateBazelTargets(ctx CodegenContext) (map[string]BazelTargets, CodegenM
	return buildFileToTargets, metrics
}

// Helper method to trim quotes around strings.
func trimQuotes(s string) string {
	if s == "" {
		// strconv.Unquote would error out on empty strings, but this method
		// allows them, so return the empty string directly.
		return ""
	}
	ret, err := strconv.Unquote(s)
	if err != nil {
		// Panic the error immediately.
		panic(fmt.Errorf("Trying to unquote '%s', but got error: %s", s, err))
	}
	return ret
}
func generateBazelTarget(ctx bpToBuildContext, m blueprint.Module, b android.BazelTargetModule) BazelTarget {
	ruleClass := b.RuleClass()
	bzlLoadLocation := b.BzlLoadLocation()

func generateBazelTarget(ctx bpToBuildContext, m blueprint.Module) BazelTarget {
	// extract the bazel attributes from the module.
	props := getBuildProperties(ctx, m)

	// extract the rule class name from the attributes. Since the string value
	// will be string-quoted, remove the quotes here.
	ruleClass := trimQuotes(props.Attrs["rule_class"])
	// Delete it from being generated in the BUILD file.
	delete(props.Attrs, "rule_class")

	// extract the bzl_load_location, and also remove the quotes around it here.
	bzlLoadLocation := trimQuotes(props.Attrs["bzl_load_location"])
	// Delete it from being generated in the BUILD file.
	delete(props.Attrs, "bzl_load_location")

	delete(props.Attrs, "bp2build_available")

	// Return the Bazel target with rule class and attributes, ready to be
Loading