Skip to content

Commit f4e8003

Browse files
Chang-EricDagger Team
authored andcommitted
Fix issue with jakarta.inject.Provider support where in certain cases requests for a Map<K, Provider<V>> would fail to compile. Similarly, fix support for @LazyClassKey with jakarta.inject.Provider.
Fixes #4572. RELNOTES=Fixes #4572. Fix issue with `jakarta.inject.Provider` support where in certain cases requests for a `Map<K, Provider<V>>` would fail to compile. PiperOrigin-RevId: 716306261
1 parent aa70ca8 commit f4e8003

File tree

5 files changed

+48
-9
lines changed

5 files changed

+48
-9
lines changed

java/dagger/internal/codegen/base/MapType.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ public boolean valuesAreFrameworkType() {
8686
return valueRequestKind() != RequestKind.INSTANCE;
8787
}
8888

89+
/** Returns {@code true} if the raw type of {@link #valueType()} is a provider type.*/
90+
public boolean valuesAreProvider() {
91+
return valuesAreTypeOf(TypeNames.PROVIDER) || valuesAreTypeOf(TypeNames.JAKARTA_PROVIDER);
92+
}
93+
8994
/**
9095
* Returns the map's {@link #valueType()} without any wrapping framework type, if one exists.
9196
*
@@ -124,19 +129,20 @@ public RequestKind valueRequestKind() {
124129
}
125130
}
126131

127-
/** {@code true} if {@code type} is a {@link java.util.Map} type. */
132+
/** Returns {@code true} if {@code type} is a {@link java.util.Map} type. */
128133
public static boolean isMap(XType type) {
129134
return isTypeOf(type, TypeNames.MAP);
130135
}
131136

132-
/** {@code true} if {@code key.type()} is a {@link java.util.Map} type. */
137+
/** Returns {@code true} if {@code key.type()} is a {@link java.util.Map} type. */
133138
public static boolean isMap(Key key) {
134139
return isMap(key.type().xprocessing());
135140
}
136141

142+
/** Returns {@code true} if the given type is a {@code Map<K, Provider<V>>}. */
137143
public static boolean isMapOfProvider(XType keyType) {
138144
if (MapType.isMap(keyType)) {
139-
return MapType.from(keyType).valuesAreTypeOf(TypeNames.PROVIDER);
145+
return MapType.from(keyType).valuesAreProvider();
140146
}
141147
return false;
142148
}

