15d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinpackage dagger.internal.codegen; 25d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 35d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.auto.common.MoreTypes; 45d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.auto.value.AutoValue; 55d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.base.Function; 65d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.base.Optional; 75d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.collect.ImmutableSet; 85d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport dagger.Module; 95d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport dagger.Provides; 105d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport dagger.producers.ProducerModule; 115d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport dagger.producers.Produces; 125d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport java.util.LinkedHashSet; 135d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport java.util.Set; 145d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport javax.lang.model.element.AnnotationMirror; 155d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport javax.lang.model.element.ExecutableElement; 165d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport javax.lang.model.element.TypeElement; 175d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport javax.lang.model.type.TypeMirror; 185d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport javax.lang.model.util.Elements; 195d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 205d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static com.google.auto.common.MoreElements.getAnnotationMirror; 215d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static com.google.auto.common.MoreElements.isAnnotationPresent; 225d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static com.google.common.base.Verify.verify; 235d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static dagger.internal.codegen.ConfigurationAnnotations.getModuleIncludes; 245d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static dagger.internal.codegen.Util.componentCanMakeNewInstances; 255d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static javax.lang.model.type.TypeKind.DECLARED; 265d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static javax.lang.model.type.TypeKind.NONE; 275d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static javax.lang.model.util.ElementFilter.methodsIn; 285d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 295d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin@AutoValue 305d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinabstract class ModuleDescriptor { 315d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin static final Function<ModuleDescriptor, TypeElement> getModuleElement() { 325d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return new Function<ModuleDescriptor, TypeElement>() { 335d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override public TypeElement apply(ModuleDescriptor input) { 345d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return input.moduleElement(); 355d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 365d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin }; 375d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 385d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 395d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin abstract AnnotationMirror moduleAnnotation(); 405d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 415d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin abstract TypeElement moduleElement(); 425d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 435d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin abstract ImmutableSet<ModuleDescriptor> includedModules(); 445d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 4587182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin abstract ImmutableSet<ContributionBinding> bindings(); 465d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 475d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin enum DefaultCreationStrategy { 485d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin PASSED, 495d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin CONSTRUCTED, 505d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 515d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 525d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin abstract DefaultCreationStrategy defaultCreationStrategy(); 535d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 545d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin static final class Factory { 555d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private final Elements elements; 565d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private final ProvisionBinding.Factory provisionBindingFactory; 575d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private final ProductionBinding.Factory productionBindingFactory; 585d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 595d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin Factory( 605d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin Elements elements, 615d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin ProvisionBinding.Factory provisionBindingFactory, 625d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin ProductionBinding.Factory productionBindingFactory) { 635d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin this.elements = elements; 645d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin this.provisionBindingFactory = provisionBindingFactory; 655d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin this.productionBindingFactory = productionBindingFactory; 665d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 675d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 685d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin ModuleDescriptor create(TypeElement moduleElement) { 695d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin AnnotationMirror moduleAnnotation = getModuleAnnotation(moduleElement).get(); 705d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 715d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin ImmutableSet.Builder<ContributionBinding> bindings = ImmutableSet.builder(); 725d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin for (ExecutableElement moduleMethod : methodsIn(elements.getAllMembers(moduleElement))) { 735d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin if (isAnnotationPresent(moduleMethod, Provides.class)) { 745d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin bindings.add( 755d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin provisionBindingFactory.forProvidesMethod(moduleMethod, moduleElement.asType())); 765d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 775d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin if (isAnnotationPresent(moduleMethod, Produces.class)) { 785d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin bindings.add( 795d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin productionBindingFactory.forProducesMethod(moduleMethod, moduleElement.asType())); 805d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 815d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 825d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 835d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin DefaultCreationStrategy defaultCreationStrategy = 845d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin (componentCanMakeNewInstances(moduleElement) 855d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin && moduleElement.getTypeParameters().isEmpty()) 865d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin ? ModuleDescriptor.DefaultCreationStrategy.CONSTRUCTED 875d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin : ModuleDescriptor.DefaultCreationStrategy.PASSED; 885d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 895d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return new AutoValue_ModuleDescriptor( 905d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin moduleAnnotation, 915d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin moduleElement, 925d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin ImmutableSet.copyOf( 935d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin collectIncludedModules(new LinkedHashSet<ModuleDescriptor>(), moduleElement)), 945d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin bindings.build(), 955d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin defaultCreationStrategy); 965d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 975d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 985d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private static Optional<AnnotationMirror> getModuleAnnotation(TypeElement moduleElement) { 995d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return getAnnotationMirror(moduleElement, Module.class) 1005d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin .or(getAnnotationMirror(moduleElement, ProducerModule.class)); 1015d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1025d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 1035d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private Set<ModuleDescriptor> collectIncludedModules( 1045d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin Set<ModuleDescriptor> includedModules, TypeElement moduleElement) { 1055d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin TypeMirror superclass = moduleElement.getSuperclass(); 1065d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin if (!superclass.getKind().equals(NONE)) { 1075d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin verify(superclass.getKind().equals(DECLARED)); 1085d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin TypeElement superclassElement = MoreTypes.asTypeElement(superclass); 1095d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin if (!superclassElement.getQualifiedName().contentEquals(Object.class.getCanonicalName())) { 1105d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin collectIncludedModules(includedModules, superclassElement); 1115d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1125d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1135d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin Optional<AnnotationMirror> moduleAnnotation = getModuleAnnotation(moduleElement); 1145d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin if (moduleAnnotation.isPresent()) { 1155d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin for (TypeMirror moduleIncludesType : getModuleIncludes(moduleAnnotation.get())) { 1165d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin includedModules.add(create(MoreTypes.asTypeElement(moduleIncludesType))); 1175d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1185d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1195d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return includedModules; 1205d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1215d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1225d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin} 123