• 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 androidx.room.compiler.processing.compat.XConverters.toJavac;
20 import static java.util.stream.Collectors.toList;
21 
22 import androidx.room.compiler.processing.XElement;
23 import androidx.room.compiler.processing.XTypeElement;
24 import com.google.auto.value.AutoValue;
25 import com.google.auto.value.extension.memoized.Memoized;
26 import com.google.common.collect.ImmutableSet;
27 import com.google.common.collect.ImmutableSortedSet;
28 import dagger.spi.model.BindingKind;
29 import dagger.spi.model.DependencyRequest;
30 import dagger.spi.model.Key;
31 import java.util.Optional;
32 import javax.lang.model.element.Element;
33 import javax.lang.model.element.ExecutableElement;
34 import javax.lang.model.element.Modifier;
35 import javax.lang.model.element.VariableElement;
36 
37 /** Represents the full members injection of a particular type. */
38 @AutoValue
39 public abstract class MembersInjectionBinding extends Binding {
create( Key key, ImmutableSet<DependencyRequest> dependencies, Optional<MembersInjectionBinding> unresolved, ImmutableSortedSet<InjectionSite> injectionSites)40   static MembersInjectionBinding create(
41       Key key,
42       ImmutableSet<DependencyRequest> dependencies,
43       Optional<MembersInjectionBinding> unresolved,
44       ImmutableSortedSet<InjectionSite> injectionSites) {
45     return new AutoValue_MembersInjectionBinding(key, dependencies, unresolved, injectionSites);
46   }
47 
48   @Override
bindingElement()49   public final Optional<XElement> bindingElement() {
50     return Optional.of(membersInjectedType());
51   }
52 
membersInjectedType()53   public final XTypeElement membersInjectedType() {
54     return key().type().xprocessing().getTypeElement();
55   }
56 
57   @Override
unresolved()58   public abstract Optional<MembersInjectionBinding> unresolved();
59 
60   @Override
contributingModule()61   public Optional<XTypeElement> contributingModule() {
62     return Optional.empty();
63   }
64 
65   /** The set of individual sites where {@link Inject} is applied. */
injectionSites()66   public abstract ImmutableSortedSet<InjectionSite> injectionSites();
67 
68   @Override
bindingType()69   public BindingType bindingType() {
70     return BindingType.MEMBERS_INJECTION;
71   }
72 
73   @Override
kind()74   public BindingKind kind() {
75     return BindingKind.MEMBERS_INJECTION;
76   }
77 
78   @Override
isNullable()79   public boolean isNullable() {
80     return false;
81   }
82 
83   /**
84    * Returns {@code true} if any of this binding's injection sites are directly on the bound type.
85    */
hasLocalInjectionSites()86   public boolean hasLocalInjectionSites() {
87     return injectionSites().stream()
88         .anyMatch(
89             injectionSite ->
90                 injectionSite
91                     .element()
92                     .getEnclosingElement()
93                     .equals(toJavac(membersInjectedType())));
94   }
95 
96   @Override
requiresModuleInstance()97   public boolean requiresModuleInstance() {
98     return false;
99   }
100 
101   @Memoized
102   @Override
hashCode()103   public abstract int hashCode();
104 
105   // TODO(ronshapiro,dpb): simplify the equality semantics
106   @Override
equals(Object obj)107   public abstract boolean equals(Object obj);
108 
109   /** Metadata about a field or method injection site. */
110   @AutoValue
111   public abstract static class InjectionSite {
112     /** The type of injection site. */
113     public enum Kind {
114       FIELD,
115       METHOD,
116     }
117 
kind()118     public abstract Kind kind();
119 
element()120     public abstract Element element();
121 
dependencies()122     public abstract ImmutableSet<DependencyRequest> dependencies();
123 
124     /**
125      * Returns the index of {@link #element()} in its parents {@code @Inject} members that have the
126      * same simple name. This method filters out private elements so that the results will be
127      * consistent independent of whether the build system uses header jars or not.
128      */
129     @Memoized
indexAmongAtInjectMembersWithSameSimpleName()130     public int indexAmongAtInjectMembersWithSameSimpleName() {
131       return element()
132           .getEnclosingElement()
133           .getEnclosedElements()
134           .stream()
135           .filter(InjectionAnnotations::hasInjectAnnotation)
136           .filter(element -> !element.getModifiers().contains(Modifier.PRIVATE))
137           .filter(element -> element.getSimpleName().equals(this.element().getSimpleName()))
138           .collect(toList())
139           .indexOf(element());
140     }
141 
field(VariableElement element, DependencyRequest dependency)142     public static InjectionSite field(VariableElement element, DependencyRequest dependency) {
143       return new AutoValue_MembersInjectionBinding_InjectionSite(
144           Kind.FIELD, element, ImmutableSet.of(dependency));
145     }
146 
method( ExecutableElement element, Iterable<DependencyRequest> dependencies)147     public static InjectionSite method(
148         ExecutableElement element, Iterable<DependencyRequest> dependencies) {
149       return new AutoValue_MembersInjectionBinding_InjectionSite(
150           Kind.METHOD, element, ImmutableSet.copyOf(dependencies));
151     }
152   }
153 }
154