Skip to content

Commit

Permalink
ECJ out of sync with JLS 9.6.4.1 (#1097)
Browse files Browse the repository at this point in the history
* Reverse the changes made for
https://bugs.eclipse.org/bugs/show_bug.cgi?id=552082

* Tweak for test failures in Jenkins

* Implement the recent changes to JLS 9.6.4.1

* Incorporate review comment
#1097 (comment)

* Additional test case for
https://bugs.eclipse.org/bugs/show_bug.cgi?id=568240

* Additional regression test for
https://bugs.eclipse.org/bugs/show_bug.cgi?id=566803

* Review follow up: Get rid of the head-scratch producing enumerator
NonJVMS4_7_20_TargetLocation.
  • Loading branch information
srikanth-sankaran committed Jun 8, 2023
1 parent 3d72ef7 commit 03658fd
Show file tree
Hide file tree
Showing 11 changed files with 386 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1511,11 +1511,7 @@ public interface IProblem {
int ConstructorReferenceNotBelow18 = Internal + Syntax + 647;
/** @since 3.10 */
int ExplicitThisParameterNotInLambda = Internal + Syntax + 648;
/**

This comment has been minimized.

Copy link
@iloveeclipse

iloveeclipse Jun 8, 2023

Member

@srikanth-sankaran : I assume this is intended?
If yes, we have to bump ecj batch compiler version & jdt core version bundles (which re-exports this API), because we have API error reported:

The minor version should be incremented in version 3.34.0, since new APIs have been added since version 3.34.0

List of compatible changes:
- The deprecation modifier has been removed from 
org.eclipse.jdt.core.compiler.IProblem

This comment has been minimized.

Copy link
@srikanth-sankaran

srikanth-sankaran Jun 8, 2023

Author Contributor

Addressed via #1133 - It was the unexpected side effect of the PR having been deferred to 4.29 for merging. Thanks

* @since 3.10
* @deprecated Per https://bugs.openjdk.java.net/browse/JDK-8231435 this problem is no longer raised
*/
@Deprecated
/** @since 3.10 */
int ExplicitAnnotationTargetRequired = TypeRelated + 649;
/** @since 3.10 */
int IllegalTypeForExplicitThis = Internal + Syntax + 650;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4578,9 +4578,9 @@ private int generateRuntimeAnnotations(final Annotation[] annotations, final lon
if (annotationMask != 0 && (annotationMask & targetMask) == 0) {
if (!jdk16packageInfoAnnotation(annotationMask, targetMask)) continue;
}
if (annotation.isRuntimeInvisible() || annotation.isRuntimeTypeInvisible()) {
if (annotation.isRuntimeInvisible() || annotation.isRuntimeTypeInvisible(false)) {
invisibleAnnotationsCounter++;
} else if (annotation.isRuntimeVisible() || annotation.isRuntimeTypeVisible()) {
} else if (annotation.isRuntimeVisible() || annotation.isRuntimeTypeVisible(false)) {
visibleAnnotationsCounter++;
}
}
Expand Down Expand Up @@ -4609,7 +4609,7 @@ private int generateRuntimeAnnotations(final Annotation[] annotations, final lon
if (annotationMask != 0 && (annotationMask & targetMask) == 0) {
if (!jdk16packageInfoAnnotation(annotationMask, targetMask)) continue;
}
if (annotation.isRuntimeInvisible() || annotation.isRuntimeTypeInvisible()) {
if (annotation.isRuntimeInvisible() || annotation.isRuntimeTypeInvisible(false)) {
int currentAnnotationOffset = this.contentsOffset;
generateAnnotation(annotation, currentAnnotationOffset);
invisibleAnnotationsCounter--;
Expand Down Expand Up @@ -4657,7 +4657,7 @@ private int generateRuntimeAnnotations(final Annotation[] annotations, final lon
if (annotationMask != 0 && (annotationMask & targetMask) == 0) {
if (!jdk16packageInfoAnnotation(annotationMask, targetMask)) continue;
}
if (annotation.isRuntimeVisible() || annotation.isRuntimeTypeVisible()) {
if (annotation.isRuntimeVisible() || annotation.isRuntimeTypeVisible(false)) {
visibleAnnotationsCounter--;
int currentAnnotationOffset = this.contentsOffset;
generateAnnotation(annotation, currentAnnotationOffset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -768,37 +768,39 @@ public boolean isRuntimeInvisible() {
return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationClassRetention;
}

public boolean isRuntimeTypeInvisible() {
public boolean isRuntimeTypeInvisible(boolean targetingTypeParameter) {
final TypeBinding annotationBinding = this.resolvedType;
if (annotationBinding == null) {
return false;
}
long metaTagBits = annotationBinding.getAnnotationTagBits(); // could be forward reference

if ((metaTagBits & (TagBits.AnnotationTargetMASK)) != 0) {
if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) == 0) {
if ((metaTagBits & (TagBits.AnnotationTargetMASK)) == 0) { // In the absence of explicit target, applicable only to declaration sites
if (!targetingTypeParameter)
return false;
}
} // else: no-@Target always applicable
} else if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) == 0) {
return false;
}

if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
return true; // by default the retention is CLASS

return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationClassRetention;
}

public boolean isRuntimeTypeVisible() {
public boolean isRuntimeTypeVisible(boolean targetingTypeParameter) {
final TypeBinding annotationBinding = this.resolvedType;
if (annotationBinding == null) {
return false;
}
long metaTagBits = annotationBinding.getAnnotationTagBits();

if ((metaTagBits & (TagBits.AnnotationTargetMASK)) != 0) {
if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) == 0) {
if ((metaTagBits & (TagBits.AnnotationTargetMASK)) == 0) { // In the absence of explicit target, applicable only to declaration sites
if (!targetingTypeParameter)
return false;
}
} // else: no-@Target always applicable
} else if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) == 0) {
return false;
}
if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
return false; // by default the retention is CLASS

Expand Down Expand Up @@ -1162,7 +1164,7 @@ public long handleNonNullByDefault(BlockScope scope) {
}

public enum AnnotationTargetAllowed {
YES, TYPE_ANNOTATION_ON_QUALIFIED_NAME, NO;
YES, NO_DUE_TO_LACKING_TARGET, TYPE_ANNOTATION_ON_QUALIFIED_NAME, NO/*_DUE_TO_MISMATCHED_TARGET*/;
}

private static AnnotationTargetAllowed isAnnotationTargetAllowed(Binding recipient, BlockScope scope, TypeBinding annotationType, int kind, long metaTagBits) {
Expand Down Expand Up @@ -1274,6 +1276,9 @@ else if (scope.compilerOptions().sourceLevel <= ClassFileConstants.JDK1_6) {
}
break;
case Binding.TYPE_PARAMETER : // jsr308
if ((metaTagBits & TagBits.AnnotationTargetMASK) == 0) {
return AnnotationTargetAllowed.YES;
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391196
if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) != 0) {
return AnnotationTargetAllowed.YES;
Expand All @@ -1300,8 +1305,11 @@ static AnnotationTargetAllowed isAnnotationTargetAllowed(Annotation annotation,

long metaTagBits = annotationType.getAnnotationTagBits(); // could be forward reference
if ((metaTagBits & TagBits.AnnotationTargetMASK) == 0) {
// does not specify any target restriction - all locations are possible
return AnnotationTargetAllowed.YES;
/* JLS 9.6.4.1: If an annotation of type java.lang.annotation.Target is not present on the
declaration of an annotation interface A, then A is applicable in all declaration
contexts and in no type contexts.
*/
return kind == Binding.TYPE_USE ? AnnotationTargetAllowed.NO_DUE_TO_LACKING_TARGET : AnnotationTargetAllowed.YES;
}

// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391201
Expand Down Expand Up @@ -1329,13 +1337,16 @@ static void checkAnnotationTarget(Annotation annotation, BlockScope scope, Refer
// no need to check annotation usage if missing
return;
}
AnnotationTargetAllowed annotationTargetAllowed = isAnnotationTargetAllowed(annotation, scope, annotationType, kind);
if (annotationTargetAllowed != AnnotationTargetAllowed.YES) {
if(annotationTargetAllowed == AnnotationTargetAllowed.TYPE_ANNOTATION_ON_QUALIFIED_NAME) {
scope.problemReporter().typeAnnotationAtQualifiedName(annotation);
} else {
scope.problemReporter().disallowedTargetForAnnotation(annotation);
}

AnnotationTargetAllowed annotationTargetAllowed = isAnnotationTargetAllowed(annotation, scope, annotationType, kind);
if (annotationTargetAllowed != AnnotationTargetAllowed.YES) {
if(annotationTargetAllowed == AnnotationTargetAllowed.TYPE_ANNOTATION_ON_QUALIFIED_NAME) {
scope.problemReporter().typeAnnotationAtQualifiedName(annotation);
} else if (annotationTargetAllowed == AnnotationTargetAllowed.NO_DUE_TO_LACKING_TARGET) {
scope.problemReporter().explitAnnotationTargetRequired(annotation);
} else {
scope.problemReporter().disallowedTargetForAnnotation(annotation);
}
if (recipient instanceof TypeBinding)
((TypeBinding)recipient).tagBits &= ~tagBitsToRevert;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,15 @@ public AnnotationCollector(RecordComponent recordComponent, int targetType, List
this.targetType = targetType;
}

private boolean targetingTypeParameter() {
return this.targetType == AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER || this.targetType == AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER;
}

private boolean internalVisit(Annotation annotation) {
AnnotationContext annotationContext = null;
if (annotation.isRuntimeTypeInvisible()) {
if (annotation.isRuntimeTypeInvisible(targetingTypeParameter())) {
annotationContext = new AnnotationContext(annotation, this.typeReference, this.targetType, AnnotationContext.INVISIBLE);
} else if (annotation.isRuntimeTypeVisible()) {
} else if (annotation.isRuntimeTypeVisible(targetingTypeParameter())) {
annotationContext = new AnnotationContext(annotation, this.typeReference, this.targetType, AnnotationContext.VISIBLE);
}
if (annotationContext != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2025,6 +2025,13 @@ public void disallowedTargetForAnnotation(Annotation annotation) {
annotation.sourceStart,
annotation.sourceEnd);
}
public void explitAnnotationTargetRequired(Annotation annotation) {
this.handle(IProblem.ExplicitAnnotationTargetRequired,
NoArgument,
NoArgument,
annotation.sourceStart,
annotation.sourceEnd);
}
public void polymorphicMethodNotBelow17(ASTNode node) {
this.handle(
IProblem.PolymorphicMethodNotBelow17,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1134,10 +1134,6 @@ Excuse excuseFor(JavacCompiler compiler) {
new JavacBug8221413(" --release 12 --enable-preview -Xlint:-preview") : null,
JavacBug8226510_switchExpression = RUN_JAVAC ? // https://bugs.openjdk.java.net/browse/JDK-8226510
new JavacBug8226510(" --release 12 --enable-preview -Xlint:-preview") : null,
JavacBug8231436 = RUN_JAVAC ? // https://bugs.openjdk.java.net/browse/JDK-8231436 to implement https://bugs.openjdk.java.net/browse/JDK-8231435
new JavacHasABug(MismatchType.JavacErrorsEclipseNone) : null,
JavacBug8231436_EclipseWarns = RUN_JAVAC ? // https://bugs.openjdk.java.net/browse/JDK-8231436 to implement https://bugs.openjdk.java.net/browse/JDK-8231435
new JavacHasABug(MismatchType.JavacErrorsEclipseWarnings) : null,
JavacBug8299416 = RUN_JAVAC ? // https://bugs.openjdk.java.net/browse/JDK-8299416
new JavacBugExtraJavacOptionsPlusMismatch(" --release 20 --enable-preview -Xlint:-preview",
MismatchType.EclipseErrorsJavacNone| MismatchType.EclipseErrorsJavacWarnings) : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -889,10 +889,11 @@ public void test017() throws Exception {
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X$Y.class", "Y", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
public void test018() throws Exception {
Runner runner = new Runner();
runner.testFiles =
this.runNegativeTest(
new String[] {
"X.java",
"import java.lang.annotation.*;\n" +
"import static java.lang.annotation.ElementType.*; \n" +
"@interface Receiver {}\n" +
"class Document {}\n" +
"interface I {\n" +
Expand All @@ -904,9 +905,18 @@ public void test018() throws Exception {
" Y(@Receiver X X.this, boolean b) { }\n" +
" }\n" +
"}\n",
};
runner.javacTestOptions = JavacTestOptions.JavacHasABug.JavacBug8231436;
runner.runConformTest();
},
"----------\n" +
"1. ERROR in X.java (at line 9)\n" +
" void foo(@Receiver X this) {}\n" +
" ^^^^^^^^^\n" +
"Annotation types that do not specify explicit target element types cannot be applied here\n" +
"----------\n" +
"2. ERROR in X.java (at line 11)\n" +
" Y(@Receiver X X.this, boolean b) { }\n" +
" ^^^^^^^^^\n" +
"Annotation types that do not specify explicit target element types cannot be applied here\n" +
"----------\n");
}
public void test019() throws Exception {
this.runConformTest(
Expand Down
Loading

0 comments on commit 03658fd

Please sign in to comment.