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