Skip to content

Commit 2a92751

Browse files
authored
Discrepancy in annotation processing, between full and incremental builds eclipse-jdt#4617 (eclipse-jdt#4639)
Store the unsorted list in BinaryTypeBinding when annotation processing is enabled and use that list in annotation models.
1 parent cb0ce53 commit 2a92751

6 files changed

Lines changed: 52 additions & 5 deletions

File tree

424 Bytes
Binary file not shown.

org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java8ElementProcessor.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
"org.eclipse.jdt.compiler.apt.tests.annotations.IFoo", "org.eclipse.jdt.compiler.apt.tests.annotations.IFooContainer",
5959
"org.eclipse.jdt.compiler.apt.tests.annotations.Goo", "org.eclipse.jdt.compiler.apt.tests.annotations.GooNonContainer",
6060
"org.eclipse.jdt.compiler.apt.tests.annotations.FooNonContainer", "targets.filer8.PackageAnnot",
61-
"java.lang.Deprecated"})
61+
"java.lang.Deprecated", "org.eclipse.jdt.compiler.apt.tests.annotations.GenClass"})
6262

6363
@SupportedSourceVersion(SourceVersion.RELEASE_8)
6464
public class Java8ElementProcessor extends BaseProcessor {
@@ -161,6 +161,7 @@ public void testAll() throws AssertionFailedError {
161161
testBug526288();
162162
testEnumConstArguments();
163163
testBug544288();
164+
testGH4617();
164165
}
165166

166167
public void testLambdaSpecifics() {
@@ -1070,6 +1071,17 @@ public void testBug544288() {
10701071
Element asElement = _typeUtils.asElement(asType);
10711072
verifyAnnotations(asElement, new String[]{"@Deprecated()"});
10721073
}
1074+
public void testGH4617() {
1075+
TypeElement type = _elementUtils.getTypeElement("targets.GH4617.ParentClass");
1076+
List<? extends Element> enclosedElements = type.getEnclosedElements();
1077+
List<ExecutableElement> methodsIn = ElementFilter.methodsIn(enclosedElements);
1078+
assertEquals("Incorrect number of methods", 3, methodsIn.size());
1079+
StringBuilder builder = new StringBuilder();
1080+
for (ExecutableElement executableElement : methodsIn) {
1081+
builder.append(executableElement.getSimpleName().toString()).append(',');
1082+
}
1083+
assertEquals("Incorrect order received", "gamma,alpha,beta,", builder.toString());
1084+
}
10731085
private void createPackageBinary() throws IOException {
10741086
String path = packageName.replace('.', '/');
10751087
ClassLoader loader = getClass().getClassLoader();
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package targets.GH4617;
2+
@org.eclipse.jdt.compiler.apt.tests.annotations.GenClass(clazz="p.q.R", method="foo")
3+
public abstract class ParentClass {
4+
public abstract int gamma();
5+
public abstract byte alpha();
6+
public abstract int beta();
7+
}

org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java8ElementsTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,12 @@ public void testBug544288() throws Exception {
413413
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
414414
internalTestWithBinary(compiler, JAVA8_ANNOTATION_PROC, "testBug544288", null, "bug544288", "9");
415415
}
416+
public void testGH4617() throws Exception {
417+
if (!canRunJava9())
418+
return;
419+
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
420+
internalTestWithBinary(compiler, JAVA8_ANNOTATION_PROC, "testGH4617", null, "GH4617", "9");
421+
}
416422
private void internalTest(JavaCompiler compiler, String processor, String testMethod) throws IOException {
417423
internalTest(compiler, processor, testMethod, null);
418424
}

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,9 @@ protected AnnotationBinding[] getAnnotationBindings()
129129
@Override
130130
public List<? extends Element> getEnclosedElements() {
131131
ReferenceBinding binding = (ReferenceBinding)this._binding;
132-
List<Element> enclosed = new ArrayList<>(binding.fieldCount() + binding.methods().length + binding.memberTypes().length);
133-
for (MethodBinding method : binding.methods()) {
132+
MethodBinding[] methods = (binding instanceof BinaryTypeBinding btb) ? btb.methodsInOriginalOrder() : binding.methods();
133+
List<Element> enclosed = new ArrayList<>(binding.fieldCount() + methods.length + binding.memberTypes().length);
134+
for (MethodBinding method : methods) {
134135
ExecutableElement executable = new ExecutableElementImpl(this._env, method);
135136
enclosed.add(executable);
136137
}
@@ -152,7 +153,9 @@ public List<? extends Element> getEnclosedElements() {
152153
TypeElement type = new TypeElementImpl(this._env, memberType, null);
153154
enclosed.add(type);
154155
}
155-
Collections.sort(enclosed, new SourceLocationComparator());
156+
// SourceLocationComparator is of no use for binaries; so skip it.
157+
if (!binding.isBinaryBinding())
158+
Collections.sort(enclosed, new SourceLocationComparator());
156159
return Collections.unmodifiableList(enclosed);
157160
}
158161

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151

5252
import java.net.URI;
5353
import java.util.ArrayList;
54+
import java.util.Arrays;
5455
import java.util.HashMap;
5556
import java.util.Map;
5657
import org.eclipse.jdt.core.compiler.CharOperation;
@@ -96,6 +97,7 @@ public class BinaryTypeBinding extends ReferenceBinding {
9697
protected FieldBinding[] fields;
9798
protected RecordComponentBinding[] components;
9899
protected MethodBinding[] methods;
100+
protected MethodBinding[] methodsInOriginalOrder;
99101
protected ReferenceBinding[] memberTypes;
100102
protected TypeVariableBinding[] typeVariables;
101103
protected ModuleBinding module;
@@ -1760,6 +1762,19 @@ private ReferenceBinding[] maybeSortedMemberTypes() {
17601762
return this.memberTypes;
17611763
}
17621764

1765+
/**
1766+
* Returns the methods in the order they appear in the class file if available. In some case,
1767+
* for e.g., when annotation processing is enabled, the original order is preserved and available
1768+
* for clients. If the original order is not available, the regular sorted array is returned.
1769+
*
1770+
* @return the methods in the original order
1771+
*/
1772+
public MethodBinding[] methodsInOriginalOrder() {
1773+
if (this.methodsInOriginalOrder != null) {
1774+
return this.methodsInOriginalOrder;
1775+
}
1776+
return this.methods;
1777+
}
17631778
// NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
17641779
@Override
17651780
public MethodBinding[] methods() {
@@ -1774,8 +1789,12 @@ public MethodBinding[] methods() {
17741789
// lazily sort methods
17751790
if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
17761791
int length = this.methods.length;
1777-
if (length > 1)
1792+
if (length > 1) {
1793+
if (this.environment.globalOptions.processAnnotations) {
1794+
this.methodsInOriginalOrder = Arrays.copyOf(this.methods, this.methods.length);
1795+
}
17781796
ReferenceBinding.sortMethods(this.methods, 0, length);
1797+
}
17791798
this.tagBits |= TagBits.AreMethodsSorted;
17801799
}
17811800
for (int i = this.methods.length; --i >= 0;)

0 commit comments

Comments
 (0)