Use generics for providers API am: 3c0a83d19f

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/2876762

Change-Id: I27279b2ebf557d4f9395cc713b8174f00a1ddc2b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Colin Cross
2023-12-18 19:32:31 +00:00
committed by Automerger Merge Worker
12 changed files with 212 additions and 30 deletions

View File

@@ -79,6 +79,7 @@ bootstrap_go_package {
"prebuilt.go",
"prebuilt_build_tool.go",
"proto.go",
"provider.go",
"register.go",
"rule_builder.go",
"sandbox.go",

View File

@@ -159,7 +159,7 @@ type AndroidMkEntriesContext interface {
}
type AndroidMkExtraEntriesContext interface {
Provider(provider blueprint.ProviderKey) interface{}
Provider(provider blueprint.AnyProviderKey) (any, bool)
}
type androidMkExtraEntriesContext struct {
@@ -167,8 +167,8 @@ type androidMkExtraEntriesContext struct {
mod blueprint.Module
}
func (a *androidMkExtraEntriesContext) Provider(provider blueprint.ProviderKey) interface{} {
return a.ctx.ModuleProvider(a.mod, provider)
func (a *androidMkExtraEntriesContext) Provider(provider blueprint.AnyProviderKey) (any, bool) {
return a.ctx.moduleProvider(a.mod, provider)
}
type AndroidMkExtraEntriesFunc func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries)
@@ -492,8 +492,9 @@ type fillInEntriesContext interface {
ModuleDir(module blueprint.Module) string
ModuleSubDir(module blueprint.Module) string
Config() Config
ModuleProvider(module blueprint.Module, provider blueprint.ProviderKey) interface{}
ModuleHasProvider(module blueprint.Module, provider blueprint.ProviderKey) bool
ModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) any
ModuleHasProvider(module blueprint.Module, provider blueprint.AnyProviderKey) bool
moduleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
ModuleType(module blueprint.Module) string
}

View File

@@ -79,26 +79,30 @@ type BaseModuleContext interface {
// not set it returns the zero value of the type of the provider, so the return value can always
// be type asserted to the type of the provider. The value returned may be a deep copy of the
// value originally passed to SetProvider.
OtherModuleProvider(m blueprint.Module, provider blueprint.ProviderKey) interface{}
OtherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) any
// OtherModuleHasProvider returns true if the provider for the given module has been set.
OtherModuleHasProvider(m blueprint.Module, provider blueprint.ProviderKey) bool
OtherModuleHasProvider(m blueprint.Module, provider blueprint.AnyProviderKey) bool
otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
// Provider returns the value for a provider for the current module. If the value is
// not set it returns the zero value of the type of the provider, so the return value can always
// be type asserted to the type of the provider. It panics if called before the appropriate
// mutator or GenerateBuildActions pass for the provider. The value returned may be a deep
// copy of the value originally passed to SetProvider.
Provider(provider blueprint.ProviderKey) interface{}
Provider(provider blueprint.AnyProviderKey) any
// HasProvider returns true if the provider for the current module has been set.
HasProvider(provider blueprint.ProviderKey) bool
HasProvider(provider blueprint.AnyProviderKey) bool
provider(provider blueprint.AnyProviderKey) (any, bool)
// SetProvider sets the value for a provider for the current module. It panics if not called
// during the appropriate mutator or GenerateBuildActions pass for the provider, if the value
// is not of the appropriate type, or if the value has already been set. The value should not
// be modified after being passed to SetProvider.
SetProvider(provider blueprint.ProviderKey, value interface{})
SetProvider(provider blueprint.AnyProviderKey, value interface{})
GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
@@ -260,19 +264,35 @@ func (b *baseModuleContext) OtherModuleReverseDependencyVariantExists(name strin
func (b *baseModuleContext) OtherModuleType(m blueprint.Module) string {
return b.bp.OtherModuleType(m)
}
func (b *baseModuleContext) OtherModuleProvider(m blueprint.Module, provider blueprint.ProviderKey) interface{} {
func (b *baseModuleContext) OtherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) any {
value, _ := b.bp.OtherModuleProvider(m, provider)
return value
}
func (b *baseModuleContext) OtherModuleHasProvider(m blueprint.Module, provider blueprint.AnyProviderKey) bool {
_, ok := b.bp.OtherModuleProvider(m, provider)
return ok
}
func (b *baseModuleContext) otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) {
return b.bp.OtherModuleProvider(m, provider)
}
func (b *baseModuleContext) OtherModuleHasProvider(m blueprint.Module, provider blueprint.ProviderKey) bool {
return b.bp.OtherModuleHasProvider(m, provider)
func (b *baseModuleContext) Provider(provider blueprint.AnyProviderKey) any {
value, _ := b.bp.Provider(provider)
return value
}
func (b *baseModuleContext) Provider(provider blueprint.ProviderKey) interface{} {
func (b *baseModuleContext) HasProvider(provider blueprint.AnyProviderKey) bool {
_, ok := b.bp.Provider(provider)
return ok
}
func (b *baseModuleContext) provider(provider blueprint.AnyProviderKey) (any, bool) {
return b.bp.Provider(provider)
}
func (b *baseModuleContext) HasProvider(provider blueprint.ProviderKey) bool {
return b.bp.HasProvider(provider)
}
func (b *baseModuleContext) SetProvider(provider blueprint.ProviderKey, value interface{}) {
func (b *baseModuleContext) SetProvider(provider blueprint.AnyProviderKey, value any) {
b.bp.SetProvider(provider, value)
}

View File

@@ -92,7 +92,8 @@ type MakeVarsContext interface {
ModuleDir(module blueprint.Module) string
ModuleSubDir(module blueprint.Module) string
ModuleType(module blueprint.Module) string
ModuleProvider(module blueprint.Module, key blueprint.ProviderKey) interface{}
ModuleProvider(module blueprint.Module, key blueprint.AnyProviderKey) any
moduleProvider(module blueprint.Module, key blueprint.AnyProviderKey) (any, bool)
BlueprintFile(module blueprint.Module) string
ModuleErrorf(module blueprint.Module, format string, args ...interface{})

View File

@@ -325,7 +325,7 @@ type BottomUpMutatorContext interface {
// if the value is not of the appropriate type, or if the module is not a newly created
// variant of the current module. The value should not be modified after being passed to
// SetVariationProvider.
SetVariationProvider(module blueprint.Module, provider blueprint.ProviderKey, value interface{})
SetVariationProvider(module blueprint.Module, provider blueprint.AnyProviderKey, value interface{})
}
type bottomUpMutatorContext struct {
@@ -746,6 +746,6 @@ func (b *bottomUpMutatorContext) CreateAliasVariation(fromVariationName, toVaria
b.bp.CreateAliasVariation(fromVariationName, toVariationName)
}
func (b *bottomUpMutatorContext) SetVariationProvider(module blueprint.Module, provider blueprint.ProviderKey, value interface{}) {
func (b *bottomUpMutatorContext) SetVariationProvider(module blueprint.Module, provider blueprint.AnyProviderKey, value interface{}) {
b.bp.SetVariationProvider(module, provider, value)
}

120
android/provider.go Normal file
View File

@@ -0,0 +1,120 @@
package android
import (
"github.com/google/blueprint"
)
// OtherModuleProviderContext is a helper interface that is a subset of ModuleContext, BottomUpMutatorContext, or
// TopDownMutatorContext for use in OtherModuleProvider.
type OtherModuleProviderContext interface {
otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
}
var _ OtherModuleProviderContext = BaseModuleContext(nil)
var _ OtherModuleProviderContext = ModuleContext(nil)
var _ OtherModuleProviderContext = BottomUpMutatorContext(nil)
var _ OtherModuleProviderContext = TopDownMutatorContext(nil)
// OtherModuleProvider reads the provider for the given module. If the provider has been set the value is
// returned and the boolean is true. If it has not been set the zero value of the provider's type is returned
// and the boolean is false. The value returned may be a deep copy of the value originally passed to SetProvider.
//
// OtherModuleProviderContext is a helper interface that accepts ModuleContext, BottomUpMutatorContext, or
// TopDownMutatorContext.
func OtherModuleProvider[K any](ctx OtherModuleProviderContext, module blueprint.Module, provider blueprint.ProviderKey[K]) (K, bool) {
value, ok := ctx.otherModuleProvider(module, provider)
if !ok {
var k K
return k, false
}
return value.(K), ok
}
// ModuleProviderContext is a helper interface that is a subset of ModuleContext, BottomUpMutatorContext, or
// TopDownMutatorContext for use in ModuleProvider.
type ModuleProviderContext interface {
provider(provider blueprint.AnyProviderKey) (any, bool)
}
var _ ModuleProviderContext = BaseModuleContext(nil)
var _ ModuleProviderContext = ModuleContext(nil)
var _ ModuleProviderContext = BottomUpMutatorContext(nil)
var _ ModuleProviderContext = TopDownMutatorContext(nil)
// ModuleProvider reads the provider for the current module. If the provider has been set the value is
// returned and the boolean is true. If it has not been set the zero value of the provider's type is returned
// and the boolean is false. The value returned may be a deep copy of the value originally passed to SetProvider.
//
// ModuleProviderContext is a helper interface that accepts ModuleContext, BottomUpMutatorContext, or
// TopDownMutatorContext.
func ModuleProvider[K any](ctx ModuleProviderContext, provider blueprint.ProviderKey[K]) (K, bool) {
value, ok := ctx.provider(provider)
if !ok {
var k K
return k, false
}
return value.(K), ok
}
type SingletonModuleProviderContext interface {
moduleProvider(blueprint.Module, blueprint.AnyProviderKey) (any, bool)
}
var _ SingletonModuleProviderContext = SingletonContext(nil)
var _ SingletonModuleProviderContext = (*TestContext)(nil)
// SingletonModuleProvider wraps blueprint.SingletonModuleProvider to provide a type-safe method to retrieve the value
// of the given provider from a module using a SingletonContext. If the provider has not been set the first return
// value will be the zero value of the provider's type, and the second return value will be false. If the provider has
// been set the second return value will be true.
func SingletonModuleProvider[K any](ctx SingletonModuleProviderContext, module blueprint.Module, provider blueprint.ProviderKey[K]) (K, bool) {
value, ok := ctx.moduleProvider(module, provider)
if !ok {
var k K
return k, false
}
return value.(K), ok
}
// SetProviderContext is a helper interface that is a subset of ModuleContext, BottomUpMutatorContext, or
// TopDownMutatorContext for use in SetProvider.
type SetProviderContext interface {
SetProvider(provider blueprint.AnyProviderKey, value any)
}
var _ SetProviderContext = BaseModuleContext(nil)
var _ SetProviderContext = ModuleContext(nil)
var _ SetProviderContext = BottomUpMutatorContext(nil)
var _ SetProviderContext = TopDownMutatorContext(nil)
// SetProvider sets the value for a provider for the current module. It panics if not called
// during the appropriate mutator or GenerateBuildActions pass for the provider, if the value
// is not of the appropriate type, or if the value has already been set. The value should not
// be modified after being passed to SetProvider.
//
// SetProviderContext is a helper interface that accepts ModuleContext, BottomUpMutatorContext, or
// TopDownMutatorContext.
func SetProvider[K any](ctx SetProviderContext, provider blueprint.ProviderKey[K], value K) {
ctx.SetProvider(provider, value)
}
var _ OtherModuleProviderContext = (*otherModuleProviderAdaptor)(nil)
// An OtherModuleProviderFunc can be passed to NewOtherModuleProviderAdaptor to create an OtherModuleProviderContext
// for use in tests.
type OtherModuleProviderFunc func(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
type otherModuleProviderAdaptor struct {
otherModuleProviderFunc OtherModuleProviderFunc
}
func (p *otherModuleProviderAdaptor) otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) {
return p.otherModuleProviderFunc(module, provider)
}
// NewOtherModuleProviderAdaptor returns an OtherModuleProviderContext that proxies calls to otherModuleProvider to
// the provided OtherModuleProviderFunc. It can be used in tests to unit test methods that need to call
// android.OtherModuleProvider.
func NewOtherModuleProviderAdaptor(otherModuleProviderFunc OtherModuleProviderFunc) OtherModuleProviderContext {
return &otherModuleProviderAdaptor{otherModuleProviderFunc}
}

View File

@@ -20,6 +20,8 @@ import (
// SingletonContext
type SingletonContext interface {
blueprintSingletonContext() blueprint.SingletonContext
Config() Config
DeviceConfig() DeviceConfig
@@ -38,10 +40,12 @@ type SingletonContext interface {
// return value can always be type-asserted to the type of the provider. The return value should
// always be considered read-only. It panics if called before the appropriate mutator or
// GenerateBuildActions pass for the provider on the module.
ModuleProvider(module blueprint.Module, provider blueprint.ProviderKey) interface{}
ModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) any
// ModuleHasProvider returns true if the provider for the given module has been set.
ModuleHasProvider(module blueprint.Module, provider blueprint.ProviderKey) bool
ModuleHasProvider(module blueprint.Module, provider blueprint.AnyProviderKey) bool
moduleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
ModuleErrorf(module blueprint.Module, format string, args ...interface{})
Errorf(format string, args ...interface{})
@@ -135,6 +139,10 @@ type singletonContextAdaptor struct {
ruleParams map[blueprint.Rule]blueprint.RuleParams
}
func (s *singletonContextAdaptor) blueprintSingletonContext() blueprint.SingletonContext {
return s.SingletonContext
}
func (s *singletonContextAdaptor) Config() Config {
return s.SingletonContext.Config().(Config)
}
@@ -282,3 +290,18 @@ func (s *singletonContextAdaptor) ModuleVariantsFromName(referer Module, name st
}
return result
}
func (s *singletonContextAdaptor) ModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) any {
value, _ := s.SingletonContext.ModuleProvider(module, provider)
return value
}
// ModuleHasProvider returns true if the provider for the given module has been set.
func (s *singletonContextAdaptor) ModuleHasProvider(module blueprint.Module, provider blueprint.AnyProviderKey) bool {
_, ok := s.SingletonContext.ModuleProvider(module, provider)
return ok
}
func (s *singletonContextAdaptor) moduleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) {
return s.SingletonContext.ModuleProvider(module, provider)
}

View File

@@ -203,7 +203,17 @@ func (ctx *TestContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
ctx.PreArchMutators(f)
}
func (ctx *TestContext) ModuleProvider(m blueprint.Module, p blueprint.ProviderKey) interface{} {
func (ctx *TestContext) ModuleProvider(m blueprint.Module, p blueprint.AnyProviderKey) any {
value, _ := ctx.Context.ModuleProvider(m, p)
return value
}
func (ctx *TestContext) ModuleHasProvider(m blueprint.Module, p blueprint.AnyProviderKey) bool {
_, ok := ctx.Context.ModuleProvider(m, p)
return ok
}
func (ctx *TestContext) moduleProvider(m blueprint.Module, p blueprint.AnyProviderKey) (any, bool) {
return ctx.Context.ModuleProvider(m, p)
}
@@ -225,6 +235,12 @@ func (ctx *TestContext) PreArchBp2BuildMutators(f RegisterMutatorFunc) {
ctx.bp2buildPreArch = append(ctx.bp2buildPreArch, f)
}
func (ctx *TestContext) OtherModuleProviderAdaptor() OtherModuleProviderContext {
return NewOtherModuleProviderAdaptor(func(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) {
return ctx.moduleProvider(module, provider)
})
}
// registeredComponentOrder defines the order in which a sortableComponent type is registered at
// runtime and provides support for reordering the components registered for a test in the same
// way.

View File

@@ -33,11 +33,11 @@ type testClasspathElementContext struct {
errs []error
}
func (t *testClasspathElementContext) OtherModuleHasProvider(module blueprint.Module, provider blueprint.ProviderKey) bool {
func (t *testClasspathElementContext) OtherModuleHasProvider(module blueprint.Module, provider blueprint.AnyProviderKey) bool {
return t.testContext.ModuleHasProvider(module, provider)
}
func (t *testClasspathElementContext) OtherModuleProvider(module blueprint.Module, provider blueprint.ProviderKey) interface{} {
func (t *testClasspathElementContext) OtherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) interface{} {
return t.testContext.ModuleProvider(module, provider)
}

View File

@@ -26,7 +26,7 @@ const bloatyDescriptorExt = ".bloaty.csv"
const protoFilename = "binary_sizes.pb.gz"
var (
fileSizeMeasurerKey blueprint.ProviderKey
fileSizeMeasurerKey blueprint.ProviderKey[measuredFiles]
pctx = android.NewPackageContext("android/soong/bloaty")
// bloaty is used to measure a binary section sizes.

View File

@@ -49,7 +49,7 @@ var prepareForTsanTest = android.FixtureAddFile("tsan/Android.bp", []byte(`
`))
type providerInterface interface {
ModuleProvider(blueprint.Module, blueprint.ProviderKey) interface{}
ModuleProvider(blueprint.Module, blueprint.AnyProviderKey) interface{}
}
// expectSharedLinkDep verifies that the from module links against the to module as a

View File

@@ -72,8 +72,8 @@ var _ ClasspathElement = (*ClasspathLibraryElement)(nil)
// ClasspathElementContext defines the context methods needed by CreateClasspathElements
type ClasspathElementContext interface {
OtherModuleHasProvider(m blueprint.Module, provider blueprint.ProviderKey) bool
OtherModuleProvider(m blueprint.Module, provider blueprint.ProviderKey) interface{}
OtherModuleHasProvider(m blueprint.Module, provider blueprint.AnyProviderKey) bool
OtherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) interface{}
ModuleErrorf(fmt string, args ...interface{})
}