Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate RootProcessor to XProcessing. #3815

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
199 changes: 89 additions & 110 deletions java/dagger/hilt/processor/internal/Processors.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,50 +16,47 @@

package dagger.hilt.processor.internal.root;

import androidx.room.compiler.processing.XTypeElement;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import dagger.hilt.processor.internal.ClassNames;
import dagger.hilt.processor.internal.Processors;
import java.io.IOException;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.TypeElement;

/** Generates an {@link dagger.hilt.internal.aggregatedroot.AggregatedRoot}. */
final class AggregatedRootGenerator {
private final TypeElement rootElement;
private final TypeElement originatingRootElement;
private final TypeElement rootAnnotation;
private final ProcessingEnvironment processingEnv;
private final XTypeElement rootElement;
private final XTypeElement originatingRootElement;
private final XTypeElement rootAnnotation;

AggregatedRootGenerator(
TypeElement rootElement,
TypeElement originatingRootElement,
TypeElement rootAnnotation,
ProcessingEnvironment processingEnv) {
XTypeElement rootElement, XTypeElement originatingRootElement, XTypeElement rootAnnotation) {
this.rootElement = rootElement;
this.originatingRootElement = originatingRootElement;
this.rootAnnotation = rootAnnotation;
this.processingEnv = processingEnv;
}

void generate() throws IOException {
AnnotationSpec.Builder aggregatedRootAnnotation = AnnotationSpec.builder(
ClassNames.AGGREGATED_ROOT)
AnnotationSpec.Builder aggregatedRootAnnotation =
AnnotationSpec.builder(ClassNames.AGGREGATED_ROOT)
.addMember("root", "$S", rootElement.getQualifiedName())
.addMember("rootPackage", "$S", ClassName.get(rootElement).packageName())
.addMember("rootPackage", "$S", rootElement.getClassName().packageName())
.addMember("originatingRoot", "$S", originatingRootElement.getQualifiedName())
.addMember("originatingRootPackage", "$S",
ClassName.get(originatingRootElement).packageName())
.addMember("rootAnnotation", "$T.class", rootAnnotation);
ClassName.get(rootElement).simpleNames().forEach(
name -> aggregatedRootAnnotation.addMember("rootSimpleNames", "$S", name));
ClassName.get(originatingRootElement).simpleNames().forEach(
name -> aggregatedRootAnnotation.addMember("originatingRootSimpleNames", "$S", name));
.addMember(
"originatingRootPackage", "$S", originatingRootElement.getClassName().packageName())
.addMember("rootAnnotation", "$T.class", rootAnnotation.getClassName());
rootElement
.getClassName()
.simpleNames()
.forEach(name -> aggregatedRootAnnotation.addMember("rootSimpleNames", "$S", name));
originatingRootElement
.getClassName()
.simpleNames()
.forEach(
name -> aggregatedRootAnnotation.addMember("originatingRootSimpleNames", "$S", name));
Processors.generateAggregatingClass(
ClassNames.AGGREGATED_ROOT_PACKAGE,
aggregatedRootAnnotation.build(),
rootElement,
getClass(),
processingEnv);
getClass());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,17 @@

import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;

import androidx.room.compiler.processing.XAnnotation;
import androidx.room.compiler.processing.XProcessingEnv;
import androidx.room.compiler.processing.XTypeElement;
import androidx.room.compiler.processing.compat.XConverters;
import com.google.auto.value.AutoValue;
import com.google.auto.value.extension.memoized.Memoized;
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.AggregatedRootIr;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.TypeElement;
import dagger.internal.codegen.xprocessing.XTypeElements;

/**
* Represents the values stored in an {@link dagger.hilt.internal.aggregatedroot.AggregatedRoot}.
Expand All @@ -40,19 +37,19 @@
abstract class AggregatedRootMetadata {

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

/** Returns the element that was annotated with the root annotation. */
abstract TypeElement rootElement();
abstract XTypeElement rootElement();

/**
* Returns the originating root element. In most cases this will be the same as
* {@link #rootElement()}.
* Returns the originating root element. In most cases this will be the same as {@link
* #rootElement()}.
*/
abstract TypeElement originatingRootElement();
abstract XTypeElement originatingRootElement();

/** Returns the root annotation as an element. */
abstract TypeElement rootAnnotation();
abstract XTypeElement rootAnnotation();

/** Returns whether this root can use a shared component. */
abstract boolean allowsSharingComponent();
Expand All @@ -62,46 +59,44 @@ RootType rootType() {
return RootType.of(rootElement());
}

static ImmutableSet<AggregatedRootMetadata> from(ProcessingEnvironment env) {
static ImmutableSet<AggregatedRootMetadata> from(XProcessingEnv env) {
return from(
AggregatedElements.from(
ClassNames.AGGREGATED_ROOT_PACKAGE, ClassNames.AGGREGATED_ROOT, env.getElementUtils()),
XTypeElements.toXProcessing(
AggregatedElements.from(
ClassNames.AGGREGATED_ROOT_PACKAGE,
ClassNames.AGGREGATED_ROOT,
XConverters.toJavac(env).getElementUtils()),
env),
env);
}

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

public static AggregatedRootIr toIr(AggregatedRootMetadata metadata) {
return new AggregatedRootIr(
ClassName.get(metadata.aggregatingElement()),
ClassName.get(metadata.rootElement()),
ClassName.get(metadata.originatingRootElement()),
ClassName.get(metadata.rootAnnotation()),
metadata.aggregatingElement().getClassName(),
metadata.rootElement().getClassName(),
metadata.originatingRootElement().getClassName(),
metadata.rootAnnotation().getClassName(),
metadata.allowsSharingComponent());
}

private static AggregatedRootMetadata create(TypeElement element, ProcessingEnvironment env) {
AnnotationMirror annotationMirror =
Processors.getAnnotationMirror(element, ClassNames.AGGREGATED_ROOT);
private static AggregatedRootMetadata create(XTypeElement element, XProcessingEnv env) {
XAnnotation annotation = element.getAnnotation(ClassNames.AGGREGATED_ROOT);

ImmutableMap<String, AnnotationValue> values =
Processors.getAnnotationValues(env.getElementUtils(), annotationMirror);

TypeElement rootElement =
env.getElementUtils().getTypeElement(AnnotationValues.getString(values.get("root")));
XTypeElement rootElement = env.requireTypeElement(annotation.getAsString("root"));
boolean allowSharingComponent = true;
return new AutoValue_AggregatedRootMetadata(
element,
rootElement,
env.getElementUtils()
.getTypeElement(AnnotationValues.getString(values.get("originatingRoot"))),
AnnotationValues.getTypeElement(values.get("rootAnnotation")),
env.requireTypeElement(annotation.getAsString("originatingRoot")),
annotation.getAsType("rootAnnotation").getTypeElement(),
allowSharingComponent);
}
}
2 changes: 2 additions & 0 deletions java/dagger/hilt/processor/internal/root/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ java_library(
"//java/dagger/internal/codegen/xprocessing",
"//third_party/java/auto:common",
"//third_party/java/auto:service",
"//third_party/java/error_prone:annotations",
"//third_party/java/guava/base",
"//third_party/java/guava/collect",
"//third_party/java/guava/graph",
Expand Down Expand Up @@ -150,6 +151,7 @@ java_library(
deps = [
"//java/dagger/hilt/processor/internal:classnames",
"//java/dagger/hilt/processor/internal:processors",
"//java/dagger/internal/codegen/xprocessing",
"//third_party/java/javapoet",
],
)
Expand Down
11 changes: 7 additions & 4 deletions java/dagger/hilt/processor/internal/root/ComponentGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList;
import static java.util.Comparator.comparing;

import androidx.room.compiler.processing.XFiler.Mode;
import androidx.room.compiler.processing.XProcessingEnv;
import com.google.common.base.Joiner;
import com.google.common.base.Utf8;
import com.google.common.collect.ImmutableCollection;
Expand All @@ -36,7 +38,6 @@
import java.util.List;
import java.util.Optional;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Modifier;

/** Generates a Dagger component or subcomponent interface. */
Expand All @@ -47,7 +48,7 @@ final class ComponentGenerator {
.thenComparing(ClassName::compareTo);
private static final Comparator<TypeName> TYPE_NAME_SORTER = comparing(TypeName::toString);

private final ProcessingEnvironment processingEnv;
private final XProcessingEnv processingEnv;
private final ClassName name;
private final Optional<ClassName> superclass;
private final ImmutableList<ClassName> modules;
Expand All @@ -58,7 +59,7 @@ final class ComponentGenerator {
private final Optional<TypeSpec> componentBuilder;

public ComponentGenerator(
ProcessingEnvironment processingEnv,
XProcessingEnv processingEnv,
ClassName name,
Optional<ClassName> superclass,
Set<? extends ClassName> modules,
Expand Down Expand Up @@ -161,7 +162,9 @@ private ClassName createPartitionInterface(List<TypeName> partition, int partiti

Processors.addGeneratedAnnotation(builder, processingEnv, ClassNames.ROOT_PROCESSOR.toString());

JavaFile.builder(name.packageName(), builder.build()).build().writeTo(processingEnv.getFiler());
processingEnv
.getFiler()
.write(JavaFile.builder(name.packageName(), builder.build()).build(), Mode.Isolating);
return partitionName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

import static javax.lang.model.element.Modifier.PUBLIC;

import androidx.room.compiler.processing.XFiler.Mode;
import androidx.room.compiler.processing.XProcessingEnv;
import androidx.room.compiler.processing.XTypeElement;
import androidx.room.compiler.processing.compat.XConverters;
import com.google.common.collect.ImmutableSet;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
Expand All @@ -30,17 +34,15 @@
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.TypeElement;

/** Generates an {@link dagger.hilt.internal.componenttreedeps.ComponentTreeDeps}. */
final class ComponentTreeDepsGenerator {
// Keeps track of already generated proxies. For correctness, this same instance of
// ComponentTreeDepsGenerator must be used for a given round.
private final Set<ClassName> generatedProxies = new HashSet<>();
private final ProcessingEnvironment env;
private final XProcessingEnv env;

ComponentTreeDepsGenerator(ProcessingEnvironment env) {
ComponentTreeDepsGenerator(XProcessingEnv env) {
this.env = env;
}

Expand All @@ -53,7 +55,8 @@ void generate(ComponentTreeDepsMetadata metadata) throws IOException {

Processors.addGeneratedAnnotation(builder, env, ClassNames.ROOT_PROCESSOR.toString());

JavaFile.builder(name.packageName(), builder.build()).build().writeTo(env.getFiler());
env.getFiler()
.write(JavaFile.builder(name.packageName(), builder.build()).build(), Mode.Isolating);
}

AnnotationSpec componentTreeDepsAnnotation(ComponentTreeDepsMetadata metadata)
Expand All @@ -68,9 +71,9 @@ AnnotationSpec componentTreeDepsAnnotation(ComponentTreeDepsMetadata metadata)
return builder.build();
}

private void addDeps(AnnotationSpec.Builder builder, ImmutableSet<TypeElement> deps, String name)
private void addDeps(AnnotationSpec.Builder builder, ImmutableSet<XTypeElement> deps, String name)
throws IOException {
for (TypeElement dep : deps) {
for (XTypeElement dep : deps) {
builder.addMember(name, "$T.class", maybeWrapInPublicProxy(dep));
}
}
Expand All @@ -85,33 +88,34 @@ private void addDeps(AnnotationSpec.Builder builder, ImmutableSet<TypeElement> d
* <p>Note: The public proxy is needed because Hilt versions < 2.35 generated package-private
* aggregating elements, which can't be referenced directly in the {@code @ComponentTreeDeps}.
*/
private ClassName maybeWrapInPublicProxy(TypeElement dep) throws IOException {
Optional<ClassName> proxyName = AggregatedElements.aggregatedElementProxyName(dep);
private ClassName maybeWrapInPublicProxy(XTypeElement dep) throws IOException {
Optional<ClassName> proxyName =
AggregatedElements.aggregatedElementProxyName(XConverters.toJavac(dep));
if (proxyName.isPresent()) {
// Check the set of already generated proxies to ensure we don't regenerate the proxy in
// this round. Also check that the element doesn't already exist to ensure we don't regenerate
// a proxy generated in a previous round.
if (generatedProxies.add(proxyName.get())
&& env.getElementUtils().getTypeElement(proxyName.get().canonicalName()) == null) {
&& env.findTypeElement(proxyName.get().canonicalName()) == null) {
generateProxy(dep, proxyName.get());
}
return proxyName.get();
}
return ClassName.get(dep);
return dep.getClassName();
}

private void generateProxy(TypeElement dep, ClassName proxyName) throws IOException {
private void generateProxy(XTypeElement dep, ClassName proxyName) throws IOException {
TypeSpec.Builder builder =
TypeSpec.classBuilder(proxyName)
.addModifiers(PUBLIC)
// No originating element since this is generated by the aggregating processor.
.addAnnotation(
AnnotationSpec.builder(ClassNames.AGGREGATED_ELEMENT_PROXY)
.addMember("value", "$T.class", dep)
.addMember("value", "$T.class", dep.getClassName())
.build());

Processors.addGeneratedAnnotation(builder, env, ClassNames.ROOT_PROCESSOR.toString());

JavaFile.builder(proxyName.packageName(), builder.build()).build().writeTo(env.getFiler());
env.getFiler()
.write(JavaFile.builder(proxyName.packageName(), builder.build()).build(), Mode.Isolating);
}
}