Skip to content
Permalink
Browse files

Make AutoValue and AutoService support Gradle incremental build. This…

… work was done by Thomas Broyer.

Closes #657

RELNOTES=Make AutoValue and AutoService support Gradle incremental build. Thanks to Thomas Broyer for this work.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=214442018
  • Loading branch information...
tbroyer authored and eamonnmcmanus committed Sep 25, 2018
1 parent 73e848a commit a5673d06f687e1354f1f069cce36136538cf532c
@@ -0,0 +1 @@
com.google.auto.service.processor.AutoServiceProcessor,AGGREGATING
@@ -56,6 +56,17 @@
<artifactId>escapevelocity</artifactId>
<version>0.9</version>
</dependency>
<dependency>
<groupId>net.ltgt.gradle.incap</groupId>
<artifactId>incap</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>net.ltgt.gradle.incap</groupId>
<artifactId>incap-processor</artifactId>
<version>0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
@@ -108,6 +108,62 @@
Set<ExecutableElement> abstractMethods();
}

/**
* Indicates to an annotation processor environment supporting incremental annotation processing
* (currently a feature specific to Gradle starting with version 4.8) the incremental type of an
* Extension.
*
* <p>The constants for this enum are ordered by increasing performance (but also constraints).
*
* @see <a
* href="https://docs.gradle.org/current/userguide/java_plugin.html#sec:incremental_annotation_processing">Gradle
* documentation of its incremental annotation processing</a>
*/
public enum IncrementalExtensionType {
/**
* The incrementality of this extension is unknown, or it is neither aggregating nor isolating.
*/
UNKNOWN,

/**
* This extension is <i>aggregating</i>, meaning that it may generate outputs based on several
* annotated input classes and it respects the constraints imposed on aggregating processors.
* It is unusual for AutoValue extensions to be aggregating.
*
* @see <a
* href="https://docs.gradle.org/current/userguide/java_plugin.html#aggregating_annotation_processors">Gradle
* definition of aggregating processors</a>
*/
AGGREGATING,

/**
* This extension is <i>isolating</i>, meaning roughly that its output depends on the
* {@code @AutoValue} class and its dependencies, but not on other {@code @AutoValue} classes
* that might be compiled at the same time. The constraints that an isolating extension must
* respect are the same as those that Gradle imposes on an isolating annotation processor.
*
* @see <a
* href="https://docs.gradle.org/current/userguide/java_plugin.html#isolating_annotation_processors">Gradle
* definition of isolating processors</a>
*/
ISOLATING
}

/**
* Determines the incremental type of this Extension.
*
* <p>The {@link ProcessingEnvironment} can be used, among other things, to obtain the processor
* options, using {@link ProcessingEnvironment#getOptions()}.
*
* <p>The actual incremental type of the AutoValue processor as a whole will be the loosest
* incremental types of the Extensions present in the annotation processor path. The default
* returned value is {@link IncrementalExtensionType#UNKNOWN}, which will disable incremental
* annotation processing entirely.
*/
public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {
return IncrementalExtensionType.UNKNOWN;
}

