Bug 449330 - [1.6] Eclipse compiler doesn't compile annotations in class files

Signed-off-by: shankha banerjee <shankhba@in.ibm.com>
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
index ee1be33..250c618 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
@@ -11244,6 +11244,10 @@
 			"	String value();\n" +
 			"}\n"
 	};
+	if (this.complianceLevel <= ClassFileConstants.JDK1_6) {
+		this.runConformTest(src, "");
+		checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p/package-info.class", "", "p123456");
+	} else {
 	this.runNegativeTest(
 			src,
 			"----------\n" +
@@ -11258,45 +11262,8 @@
 			true, // generate output
 			false,
 			false);
-}
-// https://bugs.eclipse.org/bugs/show_bug.cgi?id=449330 - [1.6]Eclipse compiler doesn't compile annotations in class files
-public void _test449330() throws Exception {
-	String[] testFiles = new String[] {
-		"p/X.java",
-		"package p;\n" +
-		"@java.lang.annotation.Target(value={java.lang.annotation.ElementType.TYPE})\n" +
-		"@interface X { public java.lang.String name(); }\n",
-		"p/package-info.java",
-		"@X(name=\"HELLO\")\n" +
-		"package p;\n"
-	};
-	if (this.complianceLevel <= ClassFileConstants.JDK1_6) {
-		this.runConformTest(testFiles, "");
-		checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p/package-info.class", "", "HELLO");
-	} else {
-		this.runNegativeTest(testFiles,
-			"----------\n" +
-			"1. ERROR in p\\package-info.java (at line 1)\n" +
-			"	@X(name=\"HELLO\")\n" +
-			"	^^\n" +
-			"The annotation @X is disallowed for this location\n" +
-			"----------\n");
 	}
 }
-//https://bugs.eclipse.org/bugs/show_bug.cgi?id=449330 - [1.6]Eclipse compiler doesn't compile annotations in class files
-// Annotation target not set
-public void _test449330a() throws Exception {
-	String[] testFiles = new String[] {
-		"p/X.java",
-		"package p;\n" +
-		"@interface X { public java.lang.String name(); }\n",
-		"p/package-info.java",
-		"@X(name=\"HELLO\")\n" +
-		"package p;\n"
-	};
-	this.runConformTest(testFiles, "");
-	checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p/package-info.class", "", "HELLO");
-}
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=456960 - Broken classfile generated for incorrect annotation usage - case 2
 public void test456960() throws Exception {
 	if (this.complianceLevel < ClassFileConstants.JDK1_5) {
@@ -11355,4 +11322,68 @@
 		fail("Error reading classfile");
 	}
 }
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=449330 - [1.6]Eclipse compiler doesn't compile annotations in class files
+public void test449330() throws Exception {
+	String[] testFiles = new String[] {
+		"p/X.java",
+		"package p;\n" +
+		"@java.lang.annotation.Target(value={java.lang.annotation.ElementType.TYPE})\n" +
+		"@interface X { public java.lang.String name(); }\n",
+		"p/package-info.java",
+		"@X(name=\"HELLO\")\n" +
+		"package p;\n"
+	};
+	if (this.complianceLevel <= ClassFileConstants.JDK1_6) {
+		this.runConformTest(testFiles);
+		checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p/package-info.class", "", "HELLO");
+	} else {
+		this.runNegativeTest(testFiles,
+			"----------\n" +
+			"1. ERROR in p\\package-info.java (at line 1)\n" +
+			"	@X(name=\"HELLO\")\n" +
+			"	^^\n" +
+			"The annotation @X is disallowed for this location\n" +
+			"----------\n");
+	}
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=449330 - [1.6]Eclipse compiler doesn't compile annotations in class files
+//Retention Policy set to RUNTIME
+public void test449330a() throws Exception {
+	String[] testFiles = new String[] {
+		"p/X.java",
+		"package p;\n" +
+		"@java.lang.annotation.Target(value={java.lang.annotation.ElementType.TYPE})\n" +
+		"@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)\n" +
+		"@interface X { public java.lang.String name(); }\n",
+		"p/package-info.java",
+		"@X(name=\"HELLO\")\n" +
+		"package p;\n"
+	};
+	if (this.complianceLevel <= ClassFileConstants.JDK1_6) {
+		this.runConformTest(testFiles, "");
+		checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p/package-info.class", "", "HELLO");
+	} else {
+		this.runNegativeTest(testFiles,
+			"----------\n" +
+			"1. ERROR in p\\package-info.java (at line 1)\n" +
+			"	@X(name=\"HELLO\")\n" +
+			"	^^\n" +
+			"The annotation @X is disallowed for this location\n" +
+			"----------\n");
+	}
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=449330 - [1.6]Eclipse compiler doesn't compile annotations in class files
+//Annotation target not set
+public void test449330b() throws Exception {
+	String[] testFiles = new String[] {
+		"p/X.java",
+		"package p;\n" +
+		"@interface X { public java.lang.String name(); }\n",
+		"p/package-info.java",
+		"@X(name=\"HELLO\")\n" +
+		"package p;\n"
+	};
+	this.runConformTest(testFiles, "");
+	checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p/package-info.class", "", "HELLO");
+}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index 659cf66..00a8fa7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -3574,6 +3574,14 @@
 		}
 	}
 
