Merge "Add sortableComponent abstraction" am: 4160a071d6

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1622499

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I50766f00403249ae3c506bdbbda86e85150e8dc1
This commit is contained in:
Paul Duffin
2021-03-08 22:19:32 +00:00
committed by Automerger Merge Worker
3 changed files with 94 additions and 36 deletions

View File

@@ -33,22 +33,8 @@ import (
// run FinalDeps mutators (CreateVariations disallowed in this phase)
// continue on to GenerateAndroidBuildActions
func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) {
for _, t := range mutators {
var handle blueprint.MutatorHandle
if t.bottomUpMutator != nil {
handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator)
} else if t.topDownMutator != nil {
handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator)
}
if t.parallel {
handle.Parallel()
}
}
}
// RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing.
func RegisterMutatorsForBazelConversion(ctx *blueprint.Context, preArchMutators, depsMutators, bp2buildMutators []RegisterMutatorFunc) {
func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators, depsMutators, bp2buildMutators []RegisterMutatorFunc) {
mctx := &registerMutatorsContext{
bazelConversionMode: true,
}
@@ -80,10 +66,10 @@ func RegisterMutatorsForBazelConversion(ctx *blueprint.Context, preArchMutators,
f(mctx)
}
registerMutatorsToContext(ctx, mctx.mutators)
mctx.mutators.registerAll(ctx)
}
func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) {
func registerMutators(ctx *Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) {
mctx := &registerMutatorsContext{}
register := func(funcs []RegisterMutatorFunc) {
@@ -103,11 +89,11 @@ func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalD
mctx.finalPhase = true
register(finalDeps)
registerMutatorsToContext(ctx, mctx.mutators)
mctx.mutators.registerAll(ctx)
}
type registerMutatorsContext struct {
mutators []*mutator
mutators sortableComponents
finalPhase bool
bazelConversionMode bool
}
@@ -473,6 +459,23 @@ func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) Mutator
return mutator
}
func (mutator *mutator) componentName() string {
return mutator.name
}
func (mutator *mutator) register(ctx *Context) {
blueprintCtx := ctx.Context
var handle blueprint.MutatorHandle
if mutator.bottomUpMutator != nil {
handle = blueprintCtx.RegisterBottomUpMutator(mutator.name, mutator.bottomUpMutator)
} else if mutator.topDownMutator != nil {
handle = blueprintCtx.RegisterTopDownMutator(mutator.name, mutator.topDownMutator)
}
if mutator.parallel {
handle.Parallel()
}
}
type MutatorHandle interface {
Parallel() MutatorHandle
}

View File

@@ -21,21 +21,78 @@ import (
"github.com/google/blueprint"
)
// A sortable component is one whose registration order affects the order in which it is executed
// and so affects the behavior of the build system. As a result it is important for the order in
// which they are registered during tests to match the order used at runtime and so the test
// infrastructure will sort them to match.
//
// The sortable components are mutators, singletons and pre-singletons. Module types are not
// sortable because their order of registration does not affect the runtime behavior.
type sortableComponent interface {
// componentName returns the name of the component.
//
// Uniquely identifies the components within the set of components used at runtimr and during
// tests.
componentName() string
// register registers this component in the supplied context.
register(ctx *Context)
}
type sortableComponents []sortableComponent
// registerAll registers all components in this slice with the supplied context.
func (r sortableComponents) registerAll(ctx *Context) {
for _, c := range r {
c.register(ctx)
}
}
type moduleType struct {
name string
factory ModuleFactory
}
func (t moduleType) register(ctx *Context) {
ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
}
var moduleTypes []moduleType
var moduleTypesForDocs = map[string]reflect.Value{}
type singleton struct {
// True if this should be registered as a pre-singleton, false otherwise.
pre bool
name string
factory SingletonFactory
}
var singletons []singleton
var preSingletons []singleton
func newSingleton(name string, factory SingletonFactory) singleton {
return singleton{false, name, factory}
}
func newPreSingleton(name string, factory SingletonFactory) singleton {
return singleton{true, name, factory}
}
func (s singleton) componentName() string {
return s.name
}
func (s singleton) register(ctx *Context) {
adaptor := SingletonFactoryAdaptor(ctx, s.factory)
if s.pre {
ctx.RegisterPreSingletonType(s.name, adaptor)
} else {
ctx.RegisterSingletonType(s.name, adaptor)
}
}
var _ sortableComponent = singleton{}
var singletons sortableComponents
var preSingletons sortableComponents
type mutator struct {
name string
@@ -44,6 +101,8 @@ type mutator struct {
parallel bool
}
var _ sortableComponent = &mutator{}
type ModuleFactory func() Module
// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
@@ -84,11 +143,11 @@ func RegisterModuleTypeForDocs(name string, factory reflect.Value) {
}
func RegisterSingletonType(name string, factory SingletonFactory) {
singletons = append(singletons, singleton{name, factory})
singletons = append(singletons, newSingleton(name, factory))
}
func RegisterPreSingletonType(name string, factory SingletonFactory) {
preSingletons = append(preSingletons, singleton{name, factory})
preSingletons = append(preSingletons, newPreSingleton(name, factory))
}
type Context struct {
@@ -107,33 +166,29 @@ func NewContext(config Config) *Context {
// files to semantically equivalent BUILD files.
func (ctx *Context) RegisterForBazelConversion() {
for _, t := range moduleTypes {
ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
t.register(ctx)
}
// Required for SingletonModule types, even though we are not using them.
for _, t := range singletons {
ctx.RegisterSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
t.register(ctx)
}
RegisterMutatorsForBazelConversion(ctx.Context, bp2buildPreArchMutators, bp2buildDepsMutators, bp2buildMutators)
RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators, bp2buildDepsMutators, bp2buildMutators)
}
// Register the pipeline of singletons, module types, and mutators for
// generating build.ninja and other files for Kati, from Android.bp files.
func (ctx *Context) Register() {
for _, t := range preSingletons {
ctx.RegisterPreSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
}
preSingletons.registerAll(ctx)
for _, t := range moduleTypes {
ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
t.register(ctx)
}
for _, t := range singletons {
ctx.RegisterSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
}
singletons.registerAll(ctx)
registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps)
registerMutators(ctx, preArch, preDeps, postDeps, finalDeps)
ctx.RegisterSingletonType("bazeldeps", SingletonFactoryAdaptor(ctx, BazelSingleton))

View File

@@ -141,14 +141,14 @@ func (ctx *TestContext) DepsBp2BuildMutators(f RegisterMutatorFunc) {
}
func (ctx *TestContext) Register() {
registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps)
registerMutators(ctx.Context, ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps)
ctx.RegisterSingletonType("env", EnvSingleton)
}
// RegisterForBazelConversion prepares a test context for bp2build conversion.
func (ctx *TestContext) RegisterForBazelConversion() {
RegisterMutatorsForBazelConversion(ctx.Context.Context, ctx.bp2buildPreArch, ctx.bp2buildDeps, ctx.bp2buildMutators)
RegisterMutatorsForBazelConversion(ctx.Context, ctx.bp2buildPreArch, ctx.bp2buildDeps, ctx.bp2buildMutators)
}
func (ctx *TestContext) ParseFileList(rootDir string, filePaths []string) (deps []string, errs []error) {