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.aliasof; 18 19 import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; 20 import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; 21 22 import com.google.auto.value.AutoValue; 23 import com.google.common.collect.ImmutableList; 24 import com.google.common.collect.ImmutableMap; 25 import com.google.common.collect.ImmutableSet; 26 import com.squareup.javapoet.ClassName; 27 import dagger.hilt.processor.internal.AggregatedElements; 28 import dagger.hilt.processor.internal.AnnotationValues; 29 import dagger.hilt.processor.internal.BadInputException; 30 import dagger.hilt.processor.internal.ClassNames; 31 import dagger.hilt.processor.internal.Processors; 32 import dagger.hilt.processor.internal.root.ir.AliasOfPropagatedDataIr; 33 import javax.lang.model.element.AnnotationMirror; 34 import javax.lang.model.element.AnnotationValue; 35 import javax.lang.model.element.TypeElement; 36 import javax.lang.model.util.Elements; 37 38 /** 39 * A class that represents the values stored in an {@link 40 * dagger.hilt.internal.aliasof.AliasOfPropagatedData} annotation. 41 */ 42 @AutoValue 43 public abstract class AliasOfPropagatedDataMetadata { 44 45 /** Returns the aggregating element */ aggregatingElement()46 public abstract TypeElement aggregatingElement(); 47 defineComponentScopeElements()48 abstract ImmutableList<TypeElement> defineComponentScopeElements(); 49 aliasElement()50 abstract TypeElement aliasElement(); 51 52 /** Returns metadata for all aggregated elements in the aggregating package. */ from(Elements elements)53 public static ImmutableSet<AliasOfPropagatedDataMetadata> from(Elements elements) { 54 return from( 55 AggregatedElements.from( 56 ClassNames.ALIAS_OF_PROPAGATED_DATA_PACKAGE, 57 ClassNames.ALIAS_OF_PROPAGATED_DATA, 58 elements), 59 elements); 60 } 61 62 /** Returns metadata for each aggregated element. */ from( ImmutableSet<TypeElement> aggregatedElements, Elements elements)63 public static ImmutableSet<AliasOfPropagatedDataMetadata> from( 64 ImmutableSet<TypeElement> aggregatedElements, Elements elements) { 65 return aggregatedElements.stream() 66 .map(aggregatedElement -> create(aggregatedElement, elements)) 67 .collect(toImmutableSet()); 68 } 69 toIr(AliasOfPropagatedDataMetadata metadata)70 public static AliasOfPropagatedDataIr toIr(AliasOfPropagatedDataMetadata metadata) { 71 return new AliasOfPropagatedDataIr( 72 ClassName.get(metadata.aggregatingElement()), 73 metadata.defineComponentScopeElements().stream() 74 .map(ClassName::get) 75 .collect(toImmutableList()), 76 ClassName.get(metadata.aliasElement())); 77 } 78 create(TypeElement element, Elements elements)79 private static AliasOfPropagatedDataMetadata create(TypeElement element, Elements elements) { 80 AnnotationMirror annotationMirror = 81 Processors.getAnnotationMirror(element, ClassNames.ALIAS_OF_PROPAGATED_DATA); 82 83 ImmutableMap<String, AnnotationValue> values = 84 Processors.getAnnotationValues(elements, annotationMirror); 85 86 ImmutableList<TypeElement> defineComponentScopes; 87 if (values.containsKey("defineComponentScopes")) { 88 defineComponentScopes = 89 ImmutableList.copyOf( 90 AnnotationValues.getTypeElements(values.get("defineComponentScopes"))); 91 } else if (values.containsKey("defineComponentScope")) { 92 // Older version of AliasOfPropagatedData only passed a single defineComponentScope class 93 // value. Fall back on reading the single value if we get old propagated data. 94 defineComponentScopes = 95 ImmutableList.of(AnnotationValues.getTypeElement(values.get("defineComponentScope"))); 96 } else { 97 throw new BadInputException( 98 "AliasOfPropagatedData is missing defineComponentScopes", element); 99 } 100 101 return new AutoValue_AliasOfPropagatedDataMetadata( 102 element, defineComponentScopes, AnnotationValues.getTypeElement(values.get("alias"))); 103 } 104 } 105