• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 dagger.internal.codegen.extension.Optionals.emptiesLast;
21 import static dagger.internal.codegen.xprocessing.XElements.getSimpleName;
22 import static java.util.Comparator.comparing;
23 
24 import androidx.room.compiler.processing.XElement;
25 import androidx.room.compiler.processing.XTypeElement;
26 import dagger.internal.codegen.model.BindingKind;
27 import dagger.internal.codegen.model.Key;
28 import dagger.internal.codegen.xprocessing.XElements;
29 import java.util.Comparator;
30 import java.util.Optional;
31 
32 /** An object that declares or specifies a binding. */
33 public abstract class BindingDeclaration {
34   /**
35    * A comparator that compares binding declarations with elements.
36    *
37    * <p>Compares, in order:
38    *
39    * <ol>
40    *   <li>Contributing module or enclosing type name
41    *   <li>Binding element's simple name
42    *   <li>Binding element's type
43    * </ol>
44    *
45    * Any binding declarations without elements are last.
46    */
47   public static final Comparator<BindingDeclaration> COMPARATOR =
48       comparing(
49               (BindingDeclaration declaration) ->
50                   declaration.contributingModule().isPresent()
51                       ? declaration.contributingModule()
52                       : declaration.bindingTypeElement(),
53               emptiesLast(comparing(XTypeElement::getQualifiedName)))
54           .thenComparing(
55               (BindingDeclaration declaration) -> declaration.bindingElement(),
56               emptiesLast(
57                   comparing((XElement element) -> getSimpleName(element))
58                       .thenComparing((XElement element) -> toJavac(element).asType().toString())));
59 
60   /** The {@link Key} of this declaration. */
key()61   public abstract Key key();
62 
63   /**
64    * The {@link XElement} that declares this binding. Absent for {@linkplain BindingKind binding
65    * kinds} that are not always declared by exactly one element.
66    *
67    * <p>For example, consider {@link BindingKind#MULTIBOUND_SET}. A component with many
68    * {@code @IntoSet} bindings for the same key will have a synthetic binding that depends on all
69    * contributions, but with no identifiying binding element. A {@code @Multibinds} method will also
70    * contribute a synthetic binding, but since multiple {@code @Multibinds} methods can coexist in
71    * the same component (and contribute to one single binding), it has no binding element.
72    */
bindingElement()73   public abstract Optional<XElement> bindingElement();
74 
75   /**
76    * The type enclosing the {@link #bindingElement()}, or {@link Optional#empty()} if {@link
77    * #bindingElement()} is empty.
78    */
bindingTypeElement()79   public final Optional<XTypeElement> bindingTypeElement() {
80     return bindingElement().map(XElements::closestEnclosingTypeElement);
81   }
82 
83   /**
84    * The installed module class that contributed the {@link #bindingElement()}. May be a subclass of
85    * the class that contains {@link #bindingElement()}. Absent if {@link #bindingElement()} is
86    * empty.
87    */
contributingModule()88   public abstract Optional<XTypeElement> contributingModule();
89 }
90