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
diff --git a/common/arch.go b/common/arch.go
index 0594567..f0f4409 100644
--- a/common/arch.go
+++ b/common/arch.go
@@ -20,15 +20,13 @@
 	"runtime"
 	"strings"
 
-	"android/soong"
-
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
 
 func init() {
-	soong.RegisterEarlyMutator("host_or_device", HostOrDeviceMutator)
-	soong.RegisterEarlyMutator("arch", ArchMutator)
+	RegisterBottomUpMutator("host_or_device", HostOrDeviceMutator)
+	RegisterBottomUpMutator("arch", ArchMutator)
 }
 
 var (
@@ -303,7 +301,7 @@
 	}
 )
 
-func HostOrDeviceMutator(mctx blueprint.EarlyMutatorContext) {
+func HostOrDeviceMutator(mctx AndroidBottomUpMutatorContext) {
 	var module AndroidModule
 	var ok bool
 	if module, ok = mctx.Module().(AndroidModule); !ok {
@@ -335,7 +333,7 @@
 	}
 }
 
-func ArchMutator(mctx blueprint.EarlyMutatorContext) {
+func ArchMutator(mctx AndroidBottomUpMutatorContext) {
 	var module AndroidModule
 	var ok bool
 	if module, ok = mctx.Module().(AndroidModule); !ok {
@@ -426,7 +424,7 @@
 
 var dashToUnderscoreReplacer = strings.NewReplacer("-", "_")
 
-func (a *AndroidModuleBase) appendProperties(ctx blueprint.EarlyMutatorContext,
+func (a *AndroidModuleBase) appendProperties(ctx AndroidBottomUpMutatorContext,
 	dst, src interface{}, field, srcPrefix string) {
 
 	src = reflect.ValueOf(src).FieldByName(field).Elem().Interface()
@@ -459,7 +457,7 @@
 }
 
 // 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
 	hod := a.commonProperties.CompileHostOrDevice
 
diff --git a/common/module.go b/common/module.go
index d31a9fc..1860ecb 100644
--- a/common/module.go
+++ b/common/module.go
@@ -72,15 +72,6 @@
 	HostOrDevice() HostOrDevice
 }
 
-type AndroidDynamicDepender interface {
-	AndroidDynamicDependencies(ctx AndroidDynamicDependerModuleContext) []string
-}
-
-type AndroidDynamicDependerModuleContext interface {
-	blueprint.DynamicDependerModuleContext
-	androidBaseContext
-}
-
 type commonProperties struct {
 	Name string
 	Deps []string
@@ -313,33 +304,20 @@
 	}
 }
 
-func (a *AndroidModuleBase) DynamicDependencies(ctx blueprint.DynamicDependerModuleContext) []string {
-	actx := &androidDynamicDependerContext{
-		DynamicDependerModuleContext: ctx,
-		androidBaseContextImpl: androidBaseContextImpl{
-			arch:   a.commonProperties.CompileArch,
-			hod:    a.commonProperties.CompileHostOrDevice,
-			config: ctx.Config().(Config),
-		},
+func (a *AndroidModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext) androidBaseContextImpl {
+	return androidBaseContextImpl{
+		arch:   a.commonProperties.CompileArch,
+		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) {
 	androidCtx := &androidModuleContext{
-		ModuleContext: ctx,
-		androidBaseContextImpl: androidBaseContextImpl{
-			arch:   a.commonProperties.CompileArch,
-			hod:    a.commonProperties.CompileHostOrDevice,
-			config: ctx.Config().(Config),
-		},
-		installDeps:  a.computeInstallDeps(ctx),
-		installFiles: a.installFiles,
+		ModuleContext:          ctx,
+		androidBaseContextImpl: a.androidBaseContextFactory(ctx),
+		installDeps:            a.computeInstallDeps(ctx),
+		installFiles:           a.installFiles,
 	}
 
 	if a.commonProperties.Disabled {
@@ -443,11 +421,6 @@
 	a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
 }
 
-type androidDynamicDependerContext struct {
-	blueprint.DynamicDependerModuleContext
-	androidBaseContextImpl
-}
-
 type fileInstaller interface {
 	filesToInstall() []string
 }
diff --git a/common/mutator.go b/common/mutator.go
new file mode 100644
index 0000000..43721ee
--- /dev/null
+++ b/common/mutator.go
@@ -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)
+		}
+	})
+}
diff --git a/common/variable.go b/common/variable.go
index 3949681..9a5998f 100644
--- a/common/variable.go
+++ b/common/variable.go
@@ -19,14 +19,11 @@
 	"reflect"
 	"strings"
 
-	"android/soong"
-
-	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
 
 func init() {
-	soong.RegisterEarlyMutator("variable", VariableMutator)
+	RegisterBottomUpMutator("variable", variableMutator)
 }
 
 type variableProperties struct {
@@ -104,7 +101,7 @@
 	}
 }
 
-func VariableMutator(mctx blueprint.EarlyMutatorContext) {
+func variableMutator(mctx AndroidBottomUpMutatorContext) {
 	var module AndroidModule
 	var ok bool
 	if module, ok = mctx.Module().(AndroidModule); !ok {
@@ -144,7 +141,7 @@
 	}
 }
 
-func (a *AndroidModuleBase) setVariableProperties(ctx blueprint.EarlyMutatorContext,
+func (a *AndroidModuleBase) setVariableProperties(ctx AndroidBottomUpMutatorContext,
 	prefix string, productVariablePropertyValue reflect.Value, variableValue interface{}) {
 
 	if variableValue != nil {