Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Clement2013-08-07 13:00:56 +0000
committerJayaprakash Arthanareeswaran2013-08-08 02:50:55 +0000
commit21d3c1ac784a9ef78a64389e4df817ec0452ce19 (patch)
tree685d07e9c03e0588ace06b1bb43aea14aae33231
parent4ddddb5424dafb4b8650d4349863e03fece6ac06 (diff)
downloadeclipse.jdt.core-21d3c1ac784a9ef78a64389e4df817ec0452ce19.tar.gz
eclipse.jdt.core-21d3c1ac784a9ef78a64389e4df817ec0452ce19.tar.xz
eclipse.jdt.core-21d3c1ac784a9ef78a64389e4df817ec0452ce19.zip
Fix for Bug 409236- [1.8][compiler] Type annotations on intersection
cast types dropped by code generator Signed-off-by: Andrew Clement <aclement@gopivotal.com>
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java239
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntersectionCastTypeReference.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java22
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java3
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java6
6 files changed, 270 insertions, 12 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java
index ccb9fde6a0..da190f934b 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java
@@ -13,6 +13,7 @@
* IBM Corporation - initial API and implementation
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ * Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -3060,6 +3061,244 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
+ public void test070a_codeblocks_castWithIntersectionCast() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.*;\n" +
+ "public class X {\n" +
+ " public void foo(Object o) {\n" +
+ " I i = (@B(1) I & J) o;\n" +
+ " J j = (I & @B(2) J) o;\n" +
+ " }\n" +
+ "}\n" +
+ "interface I {}\n" +
+ "interface J {}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B {\n" +
+ " int value() default 1;\n" +
+ "}\n",
+ },
+ "");
+ String expectedOutput =
+ " // Method descriptor #15 (Ljava/lang/Object;)V\n" +
+ " // Stack: 1, Locals: 4\n" +
+ " public void foo(java.lang.Object o);\n" +
+ " 0 aload_1 [o]\n" +
+ " 1 checkcast I [16]\n" +
+ " 4 checkcast J [18]\n" +
+ " 7 astore_2 [i]\n" +
+ " 8 aload_1 [o]\n" +
+ " 9 checkcast I [16]\n" +
+ " 12 checkcast J [18]\n" +
+ " 15 astore_3 [j]\n" +
+ " 16 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 4]\n" +
+ " [pc: 8, line: 5]\n" +
+ " [pc: 16, line: 6]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 17] local: this index: 0 type: X\n" +
+ " [pc: 0, pc: 17] local: o index: 1 type: java.lang.Object\n" +
+ " [pc: 8, pc: 17] local: i index: 2 type: I\n" +
+ " [pc: 16, pc: 17] local: j index: 3 type: J\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #27 @B(\n" +
+ " #28 value=(int) 1 (constant type)\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 1\n" +
+ " type argument index = 0\n" +
+ " )\n" +
+ " #27 @B(\n" +
+ " #28 value=(int) 2 (constant type)\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 9\n" +
+ " type argument index = 1\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test070b_codeblocks_castWithIntersectionCast() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.*;\n" +
+ "public class X {\n" +
+ " public void foo(Object o) {\n" +
+ " System.out.println(123);\n" +
+ " I<String> i = (I<@B(1) String> & @B(2) J<String>) o;\n" +
+ " }\n" +
+ "}\n" +
+ "interface I<T> {}\n" +
+ "interface J<T> {}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B {\n" +
+ " int value() default 1;\n" +
+ "}\n",
+ },
+ "");
+ String expectedOutput =
+ " public void foo(java.lang.Object o);\n" +
+ " 0 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 3 bipush 123\n" +
+ " 5 invokevirtual java.io.PrintStream.println(int) : void [22]\n" +
+ " 8 aload_1 [o]\n" +
+ " 9 checkcast I [28]\n" +
+ " 12 checkcast J [30]\n" +
+ " 15 astore_2 [i]\n" +
+ " 16 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 4]\n" +
+ " [pc: 8, line: 5]\n" +
+ " [pc: 16, line: 6]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 17] local: this index: 0 type: X\n" +
+ " [pc: 0, pc: 17] local: o index: 1 type: java.lang.Object\n" +
+ " [pc: 16, pc: 17] local: i index: 2 type: I\n" +
+ " Local variable type table:\n" +
+ " [pc: 16, pc: 17] local: i index: 2 type: I<java.lang.String>\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #39 @B(\n" +
+ " #40 value=(int) 1 (constant type)\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 9\n" +
+ " type argument index = 0\n" +
+ " location = [TYPE_ARGUMENT(0)]\n" +
+ " )\n" +
+ " #39 @B(\n" +
+ " #40 value=(int) 2 (constant type)\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 9\n" +
+ " type argument index = 1\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test070c_codeblocks_castTwiceInExpression() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.*;\n" +
+ "public class X {\n" +
+ " public void foo(Object o) {\n" +
+ " System.out.println(123);\n" +
+ " I i = (@B(1) I)(@B(2) J) o;\n" +
+ " }\n" +
+ "}\n" +
+ "interface I {}\n" +
+ "interface J {}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B {\n" +
+ " int value() default 1;\n" +
+ "}\n",
+ },
+ "");
+ String expectedOutput =
+ " 0 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 3 bipush 123\n" +
+ " 5 invokevirtual java.io.PrintStream.println(int) : void [22]\n" +
+ " 8 aload_1 [o]\n" +
+ " 9 checkcast J [28]\n" +
+ " 12 checkcast I [30]\n" +
+ " 15 astore_2 [i]\n" +
+ " 16 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 4]\n" +
+ " [pc: 8, line: 5]\n" +
+ " [pc: 16, line: 6]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 17] local: this index: 0 type: X\n" +
+ " [pc: 0, pc: 17] local: o index: 1 type: java.lang.Object\n" +
+ " [pc: 16, pc: 17] local: i index: 2 type: I\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #37 @B(\n" +
+ " #38 value=(int) 2 (constant type)\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 9\n" +
+ " type argument index = 0\n" +
+ " )\n" +
+ " #37 @B(\n" +
+ " #38 value=(int) 1 (constant type)\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 12\n" +
+ " type argument index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
+ public void test070d_codeblocks_castDoubleIntersectionCastInExpression() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.io.*;\n" +
+ "public class X {\n" +
+ " public void foo(Object o) {\n" +
+ " System.out.println(123);\n" +
+ " I i = (@B(1) I & J)(K & @B(2) L) o;\n" +
+ " }\n" +
+ "}\n" +
+ "interface I {}\n" +
+ "interface J {}\n" +
+ "interface K {}\n" +
+ "interface L {}\n",
+
+ "B.java",
+ "import java.lang.annotation.*;\n" +
+ "@Target(ElementType.TYPE_USE)\n" +
+ "@Retention(RetentionPolicy.RUNTIME)\n" +
+ "@interface B {\n" +
+ " int value() default 1;\n" +
+ "}\n",
+ },
+ "");
+ String expectedOutput =
+ " public void foo(java.lang.Object o);\n" +
+ " 0 getstatic java.lang.System.out : java.io.PrintStream [16]\n" +
+ " 3 bipush 123\n" +
+ " 5 invokevirtual java.io.PrintStream.println(int) : void [22]\n" +
+ " 8 aload_1 [o]\n" +
+ " 9 checkcast K [28]\n" +
+ " 12 checkcast L [30]\n" +
+ " 15 checkcast I [32]\n" +
+ " 18 checkcast J [34]\n" +
+ " 21 astore_2 [i]\n" +
+ " 22 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 4]\n" +
+ " [pc: 8, line: 5]\n" +
+ " [pc: 22, line: 6]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 23] local: this index: 0 type: X\n" +
+ " [pc: 0, pc: 23] local: o index: 1 type: java.lang.Object\n" +
+ " [pc: 22, pc: 23] local: i index: 2 type: I\n" +
+ " RuntimeVisibleTypeAnnotations: \n" +
+ " #41 @B(\n" +
+ " #42 value=(int) 2 (constant type)\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 9\n" +
+ " type argument index = 1\n" +
+ " )\n" +
+ " #41 @B(\n" +
+ " #42 value=(int) 1 (constant type)\n" +
+ " target type = 0x47 CAST\n" +
+ " offset = 15\n" +
+ " type argument index = 0\n" +
+ " )\n";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+
public void test071_codeblocks_constructorInvocationTypeArgument() throws Exception {
this.runConformTest(
new String[] {
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 b3547fb297..a7d3b6199c 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
@@ -15,6 +15,7 @@
* Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ * Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator
*******************************************************************************/
package org.eclipse.jdt.internal.compiler;
@@ -2190,8 +2191,7 @@ public class ClassFile implements TypeConstants, TypeIds {
// bytecode offset
this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
this.contents[this.contentsOffset++] = (byte) annotationContext.info;
- // type_argument_index not set for cast
- this.contents[this.contentsOffset++] = (byte)0;
+ this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
break;
case AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntersectionCastTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntersectionCastTypeReference.java
index f4020cb8b9..27da4692c2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntersectionCastTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntersectionCastTypeReference.java
@@ -11,6 +11,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -30,6 +32,12 @@ public class IntersectionCastTypeReference extends TypeReference {
this.sourceStart = typeReferences[0].sourceStart;
int length = typeReferences.length;
this.sourceEnd = typeReferences[length - 1].sourceEnd;
+ for (int i = 0, max = typeReferences.length; i < max; i++) {
+ if ((typeReferences[i].bits & ASTNode.HasTypeAnnotations) != 0) {
+ this.bits |= ASTNode.HasTypeAnnotations;
+ break;
+ }
+ }
}
public TypeReference copyDims(int dim) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
index 3a2d918748..3ab3e2d141 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
@@ -16,6 +16,7 @@
* bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ * Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -51,8 +52,8 @@ static class AnnotationCollector extends ASTVisitor {
TypeReference typeReference;
int targetType;
Annotation[] primaryAnnotations;
- int info = -1;
- int info2 = -1;
+ int info = 0;
+ int info2 = 0;
LocalVariableBinding localVariable;
Annotation[][] annotationsOnDimensions;
int dimensions;
@@ -183,12 +184,6 @@ static class AnnotationCollector extends ASTVisitor {
case AnnotationTargetTypeConstants.NEW :
case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE :
case AnnotationTargetTypeConstants.METHOD_REFERENCE :
- case AnnotationTargetTypeConstants.CAST:
- annotationContext.info = this.info;
- break;
- case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
- case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
- annotationContext.info2 = this.info2;
annotationContext.info = this.info;
break;
case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
@@ -199,6 +194,9 @@ static class AnnotationCollector extends ASTVisitor {
case AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
case AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
+ case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
+ case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
+ case AnnotationTargetTypeConstants.CAST:
annotationContext.info2 = this.info2;
annotationContext.info = this.info;
break;
@@ -225,6 +223,14 @@ static class AnnotationCollector extends ASTVisitor {
this.currentWildcard = wildcard;
return true;
}
+ public boolean visit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) {
+ int length = intersectionCastTypeReference.typeReferences == null ? 0 : intersectionCastTypeReference.typeReferences.length;
+ for (int i = 0; i < length; i++) {
+ this.info2 = i;
+ intersectionCastTypeReference.typeReferences[i].traverse(this, scope);
+ }
+ return false; // iteration was done here, do not repeat in the caller
+ }
public boolean visit(Argument argument, BlockScope scope) {
if ((argument.bits & ASTNode.IsUnionType) == 0) {
return true;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index b44dd65eb1..1422f74db4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -19,6 +19,7 @@
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
* Bug 409247 - [1.8][compiler] Verify error with code allocating multidimensional array
+ * Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;
@@ -657,7 +658,7 @@ public void checkcast(TypeReference typeReference, TypeBinding typeBinding) {
reality this should not matter. In its intended use form such as (I & Serializable) () -> {}, no cast is emitted at all
*/
TypeBinding [] types = typeBinding instanceof IntersectionCastTypeBinding ? typeBinding.getIntersectingTypes() : new TypeBinding [] { typeBinding };
- for (int i = types.length - 1; i >=0; i--) {
+ for (int i = 0, max = types.length; i < max; i++) {
this.countLabels = 0;
if (this.classFileOffset + 2 >= this.bCodeStream.length) {
resizeByteArray();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java
index 902b329678..634a1dc335 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java
@@ -13,6 +13,7 @@
* IBM Corporation - initial API and implementation
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ * Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator
*******************************************************************************/
package org.eclipse.jdt.internal.core.util;
@@ -209,7 +210,10 @@ public class ExtendedAnnotation extends ClassFileStruct implements IExtendedAnno
case IExtendedAnnotationConstants.CAST :
this.offset = u2At(classFileBytes, this.readOffset, localOffset);
- this.readOffset += 3; // skipping the 3rd byte which will be 0 for CAST
+ this.readOffset += 2;
+ // read type_argument_index
+ this.annotationTypeIndex = u1At(classFileBytes, this.readOffset, localOffset);
+ this.readOffset++;
break;
case IExtendedAnnotationConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :

Back to the top