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

Fix classes being 'lost' when earlier rounds of annotation processing succeed before a later round fails #3324

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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
package org.eclipse.jdt.internal.compiler;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CharOperation;
Expand Down Expand Up @@ -480,13 +482,14 @@ private void compile(ICompilationUnit[] sourceUnits, boolean lastRound) {
// a generated type was referenced before it was created
// the compiler either created a MissingType or found a BinaryType for it
// so add the processor's generated files & start over,
// but remember to only pass the generated files to the annotation processor
// but remember to only pass the failing files to the annotation processor
int originalLength = originalUnits.length;
int newProcessedLength = e.newAnnotationProcessorUnits.length;
ICompilationUnit[] combinedUnits = new ICompilationUnit[originalLength + newProcessedLength];
System.arraycopy(originalUnits, 0, combinedUnits, 0, originalLength);
System.arraycopy(e.newAnnotationProcessorUnits, 0, combinedUnits, originalLength, newProcessedLength);
this.annotationProcessorStartIndex = originalLength;
// need to offset by originalLength
this.annotationProcessorStartIndex = originalLength + e.annotationProcessorStartIndex;
compile(combinedUnits, e.isLastRound);
return;
}
Expand Down Expand Up @@ -982,6 +985,9 @@ protected void processAnnotations() {
ReferenceBinding[] binaryTypeBindingsTemp = this.referenceBindings;
if (top == 0 && binaryTypeBindingsTemp == null) return;
this.referenceBindings = null;
// we can go through multiple rounds that each add newUnits - can't assume that the only units
// added were in the current round
List<ICompilationUnit> allNewUnits = new ArrayList<>();
do {
// extract units to process
int length = top - bottom;
Expand All @@ -1008,16 +1014,18 @@ protected void processAnnotations() {
this.annotationProcessorStartIndex = top;
ICompilationUnit[] newUnits = this.annotationProcessorManager.getNewUnits();
newUnitSize = newUnits.length;
allNewUnits.addAll(Arrays.asList(newUnits));
ReferenceBinding[] newClassFiles = this.annotationProcessorManager.getNewClassFiles();
binaryTypeBindingsTemp = newClassFiles;
newClassFilesSize = newClassFiles.length;
if (newUnitSize != 0) {
ICompilationUnit[] newProcessedUnits = newUnits.clone(); // remember new units in case a source type collision occurs
try {
this.lookupEnvironment.isProcessingAnnotations = true;
internalBeginToCompile(newUnits, newUnitSize);
} catch (SourceTypeCollisionException e) {
e.newAnnotationProcessorUnits = newProcessedUnits;
e.newAnnotationProcessorUnits = allNewUnits.toArray(new ICompilationUnit[0]);
// need to restart again from where the *current* round failed, not all new units
e.annotationProcessorStartIndex = allNewUnits.size() - newUnitSize;
throw e;
} finally {
this.lookupEnvironment.isProcessingAnnotations = false;
Expand All @@ -1036,15 +1044,17 @@ protected void processAnnotations() {
// process potential units added in the final round see 329156
ICompilationUnit[] newUnits = this.annotationProcessorManager.getNewUnits();
newUnitSize = newUnits.length;
allNewUnits.addAll(Arrays.asList(newUnits));
try {
if (newUnitSize != 0) {
ICompilationUnit[] newProcessedUnits = newUnits.clone(); // remember new units in case a source type collision occurs
try {
this.lookupEnvironment.isProcessingAnnotations = true;
internalBeginToCompile(newUnits, newUnitSize);
} catch (SourceTypeCollisionException e) {
e.isLastRound = true;
e.newAnnotationProcessorUnits = newProcessedUnits;
e.newAnnotationProcessorUnits = allNewUnits.toArray(new ICompilationUnit[0]);
// need to restart again from where the *current* round failed, not all new units
e.annotationProcessorStartIndex = allNewUnits.size() - newUnitSize;
throw e;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@ public class SourceTypeCollisionException extends RuntimeException {
private static final long serialVersionUID = 4798247636899127380L;
public boolean isLastRound = false;
public ICompilationUnit[] newAnnotationProcessorUnits;
/**
* The index within {@link #newAnnotationProcessorUnits} where annotation processing should
* resume.
*/
public int annotationProcessorStartIndex;
}
Loading