blob: 5eeca8d52a0430842fd9a54a0f8528ebb35c417b [file] [log] [blame]
Christian Edward Gruber4df36792014-04-15 14:01:28 -07001/*
ronshapiro5dde42d2016-06-17 09:03:35 -07002 * Copyright (C) 2014 The Dagger Authors.
Christian Edward Gruber4df36792014-04-15 14:01:28 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
dpb1b65b6a2016-07-11 12:11:24 -070016
Christian Edward Gruber4df36792014-04-15 14:01:28 -070017package dagger.internal.codegen;
18
gake55f0742016-07-12 15:36:42 -070019import static com.google.auto.common.MoreElements.isAnnotationPresent;
20import static com.google.auto.common.MoreTypes.asDeclared;
21import static com.google.common.base.Preconditions.checkArgument;
22import static com.google.common.base.Preconditions.checkNotNull;
23import static com.google.common.base.Preconditions.checkState;
24import static dagger.internal.codegen.InjectionAnnotations.getQualifier;
25import static dagger.internal.codegen.MapKeys.getMapKey;
26import static dagger.internal.codegen.MoreAnnotationMirrors.wrapOptionalInEquivalence;
ronshapiroe05f9212017-08-08 11:22:11 -070027import static dagger.internal.codegen.Util.toImmutableSet;
gake55f0742016-07-12 15:36:42 -070028import static javax.lang.model.element.ElementKind.CONSTRUCTOR;
gake55f0742016-07-12 15:36:42 -070029import static javax.lang.model.element.ElementKind.METHOD;
30
Christian Edward Gruber6a66a5b2014-06-12 21:10:17 -070031import com.google.auto.common.MoreElements;
sameb2ea676a2015-01-15 10:20:24 -080032import com.google.auto.common.MoreTypes;
Christian Edward Gruber6a66a5b2014-06-12 21:10:17 -070033import com.google.auto.value.AutoValue;
ronshapiroe05f9212017-08-08 11:22:11 -070034import com.google.auto.value.extension.memoized.Memoized;
Christian Edward Gruber6a66a5b2014-06-12 21:10:17 -070035import com.google.common.collect.ImmutableSet;
ronshapiroe05f9212017-08-08 11:22:11 -070036import com.google.common.collect.ImmutableSortedSet;
bederb50b8ae2016-12-07 08:36:26 -080037import com.google.common.collect.Iterables;
dpb6313ae32016-06-21 15:15:26 -070038import com.google.errorprone.annotations.CanIgnoreReturnValue;
bederb50b8ae2016-12-07 08:36:26 -080039import dagger.internal.codegen.ComponentDescriptor.BuilderRequirementMethod;
ronshapiroe05f9212017-08-08 11:22:11 -070040import dagger.internal.codegen.MembersInjectionBinding.InjectionSite;
dpbffd98f62016-12-20 10:05:16 -080041import java.util.Optional;
dpb6313ae32016-06-21 15:15:26 -070042import javax.annotation.CheckReturnValue;
Christian Edward Gruber6a66a5b2014-06-12 21:10:17 -070043import javax.inject.Inject;
ronshapiro23c17b82016-06-10 09:57:13 -070044import javax.inject.Provider;
Christian Edward Gruber6a66a5b2014-06-12 21:10:17 -070045import javax.lang.model.element.Element;
Christian Edward Gruber6a66a5b2014-06-12 21:10:17 -070046import javax.lang.model.element.ExecutableElement;
47import javax.lang.model.element.TypeElement;
bederb50b8ae2016-12-07 08:36:26 -080048import javax.lang.model.element.VariableElement;
sameb2ea676a2015-01-15 10:20:24 -080049import javax.lang.model.type.DeclaredType;
50import javax.lang.model.type.ExecutableType;
51import javax.lang.model.type.TypeMirror;
Christian Edward Gruber6a66a5b2014-06-12 21:10:17 -070052import javax.lang.model.util.Types;
53
Christian Edward Gruber4df36792014-04-15 14:01:28 -070054/**
55 * A value object representing the mechanism by which a {@link Key} can be provided. New instances
56 * should be created using an instance of the {@link Factory}.
57 *
58 * @author Gregory Kick
59 * @since 2.0
60 */
61@AutoValue
bederca9c82b2015-01-23 18:30:22 -080062abstract class ProvisionBinding extends ContributionBinding {
dpb57198802015-12-17 12:18:15 -080063
gak09075bc2014-07-31 11:02:39 -070064 @Override
ronshapiroe05f9212017-08-08 11:22:11 -070065 @Memoized
66 ImmutableSet<DependencyRequest> explicitDependencies() {
67 return ImmutableSet.<DependencyRequest>builder()
68 .addAll(provisionDependencies())
69 .addAll(membersInjectionDependencies())
70 .build();
gak6fc2b5a2016-08-10 11:32:20 -070071 }
72
ronshapiroe05f9212017-08-08 11:22:11 -070073 /**
74 * Dependencies necessary to invoke an {@code @Inject} constructor or {@code @Provides} method.
75 */
76 abstract ImmutableSet<DependencyRequest> provisionDependencies();
77
78 @Memoized
79 ImmutableSet<DependencyRequest> membersInjectionDependencies() {
80 return injectionSites()
81 .stream()
82 .flatMap(i -> i.dependencies().stream())
83 .collect(toImmutableSet());
84 }
85
86 /**
87 * {@link InjectionSite}s for all {@code @Inject} members if {@link #bindingKind()} is {@link
88 * ContributionBinding.Kind#INJECTION}, otherwise empty.
89 */
90 abstract ImmutableSortedSet<InjectionSite> injectionSites();
gak6fc2b5a2016-08-10 11:32:20 -070091
92 @Override
dpba2620422015-08-15 10:06:54 -070093 public BindingType bindingType() {
94 return BindingType.PROVISION;
gak09075bc2014-07-31 11:02:39 -070095 }
dpb57198802015-12-17 12:18:15 -080096
97 @Override
98 abstract Optional<ProvisionBinding> unresolved();
99
dpb6bd55de2015-09-28 07:58:09 -0700100 @Override
beder3bdf32d2016-02-16 11:37:07 -0800101 abstract Optional<Scope> scope();
gake1b68a22016-04-07 11:54:06 -0700102
dpb6313ae32016-06-21 15:15:26 -0700103 private static Builder builder() {
104 return new AutoValue_ProvisionBinding.Builder()
ronshapiroe05f9212017-08-08 11:22:11 -0700105 .provisionDependencies(ImmutableSet.of())
106 .injectionSites(ImmutableSortedSet.of());
dpb6313ae32016-06-21 15:15:26 -0700107 }
ronshapirod804a302016-11-08 10:21:56 -0800108
dpbd8d950a2016-08-30 09:24:37 -0700109 abstract Builder toBuilder();
110
ronshapiro1c891fb2017-07-09 11:53:51 -0400111 boolean shouldCheckForNull(CompilerOptions compilerOptions) {
112 return !providesPrimitiveType()
113 && !nullableType().isPresent()
114 && compilerOptions.doCheckForNulls();
115 }
116
117 private boolean providesPrimitiveType() {
118 return bindingElement().isPresent()
119 && MoreElements.asExecutable(bindingElement().get())
120 .getReturnType()
121 .getKind()
122 .isPrimitive();
123 }
124
dpb6313ae32016-06-21 15:15:26 -0700125 @AutoValue.Builder
126 @CanIgnoreReturnValue
127 abstract static class Builder extends ContributionBinding.Builder<Builder> {
ronshapiroe05f9212017-08-08 11:22:11 -0700128 abstract Builder provisionDependencies(DependencyRequest... provisionDependencies);
129 abstract Builder provisionDependencies(ImmutableSet<DependencyRequest> provisionDependencies);
dpb6313ae32016-06-21 15:15:26 -0700130
ronshapiroe05f9212017-08-08 11:22:11 -0700131 abstract Builder injectionSites(ImmutableSortedSet<InjectionSite> injectionSites);
gak6fc2b5a2016-08-10 11:32:20 -0700132
dpb6313ae32016-06-21 15:15:26 -0700133 abstract Builder unresolved(ProvisionBinding unresolved);
134
135 abstract Builder scope(Optional<Scope> scope);
136
137 @CheckReturnValue
138 abstract ProvisionBinding build();
139 }
140
Christian Edward Gruber4df36792014-04-15 14:01:28 -0700141 static final class Factory {
Gregory Kick281cf482014-06-12 19:51:41 -0700142 private final Types types;
Christian Edward Gruber9daba782014-05-04 18:06:26 -0700143 private final Key.Factory keyFactory;
Christian Edward Gruber4aec5ba2014-05-20 19:37:11 -0700144 private final DependencyRequest.Factory dependencyRequestFactory;
ronshapiroe05f9212017-08-08 11:22:11 -0700145 private final MembersInjectionBinding.Factory membersInjectionBindingFactory;
Christian Edward Gruberfbb8e4b2014-04-15 14:02:34 -0700146
ronshapiroe05f9212017-08-08 11:22:11 -0700147 Factory(
148 Types types,
149 Key.Factory keyFactory,
150 DependencyRequest.Factory dependencyRequestFactory,
151 MembersInjectionBinding.Factory membersInjectionBindingFactory) {
Gregory Kick281cf482014-06-12 19:51:41 -0700152 this.types = types;
Christian Edward Gruber9daba782014-05-04 18:06:26 -0700153 this.keyFactory = keyFactory;
Christian Edward Gruber4aec5ba2014-05-20 19:37:11 -0700154 this.dependencyRequestFactory = dependencyRequestFactory;
ronshapiroe05f9212017-08-08 11:22:11 -0700155 this.membersInjectionBindingFactory = membersInjectionBindingFactory;
Christian Edward Gruberfbb8e4b2014-04-15 14:02:34 -0700156 }
gakcc087192015-01-25 20:29:15 -0800157
sameb2ea676a2015-01-15 10:20:24 -0800158 /**
159 * Returns a ProvisionBinding for the given element. If {@code resolvedType} is present, this
dpb54203462016-10-19 13:46:43 -0700160 * will return a resolved binding, with the key and type resolved to the given type (using
sameba5bf53f2015-01-28 15:51:27 -0800161 * {@link Types#asMemberOf(DeclaredType, Element)}).
sameb2ea676a2015-01-15 10:20:24 -0800162 */
dpb54203462016-10-19 13:46:43 -0700163 ProvisionBinding forInjectConstructor(
164 ExecutableElement constructorElement, Optional<TypeMirror> resolvedType) {
Christian Edward Gruber4df36792014-04-15 14:01:28 -0700165 checkNotNull(constructorElement);
166 checkArgument(constructorElement.getKind().equals(CONSTRUCTOR));
Christian Edward Gruber8bcede42014-07-18 18:08:42 -0700167 checkArgument(isAnnotationPresent(constructorElement, Inject.class));
sameb2ea676a2015-01-15 10:20:24 -0800168 checkArgument(!getQualifier(constructorElement).isPresent());
169
sameb2ea676a2015-01-15 10:20:24 -0800170 ExecutableType cxtorType = MoreTypes.asExecutable(constructorElement.asType());
171 DeclaredType enclosingCxtorType =
172 MoreTypes.asDeclared(constructorElement.getEnclosingElement().asType());
173 // If the class this is constructing has some type arguments, resolve everything.
174 if (!enclosingCxtorType.getTypeArguments().isEmpty() && resolvedType.isPresent()) {
175 DeclaredType resolved = MoreTypes.asDeclared(resolvedType.get());
176 // Validate that we're resolving from the correct type.
177 checkState(types.isSameType(types.erasure(resolved), types.erasure(enclosingCxtorType)),
178 "erased expected type: %s, erased actual type: %s",
179 types.erasure(resolved), types.erasure(enclosingCxtorType));
180 cxtorType = MoreTypes.asExecutable(types.asMemberOf(resolved, constructorElement));
181 enclosingCxtorType = resolved;
sameb2ea676a2015-01-15 10:20:24 -0800182 }
183
184 Key key = keyFactory.forInjectConstructorWithResolvedType(enclosingCxtorType);
Christian Edward Gruber4df36792014-04-15 14:01:28 -0700185 checkArgument(!key.qualifier().isPresent());
ronshapiroe05f9212017-08-08 11:22:11 -0700186 ImmutableSet<DependencyRequest> provisionDependencies =
dpb31ce6732016-04-29 09:19:30 -0700187 dependencyRequestFactory.forRequiredResolvedVariables(
188 constructorElement.getParameters(), cxtorType.getParameterTypes());
ronshapiroe05f9212017-08-08 11:22:11 -0700189 // TODO(ronshapiro): instead of creating a MembersInjectionBinding just to retrieve the
190 // injection sites, create an InjectionSite.Factory and pass that in here.
191 ImmutableSortedSet<InjectionSite> injectionSites =
192 membersInjectionBindingFactory
193 .forInjectedType(enclosingCxtorType, Optional.empty())
194 .injectionSites();
dpb6313ae32016-06-21 15:15:26 -0700195
196 ProvisionBinding.Builder builder =
197 ProvisionBinding.builder()
198 .contributionType(ContributionType.UNIQUE)
199 .bindingElement(constructorElement)
200 .key(key)
ronshapiroe05f9212017-08-08 11:22:11 -0700201 .provisionDependencies(provisionDependencies)
202 .injectionSites(injectionSites)
dpb6313ae32016-06-21 15:15:26 -0700203 .bindingKind(Kind.INJECTION)
204 .scope(Scope.uniqueScopeOf(constructorElement.getEnclosingElement()));
gakb82b5002015-02-19 00:08:30 -0800205
sameba5bf53f2015-01-28 15:51:27 -0800206 TypeElement bindingTypeElement =
207 MoreElements.asType(constructorElement.getEnclosingElement());
dpb6313ae32016-06-21 15:15:26 -0700208 if (hasNonDefaultTypeParameters(bindingTypeElement, key.type(), types)) {
dpbffd98f62016-12-20 10:05:16 -0800209 builder.unresolved(forInjectConstructor(constructorElement, Optional.empty()));
dpb6313ae32016-06-21 15:15:26 -0700210 }
211 return builder.build();
Christian Edward Gruberfbb8e4b2014-04-15 14:02:34 -0700212 }
213
dpbdb240722016-01-25 14:06:41 -0800214 ProvisionBinding forProvidesMethod(
215 ExecutableElement providesMethod, TypeElement contributedBy) {
Christian Edward Gruber9daba782014-05-04 18:06:26 -0700216 checkArgument(providesMethod.getKind().equals(METHOD));
sameb0d49be82015-01-22 17:29:48 -0800217 ExecutableType resolvedMethod =
dpb4955ef92016-04-29 12:31:14 -0700218 MoreTypes.asExecutable(
219 types.asMemberOf(MoreTypes.asDeclared(contributedBy.asType()), providesMethod));
220 Key key = keyFactory.forProvidesMethod(providesMethod, contributedBy);
gak09075bc2014-07-31 11:02:39 -0700221 ImmutableSet<DependencyRequest> dependencies =
sameb0d49be82015-01-22 17:29:48 -0800222 dependencyRequestFactory.forRequiredResolvedVariables(
sameb0d49be82015-01-22 17:29:48 -0800223 providesMethod.getParameters(),
224 resolvedMethod.getParameterTypes());
dpb6313ae32016-06-21 15:15:26 -0700225 return ProvisionBinding.builder()
226 .contributionType(ContributionType.fromBindingMethod(providesMethod))
227 .bindingElement(providesMethod)
228 .contributingModule(contributedBy)
229 .key(key)
ronshapiroe05f9212017-08-08 11:22:11 -0700230 .provisionDependencies(dependencies)
dpb6313ae32016-06-21 15:15:26 -0700231 .nullableType(ConfigurationAnnotations.getNullableType(providesMethod))
232 .wrappedMapKey(wrapOptionalInEquivalence(getMapKey(providesMethod)))
233 .bindingKind(Kind.PROVISION)
234 .scope(Scope.uniqueScopeOf(providesMethod))
235 .build();
Christian Edward Gruber4df36792014-04-15 14:01:28 -0700236 }
gake1b68a22016-04-07 11:54:06 -0700237
gakf53c3f92016-08-17 09:55:56 -0700238 /** A synthetic binding of {@code Map<K, V>} that depends on {@code Map<K, Provider<V>>}. */
239 ProvisionBinding syntheticMapOfValuesBinding(Key mapOfValuesKey) {
240 checkNotNull(mapOfValuesKey);
241 Optional<Key> mapOfProvidersKey = keyFactory.implicitMapProviderKeyFrom(mapOfValuesKey);
242 checkArgument(mapOfProvidersKey.isPresent(), "%s is not a key for Map<K, V>", mapOfValuesKey);
dpbad763612016-04-05 14:30:09 -0700243 DependencyRequest requestForMapOfProviders =
gaked30daa2017-01-06 15:38:17 -0800244 dependencyRequestFactory.providerForImplicitMapBinding(mapOfProvidersKey.get());
dpb6313ae32016-06-21 15:15:26 -0700245 return ProvisionBinding.builder()
246 .contributionType(ContributionType.UNIQUE)
gakf53c3f92016-08-17 09:55:56 -0700247 .key(mapOfValuesKey)
ronshapiroe05f9212017-08-08 11:22:11 -0700248 .provisionDependencies(requestForMapOfProviders)
dpb6313ae32016-06-21 15:15:26 -0700249 .bindingKind(Kind.SYNTHETIC_MAP)
dpb6313ae32016-06-21 15:15:26 -0700250 .build();
houcycb6c79f2014-08-08 12:42:22 -0700251 }
Christian Edward Gruber98ad6e22014-06-04 12:42:49 -0700252
dpbdb240722016-01-25 14:06:41 -0800253 /**
dpbad763612016-04-05 14:30:09 -0700254 * A synthetic binding that depends explicitly on a set of individual provision multibinding
255 * contribution methods.
dpb7edcd4d2016-06-21 07:52:39 -0700256 *
dpbad763612016-04-05 14:30:09 -0700257 * <p>Note that these could be set multibindings or map multibindings.
dpbdb240722016-01-25 14:06:41 -0800258 */
259 ProvisionBinding syntheticMultibinding(
gakf53c3f92016-08-17 09:55:56 -0700260 Key key, Iterable<ContributionBinding> multibindingContributions) {
dpb6313ae32016-06-21 15:15:26 -0700261 return ProvisionBinding.builder()
262 .contributionType(ContributionType.UNIQUE)
gakf53c3f92016-08-17 09:55:56 -0700263 .key(key)
ronshapiroe05f9212017-08-08 11:22:11 -0700264 .provisionDependencies(
dpb34e4ef72016-08-10 07:23:36 -0700265 dependencyRequestFactory.forMultibindingContributions(multibindingContributions))
gakf53c3f92016-08-17 09:55:56 -0700266 .bindingKind(Kind.forMultibindingKey(key))
dpb6313ae32016-06-21 15:15:26 -0700267 .build();
dpbdb240722016-01-25 14:06:41 -0800268 }
269
Christian Edward Gruber98ad6e22014-06-04 12:42:49 -0700270 ProvisionBinding forComponent(TypeElement componentDefinitionType) {
271 checkNotNull(componentDefinitionType);
dpb6313ae32016-06-21 15:15:26 -0700272 return ProvisionBinding.builder()
273 .contributionType(ContributionType.UNIQUE)
274 .bindingElement(componentDefinitionType)
275 .key(keyFactory.forComponent(componentDefinitionType.asType()))
276 .bindingKind(Kind.COMPONENT)
277 .build();
Christian Edward Gruber98ad6e22014-06-04 12:42:49 -0700278 }
Christian Edward Gruber14aafa62014-07-18 18:06:25 -0700279
280 ProvisionBinding forComponentMethod(ExecutableElement componentMethod) {
281 checkNotNull(componentMethod);
282 checkArgument(componentMethod.getKind().equals(METHOD));
283 checkArgument(componentMethod.getParameters().isEmpty());
dpb6313ae32016-06-21 15:15:26 -0700284 return ProvisionBinding.builder()
285 .contributionType(ContributionType.UNIQUE)
286 .bindingElement(componentMethod)
287 .key(keyFactory.forComponentMethod(componentMethod))
288 .nullableType(ConfigurationAnnotations.getNullableType(componentMethod))
289 .bindingKind(Kind.COMPONENT_PROVISION)
290 .scope(Scope.uniqueScopeOf(componentMethod))
291 .build();
Christian Edward Gruber14aafa62014-07-18 18:06:25 -0700292 }
dpb99d64082015-11-12 11:27:12 -0800293
bederb50b8ae2016-12-07 08:36:26 -0800294 ProvisionBinding forBuilderBinding(BuilderRequirementMethod method) {
295 ExecutableElement builderMethod = method.method();
296
297 checkNotNull(builderMethod);
298 checkArgument(builderMethod.getKind().equals(METHOD));
299 checkArgument(builderMethod.getParameters().size() == 1);
300 VariableElement parameterElement = Iterables.getOnlyElement(builderMethod.getParameters());
301 return ProvisionBinding.builder()
302 .contributionType(ContributionType.UNIQUE)
303 .bindingElement(builderMethod)
304 .key(method.requirement().key().get())
305 .nullableType(ConfigurationAnnotations.getNullableType(parameterElement))
306 .bindingKind(Kind.BUILDER_BINDING)
307 .build();
308 }
309
dpb99d64082015-11-12 11:27:12 -0800310 ProvisionBinding forSubcomponentBuilderMethod(
311 ExecutableElement subcomponentBuilderMethod, TypeElement contributedBy) {
312 checkNotNull(subcomponentBuilderMethod);
313 checkArgument(subcomponentBuilderMethod.getKind().equals(METHOD));
314 checkArgument(subcomponentBuilderMethod.getParameters().isEmpty());
315 DeclaredType declaredContainer = asDeclared(contributedBy.asType());
dpb6313ae32016-06-21 15:15:26 -0700316 return ProvisionBinding.builder()
317 .contributionType(ContributionType.UNIQUE)
318 .bindingElement(subcomponentBuilderMethod)
319 .key(
320 keyFactory.forSubcomponentBuilderMethod(subcomponentBuilderMethod, declaredContainer))
321 .bindingKind(Kind.SUBCOMPONENT_BUILDER)
322 .build();
dpb99d64082015-11-12 11:27:12 -0800323 }
gake1b68a22016-04-07 11:54:06 -0700324
ronshapirofbb68402016-08-31 06:44:45 -0700325 ProvisionBinding syntheticSubcomponentBuilder(
326 ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations) {
327 SubcomponentDeclaration subcomponentDeclaration = subcomponentDeclarations.iterator().next();
328 return ProvisionBinding.builder()
329 .contributionType(ContributionType.UNIQUE)
330 .key(subcomponentDeclaration.key())
331 .bindingKind(Kind.SUBCOMPONENT_BUILDER)
332 .build();
333 }
334
gake1b68a22016-04-07 11:54:06 -0700335 ProvisionBinding delegate(
336 DelegateDeclaration delegateDeclaration, ProvisionBinding delegate) {
ronshapiroa0bd7752016-08-10 09:48:51 -0700337 return delegateBuilder(delegateDeclaration).nullableType(delegate.nullableType()).build();
338 }
339
340 /**
341 * A form of {@link #delegate(DelegateDeclaration, ProvisionBinding)} when the right-hand-side
342 * of a {@link dagger.Binds} method cannot be resolved.
343 */
344 ProvisionBinding missingDelegate(DelegateDeclaration delegateDeclaration) {
345 return delegateBuilder(delegateDeclaration).build();
346 }
347
348 private ProvisionBinding.Builder delegateBuilder(DelegateDeclaration delegateDeclaration) {
dpb6313ae32016-06-21 15:15:26 -0700349 return ProvisionBinding.builder()
350 .contributionType(delegateDeclaration.contributionType())
dpbdd276032016-07-11 09:34:43 -0700351 .bindingElement(delegateDeclaration.bindingElement().get())
dpb6313ae32016-06-21 15:15:26 -0700352 .contributingModule(delegateDeclaration.contributingModule().get())
353 .key(keyFactory.forDelegateBinding(delegateDeclaration, Provider.class))
ronshapiroe05f9212017-08-08 11:22:11 -0700354 .provisionDependencies(delegateDeclaration.delegateRequest())
dpb6313ae32016-06-21 15:15:26 -0700355 .wrappedMapKey(delegateDeclaration.wrappedMapKey())
356 .bindingKind(Kind.SYNTHETIC_DELEGATE_BINDING)
ronshapiroa0bd7752016-08-10 09:48:51 -0700357 .scope(Scope.uniqueScopeOf(delegateDeclaration.bindingElement().get()));
gake1b68a22016-04-07 11:54:06 -0700358 }
dpbd8d950a2016-08-30 09:24:37 -0700359
360 /**
ronshapirod804a302016-11-08 10:21:56 -0800361 * Returns a synthetic binding for a {@code @ForReleasableReferences(scope)
362 * ReleasableReferenceManager} that provides the component-instantiated object.
363 */
364 ProvisionBinding provideReleasableReferenceManager(Scope scope) {
365 return ProvisionBinding.builder()
366 .contributionType(ContributionType.UNIQUE)
367 .key(keyFactory.forReleasableReferenceManager(scope))
368 .bindingKind(Kind.SYNTHETIC_RELEASABLE_REFERENCE_MANAGER)
369 .build();
370 }
371
372 /**
373 * Returns a synthetic binding for a {@code @ForReleasableReferences(scope)
374 * TypedReleasableReferenceManager<metadataType>} that provides the component-instantiated
375 * object.
376 */
377 ContributionBinding provideTypedReleasableReferenceManager(
378 Scope scope, DeclaredType metadataType) {
379 return provideReleasableReferenceManager(scope)
380 .toBuilder()
381 .key(keyFactory.forTypedReleasableReferenceManager(scope, metadataType))
382 .build();
383 }
384
385 /** Returns a synthetic binding for {@code Set<ReleasableReferenceManager>}. */
386 ProvisionBinding provideSetOfReleasableReferenceManagers() {
387 return ProvisionBinding.builder()
388 .contributionType(ContributionType.UNIQUE)
389 .key(keyFactory.forSetOfReleasableReferenceManagers())
390 .bindingKind(Kind.SYNTHETIC_RELEASABLE_REFERENCE_MANAGERS)
391 .build();
392 }
393
394 /**
395 * Returns a synthetic binding for {@code Set<TypedReleasableReferenceManager<metadataType>}.
396 */
397 ContributionBinding provideSetOfTypedReleasableReferenceManagers(DeclaredType metadataType) {
398 return provideSetOfReleasableReferenceManagers()
399 .toBuilder()
400 .key(keyFactory.forSetOfTypedReleasableReferenceManagers(metadataType))
401 .build();
402 }
403
404 /**
dpbd8d950a2016-08-30 09:24:37 -0700405 * Returns a synthetic binding for an {@linkplain dagger.BindsOptionalOf optional binding} in a
406 * component with no binding for the underlying key.
407 */
408 ProvisionBinding syntheticAbsentBinding(Key key) {
409 return ProvisionBinding.builder()
410 .contributionType(ContributionType.UNIQUE)
411 .key(key)
412 .bindingKind(Kind.SYNTHETIC_OPTIONAL_BINDING)
413 .build();
414 }
415
416 /**
417 * Returns a synthetic binding for an {@linkplain dagger.BindsOptionalOf optional binding} in a
418 * component with a binding for the underlying key.
419 */
ronshapiro3a891dd2017-07-04 20:04:14 -0700420 ProvisionBinding syntheticPresentBinding(Key key, DependencyRequest.Kind kind) {
dpbd8d950a2016-08-30 09:24:37 -0700421 return syntheticAbsentBinding(key)
422 .toBuilder()
ronshapiroe05f9212017-08-08 11:22:11 -0700423 .provisionDependencies(
ronshapiro3a891dd2017-07-04 20:04:14 -0700424 dependencyRequestFactory.forSyntheticPresentOptionalBinding(key, kind))
dpbd8d950a2016-08-30 09:24:37 -0700425 .build();
426 }
Christian Edward Gruber4df36792014-04-15 14:01:28 -0700427 }
428}