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

Commit 4160a071 authored by Paul Duffin's avatar Paul Duffin Committed by Gerrit Code Review
Browse files

Merge "Add sortableComponent abstraction"

parents 7314fedd 1d2d42f8
Loading
Loading
Loading
Loading
+22 −19
Original line number Diff line number Diff line
@@ -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
}
+70 −15
Original line number Diff line number Diff line
@@ -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))

+2 −2
Original line number Diff line number Diff line
@@ -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) {