• 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.Ascii.toUpperCase;
20 import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;
21 import static dagger.internal.codegen.extension.DaggerStreams.valuesOf;
22 import static java.util.stream.Collectors.mapping;
23 
24 import androidx.room.compiler.processing.XTypeElement;
25 import com.google.common.collect.ImmutableSet;
26 import com.squareup.javapoet.ClassName;
27 import dagger.internal.codegen.javapoet.TypeNames;
28 import java.util.stream.Collector;
29 import java.util.stream.Stream;
30 
31 /** Simple representation of a component creator annotation type. */
32 public enum ComponentCreatorAnnotation {
33   COMPONENT_BUILDER(TypeNames.COMPONENT_BUILDER),
34   COMPONENT_FACTORY(TypeNames.COMPONENT_FACTORY),
35   SUBCOMPONENT_BUILDER(TypeNames.SUBCOMPONENT_BUILDER),
36   SUBCOMPONENT_FACTORY(TypeNames.SUBCOMPONENT_FACTORY),
37   PRODUCTION_COMPONENT_BUILDER(TypeNames.PRODUCTION_COMPONENT_BUILDER),
38   PRODUCTION_COMPONENT_FACTORY(TypeNames.PRODUCTION_COMPONENT_FACTORY),
39   PRODUCTION_SUBCOMPONENT_BUILDER(TypeNames.PRODUCTION_SUBCOMPONENT_BUILDER),
40   PRODUCTION_SUBCOMPONENT_FACTORY(TypeNames.PRODUCTION_SUBCOMPONENT_FACTORY),
41   ;
42 
43   private final ClassName annotation;
44   private final ComponentCreatorKind creatorKind;
45   private final ClassName componentAnnotation;
46 
ComponentCreatorAnnotation(ClassName annotation)47   ComponentCreatorAnnotation(ClassName annotation) {
48     this.annotation = annotation;
49     this.creatorKind = ComponentCreatorKind.valueOf(toUpperCase(annotation.simpleName()));
50     this.componentAnnotation = annotation.enclosingClassName();
51   }
52 
53   /** The actual annotation type. */
annotation()54   public ClassName annotation() {
55     return annotation;
56   }
57 
58   /** The component annotation type that encloses this creator annotation type. */
componentAnnotation()59   public final ClassName componentAnnotation() {
60     return componentAnnotation;
61   }
62 
63   /** Returns {@code true} if the creator annotation is for a subcomponent. */
isSubcomponentCreatorAnnotation()64   public final boolean isSubcomponentCreatorAnnotation() {
65     return componentAnnotation().simpleName().endsWith("Subcomponent");
66   }
67 
68   /**
69    * Returns {@code true} if the creator annotation is for a production component or subcomponent.
70    */
isProductionCreatorAnnotation()71   public final boolean isProductionCreatorAnnotation() {
72     return componentAnnotation().simpleName().startsWith("Production");
73   }
74 
75   /** The creator kind the annotation is associated with. */
76   // TODO(dpb): Remove ComponentCreatorKind.
creatorKind()77   public ComponentCreatorKind creatorKind() {
78     return creatorKind;
79   }
80 
81   @Override
toString()82   public final String toString() {
83     return annotation().canonicalName();
84   }
85 
86   /** Returns all component creator annotations. */
allCreatorAnnotations()87   public static ImmutableSet<ClassName> allCreatorAnnotations() {
88     return stream().collect(toAnnotationClasses());
89   }
90 
91   /** Returns all root component creator annotations. */
rootComponentCreatorAnnotations()92   public static ImmutableSet<ClassName> rootComponentCreatorAnnotations() {
93     return stream()
94         .filter(
95             componentCreatorAnnotation ->
96                 !componentCreatorAnnotation.isSubcomponentCreatorAnnotation())
97         .collect(toAnnotationClasses());
98   }
99 
100   /** Returns all subcomponent creator annotations. */
subcomponentCreatorAnnotations()101   public static ImmutableSet<ClassName> subcomponentCreatorAnnotations() {
102     return stream()
103         .filter(
104             componentCreatorAnnotation ->
105                 componentCreatorAnnotation.isSubcomponentCreatorAnnotation())
106         .collect(toAnnotationClasses());
107   }
108 
109   /** Returns all production component creator annotations. */
productionCreatorAnnotations()110   public static ImmutableSet<ClassName> productionCreatorAnnotations() {
111     return stream()
112         .filter(
113             componentCreatorAnnotation ->
114                 componentCreatorAnnotation.isProductionCreatorAnnotation())
115         .collect(toAnnotationClasses());
116   }
117 
118   /** Returns the legal creator annotations for the given {@code componentAnnotation}. */
creatorAnnotationsFor( ComponentAnnotation componentAnnotation)119   public static ImmutableSet<ClassName> creatorAnnotationsFor(
120       ComponentAnnotation componentAnnotation) {
121     return stream()
122         .filter(
123             creatorAnnotation ->
124                 creatorAnnotation
125                     .componentAnnotation()
126                     .simpleName()
127                     .equals(componentAnnotation.simpleName()))
128         .collect(toAnnotationClasses());
129   }
130 
131   /** Returns all creator annotations present on the given {@code type}. */
getCreatorAnnotations(XTypeElement type)132   public static ImmutableSet<ComponentCreatorAnnotation> getCreatorAnnotations(XTypeElement type) {
133     return stream().filter(cca -> type.hasAnnotation(cca.annotation())).collect(toImmutableSet());
134   }
135 
stream()136   private static Stream<ComponentCreatorAnnotation> stream() {
137     return valuesOf(ComponentCreatorAnnotation.class);
138   }
139 
140   private static Collector<ComponentCreatorAnnotation, ?, ImmutableSet<ClassName>>
toAnnotationClasses()141       toAnnotationClasses() {
142     return mapping(ComponentCreatorAnnotation::annotation, toImmutableSet());
143   }
144 }
145