Home | History | Annotate | Download | only in codegen
      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 
     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
     62   public Set<Class<? extends Annotation>> annotations() {
     63     return ImmutableSet.<Class<? extends Annotation>>of(MapKey.class);
     64   }
     65 
     66   @Override
     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 
     91   private void writeCreatorClass(MapKeyCreatorSpecification mapKeyCreatorType) {
     92     try {
     93       mapKeyGenerator.generate(mapKeyCreatorType);
     94     } catch (SourceFileGenerationException e) {
     95       e.printMessageTo(messager);
     96     }
     97   }
     98 }
     99