• 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.aggregateddeps;
18 
19 import static com.google.common.base.Preconditions.checkState;
20 import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;
21 
22 import com.google.auto.value.AutoValue;
23 import com.google.common.collect.ImmutableSet;
24 import com.google.common.collect.ImmutableSetMultimap;
25 import com.squareup.javapoet.ClassName;
26 import dagger.hilt.processor.internal.ClassNames;
27 import dagger.hilt.processor.internal.ComponentDescriptor;
28 import dagger.hilt.processor.internal.earlyentrypoint.AggregatedEarlyEntryPointMetadata;
29 import dagger.hilt.processor.internal.uninstallmodules.AggregatedUninstallModulesMetadata;
30 import javax.lang.model.element.TypeElement;
31 import javax.lang.model.util.Elements;
32 
33 /** Represents information needed to create a component (i.e. modules, entry points, etc) */
34 @AutoValue
35 public abstract class ComponentDependencies {
builder()36   private static Builder builder() {
37     return new AutoValue_ComponentDependencies.Builder();
38   }
39 
40   /** Returns the modules for a component, without any filtering. */
modules()41   public abstract ImmutableSetMultimap<ClassName, TypeElement> modules();
42 
43   /** Returns the entry points associated with the given a component. */
entryPoints()44   public abstract ImmutableSetMultimap<ClassName, TypeElement> entryPoints();
45 
46   /** Returns the component entry point associated with the given a component. */
componentEntryPoints()47   public abstract ImmutableSetMultimap<ClassName, TypeElement> componentEntryPoints();
48 
49   @AutoValue.Builder
50   abstract static class Builder {
modulesBuilder()51     abstract ImmutableSetMultimap.Builder<ClassName, TypeElement> modulesBuilder();
52 
entryPointsBuilder()53     abstract ImmutableSetMultimap.Builder<ClassName, TypeElement> entryPointsBuilder();
54 
componentEntryPointsBuilder()55     abstract ImmutableSetMultimap.Builder<ClassName, TypeElement> componentEntryPointsBuilder();
56 
build()57     abstract ComponentDependencies build();
58   }
59 
60   /** Returns the component dependencies for the given metadata. */
from( ImmutableSet<ComponentDescriptor> descriptors, ImmutableSet<AggregatedDepsMetadata> aggregatedDepsMetadata, ImmutableSet<AggregatedUninstallModulesMetadata> aggregatedUninstallModulesMetadata, ImmutableSet<AggregatedEarlyEntryPointMetadata> aggregatedEarlyEntryPointMetadata, Elements elements)61   public static ComponentDependencies from(
62       ImmutableSet<ComponentDescriptor> descriptors,
63       ImmutableSet<AggregatedDepsMetadata> aggregatedDepsMetadata,
64       ImmutableSet<AggregatedUninstallModulesMetadata> aggregatedUninstallModulesMetadata,
65       ImmutableSet<AggregatedEarlyEntryPointMetadata> aggregatedEarlyEntryPointMetadata,
66       Elements elements) {
67     ImmutableSet<TypeElement> uninstalledModules =
68         ImmutableSet.<TypeElement>builder()
69             .addAll(
70                 aggregatedUninstallModulesMetadata.stream()
71                     .flatMap(metadata -> metadata.uninstallModuleElements().stream())
72                     // @AggregatedUninstallModules always references the user module, so convert to
73                     // the generated public wrapper if needed.
74                     // TODO(bcorso): Consider converting this to the public module in the processor.
75                     .map(module -> PkgPrivateMetadata.publicModule(module, elements))
76                     .collect(toImmutableSet()))
77             .addAll(
78                 aggregatedDepsMetadata.stream()
79                     .flatMap(metadata -> metadata.replacedDependencies().stream())
80                     .collect(toImmutableSet()))
81             .build();
82 
83     ComponentDependencies.Builder componentDependencies = ComponentDependencies.builder();
84     ImmutableSet<ClassName> componentNames =
85         descriptors.stream().map(ComponentDescriptor::component).collect(toImmutableSet());
86     for (AggregatedDepsMetadata metadata : aggregatedDepsMetadata) {
87       for (TypeElement componentElement : metadata.componentElements()) {
88         ClassName componentName = ClassName.get(componentElement);
89         checkState(
90             componentNames.contains(componentName), "%s is not a valid Component.", componentName);
91         switch (metadata.dependencyType()) {
92           case MODULE:
93             if (!uninstalledModules.contains(metadata.dependency())) {
94               componentDependencies.modulesBuilder().put(componentName, metadata.dependency());
95             }
96             break;
97           case ENTRY_POINT:
98             componentDependencies.entryPointsBuilder().put(componentName, metadata.dependency());
99             break;
100           case COMPONENT_ENTRY_POINT:
101             componentDependencies
102                 .componentEntryPointsBuilder()
103                 .put(componentName, metadata.dependency());
104             break;
105         }
106       }
107     }
108 
109     componentDependencies
110         .entryPointsBuilder()
111         .putAll(
112             ClassNames.SINGLETON_COMPONENT,
113             aggregatedEarlyEntryPointMetadata.stream()
114                 .map(AggregatedEarlyEntryPointMetadata::earlyEntryPoint)
115                 // @AggregatedEarlyEntryPointMetadata always references the user module, so convert
116                 // to the generated public wrapper if needed.
117                 // TODO(bcorso): Consider converting this to the public module in the processor.
118                 .map(entryPoint -> PkgPrivateMetadata.publicEarlyEntryPoint(entryPoint, elements))
119                 .collect(toImmutableSet()));
120 
121     return componentDependencies.build();
122   }
123 }
124