Use generics for providers API
Using generics for the providers API allows a type to be associated
with a ProviderKey, resulting in a type-safe API without that doesn't
require runtime type assertions by every caller.
Unfortunately, Go does not allow generic types in methods, only in
functions [1]. This prevents a type-safe API on ModuleContext, and
requires moving the API to be functions that take a ModuleContext as
a parameter.
This CL creates the new API, but doesn't convert all of the callers.
[1] https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#no-parameterized-methods)
Bug: 316410648
Test: builds
Change-Id: I3e30d68b966b730efd968166a38a25cc144bd6de
diff --git a/android/singleton.go b/android/singleton.go
index 7c6cf4f..8936cac 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -20,6 +20,8 @@
// SingletonContext
type SingletonContext interface {
+ blueprintSingletonContext() blueprint.SingletonContext
+
Config() Config
DeviceConfig() DeviceConfig
@@ -38,10 +40,12 @@
// 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 @@
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 @@
}
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)
+}