+	private boolean jdk16packageInfoAnnotation(final long annotationMask, final long targetMask) {
+		if (this.targetJDK <= ClassFileConstants.JDK1_6 &&
+				targetMask == TagBits.AnnotationForPackage && annotationMask != 0 &&
+				(annotationMask & TagBits.AnnotationForPackage) == 0) {
+			return true;
+		}
+		return false;
+	}
 	/**
 	 * @param annotations
 	 * @param targetMask allowed targets
@@ -3588,7 +3596,9 @@
 			Annotation annotation;
 			if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container.
 			long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
-			if (annotationMask != 0 && (annotationMask & targetMask) == 0) continue;
+			if (annotationMask != 0 && (annotationMask & targetMask) == 0) {
+				if (!jdk16packageInfoAnnotation(annotationMask, targetMask)) continue;
+			}
 			if (annotation.isRuntimeInvisible() || annotation.isRuntimeTypeInvisible()) {
 				invisibleAnnotationsCounter++;
 			} else if (annotation.isRuntimeVisible() || annotation.isRuntimeTypeVisible()) {
@@ -3619,7 +3629,9 @@
 				Annotation annotation;
 				if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container.
 				long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
-				if (annotationMask != 0 && (annotationMask & targetMask) == 0) continue;
+				if (annotationMask != 0 && (annotationMask & targetMask) == 0) {
+					if (!jdk16packageInfoAnnotation(annotationMask, targetMask)) continue;
+				}
 				if (annotation.isRuntimeInvisible() || annotation.isRuntimeTypeInvisible()) {
 					int currentAnnotationOffset = this.contentsOffset;
 					generateAnnotation(annotation, currentAnnotationOffset);
@@ -3669,7 +3681,9 @@
 				Annotation annotation;
 				if ((annotation = annotations[i].getPersistibleAnnotation()) == null) continue; // already packaged into container.
 				long annotationMask = annotation.resolvedType != null ? annotation.resolvedType.getAnnotationTagBits() & TagBits.AnnotationTargetMASK : 0;
-				if (annotationMask != 0 && (annotationMask & targetMask) == 0) continue;
+				if (annotationMask != 0 && (annotationMask & targetMask) == 0) {
+					if (!jdk16packageInfoAnnotation(annotationMask, targetMask)) continue;
+				}
 				if (annotation.isRuntimeVisible() || annotation.isRuntimeTypeVisible()) {
 					visibleAnnotationsCounter--;
 					int currentAnnotationOffset = this.contentsOffset;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
index 85839f3..bf17500 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
@@ -989,6 +989,11 @@
 			case Binding.PACKAGE :
 				if ((metaTagBits & TagBits.AnnotationForPackage) != 0)
 					return true;
+				else if (scope.compilerOptions().sourceLevel <= ClassFileConstants.JDK1_6) {
+					SourceTypeBinding sourceType = (SourceTypeBinding) annotation.recipient;
+					if (CharOperation.equals(sourceType.sourceName, TypeConstants.PACKAGE_INFO_NAME))
+						return true;
+				}
 				break;
 			case Binding.TYPE_USE :
 				if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {