• 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;
18 
19 import static dagger.internal.codegen.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.MembersInjectionBinding.InjectionSite;
29 import dagger.model.BindingKind;
30 import dagger.model.DependencyRequest;
31 import dagger.model.Key;
32 import dagger.model.Scope;
33 import java.util.Optional;
34 
35 /**
36  * A value object representing the mechanism by which a {@link Key} can be provided.
37  */
38 @AutoValue
39 abstract class ProvisionBinding extends ContributionBinding {
40 
41   @Override
42   @Memoized
explicitDependencies()43   ImmutableSet<DependencyRequest> explicitDependencies() {
44     return ImmutableSet.<DependencyRequest>builder()
45         .addAll(provisionDependencies())
46         .addAll(membersInjectionDependencies())
47         .build();
48   }
49 
50   /**
51    * Dependencies necessary to invoke an {@code @Inject} constructor or {@code @Provides} method.
52    */
provisionDependencies()53   abstract ImmutableSet<DependencyRequest> provisionDependencies();
54 
55   @Memoized
membersInjectionDependencies()56   ImmutableSet<DependencyRequest> membersInjectionDependencies() {
57     return injectionSites()
58         .stream()
59         .flatMap(i -> i.dependencies().stream())
60         .collect(toImmutableSet());
61   }
62 
63   /**
64    * {@link InjectionSite}s for all {@code @Inject} members if {@link #kind()} is {@link
65    * BindingKind#INJECTION}, otherwise empty.
66    */
injectionSites()67   abstract ImmutableSortedSet<InjectionSite> injectionSites();
68 
69   @Override
bindingType()70   public BindingType bindingType() {
71     return BindingType.PROVISION;
72   }
73 
74   @Override
unresolved()75   abstract Optional<ProvisionBinding> unresolved();
76 
77   // TODO(ronshapiro): we should be able to remove this, but AutoValue barks on the Builder's scope
78   // method, saying that the method doesn't correspond to a property of ProvisionBinding
79   @Override
scope()80   public abstract Optional<Scope> scope();
81 
builder()82   static Builder builder() {
83     return new AutoValue_ProvisionBinding.Builder()
84         .provisionDependencies(ImmutableSet.of())
85         .injectionSites(ImmutableSortedSet.of());
86   }
87 
toBuilder()88   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   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   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   @AutoValue.Builder
117   @CanIgnoreReturnValue
118   abstract static class Builder extends ContributionBinding.Builder<ProvisionBinding, Builder> {
119 
120     @Override
dependencies(Iterable<DependencyRequest> dependencies)121     Builder dependencies(Iterable<DependencyRequest> dependencies) {
122       return provisionDependencies(dependencies);
123     }
124 
provisionDependencies(Iterable<DependencyRequest> provisionDependencies)125     abstract Builder provisionDependencies(Iterable<DependencyRequest> provisionDependencies);
126 
injectionSites(ImmutableSortedSet<InjectionSite> injectionSites)127     abstract Builder injectionSites(ImmutableSortedSet<InjectionSite> injectionSites);
128 
129     @Override
unresolved(ProvisionBinding unresolved)130     abstract Builder unresolved(ProvisionBinding unresolved);
131 
scope(Optional<Scope> scope)132     abstract Builder scope(Optional<Scope> scope);
133   }
134 
135 }
136