• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 Google, Inc.
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 package dagger.internal.codegen;
17 
18 import com.google.auto.common.BasicAnnotationProcessor;
19 import com.google.auto.common.MoreElements;
20 import com.google.auto.common.MoreTypes;
21 import com.google.common.collect.ImmutableSet;
22 import com.google.common.collect.SetMultimap;
23 import dagger.MapKey;
24 import dagger.internal.codegen.MapKeyGenerator.MapKeyCreatorSpecification;
25 import java.lang.annotation.Annotation;
26 import java.util.Set;
27 import javax.annotation.processing.Messager;
28 import javax.lang.model.element.Element;
29 import javax.lang.model.element.ElementKind;
30 import javax.lang.model.type.DeclaredType;
31 import javax.lang.model.util.Types;
32 
33 import static dagger.internal.codegen.MapKeyGenerator.MapKeyCreatorSpecification.unwrappedMapKeyWithAnnotationValue;
34 import static dagger.internal.codegen.MapKeyGenerator.MapKeyCreatorSpecification.wrappedMapKey;
35 import static dagger.internal.codegen.MapKeys.getUnwrappedMapKeyType;
36 
37 /**
38  * The annotation processor responsible for validating the mapKey annotation and auto-generate
39  * implementation of annotations marked with &#064MapKey where necessary.
40  *
41  * @author Chenying Hou
42  * @since 2.0
43  */
44 public class MapKeyProcessingStep implements BasicAnnotationProcessor.ProcessingStep {
45   private final Messager messager;
46   private final Types types;
47   private final MapKeyValidator mapKeyValidator;
48   private final MapKeyGenerator mapKeyGenerator;
49 
MapKeyProcessingStep( Messager messager, Types types, MapKeyValidator mapKeyValidator, MapKeyGenerator mapKeyGenerator)50   MapKeyProcessingStep(
51       Messager messager,
52       Types types,
53       MapKeyValidator mapKeyValidator,
54       MapKeyGenerator mapKeyGenerator) {
55     this.messager = messager;
56     this.types = types;
57     this.mapKeyValidator = mapKeyValidator;
58     this.mapKeyGenerator = mapKeyGenerator;
59   }
60 
61   @Override
annotations()62   public Set<Class<? extends Annotation>> annotations() {
63     return ImmutableSet.<Class<? extends Annotation>>of(MapKey.class);
64   }
65 
66   @Override
process( SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation)67   public Set<Element> process(
68       SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
69     for (Element element : elementsByAnnotation.get(MapKey.class)) {
70       ValidationReport<Element> mapKeyReport = mapKeyValidator.validate(element);
71       mapKeyReport.printMessagesTo(messager);
72 
73       if (mapKeyReport.isClean()) {
74         MapKey mapkey = element.getAnnotation(MapKey.class);
75         if (mapkey.unwrapValue()) {
76           DeclaredType keyType =
77               getUnwrappedMapKeyType(MoreTypes.asDeclared(element.asType()), types);
78           if (keyType.asElement().getKind() == ElementKind.ANNOTATION_TYPE) {
79             writeCreatorClass(
80                 unwrappedMapKeyWithAnnotationValue(
81                     MoreElements.asType(element), MoreTypes.asTypeElement(keyType)));
82           }
83         } else {
84           writeCreatorClass(wrappedMapKey(MoreElements.asType(element)));
85         }
86       }
87     }
88     return ImmutableSet.of();
89   }
90 
writeCreatorClass(MapKeyCreatorSpecification mapKeyCreatorType)91   private void writeCreatorClass(MapKeyCreatorSpecification mapKeyCreatorType) {
92     try {
93       mapKeyGenerator.generate(mapKeyCreatorType);
94     } catch (SourceFileGenerationException e) {
95       e.printMessageTo(messager);
96     }
97   }
98 }
99