• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.base;
18 
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList;
21 import static dagger.internal.codegen.xprocessing.XAnnotations.getClassName;
22 import static dagger.internal.codegen.xprocessing.XElements.getAnyAnnotation;
23 
24 import androidx.room.compiler.processing.XAnnotation;
25 import androidx.room.compiler.processing.XElement;
26 import androidx.room.compiler.processing.XType;
27 import androidx.room.compiler.processing.XTypeElement;
28 import com.google.auto.value.AutoValue;
29 import com.google.auto.value.extension.memoized.Memoized;
30 import com.google.common.collect.ImmutableList;
31 import com.google.common.collect.ImmutableSet;
32 import com.squareup.javapoet.ClassName;
33 import dagger.internal.codegen.javapoet.TypeNames;
34 import java.util.Optional;
35 
36 /** A {@code @Module} or {@code @ProducerModule} annotation. */
37 @AutoValue
38 public abstract class ModuleAnnotation {
39   private static final ImmutableSet<ClassName> MODULE_ANNOTATIONS =
40       ImmutableSet.of(TypeNames.MODULE, TypeNames.PRODUCER_MODULE);
41 
42   private XAnnotation annotation;
43 
44   /** The annotation itself. */
annotation()45   public final XAnnotation annotation() {
46     return annotation;
47   }
48 
49   /** Returns the {@link ClassName} name of the annotation. */
className()50   public abstract ClassName className();
51 
52   /** The simple name of the annotation. */
simpleName()53   public String simpleName() {
54     return className().simpleName();
55   }
56 
57   /**
58    * The types specified in the {@code includes} attribute.
59    *
60    * @throws IllegalArgumentException if any of the values are error types
61    */
62   @Memoized
includes()63   public ImmutableList<XTypeElement> includes() {
64     return annotation.getAsTypeList("includes").stream()
65         .map(XType::getTypeElement)
66         .collect(toImmutableList());
67   }
68 
69   /**
70    * The types specified in the {@code subcomponents} attribute.
71    *
72    * @throws IllegalArgumentException if any of the values are error types
73    */
74   @Memoized
subcomponents()75   public ImmutableList<XTypeElement> subcomponents() {
76     return annotation.getAsTypeList("subcomponents").stream()
77         .map(XType::getTypeElement)
78         .collect(toImmutableList());
79   }
80 
81   /** Returns {@code true} if the argument is a {@code @Module} or {@code @ProducerModule}. */
isModuleAnnotation(XAnnotation annotation)82   public static boolean isModuleAnnotation(XAnnotation annotation) {
83     return MODULE_ANNOTATIONS.contains(getClassName(annotation));
84   }
85 
86   /** The module annotation types. */
moduleAnnotations()87   public static ImmutableSet<ClassName> moduleAnnotations() {
88     return MODULE_ANNOTATIONS;
89   }
90 
create(XAnnotation annotation)91   private static ModuleAnnotation create(XAnnotation annotation) {
92     checkArgument(
93         isModuleAnnotation(annotation),
94         "%s is not a Module or ProducerModule annotation",
95         annotation);
96     ModuleAnnotation moduleAnnotation = new AutoValue_ModuleAnnotation(getClassName(annotation));
97     moduleAnnotation.annotation = annotation;
98     return moduleAnnotation;
99   }
100 
101   /**
102    * Returns an object representing the {@code @Module} or {@code @ProducerModule} annotation if one
103    * annotates {@code typeElement}.
104    */
moduleAnnotation( XElement element, DaggerSuperficialValidation superficialValidation)105   public static Optional<ModuleAnnotation> moduleAnnotation(
106       XElement element, DaggerSuperficialValidation superficialValidation) {
107     return getAnyAnnotation(element, TypeNames.MODULE, TypeNames.PRODUCER_MODULE)
108         .map(
109             annotation -> {
110               superficialValidation.validateAnnotationOf(element, annotation);
111               return create(annotation);
112             });
113   }
114 }
115