1 /* 2 * Copyright (C) 2019 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.aggregateddeps; 18 19 import static com.google.auto.common.Visibility.effectiveVisibilityOfElement; 20 21 import com.google.auto.common.MoreElements; 22 import com.google.auto.common.Visibility; 23 import com.google.auto.value.AutoValue; 24 import com.squareup.javapoet.ClassName; 25 import com.squareup.javapoet.TypeName; 26 import dagger.hilt.processor.internal.ClassNames; 27 import dagger.hilt.processor.internal.KotlinMetadataUtils; 28 import dagger.hilt.processor.internal.Processors; 29 import java.util.Optional; 30 import javax.lang.model.element.AnnotationMirror; 31 import javax.lang.model.element.TypeElement; 32 import javax.lang.model.util.Elements; 33 34 /** PkgPrivateModuleMetadata contains a set of utilities for processing package private modules. */ 35 @AutoValue 36 public abstract class PkgPrivateMetadata { 37 /** Returns the public Hilt wrapped type or the type itself if it is already public. */ publicModule(TypeElement element, Elements elements)38 public static TypeElement publicModule(TypeElement element, Elements elements) { 39 return publicDep(element, elements, ClassNames.MODULE); 40 } 41 42 /** Returns the public Hilt wrapped type or the type itself if it is already public. */ publicEarlyEntryPoint(TypeElement element, Elements elements)43 public static TypeElement publicEarlyEntryPoint(TypeElement element, Elements elements) { 44 return publicDep(element, elements, ClassNames.EARLY_ENTRY_POINT); 45 } 46 publicDep( TypeElement element, Elements elements, ClassName annotation)47 private static TypeElement publicDep( 48 TypeElement element, Elements elements, ClassName annotation) { 49 return of(elements, element, annotation) 50 .map(PkgPrivateMetadata::generatedClassName) 51 .map(ClassName::canonicalName) 52 .map(elements::getTypeElement) 53 .orElse(element); 54 } 55 56 private static final String PREFIX = "HiltWrapper_"; 57 58 /** Returns the base class name of the elemenet. */ baseClassName()59 TypeName baseClassName() { 60 return TypeName.get(getTypeElement().asType()); 61 } 62 63 /** Returns TypeElement for the module element the metadata object represents */ getTypeElement()64 abstract TypeElement getTypeElement(); 65 66 /** 67 * Returns an optional @InstallIn AnnotationMirror for the module element the metadata object 68 * represents 69 */ getOptionalInstallInAnnotationMirror()70 abstract Optional<AnnotationMirror> getOptionalInstallInAnnotationMirror(); 71 72 /** Return the Type of this package private element. */ getAnnotation()73 abstract ClassName getAnnotation(); 74 75 /** Returns the expected genenerated classname for the element the metadata object represents */ generatedClassName()76 final ClassName generatedClassName() { 77 return Processors.prepend( 78 Processors.getEnclosedClassName(ClassName.get(getTypeElement())), PREFIX); 79 } 80 81 /** 82 * Returns an Optional PkgPrivateMetadata requiring Hilt processing, otherwise returns an empty 83 * Optional. 84 */ of( Elements elements, TypeElement element, ClassName annotation)85 static Optional<PkgPrivateMetadata> of( 86 Elements elements, TypeElement element, ClassName annotation) { 87 // If this is a public element no wrapping is needed 88 if (effectiveVisibilityOfElement(element) == Visibility.PUBLIC 89 && !KotlinMetadataUtils.getMetadataUtil().isVisibilityInternal(element)) { 90 return Optional.empty(); 91 } 92 93 Optional<AnnotationMirror> installIn; 94 if (Processors.hasAnnotation(element, ClassNames.INSTALL_IN)) { 95 installIn = Optional.of(Processors.getAnnotationMirror(element, ClassNames.INSTALL_IN)); 96 } else if (Processors.hasAnnotation(element, ClassNames.TEST_INSTALL_IN)) { 97 installIn = Optional.of(Processors.getAnnotationMirror(element, ClassNames.TEST_INSTALL_IN)); 98 } else { 99 throw new IllegalStateException( 100 "Expected element to be annotated with @InstallIn: " + element); 101 } 102 103 if (annotation.equals(ClassNames.MODULE) 104 ) { 105 // Skip modules that require a module instance. Required by 106 // dagger (b/31489617) 107 if (Processors.requiresModuleInstance(elements, MoreElements.asType(element))) { 108 return Optional.empty(); 109 } 110 } 111 return Optional.of( 112 new AutoValue_PkgPrivateMetadata(MoreElements.asType(element), installIn, annotation)); 113 } 114 } 115