java/dagger/internal/codegen/binding/SourceFiles.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import static com.google.common.base.Verify.verify;
2525
import static dagger.internal.codegen.javapoet.TypeNames.DOUBLE_CHECK;
2626
import static dagger.internal.codegen.javapoet.TypeNames.PRODUCER;
27-
import static dagger.internal.codegen.javapoet.TypeNames.PROVIDER;
2827
import static dagger.internal.codegen.javapoet.TypeNames.PROVIDER_OF_LAZY;
2928
import static dagger.internal.codegen.model.BindingKind.ASSISTED_INJECTION;
3029
import static dagger.internal.codegen.model.BindingKind.INJECTION;
@@ -280,7 +279,7 @@ public static XClassName mapFactoryClassName(MultiboundMapBinding binding) {
280279
MapType mapType = MapType.from(binding.key());
281280
switch (binding.bindingType()) {
282281
case PROVISION:
283-
return mapType.valuesAreTypeOf(PROVIDER)
282+
return mapType.valuesAreProvider()
284283
? XTypeNames.MAP_PROVIDER_FACTORY : XTypeNames.MAP_FACTORY;
285284
case PRODUCTION:
286285
return mapType.valuesAreFrameworkType()

java/dagger/internal/codegen/bindinggraphvalidation/DependencyCycleValidator.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
import dagger.internal.codegen.base.MapType;
4444
import dagger.internal.codegen.base.OptionalType;
4545
import dagger.internal.codegen.binding.DependencyRequestFormatter;
46-
import dagger.internal.codegen.javapoet.TypeNames;
4746
import dagger.internal.codegen.model.Binding;
4847
import dagger.internal.codegen.model.BindingGraph;
4948
import dagger.internal.codegen.model.BindingGraph.ComponentNode;
@@ -242,7 +241,7 @@ private boolean breaksCycle(XType requestedType, RequestKind requestKind) {
242241

243242
case INSTANCE:
244243
if (MapType.isMap(requestedType)) {
245-
return MapType.from(requestedType).valuesAreTypeOf(TypeNames.PROVIDER);
244+
return MapType.from(requestedType).valuesAreProvider();
246245
}
247246
// fall through
248247

java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ private static ClassName lazyMapFactoryClassName(MultiboundMapBinding binding) {
101101
MapType mapType = MapType.from(binding.key());
102102
switch (binding.bindingType()) {
103103
case PROVISION:
104-
return mapType.valuesAreTypeOf(TypeNames.PROVIDER)
104+
return mapType.valuesAreProvider()
105105
? TypeNames.LAZY_CLASS_KEY_MAP_PROVIDER_FACTORY
106106
: TypeNames.LAZY_CLASS_KEY_MAP_FACTORY;
107107
case PRODUCTION:

javatests/dagger/functional/jakarta/JakartaProviderTest.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import dagger.Module;
2727
import dagger.Provides;
2828
import dagger.multibindings.IntoMap;
29+
import dagger.multibindings.LazyClassKey;
2930
import dagger.multibindings.StringKey;
3031
import jakarta.inject.Inject;
3132
import jakarta.inject.Provider;
@@ -75,6 +76,10 @@ interface TestComponent {
7576

7677
Map<String, javax.inject.Provider<Bar>> getJavaxProviderMap();
7778

79+
Map<Class<?>, Provider<Bar>> getJakartaProviderClassMap();
80+
81+
Map<Class<?>, javax.inject.Provider<Bar>> getJavaxProviderClassMap();
82+
7883
Map<String, Provider<Lazy<Bar>>> getJakartaProviderLazyMap();
7984

8085
Map<String, javax.inject.Provider<Lazy<Bar>>> getJavaxProviderLazyMap();
@@ -103,10 +108,17 @@ public static final class Bar {
103108
Bar() {}
104109
}
105110

111+
// Scoped as this forces the generated code to use a Provider instead of inlining
112+
// in default mode
113+
@TestScope
106114
public static final class InjectUsages {
107115
Provider<Bar> jakartaBar;
108116
Provider<Bar> jakartaQualifiedBar;
109117
javax.inject.Provider<Bar> javaxQualifiedBar;
118+
Map<String, javax.inject.Provider<Bar>> javaxProviderMap;
119+
Map<String, Provider<Bar>> jakartaProviderMap;
120+
Map<Class<?>, javax.inject.Provider<Bar>> javaxProviderClassMap;
121+
Map<Class<?>, Provider<Bar>> jakartaProviderClassMap;
110122

111123
@Inject
112124
InjectUsages(Provider<Bar> jakartaBar) {
@@ -117,9 +129,18 @@ public static final class InjectUsages {
117129

118130
@Inject
119131
void injectBar(
120-
Provider<Bar> jakartaQualifiedBar, javax.inject.Provider<Bar> javaxQualifiedBar) {
132+
Provider<Bar> jakartaQualifiedBar,
133+
javax.inject.Provider<Bar> javaxQualifiedBar,
134+
Map<String, javax.inject.Provider<Bar>> javaxProviderMap,
135+
Map<String, Provider<Bar>> jakartaProviderMap,
136+
Map<Class<?>, javax.inject.Provider<Bar>> javaxProviderClassMap,
137+
Map<Class<?>, Provider<Bar>> jakartaProviderClassMap) {
121138
this.jakartaQualifiedBar = jakartaQualifiedBar;
122139
this.javaxQualifiedBar = javaxQualifiedBar;
140+
this.javaxProviderMap = javaxProviderMap;
141+
this.jakartaProviderMap = jakartaProviderMap;
142+
this.javaxProviderClassMap = javaxProviderClassMap;
143+
this.jakartaProviderClassMap = jakartaProviderClassMap;
123144
}
124145
}
125146

@@ -146,6 +167,11 @@ static Bar provideBar(
146167
@StringKey("bar")
147168
abstract Bar bindBarIntoMap(Bar bar);
148169

170+
@Binds
171+
@IntoMap
172+
@LazyClassKey(Bar.class)
173+
abstract Bar bindBarIntoClassMap(Bar bar);
174+
149175
// TODO(b/65118638): Use @Binds @IntoMap Lazy<T> once that works properly.
150176
@Provides
151177
@IntoMap
@@ -210,9 +236,18 @@ public void testJakartaProviders() {
210236
assertThat(testComponent.getJakartaProviderMap().get("bar").get()).isSameInstanceAs(
211237
testComponent.getJavaxProviderMap().get("bar").get());
212238

239+
assertThat(testComponent.getJakartaProviderClassMap().get(Bar.class).get()).isSameInstanceAs(
240+
testComponent.getJavaxProviderClassMap().get(Bar.class).get());
241+
213242
assertThat(testComponent.getJakartaProviderLazyMap().get("bar").get().get()).isSameInstanceAs(
214243
testComponent.getJavaxProviderLazyMap().get("bar").get().get());
215244

245+
assertThat(injectUsages.jakartaProviderMap.get("bar").get()).isSameInstanceAs(
246+
injectUsages.javaxProviderMap.get("bar").get());
247+
248+
assertThat(injectUsages.jakartaProviderClassMap.get(Bar.class).get()).isSameInstanceAs(
249+
injectUsages.javaxProviderClassMap.get(Bar.class).get());
250+
216251
Map<Long, Provider<Long>> manualJakartaMap = testComponent.getManuallyProvidedJakartaMap();
217252
assertThat(manualJakartaMap.keySet()).containsExactly(9L);
218253

0 commit comments

Comments
 (0)