From 1b115d32b4f546261e007a18dfe8ff2bcdc187f2 Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Wed, 29 Apr 2020 16:47:28 +0100 Subject: Add hook to be called after defaults have been applied Previously, the only way for a module type to create modules (other than defining its own mutator) was to register a LoadHook. However, that is called before defaults are applied so any properties used in that hook cannot take advantage of defaults, e.g. java_sdk_library cannot use defaults to set its sdk_version property and have that affect its child modules. This change adds a new SetDefaultableHook() to DefaultableModule to register a hook that is called after any defaults have been applied. Also adds some tests to ensure that errors in the visibility property introduced in a DefaultableHook are reported in the gather phase of visibility processing. A follow up change will switch java_sdk_library to use that instead of the AddLoadHook() mechanism. Bug: 155295806 Test: m checkapi Merged-In: I13df3115f9e225f7324b6725eaeb16a78cc2538a Change-Id: I13df3115f9e225f7324b6725eaeb16a78cc2538a (cherry picked from commit afa9fa104d932821f779db02acccb8a09f0c6896) --- android/defaults.go | 71 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 18 deletions(-) (limited to 'android/defaults.go') diff --git a/android/defaults.go b/android/defaults.go index 6a908ea8..81e340e8 100644 --- a/android/defaults.go +++ b/android/defaults.go @@ -35,6 +35,9 @@ type DefaultableModuleBase struct { defaultsProperties defaultsProperties defaultableProperties []interface{} defaultableVariableProperties interface{} + + // The optional hook to call after any defaults have been applied. + hook DefaultableHook } func (d *DefaultableModuleBase) defaults() *defaultsProperties { @@ -46,6 +49,16 @@ func (d *DefaultableModuleBase) setProperties(props []interface{}, variablePrope d.defaultableVariableProperties = variableProperties } +func (d *DefaultableModuleBase) SetDefaultableHook(hook DefaultableHook) { + d.hook = hook +} + +func (d *DefaultableModuleBase) callHookIfAvailable(ctx DefaultableHookContext) { + if d.hook != nil { + d.hook(ctx) + } +} + // Interface that must be supported by any module to which defaults can be applied. type Defaultable interface { // Get a pointer to the struct containing the Defaults property. @@ -57,6 +70,15 @@ type Defaultable interface { // Apply defaults from the supplied Defaults to the property structures supplied to // setProperties(...). applyDefaults(TopDownMutatorContext, []Defaults) + + // Set the hook to be called after any defaults have been applied. + // + // Should be used in preference to a AddLoadHook when the behavior of the load + // hook is dependent on properties supplied in the Android.bp file. + SetDefaultableHook(hook DefaultableHook) + + // Call the hook if specified. + callHookIfAvailable(context DefaultableHookContext) } type DefaultableModule interface { @@ -75,6 +97,15 @@ func InitDefaultableModule(module DefaultableModule) { module.AddProperties(module.defaults()) } +// A restricted subset of context methods, similar to LoadHookContext. +type DefaultableHookContext interface { + EarlyModuleContext + + CreateModule(ModuleFactory, ...interface{}) Module +} + +type DefaultableHook func(ctx DefaultableHookContext) + // The Defaults_visibility property. type DefaultsVisibilityProperties struct { @@ -268,25 +299,29 @@ func defaultsDepsMutator(ctx BottomUpMutatorContext) { } func defaultsMutator(ctx TopDownMutatorContext) { - if defaultable, ok := ctx.Module().(Defaultable); ok && len(defaultable.defaults().Defaults) > 0 { - var defaultsList []Defaults - seen := make(map[Defaults]bool) - - ctx.WalkDeps(func(module, parent Module) bool { - if ctx.OtherModuleDependencyTag(module) == DefaultsDepTag { - if defaults, ok := module.(Defaults); ok { - if !seen[defaults] { - seen[defaults] = true - defaultsList = append(defaultsList, defaults) - return len(defaults.defaults().Defaults) > 0 + if defaultable, ok := ctx.Module().(Defaultable); ok { + if len(defaultable.defaults().Defaults) > 0 { + var defaultsList []Defaults + seen := make(map[Defaults]bool) + + ctx.WalkDeps(func(module, parent Module) bool { + if ctx.OtherModuleDependencyTag(module) == DefaultsDepTag { + if defaults, ok := module.(Defaults); ok { + if !seen[defaults] { + seen[defaults] = true + defaultsList = append(defaultsList, defaults) + return len(defaults.defaults().Defaults) > 0 + } + } else { + ctx.PropertyErrorf("defaults", "module %s is not an defaults module", + ctx.OtherModuleName(module)) } - } else { - ctx.PropertyErrorf("defaults", "module %s is not an defaults module", - ctx.OtherModuleName(module)) } - } - return false - }) - defaultable.applyDefaults(ctx, defaultsList) + return false + }) + defaultable.applyDefaults(ctx, defaultsList) + } + + defaultable.callHookIfAvailable(ctx) } } -- cgit v1.2.3