• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Dagger Authors.
3  *
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  */
16 
17 package dagger.internal.codegen.binding;
18 
19 import static dagger.internal.codegen.xprocessing.XElements.asMethod;
20 import static java.util.Arrays.asList;
21 
22 import androidx.room.compiler.processing.XElement;
23 import androidx.room.compiler.processing.XElementKt;
24 import androidx.room.compiler.processing.XType;
25 import androidx.room.compiler.processing.XTypeElement;
26 import com.google.errorprone.annotations.CanIgnoreReturnValue;
27 import com.google.errorprone.annotations.CheckReturnValue;
28 import dagger.internal.codegen.base.ContributionType;
29 import dagger.internal.codegen.base.ContributionType.HasContributionType;
30 import dagger.internal.codegen.base.MapType;
31 import dagger.internal.codegen.base.SetType;
32 import dagger.internal.codegen.model.BindingKind;
33 import dagger.internal.codegen.model.DaggerAnnotation;
34 import dagger.internal.codegen.model.DependencyRequest;
35 import dagger.internal.codegen.model.Key;
36 import dagger.internal.codegen.xprocessing.XTypes;
37 import java.util.Optional;
38 
39 /**
40  * An abstract class for a value object representing the mechanism by which a {@link Key} can be
41  * contributed to a dependency graph.
42  */
43 @CheckReturnValue
44 public abstract class ContributionBinding extends Binding implements HasContributionType {
45 
46   /** Returns the nullability of this binding. */
nullability()47   public abstract Nullability nullability();
48 
49   // Note: We're using DaggerAnnotation instead of XAnnotation for its equals/hashcode
mapKey()50   public abstract Optional<DaggerAnnotation> mapKey();
51 
52   /** If {@link #bindingElement()} is a method that returns a primitive type, returns that type. */
contributedPrimitiveType()53   public final Optional<XType> contributedPrimitiveType() {
54     return bindingElement()
55         .filter(XElementKt::isMethod)
56         .map(bindingElement -> asMethod(bindingElement).getReturnType())
57         .filter(XTypes::isPrimitive);
58   }
59 
60   @Override
requiresModuleInstance()61   public boolean requiresModuleInstance() {
62     return !isContributingModuleKotlinObject() && super.requiresModuleInstance();
63   }
64 
65   @Override
isNullable()66   public final boolean isNullable() {
67     return nullability().isNullable();
68   }
69 
70   /**
71    * Returns {@code true} if the contributing module is a Kotlin object. Note that a companion
72    * object is also considered a Kotlin object.
73    */
isContributingModuleKotlinObject()74   private boolean isContributingModuleKotlinObject() {
75     return contributingModule().isPresent()
76         && (contributingModule().get().isKotlinObject()
77             || contributingModule().get().isCompanionObject());
78   }
79 
80   /**
81    * The {@link XType type} for the {@code Factory<T>} or {@code Producer<T>} which is created for
82    * this binding. Uses the binding's key, V in the case of {@code Map<K, FrameworkClass<V>>>}, and
83    * E {@code Set<E>} for {@link dagger.multibindings.IntoSet @IntoSet} methods.
84    */
contributedType()85   public final XType contributedType() {
86     switch (contributionType()) {
87       case MAP:
88         return MapType.from(key()).unwrappedFrameworkValueType();
89       case SET:
90         return SetType.from(key()).elementType();
91       case SET_VALUES:
92       case UNIQUE:
93         return key().type().xprocessing();
94     }
95     throw new AssertionError();
96   }
97 
toBuilder()98   public abstract Builder<?, ?> toBuilder();
99 
100   /**
101    * Base builder for {@link com.google.auto.value.AutoValue @AutoValue} subclasses of {@link
102    * ContributionBinding}.
103    */
104   public abstract static class Builder<C extends ContributionBinding, B extends Builder<C, B>> {
105     @CanIgnoreReturnValue
dependencies(Iterable<DependencyRequest> dependencies)106     public abstract B dependencies(Iterable<DependencyRequest> dependencies);
107 
108     @CanIgnoreReturnValue
dependencies(DependencyRequest... dependencies)109     public B dependencies(DependencyRequest... dependencies) {
110       return dependencies(asList(dependencies));
111     }
112 
113     @CanIgnoreReturnValue
unresolved(C unresolved)114     public abstract B unresolved(C unresolved);
115 
116     @CanIgnoreReturnValue
contributionType(ContributionType contributionType)117     public abstract B contributionType(ContributionType contributionType);
118 
119     @CanIgnoreReturnValue
bindingElement(XElement bindingElement)120     public abstract B bindingElement(XElement bindingElement);
121 
122     @CanIgnoreReturnValue
bindingElement(Optional<XElement> bindingElement)123     abstract B bindingElement(Optional<XElement> bindingElement);
124 
125     @CanIgnoreReturnValue
clearBindingElement()126     public final B clearBindingElement() {
127       return bindingElement(Optional.empty());
128     };
129 
130     @CanIgnoreReturnValue
contributingModule(XTypeElement contributingModule)131     abstract B contributingModule(XTypeElement contributingModule);
132 
133     @CanIgnoreReturnValue
key(Key key)134     public abstract B key(Key key);
135 
136     @CanIgnoreReturnValue
nullability(Nullability nullability)137     public abstract B nullability(Nullability nullability);
138 
139     @CanIgnoreReturnValue
mapKey(Optional<DaggerAnnotation> mapKey)140     abstract B mapKey(Optional<DaggerAnnotation> mapKey);
141 
142     @CanIgnoreReturnValue
kind(BindingKind kind)143     public abstract B kind(BindingKind kind);
144 
build()145     abstract C build();
146   }
147 }
148