• 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 com.google.common.base.Suppliers.memoize;
20 import static dagger.internal.codegen.xprocessing.XElements.isAbstract;
21 import static dagger.internal.codegen.xprocessing.XElements.isStatic;
22 
23 import com.google.common.base.Supplier;
24 import com.google.common.collect.ImmutableSet;
25 import com.google.common.collect.Sets;
26 import dagger.internal.codegen.model.BindingKind;
27 import dagger.internal.codegen.model.DependencyRequest;
28 import dagger.internal.codegen.model.Scope;
29 import java.util.Optional;
30 
31 /**
32  * An abstract type for classes representing a Dagger binding. Particularly, contains the element
33  * that generated the binding and the {@link DependencyRequest} instances that are required to
34  * satisfy the binding, but leaves the specifics of the <i>mechanism</i> of the binding to the
35  * subtypes.
36  */
37 public abstract class Binding extends BindingDeclaration {
38 
39   /**
40    * Returns {@code true} if using this binding requires an instance of the {@link
41    * #contributingModule()}.
42    */
requiresModuleInstance()43   public boolean requiresModuleInstance() {
44     return contributingModule().isPresent()
45         && bindingElement().isPresent()
46         && !isAbstract(bindingElement().get())
47         && !isStatic(bindingElement().get());
48   }
49 
50   /**
51    * Returns {@code true} if this binding may provide {@code null} instead of an instance of {@link
52    * #key()}. Nullable bindings cannot be requested from {@linkplain DependencyRequest#isNullable()
53    * non-nullable dependency requests}.
54    */
isNullable()55   public abstract boolean isNullable();
56 
57   /** The kind of binding this instance represents. */
kind()58   public abstract BindingKind kind();
59 
60   /** The {@link BindingType} of this binding. */
bindingType()61   public abstract BindingType bindingType();
62 
63   /** The {@link FrameworkType} of this binding. */
frameworkType()64   public final FrameworkType frameworkType() {
65     return FrameworkType.forBindingType(bindingType());
66   }
67 
68   /**
69    * The explicit set of {@link DependencyRequest dependencies} required to satisfy this binding as
70    * defined by the user-defined injection sites.
71    */
explicitDependencies()72   public abstract ImmutableSet<DependencyRequest> explicitDependencies();
73 
74   /**
75    * The set of {@link DependencyRequest dependencies} that are added by the framework rather than a
76    * user-defined injection site. This returns an unmodifiable set.
77    */
implicitDependencies()78   public ImmutableSet<DependencyRequest> implicitDependencies() {
79     return ImmutableSet.of();
80   }
81 
82   private final Supplier<ImmutableSet<DependencyRequest>> dependencies =
83       memoize(
84           () -> {
85             ImmutableSet<DependencyRequest> implicitDependencies = implicitDependencies();
86             return ImmutableSet.copyOf(
87                 implicitDependencies.isEmpty()
88                     ? explicitDependencies()
89                     : Sets.union(implicitDependencies, explicitDependencies()));
90           });
91 
92   /**
93    * The set of {@link DependencyRequest dependencies} required to satisfy this binding. This is the
94    * union of {@link #explicitDependencies()} and {@link #implicitDependencies()}. This returns an
95    * unmodifiable set.
96    */
dependencies()97   public final ImmutableSet<DependencyRequest> dependencies() {
98     return dependencies.get();
99   }
100 
101   /**
102    * If this binding's key's type parameters are different from those of the {@link
103    * #bindingTypeElement()}, this is the binding for the {@link #bindingTypeElement()}'s unresolved
104    * type.
105    */
unresolved()106   public abstract Optional<? extends Binding> unresolved();
107 
scope()108   public Optional<Scope> scope() {
109     return Optional.empty();
110   }
111 }
112