diff --git a/core/src/com/google/inject/internal/RealMapBinder.java b/core/src/com/google/inject/internal/RealMapBinder.java index 3c22322245..3c4b359f37 100644 --- a/core/src/com/google/inject/internal/RealMapBinder.java +++ b/core/src/com/google/inject/internal/RealMapBinder.java @@ -340,52 +340,50 @@ public LinkedBindingBuilder addBinding(K key) { return binder.bind(getKeyForNewValue(key)); } + @SuppressWarnings({"unchecked", "rawtypes"}) // we use raw Key to link bindings. @Override public void configure(Binder binder) { checkConfiguration(!bindingSelection.isInitialized(), "MapBinder was already initialized"); // Binds a Map> - RealProviderMapProvider providerMapProvider = - new RealProviderMapProvider<>(bindingSelection); - binder.bind(bindingSelection.getProviderMapKey()).toProvider(providerMapProvider); + binder + .bind(bindingSelection.getProviderMapKey()) + .toProvider(new RealProviderMapProvider<>(bindingSelection)); // The map this exposes is internally an ImmutableMap, so it's OK to massage // the guice Provider to jakarta Provider in the value (since Guice provider // implements jakarta Provider). - @SuppressWarnings({"unchecked", "rawtypes"}) - Provider>> jakartaProviderMapProvider = - (Provider) providerMapProvider; - binder.bind(bindingSelection.getJakartaProviderMapKey()).toProvider(jakartaProviderMapProvider); + binder + .bind(bindingSelection.getJakartaProviderMapKey()) + .to((Key) bindingSelection.getProviderMapKey()); // The map this exposes is internally an ImmutableMap, so it's OK to massage // the guice Provider to javax Provider in the value (since Guice provider // implements javax Provider). - @SuppressWarnings({"unchecked", "rawtypes"}) - Provider>> javaxProviderMapProvider = - (Provider) providerMapProvider; - binder.bind(bindingSelection.getJavaxProviderMapKey()).toProvider(javaxProviderMapProvider); + binder + .bind(bindingSelection.getJavaxProviderMapKey()) + .to((Key) bindingSelection.getProviderMapKey()); - RealMapProvider mapProvider = new RealMapProvider<>(bindingSelection); // Bind Map to the provider w/ extension support. binder .bind(bindingSelection.getMapKey()) - .toProvider(new ExtensionRealMapProvider<>(mapProvider)); + .toProvider(new ExtensionRealMapProvider<>(bindingSelection)); // Bind Map to the provider w/o the extension support. - binder.bind(bindingSelection.getMapOfKeyExtendsValueKey()).toProvider(mapProvider); + binder + .bind(bindingSelection.getMapOfKeyExtendsValueKey()) + .to((Key) bindingSelection.getMapKey()); // The Map.Entries are all ProviderMapEntry instances which do not allow setValue, so it is // safe to massage the return type like this - @SuppressWarnings({"unchecked", "rawtypes"}) - Key>>> jakartaEntrySetProviderKey = - (Key) bindingSelection.getEntrySetBinder().getSetKey(); - binder.bind(bindingSelection.getEntrySetJakartaProviderKey()).to(jakartaEntrySetProviderKey); + binder + .bind(bindingSelection.getEntrySetJakartaProviderKey()) + .to((Key) bindingSelection.getEntrySetBinder().getSetKey()); // The Map.Entries are all ProviderMapEntry instances which do not allow setValue, so it is // safe to massage the return type like this - @SuppressWarnings({"unchecked", "rawtypes"}) - Key>>> massagedEntrySetProviderKey = - (Key) bindingSelection.getEntrySetBinder().getSetKey(); - binder.bind(bindingSelection.getEntrySetJavaxProviderKey()).to(massagedEntrySetProviderKey); + binder + .bind(bindingSelection.getEntrySetJavaxProviderKey()) + .to((Key) bindingSelection.getEntrySetBinder().getSetKey()); } @Override @@ -847,8 +845,14 @@ protected Map> doProvision(InternalContext context, Dependency } } - private static final class RealMapProvider - extends RealMapBinderProviderWithDependencies> { + /** + * Implementation of a provider instance for the map that also exposes details about the MapBinder + * using the extension SPI, delegating to another provider instance for non-extension (e.g, the + * actual provider instance info) data. + */ + private static final class ExtensionRealMapProvider + extends RealMapBinderProviderWithDependencies> + implements ProviderWithExtensionVisitor>, MapBinderBinding> { Set> dependencies = RealMapBinder.MODULE_DEPENDENCIES; /** @@ -862,14 +866,10 @@ private static final class RealMapProvider private boolean initialized = false; - RealMapProvider(BindingSelection bindingSelection) { + ExtensionRealMapProvider(BindingSelection bindingSelection) { super(bindingSelection); } - BindingSelection getBindingSelection() { - return bindingSelection; - } - @Override protected void doInitialize(InjectorImpl injector, Errors errors) throws ErrorsException { if (initialized) { @@ -931,43 +931,11 @@ protected Map doProvision(InternalContext context, Dependency dependenc public Set> getDependencies() { return dependencies; } - } - - /** - * Implementation of a provider instance for the map that also exposes details about the MapBinder - * using the extension SPI, delegating to another provider instance for non-extension (e.g, the - * actual provider instance info) data. - */ - private static final class ExtensionRealMapProvider - extends RealMapBinderProviderWithDependencies> - implements ProviderWithExtensionVisitor>, MapBinderBinding> { - final RealMapProvider delegate; - - ExtensionRealMapProvider(RealMapProvider delegate) { - super(delegate.bindingSelection); - this.delegate = delegate; - } BindingSelection getBindingSelection() { return bindingSelection; } - @Override - protected void doInitialize(InjectorImpl injector, Errors errors) throws ErrorsException { - delegate.doInitialize(injector, errors); - } - - @Override - protected Map doProvision(InternalContext context, Dependency dependency) - throws InternalProvisionException { - return delegate.doProvision(context, dependency); - } - - @Override - public Set> getDependencies() { - return delegate.getDependencies(); - } - @Override @SuppressWarnings("unchecked") public W acceptExtensionVisitor( @@ -1154,55 +1122,46 @@ private MultimapBinder(BindingSelection bindingSelection) { this.bindingSelection = bindingSelection; } + @SuppressWarnings({"unchecked", "rawtypes"}) // we use raw Key to link bindings together. @Override public void configure(Binder binder) { // Binds a Map>> - Provider>>> multimapProvider = - new RealProviderMultimapProvider(bindingSelection.getMapKey()); - binder.bind(bindingSelection.getProviderSetMultimapKey()).toProvider(multimapProvider); + binder + .bind(bindingSelection.getProviderSetMultimapKey()) + .toProvider(new RealProviderMultimapProvider(bindingSelection.getMapKey())); // Provide links from a few different public keys to the providerMultimapKey. // The collection this exposes is internally an ImmutableMap, so it's OK to massage // the guice Provider to javax Provider in the value (since the guice Provider implements // javax Provider). - @SuppressWarnings({"unchecked", "rawtypes"}) - Provider>>> javaxProvider = (Provider) multimapProvider; - binder.bind(bindingSelection.getJavaxProviderSetMultimapKey()).toProvider(javaxProvider); + binder + .bind(bindingSelection.getJavaxProviderSetMultimapKey()) + .to((Key) bindingSelection.getProviderSetMultimapKey()); // Provide links from a few different public keys to the providerMultimapKey. // The collection this exposes is internally an ImmutableMap, so it's OK to massage // the guice Provider to jakarta Provider in the value (since the guice Provider implements // jakarta Provider). - @SuppressWarnings({"unchecked", "rawtypes"}) - Provider>>> jakartaProvider = - (Provider) multimapProvider; - binder.bind(bindingSelection.getJakartaProviderSetMultimapKey()).toProvider(jakartaProvider); + binder + .bind(bindingSelection.getJakartaProviderSetMultimapKey()) + .to((Key) bindingSelection.getProviderSetMultimapKey()); - @SuppressWarnings({"unchecked", "rawtypes"}) - Provider>>> collectionProvider = (Provider) multimapProvider; binder .bind(bindingSelection.getProviderCollectionMultimapKey()) - .toProvider(collectionProvider); + .to((Key) bindingSelection.getProviderSetMultimapKey()); - @SuppressWarnings({"unchecked", "rawtypes"}) - Provider>>> collectionJakartaProvider = - (Provider) multimapProvider; binder .bind(bindingSelection.getJakartaProviderCollectionMultimapKey()) - .toProvider(collectionJakartaProvider); + .to((Key) bindingSelection.getProviderSetMultimapKey()); - @SuppressWarnings({"unchecked", "rawtypes"}) - Provider>>> collectionJavaxProvider = - (Provider) multimapProvider; binder .bind(bindingSelection.getJavaxProviderCollectionMultimapKey()) - .toProvider(collectionJavaxProvider); + .to((Key) bindingSelection.getProviderSetMultimapKey()); // Binds a Map> - @SuppressWarnings({"unchecked", "rawtypes"}) - Provider>> realMultimapProvider = - new RealMultimapProvider(bindingSelection.getMapKey()); - binder.bind(bindingSelection.getMultimapKey()).toProvider(realMultimapProvider); + binder + .bind(bindingSelection.getMultimapKey()) + .toProvider(new RealMultimapProvider(bindingSelection.getMapKey())); } @Override diff --git a/core/src/com/google/inject/internal/RealMultibinder.java b/core/src/com/google/inject/internal/RealMultibinder.java index e9981389ec..f038decc25 100644 --- a/core/src/com/google/inject/internal/RealMultibinder.java +++ b/core/src/com/google/inject/internal/RealMultibinder.java @@ -105,41 +105,34 @@ static TypeLiteral> setOfExtendsOf(TypeLiteral elementTy this.bindingSelection = new BindingSelection<>(key); } + @SuppressWarnings({"unchecked", "rawtypes"}) // we use raw Key to link bindings together. @Override public void configure(Binder binder) { checkConfiguration(!bindingSelection.isInitialized(), "Multibinder was already initialized"); - RealMultibinderProvider setProvider = new RealMultibinderProvider(bindingSelection); // Bind the setKey to the provider wrapped w/ extension support. binder .bind(bindingSelection.getSetKey()) - .toProvider(new ExtensionRealMultibinderProvider<>(setProvider)); - // Bind the to the provider w/o extension support. - // It's important the exactly one binding implement the extension support and show - // the other keys as aliases, to adhere to the extension contract. - binder.bind(bindingSelection.getSetOfExtendsKey()).toProvider(setProvider); - - Provider>> collectionOfProvidersProvider = - new RealMultibinderCollectionOfProvidersProvider(bindingSelection); + .toProvider(new RealMultibinderProvider<>(bindingSelection)); + binder.bind(bindingSelection.getSetOfExtendsKey()).to(bindingSelection.getSetKey()); + binder .bind(bindingSelection.getCollectionOfProvidersKey()) - .toProvider(collectionOfProvidersProvider); + .toProvider(new RealMultibinderCollectionOfProvidersProvider(bindingSelection)); // The collection this exposes is internally an ImmutableList, so it's OK to massage // the guice Provider to jakarta Provider in the value (since the guice Provider implements // jakarta Provider). - @SuppressWarnings("unchecked") - Provider>> jakartaProvider = - (Provider) collectionOfProvidersProvider; - binder.bind(bindingSelection.getCollectionOfJakartaProvidersKey()).toProvider(jakartaProvider); + binder + .bind(bindingSelection.getCollectionOfJakartaProvidersKey()) + .to((Key) bindingSelection.getCollectionOfProvidersKey()); // The collection this exposes is internally an ImmutableList, so it's OK to massage // the guice Provider to javax Provider in the value (since the guice Provider implements // javax Provider). - @SuppressWarnings("unchecked") - Provider>> javaxProvider = - (Provider) collectionOfProvidersProvider; - binder.bind(bindingSelection.getCollectionOfJavaxProvidersKey()).toProvider(javaxProvider); + binder + .bind(bindingSelection.getCollectionOfJavaxProvidersKey()) + .to((Key) bindingSelection.getCollectionOfProvidersKey()); } public void permitDuplicates() { @@ -233,7 +226,8 @@ public int hashCode() { * so it can be used to supply a {@code Set} and {@code Set}, the latter being * useful for Kotlin support. */ - private static final class RealMultibinderProvider extends BaseFactory> { + private static final class RealMultibinderProvider extends BaseFactory> + implements ProviderWithExtensionVisitor>, MultibinderBinding> { List> bindings; SingleParameterInjector[] injectors; boolean permitDuplicates; @@ -296,33 +290,6 @@ private InternalProvisionException newDuplicateValuesException(T[] values) { bindingSelection.getSetKey(), bindings, values, ImmutableList.of(getSource()))); return new InternalProvisionException(message); } - } - - /** - * Implementation of BaseFactory that exposes details about the multibinder through the extension - * SPI. - */ - private static final class ExtensionRealMultibinderProvider extends BaseFactory> - implements ProviderWithExtensionVisitor>, MultibinderBinding> { - final RealMultibinderProvider delegate; - - ExtensionRealMultibinderProvider(RealMultibinderProvider delegate) { - // Note: method reference doesn't work for the 2nd arg for some reason when compiling on java8 - super(delegate.bindingSelection, bs -> bs.getDependencies()); - this.delegate = delegate; - } - - @Override - protected void doInitialize() { - delegate.doInitialize(); - } - - @Override - protected ImmutableSet doProvision(InternalContext context, Dependency dependency) - throws InternalProvisionException { - return delegate.doProvision(context, dependency); - } - @SuppressWarnings("unchecked") @Override public V acceptExtensionVisitor( diff --git a/core/src/com/google/inject/internal/RealOptionalBinder.java b/core/src/com/google/inject/internal/RealOptionalBinder.java index 45b36c1ad7..931ee8f722 100644 --- a/core/src/com/google/inject/internal/RealOptionalBinder.java +++ b/core/src/com/google/inject/internal/RealOptionalBinder.java @@ -202,6 +202,7 @@ public LinkedBindingBuilder setBinding() { return binder.bind(getKeyForActualBinding()); } + @SuppressWarnings({"unchecked", "rawtypes"}) // we use raw Key to link bindings together. @Override public void configure(Binder binder) { bindingSelection.checkNotInitialized(); @@ -216,66 +217,40 @@ public void configure(Binder binder) { // * T is bound // cgcb.Optional> - InternalProviderInstanceBindingImpl.Factory>> optionalProviderFactory = - new RealOptionalProviderProvider<>(bindingSelection); - binder.bind(key.ofType(optionalOfProvider(typeLiteral))).toProvider(optionalProviderFactory); + Key>> guavaOptProviderKey = key.ofType(optionalOfProvider(typeLiteral)); + binder + .bind(guavaOptProviderKey) + .toProvider(new RealOptionalProviderProvider<>(bindingSelection)); // ju.Optional> - InternalProviderInstanceBindingImpl.Factory>> - javaOptionalProviderFactory = new JavaOptionalProviderProvider<>(bindingSelection); + Key>> javaOptProviderKey = + key.ofType(javaOptionalOfProvider(typeLiteral)); binder - .bind(key.ofType(javaOptionalOfProvider(typeLiteral))) - .toProvider(javaOptionalProviderFactory); + .bind(javaOptProviderKey) + .toProvider(new JavaOptionalProviderProvider<>(bindingSelection)); // Provider is assignable to javax.inject.Provider and the provider that the factory contains // cannot be modified so we can use some rawtypes hackery to share the same implementation. - - // cgcb.Optional> - @SuppressWarnings("unchecked") - InternalProviderInstanceBindingImpl.Factory>> - optionalJavaxProviderFactory = - (InternalProviderInstanceBindingImpl.Factory) optionalProviderFactory; - binder - .bind(key.ofType(optionalOfJavaxProvider(typeLiteral))) - .toProvider(optionalJavaxProviderFactory); + binder.bind(key.ofType(optionalOfJavaxProvider(typeLiteral))).to((Key) guavaOptProviderKey); // ju.Optional> - @SuppressWarnings("unchecked") - InternalProviderInstanceBindingImpl.Factory>> - javaOptionalJavaxProviderFactory = - (InternalProviderInstanceBindingImpl.Factory) javaOptionalProviderFactory; - binder - .bind(key.ofType(javaOptionalOfJavaxProvider(typeLiteral))) - .toProvider(javaOptionalJavaxProviderFactory); + binder.bind(key.ofType(javaOptionalOfJavaxProvider(typeLiteral))).to((Key) javaOptProviderKey); // Provider is assignable to jakarta.inject.Provider and the provider that the factory contains // cannot be modified so we can use some rawtypes hackery to share the same implementation. - // cgcb.Optional> - @SuppressWarnings("unchecked") - InternalProviderInstanceBindingImpl.Factory>> - optionalJakartaProviderFactory = - (InternalProviderInstanceBindingImpl.Factory) optionalProviderFactory; - binder - .bind(key.ofType(optionalOfJakartaProvider(typeLiteral))) - .toProvider(optionalJakartaProviderFactory); + binder.bind(key.ofType(optionalOfJakartaProvider(typeLiteral))).to((Key) guavaOptProviderKey); // ju.Optional> - @SuppressWarnings("unchecked") - InternalProviderInstanceBindingImpl.Factory>> - javaOptionalJakartaProviderFactory = - (InternalProviderInstanceBindingImpl.Factory) javaOptionalProviderFactory; binder .bind(key.ofType(javaOptionalOfJakartaProvider(typeLiteral))) - .toProvider(javaOptionalJakartaProviderFactory); + .to((Key) javaOptProviderKey); // cgcb.Optional - Key> optionalKey = key.ofType(optionalOf(typeLiteral)); + Key> guavaOptKey = key.ofType(optionalOf(typeLiteral)); binder - .bind(optionalKey) - .toProvider(new RealOptionalKeyProvider<>(bindingSelection, optionalKey)); + .bind(guavaOptKey) + .toProvider(new RealOptionalKeyProvider<>(bindingSelection, guavaOptKey)); // ju.Optional - Key> javaOptionalKey = key.ofType(javaOptionalOf(typeLiteral)); - binder - .bind(javaOptionalKey) - .toProvider(new JavaOptionalProvider<>(bindingSelection, javaOptionalKey)); + Key> javaOptKey = key.ofType(javaOptionalOf(typeLiteral)); + binder.bind(javaOptKey).toProvider(new JavaOptionalProvider<>(bindingSelection, javaOptKey)); } /** Provides the binding for {@code java.util.Optional}. */ @@ -704,8 +679,7 @@ Dependency getDependency() { /** Implementation of {@link OptionalBinderBinding#containsElement}. */ boolean containsElement(Element element) { - // All of our bindings are ProviderInstanceBindings whose providers extend - // RealOptionalBinderProviderWithDependencies and have 'this' as its binding selection. + // We contain it if the provider is us. if (element instanceof ProviderInstanceBinding) { javax.inject.Provider providerInstance = ((ProviderInstanceBinding) element).getUserSuppliedProvider(); @@ -714,11 +688,18 @@ boolean containsElement(Element element) { .bindingSelection.equals(this); } } + if (element instanceof Binding) { + TypeLiteral typeLiteral = key.getTypeLiteral(); Key elementKey = ((Binding) element).getKey(); - // if it isn't one of the things we bound directly it might be an actual or default key + // if it isn't one of the things we bound directly it might be an actual or default key, + // or the javax or jakarta aliases of the optional provider. return elementKey.equals(getKeyForActualBinding()) - || elementKey.equals(getKeyForDefaultBinding()); + || elementKey.equals(getKeyForDefaultBinding()) + || elementKey.equals(key.ofType(javaOptionalOfJavaxProvider(typeLiteral))) + || elementKey.equals(key.ofType(optionalOfJavaxProvider(typeLiteral))) + || elementKey.equals(key.ofType(javaOptionalOfJakartaProvider(typeLiteral))) + || elementKey.equals(key.ofType(optionalOfJakartaProvider(typeLiteral))); } return false; // cannot match; }