• 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.extension.DaggerStreams.toImmutableSet;
20 import static dagger.model.BindingKind.COMPONENT_PROVISION;
21 import static dagger.model.BindingKind.PROVISION;
22 
23 import com.google.auto.value.AutoValue;
24 import com.google.auto.value.extension.memoized.Memoized;
25 import com.google.common.collect.ImmutableSet;
26 import com.google.common.collect.ImmutableSortedSet;
27 import com.google.errorprone.annotations.CanIgnoreReturnValue;
28 import dagger.internal.codegen.binding.MembersInjectionBinding.InjectionSite;
29 import dagger.internal.codegen.compileroption.CompilerOptions;
30 import dagger.model.BindingKind;
31 import dagger.model.DependencyRequest;
32 import dagger.model.Key;
33 import dagger.model.Scope;
34 import java.util.Optional;
35 
36 /** A value object representing the mechanism by which a {@link Key} can be provided. */
37 @AutoValue
38 public abstract class ProvisionBinding extends ContributionBinding {
39 
40   @Override
41   @Memoized
explicitDependencies()42   public ImmutableSet<DependencyRequest> explicitDependencies() {
43     return ImmutableSet.<DependencyRequest>builder()
44         .addAll(provisionDependencies())
45         .addAll(membersInjectionDependencies())
46         .build();
47   }
48 
49   /**
50    * Dependencies necessary to invoke an {@code @Inject} constructor or {@code @Provides} method.
51    */
provisionDependencies()52   public abstract ImmutableSet<DependencyRequest> provisionDependencies();
53 
54   @Memoized
membersInjectionDependencies()55   ImmutableSet<DependencyRequest> membersInjectionDependencies() {
56     return injectionSites()
57         .stream()
58         .flatMap(i -> i.dependencies().stream())
59         .collect(toImmutableSet());
60   }
61 
62   /**
63    * {@link InjectionSite}s for all {@code @Inject} members if {@link #kind()} is {@link
64    * BindingKind#INJECTION}, otherwise empty.
65    */
injectionSites()66   public abstract ImmutableSortedSet<InjectionSite> injectionSites();
67 
68   @Override
bindingType()69   public BindingType bindingType() {
70     return BindingType.PROVISION;
71   }
72 
73   @Override
unresolved()74   public abstract Optional<ProvisionBinding> unresolved();
75 
76   // TODO(ronshapiro): we should be able to remove this, but AutoValue barks on the Builder's scope
77   // method, saying that the method doesn't correspond to a property of ProvisionBinding
78   @Override
scope()79   public abstract Optional<Scope> scope();
80 
builder()81   public static Builder builder() {
82     return new AutoValue_ProvisionBinding.Builder()
83         .provisionDependencies(ImmutableSet.of())
84         .injectionSites(ImmutableSortedSet.of());
85   }
86 
87   @Override
toBuilder()88   public abstract Builder toBuilder();
89 
90   private static final ImmutableSet<BindingKind> KINDS_TO_CHECK_FOR_NULL =
91       ImmutableSet.of(PROVISION, COMPONENT_PROVISION);
92 
shouldCheckForNull(CompilerOptions compilerOptions)93   public boolean shouldCheckForNull(CompilerOptions compilerOptions) {
94     return KINDS_TO_CHECK_FOR_NULL.contains(kind())
95         && !contributedPrimitiveType().isPresent()
96         && !nullableType().isPresent()
97         && compilerOptions.doCheckForNulls();
98   }
99 
100   // Profiling determined that this method is called enough times that memoizing it had a measurable
101   // performance improvement for large components.
102   @Memoized
103   @Override
requiresModuleInstance()104   public boolean requiresModuleInstance() {
105     return super.requiresModuleInstance();
106   }
107 
108   @Memoized
109   @Override
hashCode()110   public abstract int hashCode();
111 
112   // TODO(ronshapiro,dpb): simplify the equality semantics
113   @Override
equals(Object obj)114   public abstract boolean equals(Object obj);
115 
116   /** A {@link ProvisionBinding} builder. */
117   @AutoValue.Builder
118   @CanIgnoreReturnValue
119   public abstract static class Builder
120       extends ContributionBinding.Builder<ProvisionBinding, Builder> {
121 
122     @Override
dependencies(Iterable<DependencyRequest> dependencies)123     public Builder dependencies(Iterable<DependencyRequest> dependencies) {
124       return provisionDependencies(dependencies);
125     }
126 
provisionDependencies(Iterable<DependencyRequest> provisionDependencies)127     abstract Builder provisionDependencies(Iterable<DependencyRequest> provisionDependencies);
128 
injectionSites(ImmutableSortedSet<InjectionSite> injectionSites)129     public abstract Builder injectionSites(ImmutableSortedSet<InjectionSite> injectionSites);
130 
131     @Override
unresolved(ProvisionBinding unresolved)132     public abstract Builder unresolved(ProvisionBinding unresolved);
133 
scope(Optional<Scope> scope)134     public abstract Builder scope(Optional<Scope> scope);
135   }
136 
137 }
138