Skip to content

Commit

Permalink
Migrate files in aggregateddeps to XProcessing.
Browse files Browse the repository at this point in the history
RELNOTES=n/a
PiperOrigin-RevId: 520004065
  • Loading branch information
kuanyingchou authored and Dagger Team committed Mar 28, 2023
1 parent 70f99e7 commit 9529279
Show file tree
Hide file tree
Showing 8 changed files with 233 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,18 @@
import static com.google.common.collect.Iterables.getOnlyElement;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;

import androidx.room.compiler.processing.XAnnotation;
import androidx.room.compiler.processing.XAnnotationValue;
import androidx.room.compiler.processing.XProcessingEnv;
import androidx.room.compiler.processing.XTypeElement;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.squareup.javapoet.ClassName;
import dagger.hilt.processor.internal.AggregatedElements;
import dagger.hilt.processor.internal.AnnotationValues;
import dagger.hilt.processor.internal.ClassNames;
import dagger.hilt.processor.internal.Processors;
import dagger.hilt.processor.internal.root.ir.AggregatedDepsIr;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;

/**
* A class that represents the values stored in an {@link
Expand All @@ -52,97 +49,94 @@ enum DependencyType {
}

/** Returns the aggregating element */
public abstract TypeElement aggregatingElement();
public abstract XTypeElement aggregatingElement();

public abstract Optional<TypeElement> testElement();
public abstract Optional<XTypeElement> testElement();

public abstract ImmutableSet<TypeElement> componentElements();
public abstract ImmutableSet<XTypeElement> componentElements();

abstract DependencyType dependencyType();

public abstract TypeElement dependency();
public abstract XTypeElement dependency();

public abstract ImmutableSet<TypeElement> replacedDependencies();
public abstract ImmutableSet<XTypeElement> replacedDependencies();

public boolean isModule() {
return dependencyType() == DependencyType.MODULE;
}

/** Returns metadata for all aggregated elements in the aggregating package. */
public static ImmutableSet<AggregatedDepsMetadata> from(Elements elements) {
public static ImmutableSet<AggregatedDepsMetadata> from(XProcessingEnv env) {
return from(
AggregatedElements.from(AGGREGATED_DEPS_PACKAGE, ClassNames.AGGREGATED_DEPS, elements),
elements);
AggregatedElements.from(AGGREGATED_DEPS_PACKAGE, ClassNames.AGGREGATED_DEPS, env), env);
}

/** Returns metadata for each aggregated element. */
public static ImmutableSet<AggregatedDepsMetadata> from(
ImmutableSet<TypeElement> aggregatedElements, Elements elements) {
ImmutableSet<XTypeElement> aggregatedElements, XProcessingEnv env) {
return aggregatedElements.stream()
.map(aggregatedElement -> create(aggregatedElement, elements))
.map(aggregatedElement -> create(aggregatedElement, env))
.collect(toImmutableSet());
}

public static AggregatedDepsIr toIr(AggregatedDepsMetadata metadata) {
return new AggregatedDepsIr(
ClassName.get(metadata.aggregatingElement()),
metadata.aggregatingElement().getClassName(),
metadata.componentElements().stream()
.map(ClassName::get)
.map(XTypeElement::getClassName)
.map(ClassName::canonicalName)
.collect(Collectors.toList()),
metadata.testElement()
.map(ClassName::get)
metadata
.testElement()
.map(XTypeElement::getClassName)
.map(ClassName::canonicalName)
.orElse(null),
metadata.replacedDependencies().stream()
.map(ClassName::get)
.map(XTypeElement::getClassName)
.map(ClassName::canonicalName)
.collect(Collectors.toList()),
metadata.dependencyType() == DependencyType.MODULE
? ClassName.get(metadata.dependency()).canonicalName()
? metadata.dependency().getClassName().canonicalName()
: null,
metadata.dependencyType() == DependencyType.ENTRY_POINT
? ClassName.get(metadata.dependency()).canonicalName()
? metadata.dependency().getClassName().canonicalName()
: null,
metadata.dependencyType() == DependencyType.COMPONENT_ENTRY_POINT
? ClassName.get(metadata.dependency()).canonicalName()
? metadata.dependency().getClassName().canonicalName()
: null);
}