/**
* Determines whether this Extension applies to the given context.
*
@@ -55,6 +55,7 @@
import java.util.Map;
import java.util.Optional;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.ExecutableElement;
@@ -76,6 +77,11 @@
private static final AnnotationSpec SUPPRESS_WARNINGS =
AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "$S", "Immutable").build();

@Override
public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {
return IncrementalExtensionType.ISOLATING;
}

@Override
public boolean applicable(Context context) {
return !memoizedMethods(context).isEmpty();
@@ -33,12 +33,15 @@
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;

/**
* An annotation {@link Processor} that reports errors for {@link Memoized @Memoized} methods that
* are not inside {@code AutoValue}-annotated classes.
*/
@AutoService(Processor.class)
@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)
@SupportedAnnotationTypes(MEMOIZED_NAME)
public final class MemoizedValidator extends AbstractProcessor {
@Override
@@ -58,6 +58,8 @@
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;

/**
* Javac annotation processor (compiler plugin) to generate annotation implementations. User code
@@ -66,6 +68,7 @@
* @author emcmanus@google.com (Éamonn McManus)
*/
@AutoService(Processor.class)
@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)
@SupportedAnnotationTypes(AUTO_ANNOTATION_NAME)
public class AutoAnnotationProcessor extends AbstractProcessor {
public AutoAnnotationProcessor() {}
@@ -36,7 +36,6 @@
import java.util.Set;
import javax.annotation.processing.Processor;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
@@ -46,6 +45,8 @@
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;

/**
* Javac annotation processor (compiler plugin) for {@linkplain com.google.auto.value.AutoOneOf
@@ -56,7 +57,7 @@
*/
@AutoService(Processor.class)
@SupportedAnnotationTypes(AUTO_ONE_OF_NAME)
@SupportedOptions("com.google.auto.value.OmitIdentifiers")
@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)
public class AutoOneOfProcessor extends AutoValueOrOneOfProcessor {
public AutoOneOfProcessor() {
super(AUTO_ONE_OF_NAME);
@@ -30,6 +30,8 @@
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;

/**
* Annotation processor that checks that the type that {@code AutoValue.Builder} is applied to is
@@ -39,6 +41,7 @@
* @author Éamonn McManus
*/
@AutoService(Processor.class)
@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)
@SupportedAnnotationTypes(AUTO_VALUE_BUILDER_NAME)
public class AutoValueBuilderProcessor extends AbstractProcessor {
@Override
@@ -33,6 +33,7 @@
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
@@ -43,14 +44,15 @@
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;

/**
* Javac annotation processor (compiler plugin) for value types; user code never references this
@@ -61,8 +63,10 @@
*/
@AutoService(Processor.class)
@SupportedAnnotationTypes(AUTO_VALUE_NAME)
@SupportedOptions("com.google.auto.value.OmitIdentifiers")
@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.DYNAMIC)
public class AutoValueProcessor extends AutoValueOrOneOfProcessor {
private static final String OMIT_IDENTIFIERS_OPTION = "com.google.auto.value.OmitIdentifiers";

public AutoValueProcessor() {
this(AutoValueProcessor.class.getClassLoader());
}
@@ -112,6 +116,28 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
}
}

@Override
public Set<String> getSupportedOptions() {
AutoValueExtension.IncrementalExtensionType incrementalType =
extensions.stream()
.map(e -> e.incrementalType(processingEnv))
.min(Comparator.naturalOrder())
.orElse(AutoValueExtension.IncrementalExtensionType.ISOLATING);
switch (incrementalType) {
case ISOLATING:
return ImmutableSet.of(
OMIT_IDENTIFIERS_OPTION,
IncrementalAnnotationProcessorType.ISOLATING.getProcessorOption());
case AGGREGATING:
return ImmutableSet.of(
OMIT_IDENTIFIERS_OPTION,
IncrementalAnnotationProcessorType.AGGREGATING.getProcessorOption());
case UNKNOWN:
return ImmutableSet.of(OMIT_IDENTIFIERS_OPTION);
}
throw new AssertionError(incrementalType);
}

private static String generatedSubclassName(TypeElement type, int depth) {
return generatedClassName(type, Strings.repeat("$", depth) + "AutoValue_");
}
@@ -201,8 +227,7 @@ void processType(TypeElement type) {
AutoValueTemplateVars vars = new AutoValueTemplateVars();
vars.finalSubclass = TypeSimplifier.simpleNameOf(finalSubclass);
vars.types = processingEnv.getTypeUtils();
vars.identifiers =
!processingEnv.getOptions().containsKey("com.google.auto.value.OmitIdentifiers");
vars.identifiers = !processingEnv.getOptions().containsKey(OMIT_IDENTIFIERS_OPTION);
defineSharedVarsForType(type, methods, vars);
defineVarsForType(type, vars, toBuilderMethods, propertyMethods, builder);

1 comment on commit a5673d0

@mtripakis

This comment has been minimized.

Copy link

commented on a5673d0 Jan 16, 2019

Great contribution! Just a small notice if it was written involuntary that way: in the javadoc the link provided is always "https://docs.gradle.org/current/userguide/...", it would be maybe better for future reference and confusion avoidance to be pointing at a specific Gradle version (like: "....org/5.0/userguide/...). That is if this standard is not fixed and could possibly evolve in the future.

Please sign in to comment.
You can’t perform that action at this time.