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 androidx.room.compiler.processing.XAnnotation; 23 import androidx.room.compiler.processing.XAnnotationValue; 24 import androidx.room.compiler.processing.XProcessingEnv; 25 import androidx.room.compiler.processing.XTypeElement; 26 import com.google.auto.value.AutoValue; 27 import com.google.common.collect.ImmutableList; 28 import com.google.common.collect.ImmutableMap; 29 import com.google.common.collect.ImmutableSet; 30 import dagger.hilt.processor.internal.AggregatedElements; 31 import dagger.hilt.processor.internal.BadInputException; 32 import dagger.hilt.processor.internal.ClassNames; 33 import dagger.hilt.processor.internal.Processors; 34 import dagger.hilt.processor.internal.root.ir.AliasOfPropagatedDataIr; 35 import dagger.internal.codegen.xprocessing.XAnnotations; 36 37 /** 38 * A class that represents the values stored in an {@link 39 * dagger.hilt.internal.aliasof.AliasOfPropagatedData} annotation. 40 */ 41 @AutoValue 42 public abstract class AliasOfPropagatedDataMetadata { 43 44 /** Returns the aggregating element */ aggregatingElement()45 public abstract XTypeElement aggregatingElement(); 46 defineComponentScopeElements()47 abstract ImmutableList<XTypeElement> defineComponentScopeElements(); 48 aliasElement()49 abstract XTypeElement aliasElement(); 50 51 /** Returns metadata for all aggregated elements in the aggregating package. */ from(XProcessingEnv env)52 public static ImmutableSet<AliasOfPropagatedDataMetadata> from(XProcessingEnv env) { 53 return from( 54 AggregatedElements.from( 55 ClassNames.ALIAS_OF_PROPAGATED_DATA_PACKAGE, ClassNames.ALIAS_OF_PROPAGATED_DATA, env)); 56 } 57 58 /** Returns metadata for each aggregated element. */ from( ImmutableSet<XTypeElement> aggregatedElements)59 public static ImmutableSet<AliasOfPropagatedDataMetadata> from( 60 ImmutableSet<XTypeElement> aggregatedElements) { 61 return aggregatedElements.stream() 62 .map(AliasOfPropagatedDataMetadata::create) 63 .collect(toImmutableSet()); 64 } 65 toIr(AliasOfPropagatedDataMetadata metadata)66 public static AliasOfPropagatedDataIr toIr(AliasOfPropagatedDataMetadata metadata) { 67 return new AliasOfPropagatedDataIr( 68 metadata.aggregatingElement().getClassName(), 69 metadata.defineComponentScopeElements().stream() 70 .map(XTypeElement::getClassName) 71 .collect(toImmutableList()), 72 metadata.aliasElement().getClassName()); 73 } 74 create(XTypeElement element)75 private static AliasOfPropagatedDataMetadata create(XTypeElement element) { 76 XAnnotation annotation = element.getAnnotation(ClassNames.ALIAS_OF_PROPAGATED_DATA); 77 78 // TODO(kuanyingchou) We can remove this once we have 79 // `XAnnotation.hasAnnotationValue(methodName: String)`. 80 ImmutableMap<String, XAnnotationValue> values = Processors.getAnnotationValues(annotation); 81 82 ImmutableList<XTypeElement> defineComponentScopes; 83 84 if (values.containsKey("defineComponentScopes")) { 85 defineComponentScopes = 86 XAnnotations.getAsTypeElementList(annotation, "defineComponentScopes"); 87 } else if (values.containsKey("defineComponentScope")) { 88 // Older version of AliasOfPropagatedData only passed a single defineComponentScope class 89 // value. Fall back on reading the single value if we get old propagated data. 90 defineComponentScopes = XAnnotations.getAsTypeElementList(annotation, "defineComponentScope"); 91 } else { 92 throw new BadInputException( 93 "AliasOfPropagatedData is missing defineComponentScopes", element); 94 } 95 96 return new AutoValue_AliasOfPropagatedDataMetadata( 97 element, defineComponentScopes, annotation.getAsType("alias").getTypeElement()); 98 } 99 } 100