private static AggregatedDepsMetadata create(TypeElement element, Elements elements) {
AnnotationMirror annotationMirror =
Processors.getAnnotationMirror(element, ClassNames.AGGREGATED_DEPS);

ImmutableMap<String, AnnotationValue> values =
Processors.getAnnotationValues(elements, annotationMirror);
private static AggregatedDepsMetadata create(XTypeElement element, XProcessingEnv env) {
XAnnotation annotation = element.getAnnotation(ClassNames.AGGREGATED_DEPS);

return new AutoValue_AggregatedDepsMetadata(
element,
getTestElement(values.get("test"), elements),
getComponents(values.get("components"), elements),
getTestElement(annotation.getAnnotationValue("test"), env),
getComponents(annotation.getAnnotationValue("components"), env),
getDependencyType(
values.get("modules"), values.get("entryPoints"), values.get("componentEntryPoints")),
annotation.getAnnotationValue("modules"),
annotation.getAnnotationValue("entryPoints"),
annotation.getAnnotationValue("componentEntryPoints")),
getDependency(
values.get("modules"),
values.get("entryPoints"),
values.get("componentEntryPoints"),
elements),
getReplacedDependencies(values.get("replaces"), elements));
annotation.getAnnotationValue("modules"),
annotation.getAnnotationValue("entryPoints"),
annotation.getAnnotationValue("componentEntryPoints"),
env),
getReplacedDependencies(annotation.getAnnotationValue("replaces"), env));
}

