1 /* 2 * Copyright (C) 2021 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.hilt.processor.internal.root; 18 19 import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; 20 21 import com.google.auto.value.AutoValue; 22 import com.google.auto.value.extension.memoized.Memoized; 23 import com.google.common.collect.ImmutableMap; 24 import com.google.common.collect.ImmutableSet; 25 import com.squareup.javapoet.ClassName; 26 import dagger.hilt.processor.internal.AggregatedElements; 27 import dagger.hilt.processor.internal.AnnotationValues; 28 import dagger.hilt.processor.internal.ClassNames; 29 import dagger.hilt.processor.internal.Processors; 30 import dagger.hilt.processor.internal.root.ir.AggregatedRootIr; 31 import javax.annotation.processing.ProcessingEnvironment; 32 import javax.lang.model.element.AnnotationMirror; 33 import javax.lang.model.element.AnnotationValue; 34 import javax.lang.model.element.TypeElement; 35 36 /** 37 * Represents the values stored in an {@link dagger.hilt.internal.aggregatedroot.AggregatedRoot}. 38 */ 39 @AutoValue 40 abstract class AggregatedRootMetadata { 41 42 /** Returns the aggregating element */ aggregatingElement()43 public abstract TypeElement aggregatingElement(); 44 45 /** Returns the element that was annotated with the root annotation. */ rootElement()46 abstract TypeElement rootElement(); 47 48 /** 49 * Returns the originating root element. In most cases this will be the same as 50 * {@link #rootElement()}. 51 */ originatingRootElement()52 abstract TypeElement originatingRootElement(); 53 54 /** Returns the root annotation as an element. */ rootAnnotation()55 abstract TypeElement rootAnnotation(); 56 57 /** Returns whether this root can use a shared component. */ allowsSharingComponent()58 abstract boolean allowsSharingComponent(); 59 60 @Memoized rootType()61 RootType rootType() { 62 return RootType.of(rootElement()); 63 } 64 from(ProcessingEnvironment env)65 static ImmutableSet<AggregatedRootMetadata> from(ProcessingEnvironment env) { 66 return from( 67 AggregatedElements.from( 68 ClassNames.AGGREGATED_ROOT_PACKAGE, ClassNames.AGGREGATED_ROOT, env.getElementUtils()), 69 env); 70 } 71 72 /** Returns metadata for each aggregated element. */ from( ImmutableSet<TypeElement> aggregatedElements, ProcessingEnvironment env)73 public static ImmutableSet<AggregatedRootMetadata> from( 74 ImmutableSet<TypeElement> aggregatedElements, ProcessingEnvironment env) { 75 return aggregatedElements.stream() 76 .map(aggregatedElement -> create(aggregatedElement, env)) 77 .collect(toImmutableSet()); 78 } 79 toIr(AggregatedRootMetadata metadata)80 public static AggregatedRootIr toIr(AggregatedRootMetadata metadata) { 81 return new AggregatedRootIr( 82 ClassName.get(metadata.aggregatingElement()), 83 ClassName.get(metadata.rootElement()), 84 ClassName.get(metadata.originatingRootElement()), 85 ClassName.get(metadata.rootAnnotation()), 86 metadata.allowsSharingComponent()); 87 } 88 create(TypeElement element, ProcessingEnvironment env)89 private static AggregatedRootMetadata create(TypeElement element, ProcessingEnvironment env) { 90 AnnotationMirror annotationMirror = 91 Processors.getAnnotationMirror(element, ClassNames.AGGREGATED_ROOT); 92 93 ImmutableMap<String, AnnotationValue> values = 94 Processors.getAnnotationValues(env.getElementUtils(), annotationMirror); 95 96 TypeElement rootElement = 97 env.getElementUtils().getTypeElement(AnnotationValues.getString(values.get("root"))); 98 boolean allowSharingComponent = true; 99 return new AutoValue_AggregatedRootMetadata( 100 element, 101 rootElement, 102 env.getElementUtils() 103 .getTypeElement(AnnotationValues.getString(values.get("originatingRoot"))), 104 AnnotationValues.getTypeElement(values.get("rootAnnotation")), 105 allowSharingComponent); 106 } 107 } 108