• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.definecomponent;
18 
19 
20 import androidx.room.compiler.processing.XElement;
21 import androidx.room.compiler.processing.XProcessingEnv;
22 import androidx.room.compiler.processing.XRoundEnv;
23 import androidx.room.compiler.processing.XTypeElement;
24 import com.google.common.collect.ImmutableSet;
25 import com.squareup.javapoet.AnnotationSpec;
26 import com.squareup.javapoet.ClassName;
27 import dagger.hilt.processor.internal.BaseProcessingStep;
28 import dagger.hilt.processor.internal.ClassNames;
29 import dagger.hilt.processor.internal.Processors;
30 import dagger.hilt.processor.internal.definecomponent.DefineComponentBuilderMetadatas.DefineComponentBuilderMetadata;
31 import dagger.hilt.processor.internal.definecomponent.DefineComponentMetadatas.DefineComponentMetadata;
32 
33 /**
34  * A processor for {@link dagger.hilt.DefineComponent} and {@link
35  * dagger.hilt.DefineComponent.Builder}.
36  */
37 public final class DefineComponentProcessingStep extends BaseProcessingStep {
38   // Note: these caches should be cleared between rounds.
39   private DefineComponentMetadatas componentMetadatas;
40   private DefineComponentBuilderMetadatas componentBuilderMetadatas;
41 
DefineComponentProcessingStep(XProcessingEnv env)42   public DefineComponentProcessingStep(XProcessingEnv env) {
43     super(env);
44   }
45 
46   @Override
preProcess(XProcessingEnv env, XRoundEnv round)47   public void preProcess(XProcessingEnv env, XRoundEnv round) {
48     componentMetadatas = DefineComponentMetadatas.create();
49     componentBuilderMetadatas = DefineComponentBuilderMetadatas.create(componentMetadatas);
50   }
51 
52   @Override
postProcess(XProcessingEnv env, XRoundEnv round)53   public void postProcess(XProcessingEnv env, XRoundEnv round) {
54     componentMetadatas = null;
55     componentBuilderMetadatas = null;
56   }
57 
58   @Override
annotationClassNames()59   protected ImmutableSet<ClassName> annotationClassNames() {
60     return ImmutableSet.of(ClassNames.DEFINE_COMPONENT, ClassNames.DEFINE_COMPONENT_BUILDER);
61   }
62 
63   @Override
processEach(ClassName annotation, XElement element)64   public void processEach(ClassName annotation, XElement element) {
65     if (annotation.equals(ClassNames.DEFINE_COMPONENT)) {
66       // TODO(bcorso): For cycles we currently process each element in the cycle. We should skip
67       // processing of subsequent elements in a cycle, but this requires ensuring that the first
68       // element processed is always the same so that our failure tests are stable.
69       DefineComponentMetadata metadata = componentMetadatas.get(element);
70       generateFile("component", metadata.component());
71     } else if (annotation.equals(ClassNames.DEFINE_COMPONENT_BUILDER)) {
72       DefineComponentBuilderMetadata metadata = componentBuilderMetadatas.get(element);
73       generateFile("builder", metadata.builder());
74     } else {
75       throw new AssertionError("Unhandled annotation type: " + annotation.canonicalName());
76     }
77   }
78 
generateFile(String member, XTypeElement typeElement)79   private void generateFile(String member, XTypeElement typeElement) {
80     Processors.generateAggregatingClass(
81         ClassNames.DEFINE_COMPONENT_CLASSES_PACKAGE,
82         AnnotationSpec.builder(ClassNames.DEFINE_COMPONENT_CLASSES)
83             .addMember(member, "$S", typeElement.getQualifiedName())
84             .build(),
85         typeElement,
86         getClass());
87   }
88 }
89