1 /* 2 * Copyright (C) 2020 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.android.processor.internal.androidentrypoint; 18 19 import static dagger.hilt.processor.internal.HiltCompilerOptions.getGradleProjectType; 20 import static dagger.hilt.processor.internal.HiltCompilerOptions.useAggregatingRootProcessor; 21 22 import androidx.room.compiler.processing.XElement; 23 import androidx.room.compiler.processing.XProcessingEnv; 24 import com.google.common.collect.ImmutableSet; 25 import com.squareup.javapoet.ClassName; 26 import dagger.hilt.android.processor.internal.AndroidClassNames; 27 import dagger.hilt.processor.internal.BaseProcessingStep; 28 import dagger.hilt.processor.internal.ProcessorErrors; 29 import dagger.hilt.processor.internal.optionvalues.GradleProjectType; 30 31 /** 32 * Processor that creates a module for classes marked with {@link 33 * dagger.hilt.android.AndroidEntryPoint}. 34 */ 35 public final class AndroidEntryPointProcessingStep extends BaseProcessingStep { AndroidEntryPointProcessingStep(XProcessingEnv env)36 public AndroidEntryPointProcessingStep(XProcessingEnv env) { 37 super(env); 38 } 39 40 @Override annotationClassNames()41 protected ImmutableSet<ClassName> annotationClassNames() { 42 return ImmutableSet.of( 43 AndroidClassNames.ANDROID_ENTRY_POINT, AndroidClassNames.HILT_ANDROID_APP); 44 } 45 46 @Override delayErrors()47 public boolean delayErrors() { 48 return true; 49 } 50 51 @Override processEach(ClassName annotation, XElement element)52 public void processEach(ClassName annotation, XElement element) throws Exception { 53 AndroidEntryPointMetadata metadata = AndroidEntryPointMetadata.of(element); 54 new InjectorEntryPointGenerator(processingEnv(), metadata).generate(); 55 switch (metadata.androidType()) { 56 case APPLICATION: 57 GradleProjectType projectType = getGradleProjectType(processingEnv()); 58 if (projectType != GradleProjectType.UNSET) { 59 ProcessorErrors.checkState( 60 projectType == GradleProjectType.APP, 61 element, 62 "Application class, %s, annotated with @HiltAndroidApp must be defined in a " 63 + "Gradle android application module (i.e. contains a build.gradle file with " 64 + "`plugins { id 'com.android.application' }`).", 65 metadata.element().getQualifiedName()); 66 } 67 68 // The generated application references the generated component so they must be generated 69 // in the same build unit. Thus, we only generate the application here if we're using the 70 // aggregating root processor. If we're using the Hilt Gradle plugin's aggregating task, we 71 // need to generate the application within ComponentTreeDepsProcessor instead. 72 if (useAggregatingRootProcessor(processingEnv())) { 73 // While we could always generate the application in ComponentTreeDepsProcessor, even if 74 // we're using the aggregating root processor, it can lead to extraneous errors when 75 // things fail before ComponentTreeDepsProcessor runs so we generate it here to avoid that 76 new ApplicationGenerator(processingEnv(), metadata).generate(); 77 } else { 78 // If we're not using the aggregating root processor, then make sure the root application 79 // does not extend the generated application directly, and instead uses bytecode injection 80 ProcessorErrors.checkState( 81 metadata.requiresBytecodeInjection(), 82 metadata.element(), 83 "'enableAggregatingTask=true' cannot be used when the application directly " 84 + "references the generated Hilt class, %s. Either extend %s directly (relying " 85 + "on the Gradle plugin described in " 86 + "https://dagger.dev/hilt/gradle-setup#why-use-the-plugin or set " 87 + "'enableAggregatingTask=false'.", 88 metadata.generatedClassName(), 89 metadata.baseClassName()); 90 } 91 break; 92 case ACTIVITY: 93 new ActivityGenerator(processingEnv(), metadata).generate(); 94 break; 95 case BROADCAST_RECEIVER: 96 new BroadcastReceiverGenerator(processingEnv(), metadata).generate(); 97 break; 98 case FRAGMENT: 99 new FragmentGenerator(processingEnv(), metadata).generate(); 100 break; 101 case SERVICE: 102 new ServiceGenerator(processingEnv(), metadata).generate(); 103 break; 104 case VIEW: 105 new ViewGenerator(processingEnv(), metadata).generate(); 106 break; 107 } 108 } 109 } 110