Convert trivial TopDown mutators to BottomUp

Many TopDown mutators can be easily converted to BottomUp mutators,
which are easier to handle for incremental and partial analysis.

Bug: 367784740
Test: all soong tests pass
Test: no change to build.ninja
Flag: EXEMPT refactor
Change-Id: I82955e844ed0eb6680854678c0744ac5398eb7ba
diff --git a/android/defaults.go b/android/defaults.go
index 0d51d9d..d3dbaed 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -69,7 +69,7 @@
 
 	// Apply defaults from the supplied Defaults to the property structures supplied to
 	// setProperties(...).
-	applyDefaults(TopDownMutatorContext, []Defaults)
+	applyDefaults(BottomUpMutatorContext, []Defaults)
 
 	// Set the hook to be called after any defaults have been applied.
 	//
@@ -209,7 +209,7 @@
 
 var _ Defaults = (*DefaultsModuleBase)(nil)
 
-func (defaultable *DefaultableModuleBase) applyDefaults(ctx TopDownMutatorContext,
+func (defaultable *DefaultableModuleBase) applyDefaults(ctx BottomUpMutatorContext,
 	defaultsList []Defaults) {
 
 	for _, defaults := range defaultsList {
@@ -226,7 +226,7 @@
 // Product variable properties need special handling, the type of the filtered product variable
 // property struct may not be identical between the defaults module and the defaultable module.
 // Use PrependMatchingProperties to apply whichever properties match.
-func (defaultable *DefaultableModuleBase) applyDefaultVariableProperties(ctx TopDownMutatorContext,
+func (defaultable *DefaultableModuleBase) applyDefaultVariableProperties(ctx BottomUpMutatorContext,
 	defaults Defaults, defaultableProp interface{}) {
 	if defaultableProp == nil {
 		return
@@ -254,7 +254,7 @@
 	}
 }
 
-func (defaultable *DefaultableModuleBase) applyDefaultProperties(ctx TopDownMutatorContext,
+func (defaultable *DefaultableModuleBase) applyDefaultProperties(ctx BottomUpMutatorContext,
 	defaults Defaults, defaultableProp interface{}) {
 
 	for _, def := range defaults.properties() {
@@ -273,7 +273,7 @@
 
 func RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) {
 	ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
-	ctx.TopDown("defaults", defaultsMutator).Parallel()
+	ctx.BottomUp("defaults", defaultsMutator).Parallel()
 }
 
 func defaultsDepsMutator(ctx BottomUpMutatorContext) {
@@ -282,8 +282,12 @@
 	}
 }
 
-func defaultsMutator(ctx TopDownMutatorContext) {
+func defaultsMutator(ctx BottomUpMutatorContext) {
 	if defaultable, ok := ctx.Module().(Defaultable); ok {
+		if _, isDefaultsModule := ctx.Module().(Defaults); isDefaultsModule {
+			// Don't squash transitive defaults into defaults modules
+			return
+		}
 		defaults := defaultable.defaults().Defaults
 		if len(defaults) > 0 {
 			var defaultsList []Defaults
diff --git a/android/mutator.go b/android/mutator.go
index 2ef4d7f..6f8990d 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -193,16 +193,16 @@
 	// Rename all variants of a module.  The new name is not visible to calls to ModuleName,
 	// AddDependency or OtherModuleName until after this mutator pass is complete.
 	Rename(name string)
+
+	// CreateModule creates a new module by calling the factory method for the specified moduleType, and applies
+	// the specified property structs to it as if the properties were set in a blueprint file.
+	CreateModule(ModuleFactory, ...interface{}) Module
 }
 
 type TopDownMutator func(TopDownMutatorContext)
 
 type TopDownMutatorContext interface {
 	BaseMutatorContext
-
-	// CreateModule creates a new module by calling the factory method for the specified moduleType, and applies
-	// the specified property structs to it as if the properties were set in a blueprint file.
-	CreateModule(ModuleFactory, ...interface{}) Module
 }
 
 type topDownMutatorContext struct {
@@ -739,6 +739,14 @@
 	b.Module().base().commonProperties.DebugName = name
 }
 
+func (b *bottomUpMutatorContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) blueprint.Module {
+	return b.bp.CreateModule(factory, name, props...)
+}
+
+func (b *bottomUpMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module {
+	return createModule(b, factory, "_bottomUpMutatorModule", props...)
+}
+
 func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module {
 	if b.baseModuleContext.checkedMissingDeps() {
 		panic("Adding deps not allowed after checking for missing deps")
diff --git a/android/visibility.go b/android/visibility.go
index 89c0adc..61f2200 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -283,7 +283,7 @@
 
 // This must be registered after the deps have been resolved.
 func RegisterVisibilityRuleEnforcer(ctx RegisterMutatorsContext) {
-	ctx.TopDown("visibilityRuleEnforcer", visibilityRuleEnforcer).Parallel()
+	ctx.BottomUp("visibilityRuleEnforcer", visibilityRuleEnforcer).Parallel()
 }
 
 // Checks the per-module visibility rule lists before defaults expansion.
@@ -507,7 +507,7 @@
 	return true, pkg, name
 }
 
-func visibilityRuleEnforcer(ctx TopDownMutatorContext) {
+func visibilityRuleEnforcer(ctx BottomUpMutatorContext) {
 	qualified := createVisibilityModuleReference(ctx.ModuleName(), ctx.ModuleDir(), ctx.Module())
 
 	// Visit all the dependencies making sure that this module has access to them all.
diff --git a/apex/apex.go b/apex/apex.go
index c12d1e4..9e3f288 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -55,11 +55,10 @@
 }
 
 func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
-	ctx.TopDown("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
+	ctx.BottomUp("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
 }
 
 func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
-	ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
 	ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
 }
 
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index f1a134e..792b571 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -265,7 +265,7 @@
 // prebuiltApexModuleCreator defines the methods that need to be implemented by prebuilt_apex and
 // apex_set in order to create the modules needed to provide access to the prebuilt .apex file.
 type prebuiltApexModuleCreator interface {
-	createPrebuiltApexModules(ctx android.TopDownMutatorContext)
+	createPrebuiltApexModules(ctx android.BottomUpMutatorContext)
 }
 
 // prebuiltApexModuleCreatorMutator is the mutator responsible for invoking the
@@ -275,7 +275,7 @@
 // will need to access dependencies added by that (exported modules) but must run before the
 // DepsMutator so that the deapexer module it creates can add dependencies onto itself from the
 // exported modules.
-func prebuiltApexModuleCreatorMutator(ctx android.TopDownMutatorContext) {
+func prebuiltApexModuleCreatorMutator(ctx android.BottomUpMutatorContext) {
 	module := ctx.Module()
 	if creator, ok := module.(prebuiltApexModuleCreator); ok {
 		creator.createPrebuiltApexModules(ctx)
@@ -543,7 +543,7 @@
 	return module
 }
 
-func createApexSelectorModule(ctx android.TopDownMutatorContext, name string, apexFileProperties *ApexFileProperties) {
+func createApexSelectorModule(ctx android.BottomUpMutatorContext, name string, apexFileProperties *ApexFileProperties) {
 	props := struct {
 		Name *string
 	}{
@@ -561,7 +561,7 @@
 // A deapexer module is only needed when the prebuilt apex specifies one or more modules in either
 // the `exported_java_libs` or `exported_bootclasspath_fragments` properties as that indicates that
 // the listed modules need access to files from within the prebuilt .apex file.
-func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string) {
+func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.BottomUpMutatorContext, deapexerName string, apexFileSource string) {
 	// Only create the deapexer module if it is needed.
 	if !p.hasExportedDeps() {
 		return
@@ -703,7 +703,7 @@
 //     /         |         \
 //     V            V            V
 //     selector  <---  deapexer  <---  exported java lib
-func (p *Prebuilt) createPrebuiltApexModules(ctx android.TopDownMutatorContext) {
+func (p *Prebuilt) createPrebuiltApexModules(ctx android.BottomUpMutatorContext) {
 	apexSelectorModuleName := apexSelectorModuleName(p.Name())
 	createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties)
 
@@ -958,7 +958,7 @@
 	return module
 }
 
-func createApexExtractorModule(ctx android.TopDownMutatorContext, name string, apexExtractorProperties *ApexExtractorProperties) {
+func createApexExtractorModule(ctx android.BottomUpMutatorContext, name string, apexExtractorProperties *ApexExtractorProperties) {
 	props := struct {
 		Name *string
 	}{
@@ -984,7 +984,7 @@
 // prebuilt_apex except that instead of creating a selector module which selects one .apex file
 // from those provided this creates an extractor module which extracts the appropriate .apex file
 // from the zip file containing them.
-func (a *ApexSet) createPrebuiltApexModules(ctx android.TopDownMutatorContext) {
+func (a *ApexSet) createPrebuiltApexModules(ctx android.BottomUpMutatorContext) {
 	apexExtractorModuleName := apexExtractorModuleName(a.Name())
 	createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties)
 
diff --git a/apex/vndk.go b/apex/vndk.go
index 781aa3c..3ececc5 100644
--- a/apex/vndk.go
+++ b/apex/vndk.go
@@ -54,30 +54,6 @@
 	Vndk_version *string
 }
 
-func apexVndkMutator(mctx android.TopDownMutatorContext) {
-	if ab, ok := mctx.Module().(*apexBundle); ok && ab.vndkApex {
-		if ab.IsNativeBridgeSupported() {
-			mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType())
-		}
-
-		vndkVersion := ab.vndkVersion()
-		if vndkVersion != "" {
-			apiLevel, err := android.ApiLevelFromUser(mctx, vndkVersion)
-			if err != nil {
-				mctx.PropertyErrorf("vndk_version", "%s", err.Error())
-				return
-			}
-
-			targets := mctx.MultiTargets()
-			if len(targets) > 0 && apiLevel.LessThan(cc.MinApiForArch(mctx, targets[0].Arch.ArchType)) {
-				// Disable VNDK APEXes for VNDK versions less than the minimum supported API
-				// level for the primary architecture.
-				ab.Disable()
-			}
-		}
-	}
-}
-
 func apexVndkDepsMutator(mctx android.BottomUpMutatorContext) {
 	if m, ok := mctx.Module().(*cc.Module); ok && cc.IsForVndkApex(mctx, m) {
 		vndkVersion := m.VndkVersion()
@@ -93,8 +69,27 @@
 			mctx.AddReverseDependency(mctx.Module(), sharedLibTag, vndkApexName)
 		}
 	} else if a, ok := mctx.Module().(*apexBundle); ok && a.vndkApex {
-		vndkVersion := proptools.StringDefault(a.vndkProperties.Vndk_version, "current")
-		mctx.AddDependency(mctx.Module(), prebuiltTag, cc.VndkLibrariesTxtModules(vndkVersion, mctx)...)
+		if a.IsNativeBridgeSupported() {
+			mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType())
+		}
+
+		vndkVersion := a.vndkVersion()
+		if vndkVersion != "" {
+			apiLevel, err := android.ApiLevelFromUser(mctx, vndkVersion)
+			if err != nil {
+				mctx.PropertyErrorf("vndk_version", "%s", err.Error())
+				return
+			}
+
+			targets := mctx.MultiTargets()
+			if len(targets) > 0 && apiLevel.LessThan(cc.MinApiForArch(mctx, targets[0].Arch.ArchType)) {
+				// Disable VNDK APEXes for VNDK versions less than the minimum supported API
+				// level for the primary architecture.
+				a.Disable()
+			} else {
+				mctx.AddDependency(mctx.Module(), prebuiltTag, cc.VndkLibrariesTxtModules(vndkVersion, mctx)...)
+			}
+		}
 	}
 }
 
diff --git a/cc/cc.go b/cc/cc.go
index 6e16142..96795d3 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -59,10 +59,10 @@
 			san.registerMutators(ctx)
 		}
 
-		ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel()
+		ctx.BottomUp("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel()
 		ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
 
-		ctx.TopDown("fuzz_deps", fuzzMutatorDeps)
+		ctx.BottomUp("fuzz_deps", fuzzMutatorDeps)
 
 		ctx.Transition("coverage", &coverageTransitionMutator{})
 
@@ -73,7 +73,7 @@
 		ctx.Transition("lto", &ltoTransitionMutator{})
 
 		ctx.BottomUp("check_linktype", checkLinkTypeMutator).Parallel()
-		ctx.TopDown("double_loadable", checkDoubleLoadableLibraries).Parallel()
+		ctx.BottomUp("double_loadable", checkDoubleLoadableLibraries).Parallel()
 	})
 
 	ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
@@ -2783,7 +2783,7 @@
 // If a library has a vendor variant and is a (transitive) dependency of an LLNDK library,
 // it is subject to be double loaded. Such lib should be explicitly marked as double_loadable: true
 // or as vndk-sp (vndk: { enabled: true, support_system_process: true}).
-func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) {
+func checkDoubleLoadableLibraries(ctx android.BottomUpMutatorContext) {
 	check := func(child, parent android.Module) bool {
 		to, ok := child.(*Module)
 		if !ok {
diff --git a/cc/fuzz.go b/cc/fuzz.go
index d9e221b..3f21bc6 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -57,7 +57,7 @@
 	return []interface{}{&fuzzer.Properties}
 }
 
-func fuzzMutatorDeps(mctx android.TopDownMutatorContext) {
+func fuzzMutatorDeps(mctx android.BottomUpMutatorContext) {
 	currentModule, ok := mctx.Module().(*Module)
 	if !ok {
 		return
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 7b0652c..b10a3dd 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -176,7 +176,7 @@
 	switch t {
 	case cfi, Hwasan, Asan, tsan, Fuzzer, scs, Memtag_stack:
 		sanitizer := &sanitizerSplitMutator{t}
-		ctx.TopDown(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator)
+		ctx.BottomUp(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator)
 		ctx.Transition(t.variationName(), sanitizer)
 	case Memtag_heap, Memtag_globals, intOverflow:
 		// do nothing
@@ -1153,7 +1153,7 @@
 // If an APEX is sanitized or not depends on whether it contains at least one
 // sanitized module. Transition mutators cannot propagate information up the
 // dependency graph this way, so we need an auxiliary mutator to do so.
-func (s *sanitizerSplitMutator) markSanitizableApexesMutator(ctx android.TopDownMutatorContext) {
+func (s *sanitizerSplitMutator) markSanitizableApexesMutator(ctx android.BottomUpMutatorContext) {
 	if sanitizeable, ok := ctx.Module().(Sanitizeable); ok {
 		enabled := sanitizeable.IsSanitizerEnabled(ctx.Config(), s.sanitizer.name())
 		ctx.VisitDirectDeps(func(dep android.Module) {
@@ -1355,7 +1355,7 @@
 }
 
 // Propagate the ubsan minimal runtime dependency when there are integer overflow sanitized static dependencies.
-func sanitizerRuntimeDepsMutator(mctx android.TopDownMutatorContext) {
+func sanitizerRuntimeDepsMutator(mctx android.BottomUpMutatorContext) {
 	// Change this to PlatformSanitizable when/if non-cc modules support ubsan sanitizers.
 	if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
 		if c.sanitize.Properties.ForceDisable {