Skip to content

Commit 6b183f8

Browse files
Chang-EricDagger Team
authored andcommitted
Support requesting Jakarta Provider types.
PiperOrigin-RevId: 697234168
1 parent d0b2cc1 commit 6b183f8

File tree

84 files changed

+128
-955
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+128
-955
lines changed

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

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

1717
package dagger.internal.codegen.base;
1818

19+
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;
1920
import static dagger.internal.codegen.xprocessing.XTypes.isTypeOf;
2021

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

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

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

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

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

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

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,8 @@
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
4038
/** The valid framework request kinds allowed on a multibinding map value. */
41-
private static final ImmutableSet<RequestKind> VALID_FRAMEWORK_REQUEST_KINDS =
39+
public static final ImmutableSet<RequestKind> VALID_FRAMEWORK_REQUEST_KINDS =
4240
ImmutableSet.of(RequestKind.PROVIDER, RequestKind.PRODUCER, RequestKind.PRODUCED);
4341

4442
private XType type;
@@ -109,19 +107,12 @@ public XType unwrappedFrameworkValueType() {
109107
*/
110108
public RequestKind valueRequestKind() {
111109
checkArgument(!isRawType());
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;
110+
for (RequestKind frameworkRequestKind : VALID_FRAMEWORK_REQUEST_KINDS) {
111+
if (valuesAreTypeOf(RequestKinds.frameworkClassName(frameworkRequestKind))) {
112+
return frameworkRequestKind;
113+
}
124114
}
115+
return RequestKind.INSTANCE;
125116
}
126117

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

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,6 @@ 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.
102100
PROVIDER, TypeNames.PROVIDER,
103101
LAZY, TypeNames.LAZY,
104102
PRODUCER, TypeNames.PRODUCER,
@@ -113,15 +111,10 @@ public static RequestKind getRequestKind(XType type) {
113111
return RequestKind.INSTANCE;
114112
}
115113

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

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

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,10 @@
2525
import com.google.common.collect.ImmutableSet;
2626
import com.google.common.collect.ImmutableSetMultimap;
2727
import com.google.common.collect.Multimaps;
28-
import com.squareup.javapoet.ClassName;
2928
import com.squareup.javapoet.ParameterizedTypeName;
3029
import com.squareup.javapoet.TypeName;
3130
import com.squareup.javapoet.WildcardTypeName;
3231
import dagger.internal.codegen.base.DaggerSuperficialValidation;
33-
import dagger.internal.codegen.base.FrameworkTypes;
3432
import dagger.internal.codegen.javapoet.TypeNames;
3533
import dagger.internal.codegen.model.DaggerAnnotation;
3634
import dagger.internal.codegen.model.Key;
@@ -40,6 +38,11 @@
4038

4139
/** Stores the bindings and declarations of a component by key. */
4240
final class ComponentDeclarations {
41+
private static final ImmutableSet<TypeName> MAP_FRAMEWORK_TYPENAMES =
42+
ImmutableSet.of(TypeNames.PROVIDER, TypeNames.PRODUCER, TypeNames.PRODUCED);
43+
private static final ImmutableSet<TypeName> SET_FRAMEWORK_TYPENAMES =
44+
ImmutableSet.of(TypeNames.PRODUCED);
45+
4346
private final KeyFactory keyFactory;
4447
private final ImmutableSetMultimap<Key, ContributionBinding> bindings;
4548
private final ImmutableSetMultimap<Key, DelegateDeclaration> delegates;
@@ -317,14 +320,14 @@ private static TypeName unwrapMultibindingTypeName(TypeName typeName) {
317320
return ParameterizedTypeName.get(
318321
mapTypeName.rawType,
319322
mapKeyTypeName,
320-
unwrapFrameworkTypeName(mapValueTypeName, FrameworkTypes.MAP_VALUE_FRAMEWORK_TYPES));
323+
unwrapFrameworkTypeName(mapValueTypeName, MAP_FRAMEWORK_TYPENAMES));
321324
}
322325
if (isValidSetMultibindingTypeName(typeName)) {
323326
ParameterizedTypeName setTypeName = (ParameterizedTypeName) typeName;
324327
TypeName setValueTypeName = getOnlyElement(setTypeName.typeArguments);
325328
return ParameterizedTypeName.get(
326329
setTypeName.rawType,
327-
unwrapFrameworkTypeName(setValueTypeName, FrameworkTypes.SET_VALUE_FRAMEWORK_TYPES));
330+
unwrapFrameworkTypeName(setValueTypeName, SET_FRAMEWORK_TYPENAMES));
328331
}
329332
return typeName;
330333
}
@@ -351,7 +354,7 @@ private static boolean isValidSetMultibindingTypeName(TypeName typeName) {
351354
}
352355

