Remove EarlyMutators and DynamicDependencies

EarlyMutators are identical to BottomUpMutators, except they run before
DynamicDependencies.  DynamicDependencies can be replaced with a
BottomUpMutator.  Replace both EarlyMutators and DynamicDependencies
with BottomUpMutators, which allows setting the order between all
mutators through registration order.

Change-Id: Id1305d798d3d2da592061c89d7c10a71780b71a3
This commit is contained in:
Colin Cross
2015-10-29 15:25:03 -07:00
parent 06a931bdb6
commit 6362e27848
10 changed files with 148 additions and 110 deletions

View File

@@ -95,6 +95,7 @@ bootstrap_go_package {
"common/env.go", "common/env.go",
"common/glob.go", "common/glob.go",
"common/module.go", "common/module.go",
"common/mutator.go",
"common/paths.go", "common/paths.go",
"common/util.go", "common/util.go",
"common/variable.go", "common/variable.go",

View File

@@ -57,8 +57,9 @@ func init() {
// LinkageMutator must be registered after common.ArchMutator, but that is guaranteed by // LinkageMutator must be registered after common.ArchMutator, but that is guaranteed by
// the Go initialization order because this package depends on common, so common's init // the Go initialization order because this package depends on common, so common's init
// functions will run first. // functions will run first.
soong.RegisterEarlyMutator("link", LinkageMutator) common.RegisterBottomUpMutator("link", linkageMutator)
soong.RegisterEarlyMutator("test_per_src", TestPerSrcMutator) common.RegisterBottomUpMutator("test_per_src", testPerSrcMutator)
common.RegisterBottomUpMutator("deps", depsMutator)
} }
var ( var (
@@ -140,20 +141,25 @@ func init() {
pctx.StaticVariable("clangPath", "${SrcDir}/prebuilts/clang/${HostPrebuiltTag}/host/3.6/bin/") pctx.StaticVariable("clangPath", "${SrcDir}/prebuilts/clang/${HostPrebuiltTag}/host/3.6/bin/")
} }
type CCModuleContext common.AndroidBaseContext
// Building C/C++ code is handled by objects that satisfy this interface via composition // Building C/C++ code is handled by objects that satisfy this interface via composition
type CCModuleType interface { type CCModuleType interface {
common.AndroidModule common.AndroidModule
// Modify property values after parsing Blueprints file but before starting dependency // Modify property values after parsing Blueprints file but before starting dependency
// resolution or build rule generation // resolution or build rule generation
ModifyProperties(common.AndroidBaseContext) ModifyProperties(CCModuleContext)
// Modify the ccFlags // Modify the ccFlags
flags(common.AndroidModuleContext, CCFlags) CCFlags flags(common.AndroidModuleContext, CCFlags) CCFlags
// Return list of dependency names for use in AndroidDynamicDependencies and in depsToPaths // Return list of dependency names for use in depsMutator
depNames(common.AndroidBaseContext, CCDeps) CCDeps depNames(common.AndroidBaseContext, CCDeps) CCDeps
// Add dynamic dependencies
depsMutator(common.AndroidBottomUpMutatorContext)
// Compile objects into final module // Compile objects into final module
compileModule(common.AndroidModuleContext, CCFlags, CCDeps, []string) compileModule(common.AndroidModuleContext, CCFlags, CCDeps, []string)
@@ -392,8 +398,6 @@ func (c *CCBase) ccModuleType() CCModuleType {
return c.module return c.module
} }
var _ common.AndroidDynamicDepender = (*CCBase)(nil)
func (c *CCBase) findToolchain(ctx common.AndroidModuleContext) Toolchain { func (c *CCBase) findToolchain(ctx common.AndroidModuleContext) Toolchain {
arch := ctx.Arch() arch := ctx.Arch()
hod := ctx.HostOrDevice() hod := ctx.HostOrDevice()
@@ -405,7 +409,7 @@ func (c *CCBase) findToolchain(ctx common.AndroidModuleContext) Toolchain {
return factory(arch.ArchVariant, arch.CpuVariant) return factory(arch.ArchVariant, arch.CpuVariant)
} }
func (c *CCBase) ModifyProperties(ctx common.AndroidBaseContext) { func (c *CCBase) ModifyProperties(ctx CCModuleContext) {
} }
func (c *CCBase) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps { func (c *CCBase) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
@@ -416,9 +420,7 @@ func (c *CCBase) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps
return depNames return depNames
} }
func (c *CCBase) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string { func (c *CCBase) depsMutator(ctx common.AndroidBottomUpMutatorContext) {
c.module.ModifyProperties(ctx)
c.savedDepNames = c.module.depNames(ctx, CCDeps{}) c.savedDepNames = c.module.depNames(ctx, CCDeps{})
c.savedDepNames.WholeStaticLibs = lastUniqueElements(c.savedDepNames.WholeStaticLibs) c.savedDepNames.WholeStaticLibs = lastUniqueElements(c.savedDepNames.WholeStaticLibs)
c.savedDepNames.StaticLibs = lastUniqueElements(c.savedDepNames.StaticLibs) c.savedDepNames.StaticLibs = lastUniqueElements(c.savedDepNames.StaticLibs)
@@ -431,15 +433,20 @@ func (c *CCBase) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerMod
ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.savedDepNames.SharedLibs...) ctx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, c.savedDepNames.SharedLibs...)
ret := append([]string(nil), c.savedDepNames.ObjFiles...) ctx.AddDependency(ctx.Module(), c.savedDepNames.ObjFiles...)
if c.savedDepNames.CrtBegin != "" { if c.savedDepNames.CrtBegin != "" {
ret = append(ret, c.savedDepNames.CrtBegin) ctx.AddDependency(ctx.Module(), c.savedDepNames.CrtBegin)
} }
if c.savedDepNames.CrtEnd != "" { if c.savedDepNames.CrtEnd != "" {
ret = append(ret, c.savedDepNames.CrtEnd) ctx.AddDependency(ctx.Module(), c.savedDepNames.CrtEnd)
} }
}
return ret func depsMutator(ctx common.AndroidBottomUpMutatorContext) {
if c, ok := ctx.Module().(CCModuleType); ok {
c.ModifyProperties(ctx)
c.depsMutator(ctx)
}
} }
// Create a ccFlags struct that collects the compile flags from global values, // Create a ccFlags struct that collects the compile flags from global values,
@@ -1285,11 +1292,6 @@ func CCObjectFactory() (blueprint.Module, []interface{}) {
return newCCBase(&module.CCBase, module, common.DeviceSupported, common.MultilibBoth) return newCCBase(&module.CCBase, module, common.DeviceSupported, common.MultilibBoth)
} }
func (*ccObject) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
// object files can't have any dynamic dependencies
return nil
}
func (*ccObject) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps { func (*ccObject) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
// object files can't have any dynamic dependencies // object files can't have any dynamic dependencies
return CCDeps{} return CCDeps{}
@@ -1418,7 +1420,7 @@ func CCBinaryFactory() (blueprint.Module, []interface{}) {
return NewCCBinary(module, module, common.HostAndDeviceSupported) return NewCCBinary(module, module, common.HostAndDeviceSupported)
} }
func (c *CCBinary) ModifyProperties(ctx common.AndroidBaseContext) { func (c *CCBinary) ModifyProperties(ctx CCModuleContext) {
if ctx.Darwin() { if ctx.Darwin() {
c.BinaryProperties.Static_executable = proptools.BoolPtr(false) c.BinaryProperties.Static_executable = proptools.BoolPtr(false)
} }
@@ -1519,7 +1521,7 @@ type testPerSrc interface {
var _ testPerSrc = (*CCBinary)(nil) var _ testPerSrc = (*CCBinary)(nil)
func TestPerSrcMutator(mctx blueprint.EarlyMutatorContext) { func testPerSrcMutator(mctx common.AndroidBottomUpMutatorContext) {
if test, ok := mctx.Module().(testPerSrc); ok { if test, ok := mctx.Module().(testPerSrc); ok {
if test.testPerSrc() { if test.testPerSrc() {
testNames := make([]string, len(test.binary().Properties.Srcs)) testNames := make([]string, len(test.binary().Properties.Srcs))
@@ -1691,11 +1693,6 @@ type toolchainLibrary struct {
CCLibrary CCLibrary
} }
func (*toolchainLibrary) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
// toolchain libraries can't have any dependencies
return nil
}
func (*toolchainLibrary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps { func (*toolchainLibrary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
// toolchain libraries can't have any dependencies // toolchain libraries can't have any dependencies
return CCDeps{} return CCDeps{}
@@ -1752,13 +1749,6 @@ type ndkPrebuiltObject struct {
ccObject ccObject
} }
func (*ndkPrebuiltObject) AndroidDynamicDependencies(
ctx common.AndroidDynamicDependerModuleContext) []string {
// NDK objects can't have any dependencies
return nil
}
func (*ndkPrebuiltObject) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps { func (*ndkPrebuiltObject) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
// NDK objects can't have any dependencies // NDK objects can't have any dependencies
return CCDeps{} return CCDeps{}
@@ -1789,13 +1779,6 @@ type ndkPrebuiltLibrary struct {
CCLibrary CCLibrary
} }
func (*ndkPrebuiltLibrary) AndroidDynamicDependencies(
ctx common.AndroidDynamicDependerModuleContext) []string {
// NDK libraries can't have any dependencies
return nil
}
func (*ndkPrebuiltLibrary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps { func (*ndkPrebuiltLibrary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
// NDK libraries can't have any dependencies // NDK libraries can't have any dependencies
return CCDeps{} return CCDeps{}
@@ -1896,7 +1879,7 @@ func (c *ndkPrebuiltStl) compileModule(ctx common.AndroidModuleContext, flags CC
c.out = libDir + "/" + libName + libExt c.out = libDir + "/" + libName + libExt
} }
func LinkageMutator(mctx blueprint.EarlyMutatorContext) { func linkageMutator(mctx common.AndroidBottomUpMutatorContext) {
if c, ok := mctx.Module().(ccLinkedInterface); ok { if c, ok := mctx.Module().(ccLinkedInterface); ok {
var modules []blueprint.Module var modules []blueprint.Module
if c.buildStatic() && c.buildShared() { if c.buildStatic() && c.buildShared() {

View File

@@ -20,15 +20,13 @@ import (
"runtime" "runtime"
"strings" "strings"
"android/soong"
"github.com/google/blueprint" "github.com/google/blueprint"
"github.com/google/blueprint/proptools" "github.com/google/blueprint/proptools"
) )
func init() { func init() {
soong.RegisterEarlyMutator("host_or_device", HostOrDeviceMutator) RegisterBottomUpMutator("host_or_device", HostOrDeviceMutator)
soong.RegisterEarlyMutator("arch", ArchMutator) RegisterBottomUpMutator("arch", ArchMutator)
} }
var ( var (
@@ -303,7 +301,7 @@ var (
} }
) )
func HostOrDeviceMutator(mctx blueprint.EarlyMutatorContext) { func HostOrDeviceMutator(mctx AndroidBottomUpMutatorContext) {
var module AndroidModule var module AndroidModule
var ok bool var ok bool
if module, ok = mctx.Module().(AndroidModule); !ok { if module, ok = mctx.Module().(AndroidModule); !ok {
@@ -335,7 +333,7 @@ func HostOrDeviceMutator(mctx blueprint.EarlyMutatorContext) {
} }
} }
func ArchMutator(mctx blueprint.EarlyMutatorContext) { func ArchMutator(mctx AndroidBottomUpMutatorContext) {
var module AndroidModule var module AndroidModule
var ok bool var ok bool
if module, ok = mctx.Module().(AndroidModule); !ok { if module, ok = mctx.Module().(AndroidModule); !ok {
@@ -426,7 +424,7 @@ func InitArchModule(m AndroidModule, defaultMultilib Multilib,
var dashToUnderscoreReplacer = strings.NewReplacer("-", "_") var dashToUnderscoreReplacer = strings.NewReplacer("-", "_")
func (a *AndroidModuleBase) appendProperties(ctx blueprint.EarlyMutatorContext, func (a *AndroidModuleBase) appendProperties(ctx AndroidBottomUpMutatorContext,
dst, src interface{}, field, srcPrefix string) { dst, src interface{}, field, srcPrefix string) {
src = reflect.ValueOf(src).FieldByName(field).Elem().Interface() src = reflect.ValueOf(src).FieldByName(field).Elem().Interface()
@@ -459,7 +457,7 @@ func (a *AndroidModuleBase) appendProperties(ctx blueprint.EarlyMutatorContext,
} }
// Rewrite the module's properties structs to contain arch-specific values. // Rewrite the module's properties structs to contain arch-specific values.
func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext) { func (a *AndroidModuleBase) setArchProperties(ctx AndroidBottomUpMutatorContext) {
arch := a.commonProperties.CompileArch arch := a.commonProperties.CompileArch
hod := a.commonProperties.CompileHostOrDevice hod := a.commonProperties.CompileHostOrDevice

View File

@@ -72,15 +72,6 @@ type AndroidModule interface {
HostOrDevice() HostOrDevice HostOrDevice() HostOrDevice
} }
type AndroidDynamicDepender interface {
AndroidDynamicDependencies(ctx AndroidDynamicDependerModuleContext) []string
}
type AndroidDynamicDependerModuleContext interface {
blueprint.DynamicDependerModuleContext
androidBaseContext
}
type commonProperties struct { type commonProperties struct {
Name string Name string
Deps []string Deps []string
@@ -313,33 +304,20 @@ func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
} }
} }
func (a *AndroidModuleBase) DynamicDependencies(ctx blueprint.DynamicDependerModuleContext) []string { func (a *AndroidModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
actx := &androidDynamicDependerContext{ return androidBaseContextImpl{
DynamicDependerModuleContext: ctx, arch: a.commonProperties.CompileArch,
androidBaseContextImpl: androidBaseContextImpl{ hod: a.commonProperties.CompileHostOrDevice,
arch: a.commonProperties.CompileArch, config: ctx.Config().(Config),
hod: a.commonProperties.CompileHostOrDevice,
config: ctx.Config().(Config),
},
} }
if dynamic, ok := a.module.(AndroidDynamicDepender); ok {
return dynamic.AndroidDynamicDependencies(actx)
}
return nil
} }
func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) { func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
androidCtx := &androidModuleContext{ androidCtx := &androidModuleContext{
ModuleContext: ctx, ModuleContext: ctx,
androidBaseContextImpl: androidBaseContextImpl{ androidBaseContextImpl: a.androidBaseContextFactory(ctx),
arch: a.commonProperties.CompileArch, installDeps: a.computeInstallDeps(ctx),
hod: a.commonProperties.CompileHostOrDevice, installFiles: a.installFiles,
config: ctx.Config().(Config),
},
installDeps: a.computeInstallDeps(ctx),
installFiles: a.installFiles,
} }
if a.commonProperties.Disabled { if a.commonProperties.Disabled {
@@ -443,11 +421,6 @@ func (a *androidModuleContext) CheckbuildFile(srcPath string) {
a.checkbuildFiles = append(a.checkbuildFiles, srcPath) a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
} }
type androidDynamicDependerContext struct {
blueprint.DynamicDependerModuleContext
androidBaseContextImpl
}
type fileInstaller interface { type fileInstaller interface {
filesToInstall() []string filesToInstall() []string
} }

69
common/mutator.go Normal file
View File

@@ -0,0 +1,69 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package common
import (
"android/soong"
"github.com/google/blueprint"
)
type AndroidTopDownMutator func(AndroidTopDownMutatorContext)
type AndroidTopDownMutatorContext interface {
blueprint.TopDownMutatorContext
androidBaseContext
}
type androidTopDownMutatorContext struct {
blueprint.TopDownMutatorContext
androidBaseContextImpl
}
type AndroidBottomUpMutator func(AndroidBottomUpMutatorContext)
type AndroidBottomUpMutatorContext interface {
blueprint.BottomUpMutatorContext
androidBaseContext
}
type androidBottomUpMutatorContext struct {
blueprint.BottomUpMutatorContext
androidBaseContextImpl
}
func RegisterBottomUpMutator(name string, mutator AndroidBottomUpMutator) {
soong.RegisterBottomUpMutator(name, func(ctx blueprint.BottomUpMutatorContext) {
if a, ok := ctx.Module().(AndroidModule); ok {
actx := &androidBottomUpMutatorContext{
BottomUpMutatorContext: ctx,
androidBaseContextImpl: a.base().androidBaseContextFactory(ctx),
}
mutator(actx)
}
})
}
func RegisterTopDownMutator(name string, mutator AndroidTopDownMutator) {
soong.RegisterTopDownMutator(name, func(ctx blueprint.TopDownMutatorContext) {
if a, ok := ctx.Module().(AndroidModule); ok {
actx := &androidTopDownMutatorContext{
TopDownMutatorContext: ctx,
androidBaseContextImpl: a.base().androidBaseContextFactory(ctx),
}
mutator(actx)
}
})
}

View File

@@ -19,14 +19,11 @@ import (
"reflect" "reflect"
"strings" "strings"
"android/soong"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools" "github.com/google/blueprint/proptools"
) )
func init() { func init() {
soong.RegisterEarlyMutator("variable", VariableMutator) RegisterBottomUpMutator("variable", variableMutator)
} }
type variableProperties struct { type variableProperties struct {
@@ -104,7 +101,7 @@ func (v *productVariables) SetDefaultConfig() {
} }
} }
func VariableMutator(mctx blueprint.EarlyMutatorContext) { func variableMutator(mctx AndroidBottomUpMutatorContext) {
var module AndroidModule var module AndroidModule
var ok bool var ok bool
if module, ok = mctx.Module().(AndroidModule); !ok { if module, ok = mctx.Module().(AndroidModule); !ok {
@@ -144,7 +141,7 @@ func VariableMutator(mctx blueprint.EarlyMutatorContext) {
} }
} }
func (a *AndroidModuleBase) setVariableProperties(ctx blueprint.EarlyMutatorContext, func (a *AndroidModuleBase) setVariableProperties(ctx AndroidBottomUpMutatorContext,
prefix string, productVariablePropertyValue reflect.Value, variableValue interface{}) { prefix string, productVariablePropertyValue reflect.Value, variableValue interface{}) {
if variableValue != nil { if variableValue != nil {

View File

@@ -27,6 +27,8 @@ import (
func init() { func init() {
soong.RegisterModuleType("gensrcs", GenSrcsFactory) soong.RegisterModuleType("gensrcs", GenSrcsFactory)
soong.RegisterModuleType("genrule", GenRuleFactory) soong.RegisterModuleType("genrule", GenRuleFactory)
common.RegisterBottomUpMutator("genrule_deps", genruleDepsMutator)
} }
var ( var (
@@ -83,12 +85,13 @@ func (g *generator) GeneratedSourceFiles() []string {
return g.outputFiles return g.outputFiles
} }
func (g *generator) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string { func genruleDepsMutator(ctx common.AndroidBottomUpMutatorContext) {
if g.properties.Tool != "" { if g, ok := ctx.Module().(*generator); ok {
ctx.AddFarVariationDependencies([]blueprint.Variation{{"hostordevice", common.Host.String()}}, if g.properties.Tool != "" {
g.properties.Tool) ctx.AddFarVariationDependencies([]blueprint.Variation{{"hostordevice", common.Host.String()}},
g.properties.Tool)
}
} }
return nil
} }
func (g *generator) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) { func (g *generator) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {

View File

@@ -67,8 +67,8 @@ type AndroidApp struct {
exportPackage string exportPackage string
} }
func (a *AndroidApp) JavaDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string { func (a *AndroidApp) JavaDependencies(ctx AndroidJavaModuleContext) []string {
deps := a.javaBase.JavaDynamicDependencies(ctx) deps := a.javaBase.JavaDependencies(ctx)
if !a.properties.No_standard_libraries { if !a.properties.No_standard_libraries {
switch a.properties.Sdk_version { // TODO: Res_sdk_version? switch a.properties.Sdk_version { // TODO: Res_sdk_version?

View File

@@ -145,9 +145,11 @@ type javaBase struct {
installFile string installFile string
} }
type AndroidJavaModuleContext common.AndroidBaseContext
type JavaModuleType interface { type JavaModuleType interface {
GenerateJavaBuildActions(ctx common.AndroidModuleContext) GenerateJavaBuildActions(ctx common.AndroidModuleContext)
JavaDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string JavaDependencies(ctx AndroidJavaModuleContext) []string
} }
type JavaDependency interface { type JavaDependency interface {
@@ -191,11 +193,13 @@ func (j *javaBase) BootClasspath(ctx common.AndroidBaseContext) string {
var defaultJavaLibraries = []string{"core-libart", "core-junit", "ext", "framework"} var defaultJavaLibraries = []string{"core-libart", "core-junit", "ext", "framework"}
func (j *javaBase) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string { func javaDepsMutator(ctx common.AndroidBottomUpMutatorContext) {
return j.module.JavaDynamicDependencies(ctx) if j, ok := ctx.Module().(JavaModuleType); ok {
ctx.AddDependency(ctx.Module(), j.JavaDependencies(ctx)...)
}
} }
func (j *javaBase) JavaDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string { func (j *javaBase) JavaDependencies(ctx AndroidJavaModuleContext) []string {
var deps []string var deps []string
if !j.properties.No_standard_libraries { if !j.properties.No_standard_libraries {

View File

@@ -30,12 +30,13 @@ type singleton struct {
var singletons []singleton var singletons []singleton
type earlyMutator struct { type mutator struct {
name string name string
mutator blueprint.EarlyMutator bottomUpMutator blueprint.BottomUpMutator
topDownMutator blueprint.TopDownMutator
} }
var earlyMutators []earlyMutator var mutators []mutator
func RegisterModuleType(name string, factory blueprint.ModuleFactory) { func RegisterModuleType(name string, factory blueprint.ModuleFactory) {
moduleTypes = append(moduleTypes, moduleType{name, factory}) moduleTypes = append(moduleTypes, moduleType{name, factory})
@@ -45,8 +46,12 @@ func RegisterSingletonType(name string, factory blueprint.SingletonFactory) {
singletons = append(singletons, singleton{name, factory}) singletons = append(singletons, singleton{name, factory})
} }
func RegisterEarlyMutator(name string, mutator blueprint.EarlyMutator) { func RegisterBottomUpMutator(name string, m blueprint.BottomUpMutator) {
earlyMutators = append(earlyMutators, earlyMutator{name, mutator}) mutators = append(mutators, mutator{name: name, bottomUpMutator: m})
}
func RegisterTopDownMutator(name string, m blueprint.TopDownMutator) {
mutators = append(mutators, mutator{name: name, topDownMutator: m})
} }
func NewContext() *blueprint.Context { func NewContext() *blueprint.Context {
@@ -60,8 +65,13 @@ func NewContext() *blueprint.Context {
ctx.RegisterSingletonType(t.name, t.factory) ctx.RegisterSingletonType(t.name, t.factory)
} }
for _, t := range earlyMutators { for _, t := range mutators {
ctx.RegisterEarlyMutator(t.name, t.mutator) if t.bottomUpMutator != nil {
ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator)
}
if t.topDownMutator != nil {
ctx.RegisterTopDownMutator(t.name, t.topDownMutator)
}
} }
return ctx return ctx