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