353356
private static TypeName unwrapFrameworkTypeName(
354-
TypeName typeName, ImmutableSet<ClassName> frameworkTypeNames) {
357+
TypeName typeName, ImmutableSet<TypeName> frameworkTypeNames) {
355358
if (typeName instanceof ParameterizedTypeName) {
356359
ParameterizedTypeName parameterizedTypeName = (ParameterizedTypeName) typeName;
357360
if (frameworkTypeNames.contains(parameterizedTypeName.rawType)) {

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

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

9998
/** Returns {@code Map<KeyType, FrameworkType<ValueType>>}. */
10099
private XType mapOfFrameworkType(XType keyType, ClassName frameworkClassName, XType valueType) {
101-
checkArgument(FrameworkTypes.MAP_VALUE_FRAMEWORK_TYPES.contains(frameworkClassName));
100+
checkArgument(
101+
MapType.VALID_FRAMEWORK_REQUEST_KINDS.stream()
102+
.map(RequestKinds::frameworkClassName)
103+
.anyMatch(frameworkClassName::equals));
102104
return mapOf(
103105
keyType,
104106
processingEnv.getDeclaredType(
@@ -315,7 +317,10 @@ public Key unwrapMapValueType(Key key) {
315317
* type.
316318
*/
317319
private Key wrapMapValue(Key key, ClassName frameworkClassName) {
318-
checkArgument(FrameworkTypes.MAP_VALUE_FRAMEWORK_TYPES.contains(frameworkClassName));
320+
checkArgument(
321+
MapType.VALID_FRAMEWORK_REQUEST_KINDS.stream()
322+
.map(RequestKinds::frameworkClassName)
323+
.anyMatch(frameworkClassName::equals));
319324
if (MapType.isMap(key)) {
320325
MapType mapType = MapType.from(key);
321326
if (!mapType.isRawType() && !mapType.valuesAreTypeOf(frameworkClassName)) {

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ public final class SourceFiles {
9595
dependency -> {
9696
ClassName frameworkClassName =
9797
frameworkTypeMapper.getFrameworkType(dependency.kind()).frameworkClassName();
98+
// Remap factory fields back to javax.inject.Provider to maintain backwards compatibility
99+
// for now. In a future release, we should change this to Dagger Provider. This will still
100+
// be a breaking change, but keeping compatibility for a while should reduce the
101+
// likelihood of breakages as it would require components built at much older versions
102+
// using factories built at newer versions to break.
103+
if (frameworkClassName.equals(TypeNames.DAGGER_PROVIDER)) {
104+
frameworkClassName = TypeNames.PROVIDER;
105+
}
98106
return FrameworkField.create(
99107
ParameterizedTypeName.get(
100108
frameworkClassName,

java/dagger/internal/codegen/javapoet/TypeNames.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ public final class TypeNames {
8888
public static final ClassName MEMBERS_INJECTORS =
8989
ClassName.get("dagger.internal", "MembersInjectors");
9090
public static final ClassName PROVIDER = ClassName.get("javax.inject", "Provider");
91-
public static final ClassName JAKARTA_PROVIDER = ClassName.get("jakarta.inject", "Provider");
9291
public static final ClassName DAGGER_PROVIDER = ClassName.get("dagger.internal", "Provider");
9392
public static final ClassName DAGGER_PROVIDERS = ClassName.get("dagger.internal", "Providers");
9493
public static final ClassName PROVIDER_OF_LAZY =

java/dagger/internal/codegen/writing/FactoryGenerator.java

Lines changed: 3 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.RAWTYPES;
3232
import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED;
3333
import static dagger.internal.codegen.javapoet.AnnotationSpecs.suppressWarnings;
34-
import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock;
3534
import static dagger.internal.codegen.javapoet.CodeBlocks.parameterNames;
3635
import static dagger.internal.codegen.javapoet.TypeNames.factoryOf;
3736
import static dagger.internal.codegen.model.BindingKind.INJECTION;
@@ -49,14 +48,12 @@
4948
import com.google.common.collect.ImmutableList;
5049
import com.google.common.collect.ImmutableMap;
5150
import com.google.common.collect.ImmutableSet;
52-
import com.google.common.collect.Lists;
5351
import com.squareup.javapoet.AnnotationSpec;
5452
import com.squareup.javapoet.ClassName;
5553
import com.squareup.javapoet.CodeBlock;
5654
import com.squareup.javapoet.FieldSpec;
5755
import com.squareup.javapoet.MethodSpec;
5856
import com.squareup.javapoet.ParameterSpec;
59-
import com.squareup.javapoet.ParameterizedTypeName;
6057
import com.squareup.javapoet.TypeName;
6158
import com.squareup.javapoet.TypeSpec;
6259
import dagger.internal.codegen.base.SourceFileGenerator;
@@ -76,7 +73,6 @@
7673
import dagger.internal.codegen.model.Scope;
7774
import dagger.internal.codegen.writing.InjectionMethods.InjectionSiteMethod;
7875
import dagger.internal.codegen.writing.InjectionMethods.ProvisionMethod;
79-
import java.util.List;
8076
import java.util.Optional;
8177
import java.util.stream.Stream;
8278
import javax.inject.Inject;
@@ -139,7 +135,7 @@ private TypeSpec.Builder factoryBuilder(ContributionBinding binding) {
139135

140136
return factoryBuilder
141137
.addMethod(getMethod(binding, factoryFields))
142-
.addMethods(staticCreateMethod(binding, factoryFields))
138+
.addMethod(staticCreateMethod(binding, factoryFields))
143139
.addMethod(staticProvisionMethod(binding));
144140
}
145141

@@ -197,12 +193,10 @@ private MethodSpec constructorMethod(FactoryFields factoryFields) {
197193
// Provider<Baz> bazProvider) {
198194
// return new FooModule_ProvidesFooFactory(module, barProvider, bazProvider);
199195
// }
200-
private ImmutableList<MethodSpec> staticCreateMethod(
201-
ContributionBinding binding, FactoryFields factoryFields) {
196+
private MethodSpec staticCreateMethod(ContributionBinding binding, FactoryFields factoryFields) {
202197
// We use a static create method so that generated components can avoid having to refer to the
203198
// generic types of the factory. (Otherwise they may have visibility problems referring to the
204199
// types.)
205-
ImmutableList.Builder<MethodSpec> methodsBuilder = ImmutableList.builder();
206200
MethodSpec.Builder createMethodBuilder =
207201
methodBuilder("create")
208202
.addModifiers(PUBLIC, STATIC)
@@ -225,32 +219,8 @@ private ImmutableList<MethodSpec> staticCreateMethod(
225219
"return new $T($L)",
226220
parameterizedGeneratedTypeNameForBinding(binding),
227221
parameterNames(parameters));
228-
// If any of the parameters take a Dagger Provider type, we also need to make a
229-
// Javax Provider type for backwards compatibility with components generated at
230-
// an older version.
231-
// Eventually, we will need to remove this and break backwards compatibility
232-
// in order to fully cut the Javax dependency.
233-
if (hasDaggerProviderParams(parameters)) {
234-
methodsBuilder.add(javaxCreateMethod(binding, parameters));
235-
}
236222
}
237-
methodsBuilder.add(createMethodBuilder.build());
238-
return methodsBuilder.build();
239-
}
240-
241-
private MethodSpec javaxCreateMethod(
242-
ContributionBinding binding, ImmutableList<ParameterSpec> parameters) {
243-
ImmutableList<ParameterSpec> remappedParams = remapParamsToJavaxProvider(parameters);
244-
return methodBuilder("create")
245-
.addModifiers(PUBLIC, STATIC)
246-
.returns(parameterizedGeneratedTypeNameForBinding(binding))
247-
.addTypeVariables(bindingTypeElementTypeVariableNames(binding))
248-
.addParameters(remappedParams)
249-
.addStatement(
250-
"return new $T($L)",
251-
parameterizedGeneratedTypeNameForBinding(binding),
252-
wrappedParametersCodeBlock(remappedParams))
253-
.build();
223+
return createMethodBuilder.build();
254224
}
255225

256226
// Example 1: Provision binding.
@@ -409,54 +379,6 @@ private static Optional<TypeName> factoryTypeName(ContributionBinding binding) {
409379
: Optional.of(factoryOf(providedTypeName(binding)));
410380
}
411381

412-
// Open for sharing with ProducerFactoryGenerator and MembersInjectorGenerator
413-
static boolean hasDaggerProviderParams(List<ParameterSpec> params) {
414-
return params.stream().anyMatch(param -> isDaggerProviderType(param.type));
415-
}
416-
417-
// Open for sharing with ProducerFactoryGenerator and MembersInjectorGenerator
418-
// Returns a code block that represents a parameter list where any javax Provider
419-
// types are wrapped in an asDaggerProvider call
420-
static CodeBlock wrappedParametersCodeBlock(List<ParameterSpec> params) {
421-
return makeParametersCodeBlock(
422-
Lists.transform(
423-
params,
424-
input ->
425-
isProviderType(input.type)
426-
? CodeBlock.of(
427-
"$T.asDaggerProvider($N)", TypeNames.DAGGER_PROVIDERS, input)
428-
: CodeBlock.of("$N", input)));
429-
}
430-
431-
// Open for sharing with ProducerFactoryGenerator and MembersInjectorGenerator
432-
static ImmutableList<ParameterSpec> remapParamsToJavaxProvider(List<ParameterSpec> params) {
433-
return params.stream()
434-
.map(param -> ParameterSpec.builder(
435-
remapDaggerProviderToProvider(param.type), param.name).build())
436-
.collect(toImmutableList());
437-
}
438-
439-
private static boolean isDaggerProviderType(TypeName type) {
440-
return type instanceof ParameterizedTypeName
441-
&& ((ParameterizedTypeName) type).rawType.equals(TypeNames.DAGGER_PROVIDER);
442-
}
443-
444-
private static boolean isProviderType(TypeName type) {
445-
return type instanceof ParameterizedTypeName
446-
&& ((ParameterizedTypeName) type).rawType.equals(TypeNames.PROVIDER);
447-
}
448-
449-
private static TypeName remapDaggerProviderToProvider(TypeName type) {
450-
if (type instanceof ParameterizedTypeName) {
451-
ParameterizedTypeName parameterizedTypeName = (ParameterizedTypeName) type;
452-
if (parameterizedTypeName.rawType.equals(TypeNames.DAGGER_PROVIDER)) {
453-
return ParameterizedTypeName.get(
454-
TypeNames.PROVIDER, parameterizedTypeName.typeArguments.toArray(new TypeName[0]));
455-
}
456-
}
457-
return type;
458-
}
459-
460382
/** Represents the available fields in the generated factory class. */
461383
private static final class FactoryFields {
462384
static FactoryFields create(ContributionBinding binding) {

0 commit comments

Comments
 (0)