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 @MapKey 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