From b2ba8ea725eea4386eea8094ed2b1de98c6e53ba Mon Sep 17 00:00:00 2001 From: Stefan Oehme Date: Mon, 22 Nov 2021 12:57:12 +0100 Subject: [PATCH] Merge annotation processing data on subsequent compilations Otherwise generated files from old compilations would be forgotten. Signed-off-by: Stefan Oehme --- ...AnnotationProcessingIntegrationTest.groovy | 19 ++++ .../IncrementalResultStoringCompiler.java | 87 +++++++++++++------ 2 files changed, 79 insertions(+), 27 deletions(-) diff --git a/subprojects/language-java/src/integTest/groovy/org/gradle/api/tasks/compile/IsolatingIncrementalAnnotationProcessingIntegrationTest.groovy b/subprojects/language-java/src/integTest/groovy/org/gradle/api/tasks/compile/IsolatingIncrementalAnnotationProcessingIntegrationTest.groovy index 94d410667753..edf9a236ce64 100644 --- a/subprojects/language-java/src/integTest/groovy/org/gradle/api/tasks/compile/IsolatingIncrementalAnnotationProcessingIntegrationTest.groovy +++ b/subprojects/language-java/src/integTest/groovy/org/gradle/api/tasks/compile/IsolatingIncrementalAnnotationProcessingIntegrationTest.groovy @@ -61,6 +61,25 @@ class IsolatingIncrementalAnnotationProcessingIntegrationTest extends AbstractIn outputs.recompiledFiles("A", "AHelper", "AHelperResource.txt") } + @Issue("https://https://github.com/micronaut-projects/micronaut-core/issues/6536") + def "remembers generated files across multiple compilations"() { + given: + def a = java "@Helper class A {}" + def b = java "@Helper class B {}" + java "class Unrelated {}" + run "compileJava" + a.text = "@Helper class A { public void foo() {} }" + outputs.snapshot { run "compileJava" } + + when: + b.text = " class B { }" + run "compileJava" + + then: + outputs.deletedFiles("BHelper", "BHelperResource") + outputs.recompiledFiles("B") + } + def "generated files are recompiled when annotated file is affected by a change"() { given: def util = java "class Util {}" diff --git a/subprojects/language-java/src/main/java/org/gradle/api/internal/tasks/compile/incremental/IncrementalResultStoringCompiler.java b/subprojects/language-java/src/main/java/org/gradle/api/internal/tasks/compile/incremental/IncrementalResultStoringCompiler.java index 3a84da9c2182..494ff722f46f 100644 --- a/subprojects/language-java/src/main/java/org/gradle/api/internal/tasks/compile/incremental/IncrementalResultStoringCompiler.java +++ b/subprojects/language-java/src/main/java/org/gradle/api/internal/tasks/compile/incremental/IncrementalResultStoringCompiler.java @@ -25,6 +25,7 @@ import org.gradle.api.internal.tasks.compile.incremental.compilerapi.CompilerApiData; import org.gradle.api.internal.tasks.compile.incremental.compilerapi.constants.ConstantToDependentsMapping; import org.gradle.api.internal.tasks.compile.incremental.compilerapi.constants.ConstantToDependentsMappingMerger; +import org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.GeneratedResource; import org.gradle.api.internal.tasks.compile.incremental.deps.ClassSetAnalysisData; import org.gradle.api.internal.tasks.compile.incremental.processing.AnnotationProcessingData; import org.gradle.api.internal.tasks.compile.incremental.processing.AnnotationProcessingResult; @@ -73,7 +74,7 @@ public WorkResult execute(T spec) { private void storeResult(JavaCompileSpec spec, WorkResult result) { ClassSetAnalysisData outputSnapshot = classpathSnapshotter.analyzeOutputFolder(spec.getDestinationDir()); ClassSetAnalysisData classpathSnapshot = classpathSnapshotter.getClasspathSnapshot(Iterables.concat(spec.getCompileClasspath(), spec.getModulePath())); - AnnotationProcessingData annotationProcessingData = getAnnotationProcessingResult(spec, result); + AnnotationProcessingData annotationProcessingData = getAnnotationProcessingData(spec, result); CompilerApiData compilerApiData = getCompilerApiData(spec, result); ClassSetAnalysisData minimizedClasspathSnapshot = classpathSnapshot.reduceToTypesAffecting(outputSnapshot, compilerApiData); PreviousCompilationData data = new PreviousCompilationData(outputSnapshot, annotationProcessingData, minimizedClasspathSnapshot, compilerApiData); @@ -81,32 +82,6 @@ private void storeResult(JavaCompileSpec spec, WorkResult result) { previousCompilationAccess.writePreviousCompilationData(data, previousCompilationDataFile); } - private AnnotationProcessingData getAnnotationProcessingResult(JavaCompileSpec spec, WorkResult result) { - Set processors = spec.getEffectiveAnnotationProcessors(); - if (processors.isEmpty()) { - return new AnnotationProcessingData(); - } - if (result instanceof IncrementalCompilationResult) { - result = ((IncrementalCompilationResult) result).getCompilerResult(); - } - if (result instanceof ApiCompilerResult) { - AnnotationProcessingResult processingResult = ((ApiCompilerResult) result).getAnnotationProcessingResult(); - return convertProcessingResult(processingResult); - } - return new AnnotationProcessingData(ImmutableMap.of(), ImmutableSet.of(), ImmutableSet.of(), ImmutableMap.of(), ImmutableSet.of(), "the chosen compiler did not support incremental annotation processing"); - } - - private AnnotationProcessingData convertProcessingResult(AnnotationProcessingResult processingResult) { - return new AnnotationProcessingData( - processingResult.getGeneratedTypesWithIsolatedOrigin(), - processingResult.getAggregatedTypes(), - processingResult.getGeneratedAggregatingTypes(), - processingResult.getGeneratedResourcesWithIsolatedOrigin(), - processingResult.getGeneratedAggregatingResources(), - processingResult.getFullRebuildCause() - ); - } - private CompilerApiData getCompilerApiData(JavaCompileSpec spec, WorkResult result) { if (spec.getCompileOptions().supportsCompilerApi()) { CompilerApiData previousCompilerApiData = null; @@ -152,4 +127,62 @@ private Map> mergeSourceClassesMappings(Map processors = spec.getEffectiveAnnotationProcessors(); + if (processors.isEmpty()) { + return new AnnotationProcessingData(); + } + AnnotationProcessingData previousAnnotationProcessingData = null; + RecompilationSpec recompilationSpec = null; + if (result instanceof IncrementalCompilationResult) { + previousAnnotationProcessingData = ((IncrementalCompilationResult) result).getPreviousCompilationData().getAnnotationProcessingData(); + recompilationSpec = ((IncrementalCompilationResult) result).getRecompilationSpec(); + result = ((IncrementalCompilationResult) result).getCompilerResult(); + } + Set changedClasses = recompilationSpec == null ? Collections.emptySet() : recompilationSpec.getClassesToCompile(); + + if (result instanceof ApiCompilerResult) { + AnnotationProcessingResult processingResult = ((ApiCompilerResult) result).getAnnotationProcessingResult(); + AnnotationProcessingData newAnnotationProcessingData = new AnnotationProcessingData( + processingResult.getGeneratedTypesWithIsolatedOrigin(), + processingResult.getAggregatedTypes(), + processingResult.getGeneratedAggregatingTypes(), + processingResult.getGeneratedResourcesWithIsolatedOrigin(), + processingResult.getGeneratedAggregatingResources(), + processingResult.getFullRebuildCause() + ); + if (previousAnnotationProcessingData == null) { + return newAnnotationProcessingData; + } + return mergeAnnotationProcessingData(previousAnnotationProcessingData, newAnnotationProcessingData, changedClasses); + } + return new AnnotationProcessingData( + ImmutableMap.of(), + ImmutableSet.of(), + ImmutableSet.of(), + ImmutableMap.of(), + ImmutableSet.of(), + "the chosen compiler did not support incremental annotation processing" + ); + + } + + private AnnotationProcessingData mergeAnnotationProcessingData(AnnotationProcessingData oldData, AnnotationProcessingData newData, Set changedClasses) { + Map> generatedTypesByOrigin = new HashMap<>(oldData.getGeneratedTypesByOrigin()); + changedClasses.forEach(generatedTypesByOrigin::remove); + generatedTypesByOrigin.putAll(newData.getGeneratedTypesByOrigin()); + Map> generatedResourcesByOrigin = new HashMap<>(oldData.getGeneratedResourcesByOrigin()); + changedClasses.forEach(generatedResourcesByOrigin::remove); + generatedResourcesByOrigin.putAll(newData.getGeneratedResourcesByOrigin()); + + return new AnnotationProcessingData( + generatedTypesByOrigin, + newData.getAggregatedTypes(), + newData.getGeneratedTypesDependingOnAllOthers(), + generatedResourcesByOrigin, + newData.getGeneratedResourcesDependingOnAllOthers(), + newData.getFullRebuildCause() + ); + } + }