private static Optional<TypeElement> getTestElement(
AnnotationValue testValue, Elements elements) {
private static Optional<XTypeElement> getTestElement(
XAnnotationValue testValue, XProcessingEnv env) {
checkNotNull(testValue);
String test = AnnotationValues.getString(testValue);
return test.isEmpty() ? Optional.empty() : Optional.of(elements.getTypeElement(test));
String test = testValue.asString();
return test.isEmpty() ? Optional.empty() : Optional.of(env.findTypeElement(test));
}

private static ImmutableSet<TypeElement> getComponents(
AnnotationValue componentsValue, Elements elements) {
private static ImmutableSet<XTypeElement> getComponents(
XAnnotationValue componentsValue, XProcessingEnv env) {
checkNotNull(componentsValue);
ImmutableSet<TypeElement> componentNames =
AnnotationValues.getAnnotationValues(componentsValue).stream()
.map(AnnotationValues::getString)
ImmutableSet<XTypeElement> componentNames =
componentsValue.asStringList().stream()
.map(
// This is a temporary hack to map the old ApplicationComponent to the new
// SingletonComponent. Technically, this is only needed for backwards compatibility
Expand All @@ -153,71 +147,70 @@ private static ImmutableSet<TypeElement> getComponents(
"dagger.hilt.android.components.ApplicationComponent")
? ClassNames.SINGLETON_COMPONENT.canonicalName()
: componentName)
.map(elements::getTypeElement)
.map(env::requireTypeElement)
.collect(toImmutableSet());
checkState(!componentNames.isEmpty());
return componentNames;
}

private static DependencyType getDependencyType(
AnnotationValue modulesValue,
AnnotationValue entryPointsValue,
AnnotationValue componentEntryPointsValue) {
XAnnotationValue modulesValue,
XAnnotationValue entryPointsValue,
XAnnotationValue componentEntryPointsValue) {
checkNotNull(modulesValue);
checkNotNull(entryPointsValue);
checkNotNull(componentEntryPointsValue);

ImmutableSet.Builder<DependencyType> dependencyTypes = ImmutableSet.builder();
if (!AnnotationValues.getAnnotationValues(modulesValue).isEmpty()) {
if (!modulesValue.asAnnotationValueList().isEmpty()) {
dependencyTypes.add(DependencyType.MODULE);
}
if (!AnnotationValues.getAnnotationValues(entryPointsValue).isEmpty()) {
if (!entryPointsValue.asAnnotationValueList().isEmpty()) {
dependencyTypes.add(DependencyType.ENTRY_POINT);
}
if (!AnnotationValues.getAnnotationValues(componentEntryPointsValue).isEmpty()) {
if (!componentEntryPointsValue.asAnnotationValueList().isEmpty()) {
dependencyTypes.add(DependencyType.COMPONENT_ENTRY_POINT);
}
return getOnlyElement(dependencyTypes.build());
}

private static TypeElement getDependency(
AnnotationValue modulesValue,
AnnotationValue entryPointsValue,
AnnotationValue componentEntryPointsValue,
Elements elements) {
private static XTypeElement getDependency(
XAnnotationValue modulesValue,
XAnnotationValue entryPointsValue,
XAnnotationValue componentEntryPointsValue,
XProcessingEnv env) {
checkNotNull(modulesValue);
checkNotNull(entryPointsValue);
checkNotNull(componentEntryPointsValue);

String dependencyName =
AnnotationValues.getString(
getOnlyElement(
ImmutableSet.<AnnotationValue>builder()
.addAll(AnnotationValues.getAnnotationValues(modulesValue))
.addAll(AnnotationValues.getAnnotationValues(entryPointsValue))
.addAll(AnnotationValues.getAnnotationValues(componentEntryPointsValue))
.build()));
TypeElement dependency = elements.getTypeElement(dependencyName);
getOnlyElement(
ImmutableSet.<XAnnotationValue>builder()
.addAll(modulesValue.asAnnotationValueList())
.addAll(entryPointsValue.asAnnotationValueList())
.addAll(componentEntryPointsValue.asAnnotationValueList())
.build())
.asString();
XTypeElement dependency = env.findTypeElement(dependencyName);
checkNotNull(dependency, "Could not get element for %s", dependencyName);
return dependency;
}

private static ImmutableSet<TypeElement> getReplacedDependencies(
AnnotationValue replacedDependenciesValue, Elements elements) {
private static ImmutableSet<XTypeElement> getReplacedDependencies(
XAnnotationValue replacedDependenciesValue, XProcessingEnv env) {
// Allow null values to support libraries using a Hilt version before @TestInstallIn was added
return replacedDependenciesValue == null
? ImmutableSet.of()
: AnnotationValues.getAnnotationValues(replacedDependenciesValue).stream()
.map(AnnotationValues::getString)
.map(elements::getTypeElement)
.map(replacedDep -> getPublicDependency(replacedDep, elements))
: replacedDependenciesValue.asStringList().stream()
.map(env::requireTypeElement)
.map(replacedDep -> getPublicDependency(replacedDep, env))
.collect(toImmutableSet());
}

/** Returns the public Hilt wrapper module, or the module itself if its already public. */
private static TypeElement getPublicDependency(TypeElement dependency, Elements elements) {
return PkgPrivateMetadata.of(elements, dependency, ClassNames.MODULE)
.map(metadata -> elements.getTypeElement(metadata.generatedClassName().toString()))
private static XTypeElement getPublicDependency(XTypeElement dependency, XProcessingEnv env) {
return PkgPrivateMetadata.of(dependency, ClassNames.MODULE)
.map(metadata -> env.requireTypeElement(metadata.generatedClassName().toString()))
.orElse(dependency);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,7 @@ private void generateAggregatedDeps(
ImmutableSet<ClassName> components = Components.getComponents(element);

if (isValidKind(element)) {
Optional<PkgPrivateMetadata> pkgPrivateMetadata =
PkgPrivateMetadata.of(processingEnv(), element, annotation);
Optional<PkgPrivateMetadata> pkgPrivateMetadata = PkgPrivateMetadata.of(element, annotation);
if (pkgPrivateMetadata.isPresent()) {
if (key.contentEquals("modules")) {
new PkgPrivateModuleGenerator(processingEnv(), pkgPrivateMetadata.get()).generate();
Expand Down
1 change: 1 addition & 0 deletions java/dagger/hilt/processor/internal/aggregateddeps/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ java_library(
"//java/dagger/hilt/processor/internal/root/ir",
"//java/dagger/hilt/processor/internal/uninstallmodules:aggregated_uninstall_modules_metadata",
"//java/dagger/internal/codegen/extension",
"//java/dagger/internal/codegen/xprocessing",
"//third_party/java/auto:value",
"//third_party/java/guava/base",
"//third_party/java/guava/collect",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import static com.google.common.base.Preconditions.checkState;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;

import androidx.room.compiler.processing.XProcessingEnv;
import androidx.room.compiler.processing.XTypeElement;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
Expand All @@ -27,8 +29,6 @@
import dagger.hilt.processor.internal.ComponentDescriptor;
import dagger.hilt.processor.internal.earlyentrypoint.AggregatedEarlyEntryPointMetadata;
import dagger.hilt.processor.internal.uninstallmodules.AggregatedUninstallModulesMetadata;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;

/** Represents information needed to create a component (i.e. modules, entry points, etc) */
@AutoValue
Expand All @@ -38,21 +38,21 @@ private static Builder builder() {
}

/** Returns the modules for a component, without any filtering. */
public abstract ImmutableSetMultimap<ClassName, TypeElement> modules();
public abstract ImmutableSetMultimap<ClassName, XTypeElement> modules();

/** Returns the entry points associated with the given a component. */
public abstract ImmutableSetMultimap<ClassName, TypeElement> entryPoints();
public abstract ImmutableSetMultimap<ClassName, XTypeElement> entryPoints();

/** Returns the component entry point associated with the given a component. */
public abstract ImmutableSetMultimap<ClassName, TypeElement> componentEntryPoints();
public abstract ImmutableSetMultimap<ClassName, XTypeElement> componentEntryPoints();

@AutoValue.Builder
abstract static class Builder {
abstract ImmutableSetMultimap.Builder<ClassName, TypeElement> modulesBuilder();
abstract ImmutableSetMultimap.Builder<ClassName, XTypeElement> modulesBuilder();

abstract ImmutableSetMultimap.Builder<ClassName, TypeElement> entryPointsBuilder();
abstract ImmutableSetMultimap.Builder<ClassName, XTypeElement> entryPointsBuilder();

abstract ImmutableSetMultimap.Builder<ClassName, TypeElement> componentEntryPointsBuilder();
abstract ImmutableSetMultimap.Builder<ClassName, XTypeElement> componentEntryPointsBuilder();

abstract ComponentDependencies build();
}
Expand All @@ -63,16 +63,16 @@ public static ComponentDependencies from(
ImmutableSet<AggregatedDepsMetadata> aggregatedDepsMetadata,
ImmutableSet<AggregatedUninstallModulesMetadata> aggregatedUninstallModulesMetadata,
ImmutableSet<AggregatedEarlyEntryPointMetadata> aggregatedEarlyEntryPointMetadata,
Elements elements) {
ImmutableSet<TypeElement> uninstalledModules =
ImmutableSet.<TypeElement>builder()
XProcessingEnv env) {
ImmutableSet<XTypeElement> uninstalledModules =
ImmutableSet.<XTypeElement>builder()
.addAll(
aggregatedUninstallModulesMetadata.stream()
.flatMap(metadata -> metadata.uninstallModuleElements().stream())
// @AggregatedUninstallModules always references the user module, so convert to
// the generated public wrapper if needed.
// TODO(bcorso): Consider converting this to the public module in the processor.
.map(module -> PkgPrivateMetadata.publicModule(module, elements))
.map(module -> PkgPrivateMetadata.publicModule(module, env))
.collect(toImmutableSet()))
.addAll(
aggregatedDepsMetadata.stream()
Expand All @@ -84,8 +84,8 @@ public static ComponentDependencies from(
ImmutableSet<ClassName> componentNames =
descriptors.stream().map(ComponentDescriptor::component).collect(toImmutableSet());
for (AggregatedDepsMetadata metadata : aggregatedDepsMetadata) {
for (TypeElement componentElement : metadata.componentElements()) {
ClassName componentName = ClassName.get(componentElement);
for (XTypeElement componentElement : metadata.componentElements()) {
ClassName componentName = componentElement.getClassName();
checkState(
componentNames.contains(componentName), "%s is not a valid Component.", componentName);
switch (metadata.dependencyType()) {
Expand Down Expand Up @@ -115,7 +115,7 @@ public static ComponentDependencies from(
// @AggregatedEarlyEntryPointMetadata always references the user module, so convert
// to the generated public wrapper if needed.
// TODO(bcorso): Consider converting this to the public module in the processor.
.map(entryPoint -> PkgPrivateMetadata.publicEarlyEntryPoint(entryPoint, elements))
.map(entryPoint -> PkgPrivateMetadata.publicEarlyEntryPoint(entryPoint, env))
.collect(toImmutableSet()));

return componentDependencies.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,17 @@ void generate() throws IOException {
TypeSpec.Builder entryPointInterfaceBuilder =
JavaPoetExtKt.addOriginatingElement(
TypeSpec.interfaceBuilder(metadata.generatedClassName().simpleName()),
metadata.getXTypeElement(env))
metadata.getTypeElement())
.addAnnotation(Processors.getOriginatingElementAnnotation(metadata.getTypeElement()))
.addModifiers(Modifier.PUBLIC)
.addSuperinterface(metadata.baseClassName())
.addAnnotation(metadata.getAnnotation());

Processors.addGeneratedAnnotation(entryPointInterfaceBuilder, env, getClass());

if (metadata.getOptionalInstallInAnnotation(env).isPresent()) {
if (metadata.getOptionalInstallInAnnotation().isPresent()) {
entryPointInterfaceBuilder.addAnnotation(
XAnnotations.getAnnotationSpec(metadata.getOptionalInstallInAnnotation(env).get()));
XAnnotations.getAnnotationSpec(metadata.getOptionalInstallInAnnotation().get()));
}

env.getFiler()
Expand Down

0 comments on commit 9529279

Please sign in to comment.