Skip to content

Commit

Permalink
Migrate RootProcessor to XProcessing.
Browse files Browse the repository at this point in the history
RELNOTES=n/a
PiperOrigin-RevId: 520028890
  • Loading branch information
kuanyingchou authored and Dagger Team committed Mar 28, 2023
1 parent 2424a6c commit a8fbfc2
Show file tree
Hide file tree
Showing 22 changed files with 446 additions and 436 deletions.
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);
}
}

0 comments on commit a8fbfc2

Please sign in to comment.