Skip to content

Commit 30a3114

Browse files
Chang-EricDagger Team
authored andcommitted
Support injecting jakarta.inject.Provider type in the places javax.inject.Provider can be used.
RELNOTES=Support injecting `jakarta.inject.Provider` PiperOrigin-RevId: 709898053
1 parent 3ac3681 commit 30a3114

File tree

8 files changed

+289
-29
lines changed

8 files changed

+289
-29
lines changed

java/dagger/internal/codegen/base/FrameworkTypes.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package dagger.internal.codegen.base;
1818

19-
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;
2019
import static dagger.internal.codegen.xprocessing.XTypes.isTypeOf;
2120

2221
import androidx.room.compiler.processing.XType;
@@ -32,7 +31,11 @@
3231
public final class FrameworkTypes {
3332
// TODO(erichang): Add the Jakarta Provider here
3433
private static final ImmutableSet<ClassName> PROVISION_TYPES =
35-
ImmutableSet.of(TypeNames.PROVIDER, TypeNames.LAZY, TypeNames.MEMBERS_INJECTOR);
34+
ImmutableSet.of(
35+
TypeNames.PROVIDER,
36+
TypeNames.JAKARTA_PROVIDER,
37+
TypeNames.LAZY,
38+
TypeNames.MEMBERS_INJECTOR);
3639

3740
// NOTE(beder): ListenableFuture is not considered a producer framework type because it is not
3841
// defined by the framework, so we can't treat it specially in ordinary Dagger.
@@ -42,13 +45,15 @@ public final class FrameworkTypes {
4245
private static final ImmutableSet<ClassName> ALL_FRAMEWORK_TYPES =
4346
ImmutableSet.<ClassName>builder().addAll(PROVISION_TYPES).addAll(PRODUCTION_TYPES).build();
4447

45-
private static final ImmutableSet<ClassName> SET_VALUE_FRAMEWORK_TYPES =
48+
public static final ImmutableSet<ClassName> SET_VALUE_FRAMEWORK_TYPES =
4649
ImmutableSet.of(TypeNames.PRODUCED);
4750

4851
public static final ImmutableSet<ClassName> MAP_VALUE_FRAMEWORK_TYPES =
49-
MapType.VALID_FRAMEWORK_REQUEST_KINDS.stream()
50-
.map(RequestKinds::frameworkClassName)
51-
.collect(toImmutableSet());
52+
ImmutableSet.of(
53+
TypeNames.PRODUCED,
54+
TypeNames.PRODUCER,
55+
TypeNames.PROVIDER,
56+
TypeNames.JAKARTA_PROVIDER);
5257

5358
/** Returns true if the type represents a producer-related framework type. */
5459
public static boolean isProducerType(XType type) {

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@
3535
@AutoValue
3636
public abstract class MapType {
3737
// TODO(b/28555349): support PROVIDER_OF_LAZY here too
38+
// TODO(b/376124787): We could consolidate this with a similar list in FrameworkTypes
39+
// if we had a better way to go from RequestKind to framework ClassName or vice versa
3840
/** The valid framework request kinds allowed on a multibinding map value. */
39-
public static final ImmutableSet<RequestKind> VALID_FRAMEWORK_REQUEST_KINDS =
41+
private static final ImmutableSet<RequestKind> VALID_FRAMEWORK_REQUEST_KINDS =
4042
ImmutableSet.of(RequestKind.PROVIDER, RequestKind.PRODUCER, RequestKind.PRODUCED);
4143

4244
private XType type;
@@ -107,12 +109,19 @@ public XType unwrappedFrameworkValueType() {
107109
*/
108110
public RequestKind valueRequestKind() {
109111
checkArgument(!isRawType());
110-
for (RequestKind frameworkRequestKind : VALID_FRAMEWORK_REQUEST_KINDS) {
111-
if (valuesAreTypeOf(RequestKinds.frameworkClassName(frameworkRequestKind))) {
112-
return frameworkRequestKind;
113-
}
112+
RequestKind requestKind = RequestKinds.getRequestKind(valueType());
113+
if (VALID_FRAMEWORK_REQUEST_KINDS.contains(requestKind)) {
114+
return requestKind;
115+
} else if (requestKind == RequestKind.PROVIDER_OF_LAZY) {
116+
// This is kind of a weird case. We don't support Map<K, Lazy<V>>, so we also don't support
117+
// Map<K, Provider<Lazy<V>>> directly. However, if the user bound that themselves, we don't
118+
// want that to get confused as a normal instance request, so return PROVIDER here.
119+
return RequestKind.PROVIDER;
120+
} else {
121+
// Not all RequestKinds are supported, so if there's a map value that matches an unsupported
122+
// RequestKind, just treat it like it is a normal instance request.
123+
return RequestKind.INSTANCE;
114124
}
115-
return RequestKind.INSTANCE;
116125
}
117126

118127
/** {@code true} if {@code type} is a {@link java.util.Map} type. */

java/dagger/internal/codegen/base/RequestKinds.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ public static TypeName requestTypeName(RequestKind requestKind, TypeName keyType
9797

9898
private static final ImmutableMap<RequestKind, ClassName> FRAMEWORK_CLASSES =
9999
ImmutableMap.of(
100+
// Default to the javax Provider since that is what is used for the binding graph
101+
// representation.
100102
PROVIDER, TypeNames.PROVIDER,
101103
LAZY, TypeNames.LAZY,
102104
PRODUCER, TypeNames.PRODUCER,
@@ -111,10 +113,15 @@ public static RequestKind getRequestKind(XType type) {
111113
return RequestKind.INSTANCE;
112114
}
113115

114-
if (isTypeOf(type, TypeNames.PROVIDER) && isTypeOf(unwrapType(type), TypeNames.LAZY)) {
116+
if ((isTypeOf(type, TypeNames.PROVIDER) || isTypeOf(type, TypeNames.JAKARTA_PROVIDER))
117+
&& isTypeOf(unwrapType(type), TypeNames.LAZY)) {
115118
return RequestKind.PROVIDER_OF_LAZY;
116119
}
117120

121+
if (isTypeOf(type, TypeNames.JAKARTA_PROVIDER)) {
122+
return RequestKind.PROVIDER;
123+
}
124+
118125
return FRAMEWORK_CLASSES.keySet().stream()
119126
.filter(kind -> isTypeOf(type, FRAMEWORK_CLASSES.get(kind)))
120127
.collect(toOptional())

java/dagger/internal/codegen/binding/ComponentDeclarations.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@
2626
import com.google.common.collect.ImmutableSet;
2727
import com.google.common.collect.ImmutableSetMultimap;
2828
import com.google.common.collect.Multimaps;
29+
import com.squareup.javapoet.ClassName;
2930
import com.squareup.javapoet.ParameterizedTypeName;
3031
import com.squareup.javapoet.TypeName;
3132
import com.squareup.javapoet.WildcardTypeName;
3233
import dagger.internal.codegen.base.DaggerSuperficialValidation;
34+
import dagger.internal.codegen.base.FrameworkTypes;
3335
import dagger.internal.codegen.javapoet.TypeNames;
3436
import dagger.internal.codegen.model.DaggerAnnotation;
3537
import dagger.internal.codegen.model.Key;
@@ -39,11 +41,6 @@
3941

4042
/** Stores the bindings and declarations of a component by key. */
4143
final class ComponentDeclarations {
42-
private static final ImmutableSet<TypeName> MAP_FRAMEWORK_TYPENAMES =
43-
ImmutableSet.of(TypeNames.PROVIDER, TypeNames.PRODUCER, TypeNames.PRODUCED);
44-
private static final ImmutableSet<TypeName> SET_FRAMEWORK_TYPENAMES =
45-
ImmutableSet.of(TypeNames.PRODUCED);
46-
4744
private final KeyFactory keyFactory;
4845
private final ImmutableSetMultimap<Key, ContributionBinding> bindings;
4946
private final ImmutableSetMultimap<Key, DelegateDeclaration> delegates;
@@ -322,14 +319,14 @@ private static TypeName unwrapMultibindingTypeName(TypeName typeName) {
322319
return ParameterizedTypeName.get(
323320
mapTypeName.rawType,
324321
mapKeyTypeName,
325-
unwrapFrameworkTypeName(mapValueTypeName, MAP_FRAMEWORK_TYPENAMES));
322+
unwrapFrameworkTypeName(mapValueTypeName, FrameworkTypes.MAP_VALUE_FRAMEWORK_TYPES));
326323
}
327324
if (isValidSetMultibindingTypeName(typeName)) {
328325
ParameterizedTypeName setTypeName = (ParameterizedTypeName) typeName;
329326
TypeName setValueTypeName = getOnlyElement(setTypeName.typeArguments);
330327
return ParameterizedTypeName.get(
331328
setTypeName.rawType,
332-
unwrapFrameworkTypeName(setValueTypeName, SET_FRAMEWORK_TYPENAMES));
329+
unwrapFrameworkTypeName(setValueTypeName, FrameworkTypes.SET_VALUE_FRAMEWORK_TYPES));
333330
}
334331
return typeName;
335332
}
@@ -356,7 +353,7 @@ private static boolean isValidSetMultibindingTypeName(TypeName typeName) {
356353
}
357354

358355
private static TypeName unwrapFrameworkTypeName(
359-
TypeName typeName, ImmutableSet<TypeName> frameworkTypeNames) {
356+
TypeName typeName, ImmutableSet<ClassName> frameworkTypeNames) {
360357
if (typeName instanceof ParameterizedTypeName) {
361358
ParameterizedTypeName parameterizedTypeName = (ParameterizedTypeName) typeName;
362359
if (frameworkTypeNames.contains(parameterizedTypeName.rawType)) {

java/dagger/internal/codegen/binding/KeyFactory.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import dagger.Binds;
3939
import dagger.BindsOptionalOf;
4040
import dagger.internal.codegen.base.ContributionType;
41+
import dagger.internal.codegen.base.FrameworkTypes;
4142
import dagger.internal.codegen.base.MapType;
4243
import dagger.internal.codegen.base.OptionalType;
4344
import dagger.internal.codegen.base.RequestKinds;
@@ -97,10 +98,7 @@ private XType optionalOf(XType type) {
9798

9899
/** Returns {@code Map<KeyType, FrameworkType<ValueType>>}. */
99100
private XType mapOfFrameworkType(XType keyType, ClassName frameworkClassName, XType valueType) {
100-
checkArgument(
101-
MapType.VALID_FRAMEWORK_REQUEST_KINDS.stream()
102-
.map(RequestKinds::frameworkClassName)
103-
.anyMatch(frameworkClassName::equals));
101+
checkArgument(FrameworkTypes.MAP_VALUE_FRAMEWORK_TYPES.contains(frameworkClassName));
104102
return mapOf(
105103
keyType,
106104
processingEnv.getDeclaredType(
@@ -317,10 +315,7 @@ public Key unwrapMapValueType(Key key) {
317315
* type.
318316
*/
319317
private Key wrapMapValue(Key key, ClassName frameworkClassName) {
320-
checkArgument(
321-
MapType.VALID_FRAMEWORK_REQUEST_KINDS.stream()
322-
.map(RequestKinds::frameworkClassName)
323-
.anyMatch(frameworkClassName::equals));
318+
checkArgument(FrameworkTypes.MAP_VALUE_FRAMEWORK_TYPES.contains(frameworkClassName));
324319
if (MapType.isMap(key)) {
325320
MapType mapType = MapType.from(key);
326321
if (!mapType.isRawType() && !mapType.valuesAreTypeOf(frameworkClassName)) {

javatests/dagger/functional/jakarta/BUILD

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,16 @@ GenJavaTests(
3232
"@maven//:jakarta_inject_jakarta_inject_api",
3333
],
3434
)
35+
36+
GenJavaTests(
37+
name = "JakartaProviderTest",
38+
srcs = ["JakartaProviderTest.java"],
39+
javacopts = DOCLINT_HTML_AND_SYNTAX,
40+
deps = [
41+
"//:dagger_with_compiler",
42+
"//third_party/java/guava/base",
43+
"//third_party/java/junit",
44+
"//third_party/java/truth",
45+
"@maven//:jakarta_inject_jakarta_inject_api",
46+
],
47+
)

0 commit comments

Comments
 (0)