/******************************************************************************* * Copyright (c) 2011, 2016 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * 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 * Bug 409246 - [1.8][compiler] Type annotations on catch parameters not handled properly * Bug 409517 - [1.8][compiler] Type annotation problems on more elaborate array references * Bug 415821 - [1.8][compiler] CLASS_EXTENDS target type annotation missing for anonymous classes * Bug 426616 - [1.8][compiler] Type Annotations, multiple problems * Stephan Herrmann - Contribution for * Bug 415911 - [1.8][compiler] NPE when TYPE_USE annotated method with missing return type * Bug 416176 - [1.8][compiler][null] null type annotations cause grief on type variables * Jesper S Moller - Contributions for * Bug 416885 - [1.8][compiler]IncompatibleClassChange error (edit) *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; import java.io.File; import java.util.Map; import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; import org.eclipse.jdt.internal.compiler.Compiler; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import junit.framework.Test; @SuppressWarnings({ "unchecked", "rawtypes" }) public class TypeAnnotationTest extends AbstractRegressionTest { static { // TESTS_NUMBERS = new int [] { 40 }; // TESTS_NAMES = new String[] { "testTypeVariable" }; } public static Class testClass() { return TypeAnnotationTest.class; } public static Test suite() { return buildMinimalComplianceTestSuite(testClass(), F_1_8); } public TypeAnnotationTest(String testName){ super(testName); } // Enables the tests to run individually protected Map getCompilerOptions() { Map defaultOptions = super.getCompilerOptions(); defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8); defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8); defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8); return defaultOptions; } private static final String HELPER_CLASS = "import java.lang.annotation.*;\n"+ "import java.lang.reflect.*;\n"+ "class Helper {\n"+ "\n"+ // Print type annotations on super types " public static void printTypeAnnotations(Class<?> clazz) {\n"+ " System.out.println(\"Annotations on superclass of \"+clazz.getName());\n"+ " AnnotatedType superat = clazz.getAnnotatedSuperclass();\n"+ " Helper.printAnnos(\" \", superat.getType(),superat.getAnnotations());\n"+ " AnnotatedType[] superinterfaces = clazz.getAnnotatedInterfaces();\n"+ " if (superinterfaces.length!=0) {\n"+ " System.out.println(\"Annotations on superinterfaces of \"+clazz.getName());\n"+ " for (int j=0;j<superinterfaces.length;j++) {\n"+ " Helper.printAnnos(\" \", superinterfaces[j].getType(),superinterfaces[j].getAnnotations());\n"+ " }\n"+ " }\n"+ " }\n"+ // Print type annotations on a type " public static void printTypeAnnotations2(Class<?> clazz) {\n"+ " System.out.print(clazz.getName()+\"<\");\n"+ " TypeVariable<?>[] tvs = clazz.getTypeParameters();\n"+ " for (int t=0;t<tvs.length;t++) {\n"+ " TypeVariable<?> tv = tvs[t];\n"+ " Annotation[] annos = tv.getAnnotations();\n"+ " for (int a=0;a<annos.length;a++) {\n"+ " System.out.print(toStringAnno(annos[a])+\" \");\n"+ " }\n"+ " System.out.print(tv.getName());\n"+ " if ((t+1)<tvs.length) System.out.print(\",\");\n"+ " }\n"+ " System.out.println(\">\");\n"+ " }\n"+ " public static String toStringAnno(Annotation anno) {\n"+ " String s = anno.toString();\n"+ " if (s.endsWith(\"()\")) return s.substring(0,s.length()-2); else return s;\n"+ " }\n"+ " \n"+ " public static void printAnnos(String header, Type t, Annotation[] annos) {\n"+ " if (annos.length==0) { System.out.println(header+t+\":no annotations\"); return;} \n"+ " System.out.print(header+t+\":\");\n"+ " for (int i=0;i<annos.length;i++) {\n"+ " System.out.print(toStringAnno(annos[i])+\" \");\n"+ " }\n"+ " System.out.println();\n"+ " }\n"+ "}\n"; // http://types.cs.washington.edu/jsr308/specification/java-annotation-design.pdf // type_annotation { // // New fields in JSR 308: // u1 target_type; // the type of the targeted program element, see Section 3.2 // union { // type_parameter_target; // supertype_target; // type_parameter_bound_target; // empty_target; // method_formal_parameter_target; // throws_target; // localvar_target; // catch_target; // offset_target; // type_argument_target; // method_reference_target; // } target_info; // identifies the targeted program element, see Section 3.3 // type_path target_path; // identifies targeted type in a compound type (array, generic, etc.), see Section 3.4 // // Original fields from "annotation" structure: // u2 type_index; // u2 num_element_value_pairs; // { // u2 element_name_index; // element_value value; // } element_value_pairs[num_element_value_pairs]; // } public void test001_classTypeParameter() throws Exception { this.runConformTest( new String[] { "X.java", "public class X<@Marker T> {}", "Marker.java", "import java.lang.annotation.*;\n" + "@Retention(RetentionPolicy.RUNTIME)\n"+ "@Target(ElementType.TYPE_PARAMETER)\n" + "@interface Marker {}", }, ""); // javac-b81: 9[0 1 0 0 0 0 13 0 0] (13=Marker annotation) String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @Marker(\n" + " target type = 0x0 CLASS_TYPE_PARAMETER\n" + " type parameter index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test002_classTypeParameter_reflection() throws Exception { this.runConformTest( new String[] { "X.java", "public class X<@Marker T> {\n"+ " public static void main(String[] argv) { Helper.printTypeAnnotations2(X.class);}\n"+ "}", "Helper.java",HELPER_CLASS, "Marker.java", "import java.lang.annotation.*;\n" + "import static java.lang.annotation.ElementType.*;\n" + "@Retention(RetentionPolicy.RUNTIME)\n"+ "@Target(TYPE_PARAMETER)\n" + "@interface Marker {}", }, "X<@Marker T>"); } public void test003_classTypeParameter() throws Exception { this.runConformTest( new String[] { "X.java", "public class X<@A1 T1,@A2 @A3 T2> {}", "A1.java", "import java.lang.annotation.*;\n" + "@Retention(RetentionPolicy.RUNTIME)\n"+ "@Target(ElementType.TYPE_PARAMETER)\n" + "@interface A1 {}", "A2.java", "import java.lang.annotation.*;\n" + "@Retention(RetentionPolicy.RUNTIME)\n"+ "@Target(ElementType.TYPE_PARAMETER)\n" + "@interface A2 {}", "A3.java", "import java.lang.annotation.*;\n" + "@Retention(RetentionPolicy.RUNTIME)\n"+ "@Target(ElementType.TYPE_PARAMETER)\n" + "@interface A3 {}", }, ""); // javac-b81: 9[0 1 0 0 0 0 13 0 0] (13=Marker) String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @A1(\n" + " target type = 0x0 CLASS_TYPE_PARAMETER\n" + " type parameter index = 0\n" + " )\n" + " #22 @A2(\n" + " target type = 0x0 CLASS_TYPE_PARAMETER\n" + " type parameter index = 1\n" + " )\n" + " #23 @A3(\n" + " target type = 0x0 CLASS_TYPE_PARAMETER\n" + " type parameter index = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test004_classTypeParameter_reflection() throws Exception { this.runConformTest( new String[] { "X.java", "public class X<@A1 T1,@A2 @A3 T2> {\n"+ " public static void main(String[] argv) { Helper.printTypeAnnotations2(X.class); }\n"+ "}", "Helper.java",HELPER_CLASS, "A1.java", "import java.lang.annotation.*;\n" + "@Retention(RetentionPolicy.RUNTIME)\n"+ "@Target(ElementType.TYPE_PARAMETER)\n" + "@interface A1 {}", "A2.java", "import java.lang.annotation.*;\n" + "import static java.lang.annotation.ElementType.*;\n" + "@Retention(RetentionPolicy.RUNTIME)\n"+ "@Target(TYPE_PARAMETER)\n" + "@interface A2 {}", "A3.java", "import java.lang.annotation.*;\n" + "import static java.lang.annotation.ElementType.*;\n" + "@Retention(RetentionPolicy.RUNTIME)\n"+ "@Target(TYPE_PARAMETER)\n" + "@interface A3 {}", }, "X<@A1 T1,@A2 @A3 T2>"); } public void test005_classTypeParameter() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_PARAMETER)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_PARAMETER)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "public class X<@A @B(3) T> {}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #25 @A(\n" + " target type = 0x0 CLASS_TYPE_PARAMETER\n" + " type parameter index = 0\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #21 @B(\n" + " #22 value=(int) 3 (constant type)\n" + " target type = 0x0 CLASS_TYPE_PARAMETER\n" + " type parameter index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test006_classTypeParameter() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_PARAMETER)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_PARAMETER)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "public class X<T1,T2,@A @B(3) T3> {}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #25 @A(\n" + " target type = 0x0 CLASS_TYPE_PARAMETER\n" + " type parameter index = 2\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #21 @B(\n" + " #22 value=(int) 3 (constant type)\n" + " target type = 0x0 CLASS_TYPE_PARAMETER\n" + " type parameter index = 2\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test007_methodTypeParameter() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_PARAMETER)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_PARAMETER)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "public class X {\n" + " <@A @B(3) T> void foo(T t) {}\n" + "}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #27 @A(\n" + " target type = 0x1 METHOD_TYPE_PARAMETER\n" + " type parameter index = 0\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #23 @B(\n" + " #24 value=(int) 3 (constant type)\n" + " target type = 0x1 METHOD_TYPE_PARAMETER\n" + " type parameter index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test008_methodTypeParameter() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_PARAMETER)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_PARAMETER)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "public class X {\n" + " <T1, @A @B(3) T2> void foo(T1 t1,T2 t2) {}\n" + "}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #29 @A(\n" + " target type = 0x1 METHOD_TYPE_PARAMETER\n" + " type parameter index = 1\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #25 @B(\n" + " #26 value=(int) 3 (constant type)\n" + " target type = 0x1 METHOD_TYPE_PARAMETER\n" + " type parameter index = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test009_classExtends() throws Exception { this.runConformTest( new String[] { "Marker.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "@Target(TYPE_USE)\n" + "@interface Marker {}", "X.java", "public class X extends @Marker Object {}", }, ""); // javac-b81 annotation contents: len:10[0 1 16 -1 -1 0 0 17 0 0] String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #17 @Marker(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = -1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test010_classExtends() throws Exception { this.runConformTest( new String[] { "Marker.java", "import java.lang.annotation.*;\n" + "import static java.lang.annotation.ElementType.*;\n" + "@Retention(RetentionPolicy.RUNTIME)\n"+ "@Target(TYPE_USE)\n" + "@interface Marker {}", "X.java", "public class X extends @Marker Object {}", }, ""); // Bytes:10[0 1 16 -1 -1 0 0 17 0 0] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #17 @Marker(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = -1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test011_classExtends_reflection() throws Exception { this.runConformTest( new String[] { "X.java", "public class X extends @Marker Object {public static void main(String[] argv) {Helper.printTypeAnnotations(X.class);}}", "Helper.java",HELPER_CLASS, "Marker.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "@Target(TYPE_USE)\n" + "@interface Marker {}" }, "Annotations on superclass of X\n"+ " class java.lang.Object:no annotations"); } public void test012_classExtends_reflection() throws Exception { this.runConformTest( new String[] { "X.java", "public class X extends @Marker Object {public static void main(String[] argv) {Helper.printTypeAnnotations(X.class);}}", "Helper.java",HELPER_CLASS, "Marker.java", "import java.lang.annotation.*;\n" + "import static java.lang.annotation.ElementType.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n"+ "@interface Marker {}" }, "Annotations on superclass of X\n"+ " class java.lang.Object:@Marker"); } public void test013_classExtends_interfaces() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String id() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "I.java", "interface I {}\n", "J.java", "interface J {}\n", "X.java", "public class X implements @A(id=\"Hello, World!\") I, @B @C('(') J {}", }, ""); // Output from javac b81 lambda // RuntimeVisibleTypeAnnotations // Bytes:28[0 2 16 0 0 0 0 13 0 1 0 14 115 0 15 16 0 1 0 0 16 0 1 0 17 67 0 18] // RuntimeInvisibleTypeAnnotations // Bytes:10[0 1 16 0 1 0 0 20 0 0] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #23 @A(\n" + " #24 id=\"Hello, World!\" (constant type)\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 0\n" + " )\n" + " #26 @C(\n" + " #27 value=\'(\' (constant type)\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 1\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #21 @B(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test014_classExtends_interfaces_reflection() throws Exception { this.runConformTest( new String[] { "X.java", "public class X implements @A I {public static void main(String[]argv) {Helper.printTypeAnnotations(X.class);}}", "Helper.java",HELPER_CLASS, "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + "}\n", "I.java", "interface I {}\n" }, "Annotations on superclass of X\n" + " class java.lang.Object:no annotations\n" + "Annotations on superinterfaces of X\n" + " interface I:@A"); } public void test015_classExtends_interfaces_reflection() throws Exception { this.runConformTest( new String[] { "X.java", "public class X implements @A(id=\"Hello, World!\") I, @B @C('i') J {public static void main(String[] argv) { Helper.printTypeAnnotations(X.class);}}", "Helper.java",HELPER_CLASS, "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String id() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "I.java", "interface I {}\n", "J.java", "interface J {}\n", }, "Annotations on superclass of X\n" + " class java.lang.Object:no annotations\n" + "Annotations on superinterfaces of X\n" + " interface I:@A(id=Hello, World!) \n" + " interface J:@C(value=i)"); } public void test016_classExtends() throws Exception { this.runConformTest( new String[] { "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "Y.java", "class Y<T> {}\n", "X.java", "public class X extends Y<@B String> {\n" + "}", }, ""); // javac-b81: Bytes:12[0 1 16 -1 -1 1 3 0 0 13 0 0] // type path: 1,3,0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #19 @B(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = -1\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test017_classExtends() throws Exception { this.runConformTest( new String[] { "Marker.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface Marker { }\n", "I.java", "interface I<T> {}\n", "X.java", "public class X implements I<@Marker String> {\n" + "}", }, ""); // javac-b81: Bytes:12[0 1 16 0 0 1 3 0 0 14 0 0] // type path: 1,3,0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @Marker(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 0\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test018_classExtends() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A { }\n", "I.java", "interface I<T1,T2> {}\n", "X.java", "public class X implements I<Integer, @A String> {}\n" }, ""); // javac-b81: Bytes:12[0 1 16 0 0 1 3 1 0 14 0 0] // type path: 1,3,1 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @A(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 0\n" + " location = [TYPE_ARGUMENT(1)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test019_classExtends() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A { }\n", "J.java", "interface J<T> {}\n", "I.java", "interface I<T> {}\n", "X.java", "public class X implements I<J<@A String>> {}\n" }, ""); // javac-b81: Bytes:14[0 1 16 0 0 2 3 0 3 0 0 14 0 0] // type path: 2,3,0,3,0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @A(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 0\n" + " location = [TYPE_ARGUMENT(0), TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test020_classExtends() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A { }\n", "I.java", "interface I<T> {}\n", "X.java", "public class X implements I<@A String[]> {}\n" }, ""); // javac-b81: Bytes:14[0 1 16 0 0 2 3 0 0 0 0 14 0 0] // type path: 2,3,0,0,0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @A(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 0\n" + " location = [TYPE_ARGUMENT(0), ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test021_classExtends() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A { }\n", "I.java", "interface I<T> {}\n", "X.java", "public class X implements I<String @A[]> {}\n" }, ""); // javac-b81: Bytes:12[0 1 16 0 0 1 3 0 0 14 0 0] // type path: 1,3,0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @A(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 0\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test022_classExtends() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A { }\n", "I.java", "interface I<T> {}\n", "X.java", "public class X implements I<String []@A[]> {}\n" }, ""); // javac-b81: Bytes:14[0 1 16 0 0 2 3 0 0 0 0 14 0 0] // type path: 2,3,0,0,0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @A(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 0\n" + " location = [TYPE_ARGUMENT(0), ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test023_classExtends() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A { }\n", "I.java", "interface I<T> {}\n", "X.java", "public class X implements I<@A String [][][]> {}\n" }, ""); // javac-b81: Bytes:10[0 1 16 0 0 0 0 12 0 0] // type path: 4,3,0,0,0,0,0,0,0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @A(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 0\n" + " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test024_classExtends() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "I.java", "interface I<T> {}\n", "J.java", "interface J<U,T> {}\n", "X.java", "public class X implements I<@A(\"Hello, World!\") String>, @B J<String, @C('(') Integer> {}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #25 @A(\n" + " #26 value=\"Hello, World!\" (constant type)\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 0\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n" + " #28 @C(\n" + " #26 value=\'(\' (constant type)\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 1\n" + " location = [TYPE_ARGUMENT(1)]\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #23 @B(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test025_classTypeParameterBound() throws Exception { this.runConformTest( new String[] { "X.java", "public class X<T extends @A String> {}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {}\n" }, ""); // javac-b81: Bytes:10[0 1 17 0 0 0 0 13 0 0] // [17 0 0] is CLASS_PARAMETER_BOUND type_parameter_index=0 bound_index=0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @A(\n" + " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" + " type parameter index = 0 type parameter bound index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test026_classTypeParameterBound() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "public class X<T extends @A String & @B(3) Cloneable> {}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #25 @A(\n" + " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" + " type parameter index = 0 type parameter bound index = 0\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #21 @B(\n" + " #22 value=(int) 3 (constant type)\n" + " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" + " type parameter index = 0 type parameter bound index = 1\n" + " )\n" ; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test027_classTypeParameterBound_complex() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "Y.java", "public class Y<T> {}", "X.java", "public class X<U, T extends Y<@A String @C[][]@B[]> & @B(3) Cloneable> {}", }, ""); // javac-b81: // Bytes:28[0 2 17 1 0 1 3 0 0 13 0 0 17 1 0 4 3 0 0 0 0 0 0 0 0 14 0 0] // Bytes:29[0 2 17 1 0 3 3 0 0 0 0 0 0 16 0 0 17 1 1 0 0 16 0 1 0 17 73 0 18] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #25 @A(\n" + " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" + " type parameter index = 1 type parameter bound index = 0\n" + " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]\n" + " )\n" + " #26 @C(\n" + " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" + " type parameter index = 1 type parameter bound index = 0\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #21 @B(\n" + " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" + " type parameter index = 1 type parameter bound index = 0\n" + " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY]\n" + " )\n" + " #21 @B(\n" + " #22 value=(int) 3 (constant type)\n" + " target type = 0x11 CLASS_TYPE_PARAMETER_BOUND\n" + " type parameter index = 1 type parameter bound index = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test028_methodTypeParameterBound() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "Z.java", "public class Z {}", "X.java", "public class X {\n" + " <T extends @A Z> void foo(T t) {}\n" + "}", }, ""); // javac-b81: Bytes:10[0 1 18 0 0 0 0 13 0 0] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #23 @A(\n" + " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" + " type parameter index = 0 type parameter bound index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test029_methodTypeParameterBound() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "Z.java", "public class Z {}", "X.java", "public class X {\n" + " <T extends @A Z & @B(3) Cloneable> void foo(T t) {}\n" + "}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #27 @A(\n" + " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" + " type parameter index = 0 type parameter bound index = 0\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #23 @B(\n" + " #24 value=(int) 3 (constant type)\n" + " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" + " type parameter index = 0 type parameter bound index = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test030_methodTypeParameterBound() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "Z.java", "public class Z {}", "Y.java", "public class Y<T> {}", "X.java", "public class X {\n" + " <T extends Y<Z [][]@B[]> & Cloneable> void foo(T t) {}\n" + "}", }, ""); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #23 @B(\n" + " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" + " type parameter index = 0 type parameter bound index = 0\n" + " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test031_methodTypeParameterBound_complex() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "Z.java", "public class Z {}", "Y.java", "public class Y<T> {}", "X.java", "public class X {\n" + " <T extends Y<@A Z @C[][]@B[]> & @B(3) Cloneable> void foo(T t) {}\n" + "}", }, ""); // javac-b81: // Bytes:28[0 2 18 0 0 1 3 0 0 13 0 0 18 0 0 4 3 0 0 0 0 0 0 0 0 14 0 0] // Bytes:29[0 2 18 0 0 3 3 0 0 0 0 0 0 16 0 0 18 0 1 0 0 16 0 1 0 17 73 0 18] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #27 @A(\n" + " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" + " type parameter index = 0 type parameter bound index = 0\n" + " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]\n" + " )\n" + " #28 @C(\n" + " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" + " type parameter index = 0 type parameter bound index = 0\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #23 @B(\n" + " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" + " type parameter index = 0 type parameter bound index = 0\n" + " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY]\n" + " )\n" + " #23 @B(\n" + " #24 value=(int) 3 (constant type)\n" + " target type = 0x12 METHOD_TYPE_PARAMETER_BOUND\n" + " type parameter index = 0 type parameter bound index = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test032_field() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {}\n", "X.java", "public class X {\n" + " @A int field;\n" + "}", }, ""); // javac-b81: Bytes:8[0 1 19 0 0 7 0 0] 19 = 0x13 (FIELD) String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @A(\n" + " target type = 0x13 FIELD\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test033_field() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {}\n", "X.java", "public class X {\n" + " java.util.List<@A String> field;\n" + "}", }, ""); // javac-b81: Bytes:10[0 1 19 1 3 0 0 9 0 0] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @A(\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test034_field() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "public class X {\n" + " @B(3) @A int field;\n" + "}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #12 @A(\n" + " target type = 0x13 FIELD\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #8 @B(\n" + " #9 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test035_field() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {}\n", "X.java", "public class X {\n" + " java.util.Map<String, @A String> field;\n" + "}", }, ""); // javac-b81: Bytes:10[0 1 19 1 3 1 0 9 0 0] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @A(\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(1)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test036_field() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {}\n", "X.java", "public class X {\n" + " java.util.List<String[][]@A[][]> field;\n" + "}", }, ""); // javac-b81: Bytes:14[0 1 19 3 3 0 0 0 0 0 0 9 0 0] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @A(\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(0), ARRAY, ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test037_field() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " java.util.List<? extends @A Number> field;\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {}\n", }, ""); // javac-b81: Bytes:12[0 1 19 2 3 0 2 0 0 9 0 0] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @A(\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(0), WILDCARD]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test038_field() throws Exception { this.runConformTest( new String[] { "X.java", "class AA { class BB<T> {}}" + "class X {\n" + " AA.@A BB field;\n" + "}\n", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A { }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @A(\n" + " target type = 0x13 FIELD\n" + " location = [INNER_TYPE]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test038a_field() throws Exception { this.runConformTest( new String[] { "X.java", "class AA { class BB<T> {}}" + "class X {\n" + " @B AA.@A BB[] @C[] field;\n" + "}\n", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A { }\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { }\n", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface C { }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @B(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #9 @A(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE]\n" + " )\n" + " #10 @C(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test039_field() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "public class X {\n" + " @A int [] @B(3) [] field;\n" + "}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #12 @A(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #8 @B(\n" + " #9 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test040_field_complex() throws Exception { this.runConformTest( new String[] { "X.java", "import java.util.Map;\n" + "import java.util.List;\n" + "public class X {\n" + " @H String @E[] @F[] @G[] field;\n" + " @A Map<@B String, @C List<@D Object>> field2;\n" + " @A Map<@B String, @H String @E[] @F[] @G[]> field3;\n" + "}", "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "D.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface D {\n" + " String value() default \"default\";\n" + "}\n", "E.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface E {\n" + " int value() default -1;\n" + "}", "F.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface F {\n" + " char value() default '-';\n" + "}\n", "G.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface G {\n" + " int value() default -1;\n" + "}", "H.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface H {\n" + " char value() default '-';\n" + "}\n", }, ""); String expectedOutput = " // Field descriptor #6 [[[Ljava/lang/String;\n" + " java.lang.String[][][] field;\n" + " RuntimeVisibleTypeAnnotations: \n" + " #11 @H(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, ARRAY]\n" + " )\n" + " #12 @F(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #8 @E(\n" + " target type = 0x13 FIELD\n" + " )\n" + " #9 @G(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " \n" + " // Field descriptor #14 Ljava/util/Map;\n" + " // Signature: Ljava/util/Map<Ljava/lang/String;Ljava/util/List<Ljava/lang/Object;>;>;\n" + " java.util.Map field2;\n" + " RuntimeVisibleTypeAnnotations: \n" + " #18 @A(\n" + " target type = 0x13 FIELD\n" + " )\n" + " #19 @C(\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(1)]\n" + " )\n" + " #20 @D(\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(1), TYPE_ARGUMENT(0)]\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #17 @B(\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n" + " \n" + " // Field descriptor #14 Ljava/util/Map;\n" + " // Signature: Ljava/util/Map<Ljava/lang/String;[[[Ljava/lang/String;>;\n" + " java.util.Map field3;\n" + " RuntimeVisibleTypeAnnotations: \n" + " #18 @A(\n" + " target type = 0x13 FIELD\n" + " )\n" + " #11 @H(\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(1), ARRAY, ARRAY, ARRAY]\n" + " )\n" + " #12 @F(\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(1), ARRAY]\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #17 @B(\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n" + " #8 @E(\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(1)]\n" + " )\n" + " #9 @G(\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(1), ARRAY, ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test041_field() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " java.lang.@H String @E[] @F[] @G[] field;\n" + "}", "E.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface E {\n" + " int value() default -1;\n" + "}", "F.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface F {\n" + " char value() default '-';\n" + "}\n", "G.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface G {\n" + " int value() default -1;\n" + "}", "H.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface H {\n" + " char value() default '-';\n" + "}\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #11 @H(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, ARRAY]\n" + " )\n" + " #12 @F(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #8 @E(\n" + " target type = 0x13 FIELD\n" + " )\n" + " #9 @G(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test042_methodReturnType() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "public class X {\n" + " @B(3) @A(value=\"test\") int foo() {\n" + " return 1;\n" + " }\n" + "}", }, ""); // javac-b81: // Bytes:13[0 1 20 0 0 11 0 1 0 12 115 0 13] // Bytes:13[0 1 20 0 0 15 0 1 0 12 73 0 16] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @A(\n" + " #18 value=\"test\" (constant type)\n" + " target type = 0x14 METHOD_RETURN\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #17 @B(\n" + " #18 value=(int) 3 (constant type)\n" + " target type = 0x14 METHOD_RETURN\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test043_methodReceiver() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "public class X {\n" + " void foo(@B(3) X this) {}\n" + "}", }, ""); // javac-b81: Bytes:13[0 1 21 0 0 10 0 1 0 11 73 0 12] String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #16 @B(\n" + " #17 value=(int) 3 (constant type)\n" + " target type = 0x15 METHOD_RECEIVER\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test044_methodReceiver() throws Exception { this.runConformTest( new String[] { "X.java", "public class X<T> {\n" + " void foo(X<@B(3) T> this) {}\n" + "}", "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", }, ""); // javac-b81: Bytes:15[0 1 21 1 3 0 0 10 0 1 0 11 73 0 12] String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #18 @B(\n" + " #19 value=(int) 3 (constant type)\n" + " target type = 0x15 METHOD_RECEIVER\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test045_methodParameter() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " int foo(@B(3) String s) {\n" + " return s.length();\n" + " }\n" + "}", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", }, ""); // javac-b81: Bytes:14[0 1 22 0 0 0 11 0 1 0 12 73 0 13] String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #25 @B(\n" + " #26 value=(int) 3 (constant type)\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test046_methodParameter() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " int foo(int i, double d, @B(3) String s) {\n" + " return s.length();\n" + " }\n" + "}", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", }, ""); // javac-b81: Bytes:14[0 1 22 1 0 0 11 0 1 0 12 73 0 13] String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #29 @B(\n" + " #30 value=(int) 3 (constant type)\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 2\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test047_methodParameterArray() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "public class X {\n" + " int foo(String @A [] @B(3) [] s) {\n" + " return s.length;\n" + " }\n" + "}", }, ""); // javac-b81: // Bytes:9[0 1 22 0 0 0 11 0 0] // Bytes:16[0 1 22 0 1 0 0 0 13 0 1 0 14 73 0 15] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #23 @A(\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #19 @B(\n" + " #20 value=(int) 3 (constant type)\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test048_throws() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n"+ "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n"+ "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.*;\n"+ "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "E.java", "class E extends RuntimeException {\n" + " private static final long serialVersionUID = 1L;\n" + "}\n", "E1.java", "class E1 extends RuntimeException {\n" + " private static final long serialVersionUID = 1L;\n" + "}\n", "E2.java", "class E2 extends RuntimeException {\n" + " private static final long serialVersionUID = 1L;\n" + "}\n", "X.java", "public class X {\n" + " void foo() throws @A(\"Hello, World!\") E, E1, @B @C('(') E2 {}\n" + "}", }, ""); // javac-b81: // Bytes:28[0 2 23 0 0 0 0 14 0 1 0 15 115 0 16 23 0 2 0 0 17 0 1 0 15 67 0 18] // Bytes:10[0 1 23 0 2 0 0 20 0 0] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #25 @A(\n" + " #26 value=\"Hello, World!\" (constant type)\n" + " target type = 0x17 THROWS\n" + " throws index = 0\n" + " )\n" + " #28 @C(\n" + " #26 value=\'(\' (constant type)\n" + " target type = 0x17 THROWS\n" + " throws index = 2\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #23 @B(\n" + " target type = 0x17 THROWS\n" + " throws index = 2\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test049_codeblocks_localVariable() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.Target;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "public class X {\n" + " public static void main(String[] args) {\n" + " @B int j = 9;\n" + " try {\n" + " System.out.print(\"SUCCESS\" + j);\n" + " } catch(@A Exception e) {\n" + " }\n" + " @B int k = 3;\n" + " System.out.println(k);\n" + " }\n" + "}", "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " String value() default \"default\";\n" + "}\n", }, "SUCCESS93"); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #56 @B(\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 3, pc: 39] index: 1\n" + " )\n" + " #56 @B(\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 31, pc: 39] index: 2\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test050_codeblocks_localVariable() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "X.java", "public class X {\n" + " String[][] bar() {\n" + " return new String[][] {};" + " }\n" + " void foo(String s) {\n" + " @C int i;\n" + " @A String [] @B(3)[] tab = bar();\n" + " if (tab != null) {\n" + " i = 0;\n" + " System.out.println(i + tab.length);\n" + " } else {\n" + " System.out.println(tab.length);\n" + " }\n" + " i = 4;\n" + " System.out.println(-i + tab.length);\n" + " }\n" + "}", }, ""); // javac-b81: // Bytes:34[0 2 64 0 1 0 34 0 12 0 2 0 0 19 0 0 64 0 1 0 5 0 41 0 3 2 0 0 0 0 0 20 0 0] // Bytes:23[0 1 64 0 1 0 5 0 41 0 3 1 0 0 0 22 0 1 0 23 73 0 24] // ECJ data varies a little here as it is splitting the range String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #45 @B(\n" + " #46 value=(int) 3 (constant type)\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 5, pc: 46] index: 3\n" + " location = [ARRAY]\n" + " )\n" + " RuntimeVisibleTypeAnnotations: \n" + " #49 @C(\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 11, pc: 24] index: 2\n" + " [pc: 34, pc: 46] index: 2\n" + " )\n" + " #50 @A(\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 5, pc: 46] index: 3\n" + " location = [ARRAY, ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test051_codeblocks_resourceVariable() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "import java.io.*;\n"+ "public class X {\n" + " public static void main(String[] argv) throws Exception {\n"+ " try (@A BufferedReader br1 = new BufferedReader(new FileReader(\"a\"));\n"+ " @B(99) BufferedReader br2 = new BufferedReader(new FileReader(\"b\"))) {\n"+ " System.out.println(br1.readLine()+br2.readLine());\n" + " }\n" + " }\n" + "}", }, ""); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #81 @B(\n" + " #82 value=(int) 99 (constant type)\n" + " target type = 0x41 RESOURCE_VARIABLE\n" + " local variable entries:\n" + " [pc: 39, pc: 94] index: 4\n" + " )\n" + " RuntimeVisibleTypeAnnotations: \n" + " #85 @A(\n" + " target type = 0x41 RESOURCE_VARIABLE\n" + " local variable entries:\n" + " [pc: 21, pc: 135] index: 3\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test052_codeblocks_exceptionParameter() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.*;\n" + "public class X {\n" + " public static void main(String[] args) {\n" + " Exception test = new Exception() {\n" + " private static final long serialVersionUID = 1L;\n" + " @Override\n" + " public String toString() {\n" + " return \"SUCCESS\";\n" + " }\n" + " };\n" + " try {\n" + " System.out.println(test);\n" + " } catch(@A Exception e) {\n" + " e.printStackTrace();\n" + " }\n" + " }\n" + "}", "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, "SUCCESS"); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #44 @A(\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test053_codeblocks_exceptionParameter() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.Target;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "public class X {\n" + " public static void main(String[] args) {\n" + " @A Exception test = new Exception() {\n" + " private static final long serialVersionUID = 1L;\n" + " @Override\n" + " public String toString() {\n" + " return \"SUCCESS\";\n" + " }\n" + " };\n" + " try {\n" + " System.out.println(test);\n" + " } catch(@A Exception e) {\n" + " e.printStackTrace();\n" + " }\n" + " }\n" + "}", "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, "SUCCESS"); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #44 @A(\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 8, pc: 24] index: 1\n" + " )\n" + " #44 @A(\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test054_codeblocks_exceptionParameter() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.Target;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "public class X {\n" + " public static void main(String[] args) {\n" + " try {\n" + " System.out.println(42);\n" + " } catch(@B(1) RuntimeException e) {\n" + " e.printStackTrace();\n" + " } catch(@B(2) Throwable t) {\n" + " t.printStackTrace();\n" + " }\n" + " }\n" + "}", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface B {\n" + " int value() default 99;\n" + "}\n", }, "42"); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #44 @B(\n" + " #45 value=(int) 1 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " )\n" + " #44 @B(\n" + " #45 value=(int) 2 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test055_codeblocks_exceptionParameterMultiCatch() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.Target;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "class Exc1 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "class Exc2 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "class Exc3 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "public class X {\n" + " public static void main(String[] args) {\n" + " try {\n" + " System.out.println(42);\n" + // @B(1) is attached to the argument, the others are attached to the type reference in the union type reference // During Parsing the @B(1) is moved from the argument to Exc1 " } catch(@B(1) Exc1 | Exc2 | @B(2) Exc3 t) {\n" + " t.printStackTrace();\n" + " }\n" + " }\n" + "}", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface B {\n" + " int value() default 99;\n" + "}\n", }, "42"); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #45 @B(\n" + " #46 value=(int) 1 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " )\n" + " #45 @B(\n" + " #46 value=(int) 2 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 2\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test056_codeblocks_instanceof() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " public void foo(Object o) {\n" + " if (o instanceof @A String) {\n" + " String tab = (String) o;\n" + " System.out.println(tab);\n" + " }\n" + " System.out.println(o);\n" + " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #38 @A(\n" + " target type = 0x43 INSTANCEOF\n" + " offset = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); expectedOutput = " 1 instanceof java.lang.String [16]\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test057_codeblocks_new() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "I.java", "interface I {}\n", "J.java", "interface J {}\n", "X.java", "public class X {\n" + " public boolean foo(String s) {\n" + " System.out.println(\"xyz\");\n" + " Object o = new @B(3) Object();\n" + " return true;\n" + " }\n" + "}", }, ""); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #35 @B(\n" + " #36 value=(int) 3 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 8\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test058_codeblocks_new2() throws Exception { this.runConformTest( new String[] { "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "public class X {\n" + " public void foo() {\n" + " Outer o = new Outer();\n" + " o.new @B(1) Inner();\n" + " }\n" + "}\n" + "class Outer { class Inner {}}\n" }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #30 @B(\n" + " #31 value=(int) 1 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 8\n" + " location = [INNER_TYPE]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test057_codeblocks_new3_415821() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface X { }\n" + "\n" + "class Foo {}\n", "C.java", "class C { void m() { new @X Foo() {}; } }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @X(\n" + " target type = 0x44 NEW\n" + " offset = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "C.class", "C", expectedOutput, ClassFileBytesDisassembler.SYSTEM); expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #28 @X(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = -1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "C$1.class", "C$1", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test057_codeblocks_new4_415821() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface X { }\n" + "\n", "C.java", "class C { void m() { new @X Runnable() { public void run() {}}; } }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #21 @X(\n" + " target type = 0x44 NEW\n" + " offset = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "C.class", "C", expectedOutput, ClassFileBytesDisassembler.SYSTEM); expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #31 @X(\n" + " target type = 0x10 CLASS_EXTENDS\n" + " type index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "C$1.class", "C$1", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test059_codeblocks_new_newArray() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "I.java", "interface I {}\n", "J.java", "interface J {}\n", "X.java", "public class X {\n" + " public boolean foo(String s) {\n" + " System.out.println(\"xyz\");\n" + " Object o = new @A String [1];\n" + " return true;\n" + " }\n" + "}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #37 @A(\n" + " target type = 0x44 NEW\n" + " offset = 9\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test060_codeblocks_new_multiNewArray() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "X.java", "public class X {\n" + " public boolean foo(String s) {\n" + " System.out.println(\"xyz\");\n" + " Object o = new @A String [2][3];\n" + " return true;\n" + " }\n" + "}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #37 @A(\n" + " target type = 0x44 NEW\n" + " offset = 10\n" + " location = [ARRAY, ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test060a_codeblocks_new_newArrayWithInitializer() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " public boolean foo(String s) {\n" + " System.out.println(\"xyz\");\n" + " X[][] x = new @A X @B [] @C[]{ { null }, { null } };\n" + " return true;\n" + " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " String value() default \"default\";\n" + "}\n", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface C {\n" + " String value() default \"default\";\n" + "}\n", }, ""); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #37 @A(\n" + " target type = 0x44 NEW\n" + " offset = 9\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #38 @B(\n" + " target type = 0x44 NEW\n" + " offset = 9\n" + " )\n" + " #39 @C(\n" + " target type = 0x44 NEW\n" + " offset = 9\n" + " location = [ARRAY]\n" + " )\n" + "}"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test060b_codeblocks_new_multiNewArray() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " public boolean foo(String s) {\n" + " System.out.println(\"xyz\");\n" + " X[][] x = new @A X @B [1] @C[2];\n" + " return true;\n" + " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " String value() default \"default\";\n" + "}\n", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface C {\n" + " String value() default \"default\";\n" + "}\n", }, ""); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #36 @A(\n" + " target type = 0x44 NEW\n" + " offset = 10\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #37 @B(\n" + " target type = 0x44 NEW\n" + " offset = 10\n" + " )\n" + " #38 @C(\n" + " target type = 0x44 NEW\n" + " offset = 10\n" + " location = [ARRAY]\n" + " )\n" + "}"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test060c_codeblocks_new_multiNewArray() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " public boolean foo(String s) {\n" + " System.out.println(\"xyz\");\n" + " X [][][] x = new @A X @B[10] @C[10] @D[];\n" + " return true;\n" + " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " String value() default \"default\";\n" + "}\n", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface C {\n" + " String value() default \"default\";\n" + "}\n", "D.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface D {\n" + " String value() default \"default\";\n" + "}\n", }, ""); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #36 @A(\n" + " target type = 0x44 NEW\n" + " offset = 12\n" + " location = [ARRAY, ARRAY, ARRAY]\n" + " )\n" + " #37 @B(\n" + " target type = 0x44 NEW\n" + " offset = 12\n" + " )\n" + " #38 @C(\n" + " target type = 0x44 NEW\n" + " offset = 12\n" + " location = [ARRAY]\n" + " )\n" + " #39 @D(\n" + " target type = 0x44 NEW\n" + " offset = 12\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + "}"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test060d_codeblocks_new_arraysWithNestedTypes() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " public boolean foo(String s) {\n" + " System.out.println(\"xyz\");\n" + " Object o = new @B(1) Outer.@B(2) Inner @B(3) [2];\n" + " return true;\n" + " }\n" + "}\n" + "class Outer { class Inner {}}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B {\n" + " int value() default 99;\n" + "}\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #37 @B(\n" + " #38 value=(int) 1 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 9\n" + " location = [ARRAY]\n" + " )\n" + " #37 @B(\n" + " #38 value=(int) 2 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 9\n" + " location = [ARRAY, INNER_TYPE]\n" + " )\n" + " #37 @B(\n" + " #38 value=(int) 3 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 9\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test060e_codeblocks_new_arraysWithNestedTypes() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " public boolean foo(String s) {\n" + " System.out.println(\"xyz\");\n" + " Object o = new @B(1) Outer.@B(2) Inner @B(3) [2] @B(4)[4];\n" + " return true;\n" + " }\n" + "}\n" + "class Outer { class Inner {}}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B {\n" + " int value() default 99;\n" + "}\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #37 @B(\n" + " #38 value=(int) 1 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 10\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #37 @B(\n" + " #38 value=(int) 2 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 10\n" + " location = [ARRAY, ARRAY, INNER_TYPE]\n" + " )\n" + " #37 @B(\n" + " #38 value=(int) 3 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 10\n" + " )\n" + " #37 @B(\n" + " #38 value=(int) 4 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 10\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test060f_codeblocks_new_arraysWithQualifiedNestedTypes() throws Exception { this.runConformTest( new String[] { "Z.java", "public class Z {}", "X.java", "package org.foo.bar;\n" + "public class X {\n" + " public boolean foo(String s) {\n" + " System.out.println(\"xyz\");\n" + " Object o = new org.foo.bar.@B(1) Outer.@B(2) Inner @B(3) [2] @B(4)[4];\n" + " return true;\n" + " }\n" + "}\n" + "class Outer { class Inner {}}\n", "B.java", "package org.foo.bar;\n" + "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B {\n" + " int value() default 99;\n" + "}\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #37 @org.foo.bar.B(\n" + " #38 value=(int) 1 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 10\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #37 @org.foo.bar.B(\n" + " #38 value=(int) 2 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 10\n" + " location = [ARRAY, ARRAY, INNER_TYPE]\n" + " )\n" + " #37 @org.foo.bar.B(\n" + " #38 value=(int) 3 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 10\n" + " )\n" + " #37 @org.foo.bar.B(\n" + " #38 value=(int) 4 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 10\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "org" + File.separator + "foo" + File.separator + "bar" + File.separator + "X.class", "org.foo.bar.X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test061_codeblocks_new_newArrayWithInitializer() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "I.java", "interface I {}\n", "J.java", "interface J {}\n", "X.java", "public class X {\n" + " public boolean foo(String s) {\n" + " System.out.println(\"xyz\");\n" + " Object o = new @A String []{\"xyz\"};\n" + " return true;\n" + " }\n" + "}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #37 @A(\n" + " target type = 0x44 NEW\n" + " offset = 9\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test062_codeblocks_newArray() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "I.java", "interface I {}\n", "J.java", "interface J {}\n", "X.java", "public class X {\n" + " public boolean foo(String s) {\n" + " System.out.println(\"xyz\");\n" + " Object o = new String @A[1];\n" + " return true;\n" + " }\n" + "}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #37 @A(\n" + " target type = 0x44 NEW\n" + " offset = 9\n" + // no type path expected here " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test062_codeblocks_newArrayWithInitializer() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "I.java", "interface I {}\n", "J.java", "interface J {}\n", "X.java", "public class X {\n" + " public boolean foo(String s) {\n" + " System.out.println(\"xyz\");\n" + " Object o = new String @A[] { \"Hello\" };\n" + " return true;\n" + " }\n" + "}", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #39 @A(\n" + " target type = 0x44 NEW\n" + " offset = 9\n" + // no type path expected here " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test063_codeblocks_new_instanceof() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "I.java", "interface I {}\n", "J.java", "interface J {}\n", "X.java", "public class X {\n" + " public boolean foo(Object o) {\n" + " boolean b = (o instanceof @C('_') Object[]);\n" + " Object o1 = new @B(3) @A(\"new Object\") Object[] {};\n" + " return b;\n" + " }\n" + "}", }, ""); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #24 @B(\n" + " #25 value=(int) 3 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 6\n" + " location = [ARRAY]\n" + " )\n" + " RuntimeVisibleTypeAnnotations: \n" + " #28 @C(\n" + " #25 value=\'_\' (constant type)\n" + " target type = 0x43 INSTANCEOF\n" + " offset = 1\n" + " location = [ARRAY]\n" + " )\n" + " #30 @A(\n" + " #25 value=\"new Object\" (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 6\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test064_codeblocks_constructorReference() throws Exception { this.runConformTest( new String[] { "X.java", "import java.util.*;\n" + "interface MR { X process(String input); }\n"+ "public class X<T> {\n" + " public X(T t) {}\n" + " public static <T> String foo(String bar) { return bar; }\n"+ " public void bar() {\n" + " System.out.println(\"abc\");\n" + " MR ref = @A X::new;\n" + " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #48 @A(\n" + " target type = 0x45 CONSTRUCTOR_REFERENCE\n" + " offset = 8\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test065_codeblocks_methodReference() throws Exception { this.runConformTest( new String[] { "X.java", "import java.util.*;\n" + "interface MR { String process(String input); }\n"+ "public class X<T> {\n" + " public static <T> String foo(String bar) { return bar; }\n"+ " public void bar() {\n" + " System.out.println(\"abc\");\n" + " MR ref = @A X::foo;\n" + " ref.process(\"abc\");\n" + " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #47 @A(\n" + " target type = 0x46 METHOD_REFERENCE\n" + " offset = 8\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test066_codeblocks_methodReference() throws Exception { this.runConformTest( new String[] { "X.java", "interface I {\n" + " Object copy(int [] ia);\n" + "}\n" + "public class X {\n" + " public static void main(String [] args) {\n" + " I i = @B(1) int @B(2)[]::<String>clone;\n" + " i.copy(new int[10]); \n" + " }\n" + "}\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 = " RuntimeVisibleTypeAnnotations: \n" + " #30 @B(\n" + " #31 value=(int) 1 (constant type)\n" + " target type = 0x46 METHOD_REFERENCE\n" + " offset = 0\n" + " location = [ARRAY]\n" + " )\n" + " #30 @B(\n" + " #31 value=(int) 2 (constant type)\n" + " target type = 0x46 METHOD_REFERENCE\n" + " offset = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test067_codeblocks_constructorReferenceTypeArgument() throws Exception { this.runConformTest( new String[] { "X.java", "import java.util.*;\n" + "interface MR { X process(String input); }\n" + "public class X<T> {\n" + " public X(T s) {};\n" + " public static <T> String foo(String bar) { return bar; }\n"+ " public void bar() {\n" + " System.out.println(\"abc\");\n" + " MR ref = X<String>::<@A String>new;\n" + " ref.process(\"abc\");\n" + " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #53 @A(\n" + " target type = 0x4a CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT\n" + " offset = 8\n" + " type argument index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test068_codeblocks_methodReferenceTypeArgument() throws Exception { this.runConformTest( new String[] { "X.java", "import java.util.*;\n" + "interface MR { String process(String input); }\n"+ "public class X<T> {\n" + " public static <T> String foo(String bar) { return bar; }\n"+ " public void bar() {\n" + " System.out.println(\"abc\");\n" + " MR ref = X::<@A String>foo;\n" + " ref.process(\"abc\");\n" + " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #47 @A(\n" + " target type = 0x4b METHOD_REFERENCE_TYPE_ARGUMENT\n" + " offset = 8\n" + " type argument index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test069_codeblocks_cast() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " public void foo(Object o) {\n" + " if (o instanceof String) {\n" + " String tab = (@A String) o;\n" + " System.out.println(tab);\n" + " }\n" + " System.out.println(o);\n" + " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, ""); // javac-b81: Bytes:11[0 1 71 0 7 0 0 0 16 0 0] // relevant numbers '71 0 7 0' which mean 0x47 (CAST) at offset 7 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #38 @A(\n" + " target type = 0x47 CAST\n" + " offset = 8\n" + " type argument index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test070_codeblocks_cast_complex() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "I.java", "interface I {}\n", "J.java", "interface J {}\n", "X.java", "public class X {\n" + " public void foo(Object o) {\n" + " if (o instanceof String[][]) {\n" + " String[][] tab = (@C('_') @B(3) String[] @A[]) o;\n" + " System.out.println(tab.length);\n" + " }\n" + " System.out.println(o);\n" + " }\n" + "}", }, ""); // javac-b81: // Bytes:31[0 2 71 0 7 0 1 0 0 0 16 0 0 71 0 7 0 2 0 0 0 0 0 17 0 1 0 18 67 0 19] // Bytes:20[0 1 71 0 7 0 2 0 0 0 0 0 21 0 1 0 18 73 0 22] String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #37 @B(\n" + " #38 value=(int) 3 (constant type)\n" + " target type = 0x47 CAST\n" + " offset = 8\n" + " type argument index = 0\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " RuntimeVisibleTypeAnnotations: \n" + " #41 @C(\n" + " #38 value=\'_\' (constant type)\n" + " target type = 0x47 CAST\n" + " offset = 8\n" + " type argument index = 0\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #43 @A(\n" + " target type = 0x47 CAST\n" + " offset = 8\n" + " type argument index = 0\n" + " location = [ARRAY]\n" + " )\n"; 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 J [16]\n" + " 4 checkcast I [18]\n" + " 7 astore_2 [i]\n" + " 8 aload_1 [o]\n" + " 9 checkcast J [16]\n" + " 12 checkcast I [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 = 4\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 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" + " 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) 2 (constant type)\n" + " target type = 0x47 CAST\n" + " offset = 9\n" + " type argument index = 1\n" + " )\n" + " #39 @B(\n" + " #40 value=(int) 1 (constant type)\n" + " target type = 0x47 CAST\n" + " offset = 12\n" + " type argument index = 0\n" + " location = [TYPE_ARGUMENT(0)]\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 L [28]\n" + " 12 checkcast K [30]\n" + " 15 checkcast J [32]\n" + " 18 checkcast I [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 = 18\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[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "X.java", "public class X {\n" + " <T> X(T t) {\n" + " }\n" + " public Object foo() {\n" + " X x = new <@A @B(1) String>X(null);\n" + " return x;\n" + " }\n" + "}", }, ""); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #27 @B(\n" + " #28 value=(int) 1 (constant type)\n" + " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" + " offset = 5\n" + " type argument index = 0\n" + " )\n" + " RuntimeVisibleTypeAnnotations: \n" + " #31 @A(\n" + " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" + " offset = 5\n" + " type argument index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test072_codeblocks_constructorInvocationTypeArgument() throws Exception { this.runConformTest( new String[] { "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", "X.java", "public class X {\n" + " <T, U> X(T t, U u) {\n" + " }\n" + " public Object foo() {\n" + " X x = new <@A Integer, @A String @C [] @B(1)[]>X(null, null);\n" + " return x;\n" + " }\n" + "}", }, ""); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #29 @B(\n" + " #30 value=(int) 1 (constant type)\n" + " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" + " offset = 6\n" + " type argument index = 1\n" + " location = [ARRAY]\n" + " )\n" + " RuntimeVisibleTypeAnnotations: \n" + " #33 @A(\n" + " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" + " offset = 6\n" + " type argument index = 0\n" + " )\n" + " #33 @A(\n" + " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" + " offset = 6\n" + " type argument index = 1\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #34 @C(\n" + " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" + " offset = 6\n" + " type argument index = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test073_codeblocks_constructorInvocationTypeArgument() throws Exception { this.runConformTest( new String[] { "X.java", "public class X<T1, T2> {\n" + " public void bar() {\n" + " new <String, @A T2>X();\n"+ " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, ""); // Example bytes:11[0 1 73 0 0 0 0 0 13 0 0] this would be for offset 0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #19 @A(\n" + " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" + " offset = 3\n" + " type argument index = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test074_codeblocks_constructorInvocationTypeArgument() throws Exception { this.runConformTest( new String[] { "X.java", "public class X<T1,T2> {\n" + " public static void foo(int i) {}\n"+ " public void bar() {\n" + " new <java.util.List<@A String>, T2>X();\n"+ " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, ""); // Example bytes:11[0 1 73 0 0 0 0 0 13 0 0] this would be for offset 0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #23 @A(\n" + " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" + " offset = 3\n" + " type argument index = 0\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test075_codeblocks_constructorInvocationTypeArgument() throws Exception { this.runConformTest( new String[] { "X.java", "public class X<T> {\n" + " public void bar() {\n" + " new <@A T>X();\n"+ " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, ""); // Example bytes:11[0 1 73 0 0 0 0 0 13 0 0] this would be for offset 0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #19 @A(\n" + " target type = 0x48 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT\n" + " offset = 3\n" + " type argument index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test076_codeblocks_methodInvocationTypeArgument() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + "\n" + " static <T, U> T foo(T t, U u) {\n" + " return t;\n" + " }\n" + " public static void main(String[] args) {\n" + " System.out.println(X.<@A @B(1) String[], @C('-') X>foo(new String[]{\"SUCCESS\"}, null)[0]);\n" + " }\n" + "}\n", "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(CLASS)\n" + "@interface B {\n" + " int value() default -1;\n" + "}", "C.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface C {\n" + " char value() default '-';\n" + "}\n", }, "SUCCESS"); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #48 @B(\n" + " #49 value=(int) 1 (constant type)\n" + " target type = 0x49 METHOD_INVOCATION_TYPE_ARGUMENT\n" + " offset = 13\n" + " type argument index = 0\n" + " location = [ARRAY]\n" + " )\n" + " RuntimeVisibleTypeAnnotations: \n" + " #52 @A(\n" + " target type = 0x49 METHOD_INVOCATION_TYPE_ARGUMENT\n" + " offset = 13\n" + " type argument index = 0\n" + " location = [ARRAY]\n" + " )\n" + " #53 @C(\n" + " #49 value=\'-\' (constant type)\n" + " target type = 0x49 METHOD_INVOCATION_TYPE_ARGUMENT\n" + " offset = 13\n" + " type argument index = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test077_codeblocks_methodInvocationTypeArgument() throws Exception { this.runConformTest( new String[] { "X.java", "public class X<T1,T2> {\n" + " public static void foo(int i) {}\n"+ " public void bar() {\n" + " X.<String, @A T2>foo(42);\n"+ " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, ""); // Example bytes:11[0 1 73 0 0 0 0 0 13 0 0] this would be for offset 0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #24 @A(\n" + " target type = 0x49 METHOD_INVOCATION_TYPE_ARGUMENT\n" + " offset = 2\n" + " type argument index = 1\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test078_codeblocks_methodInvocationTypeArgument() throws Exception { this.runConformTest( new String[] { "X.java", "public class X<T1,T2> {\n" + " public static void foo(int i) {}\n"+ " public void bar() {\n" + " X.<java.util.List<@A String>, T2>foo(42);\n"+ " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, ""); // Example bytes:11[0 1 73 0 0 0 0 0 13 0 0] this would be for offset 0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #24 @A(\n" + " target type = 0x49 METHOD_INVOCATION_TYPE_ARGUMENT\n" + " offset = 2\n" + " type argument index = 0\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test079_codeblocks_methodInvocationTypeArgument() throws Exception { this.runConformTest( new String[] { "X.java", "public class X<T> {\n" + " public static void foo(int i) {}\n"+ " public void bar() {\n" + " X.<@A T>foo(42);\n"+ " }\n" + "}", "A.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface A {\n" + " String value() default \"default\";\n" + "}\n", }, ""); // Example bytes:11[0 1 73 0 0 0 0 0 13 0 0] this would be for offset 0 String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #24 @A(\n" + " target type = 0x49 METHOD_INVOCATION_TYPE_ARGUMENT\n" + " offset = 2\n" + " type argument index = 0\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } // Annotation should appear twice in this case public void test080_multiuseAnnotations() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " @B(1) int foo() { return 0; }\n" + "}", "B.java", "import java.lang.annotation.*;\n" + "@Target({ElementType.METHOD, ElementType.TYPE_USE})\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B {\n" + " int value() default 99;\n" + "}\n", }, ""); String expectedOutput = " RuntimeVisibleAnnotations: \n" + " #17 @B(\n" + " #18 value=(int) 1 (constant type)\n" + " )\n" + " RuntimeVisibleTypeAnnotations: \n" + " #17 @B(\n" + " #18 value=(int) 1 (constant type)\n" + " target type = 0x14 METHOD_RETURN\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test081_multiuseAnnotations() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.*;\n" + "@Target({ElementType.METHOD, ElementType.TYPE_USE})\n" + "@interface Annot {\n" + " int value() default 0;\n" + "}\n" + "public class X {\n" + " @Annot(4) public String foo() { return \"hello\"; }" + "}", }, ""); String expectedOutput = " RuntimeInvisibleAnnotations: \n" + " #17 @Annot(\n" + " #18 value=(int) 4 (constant type)\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #17 @Annot(\n" + " #18 value=(int) 4 (constant type)\n" + " target type = 0x14 METHOD_RETURN\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } // When not annotated with any TYPE it assumes the Java7 set (i.e. not TYPE_USE/TYPE_PARAMETER) public void test082_multiuseAnnotations() throws Exception { this.runConformTest( new String[] { "X.java", "@interface Annot {\r\n" + " int value() default 0;\r\n" + "}\r\n" + "public class X {\r\n" + " @Annot(4)\r\n" + " public void foo() {\r\n" + " }\r\n" + "}", }, ""); String expectedOutput = " // Method descriptor #6 ()V\n" + " // Stack: 0, Locals: 1\n" + " public void foo();\n" + " 0 return\n" + " Line numbers:\n" + " [pc: 0, line: 7]\n" + " Local variable table:\n" + " [pc: 0, pc: 1] local: this index: 0 type: X\n" + " RuntimeInvisibleAnnotations: \n" + " #16 @Annot(\n" + " #17 value=(int) 4 (constant type)\n" + " )\n" + "}"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test100_pqtr() throws Exception { // PQTR (ParameterizedQualifiedTypeReference) this.runConformTest( new String[] { "X.java", "class X {\n" + " java.util.@B(2) List<String> field2;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test100a_pqtr() throws Exception { this.runConformTest( new String[] { "X.java", "class X {\n" + " java.util.@B(2) List<String>[] field3;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test100b_pqtr() throws Exception { this.runConformTest( new String[] { "X.java", "class X {\n" + " java.util.List<@B(3) String>[] field3;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test100c_pqtr() throws Exception { this.runConformTest( new String[] { "X.java", "class X {\n" + " java.util.List<String> @B(3)[] field3;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test100d_pqtr() throws Exception { this.runConformTest( new String[] { "X.java", "class X {\n" + " java.util.@B(2) List<@B(5) String> @B(3)[]@B(4)[] field;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #10 @B(\n" + " #11 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n" + " #10 @B(\n" + " #11 value=(int) 4 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n" + " #10 @B(\n" + " #11 value=(int) 5 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test100e_pqtr() throws Exception { this.runConformTest( new String[] { "X.java", "class X {\n" + " java.util.Map.@B(2) Entry<String,String> field;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test100f_pqtr() throws Exception { this.runConformTest( new String[] { "Foo.java", "class Foo {}\n", "Levels.java", "package one.two.three;\n" + "class Level1 { static class Level2 { class Level3 { class Level4 { class Level5<T> { } } } } }\n", "X.java", "package one.two.three;\n" + "class X {\n" + " one.two.three.Level1.Level2.@B(2) Level3.Level4.@B(3) Level5<String> instance;\n" + "}\n", "B.java", "package one.two.three;\n" + "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @one.two.three.B(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [INNER_TYPE]\n" + " )\n" + " #10 @one.two.three.B(\n" + " #11 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [INNER_TYPE, INNER_TYPE, INNER_TYPE]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "one" + File.separator + "two" + File.separator + "three" + File.separator + "X.class", "one.two.three.X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test100g_pqtr() throws Exception { this.runConformTest( new String[] { "Foo.java", "class Foo {}\n", "Levels.java", "package one.two.three;\n" + "class Level1 { static class Level2 { class Level3 { class Level4 { class Level5<T> { } } } } }\n", "X.java", "package one.two.three;\n" + "class X {\n" + " one.two.three.Level1.Level2.@B(2) Level3.Level4.@B(3) Level5<String>[][] instance;\n" + "}\n", "B.java", "package one.two.three;\n" + "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @one.two.three.B(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE]\n" + " )\n" + " #10 @one.two.three.B(\n" + " #11 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE, INNER_TYPE, INNER_TYPE]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "one" + File.separator + "two" + File.separator + "three" + File.separator + "X.class", "one.two.three.X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test100h_pqtr() throws Exception { this.runConformTest( new String[] { "X.java", "class X {\n" + " Level1.Level2.@B(2) Level3.Level4.@B(3) Level5<String>[][] instance;\n" + "}\n", "Levels.java", "class Level1 { static class Level2 { class Level3 { class Level4 { class Level5<T> { } } } } }\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE]\n" + " )\n" + " #10 @B(\n" + " #11 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE, INNER_TYPE, INNER_TYPE]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test100i_pqtr() throws Exception { this.runConformTest( new String[] { "X.java", "class X {\n" + " Level1.Level2.Level3.Level4.Level5<@B(1) String>[][] instance;\n" + "}\n", "Levels.java", "class Level1 { static class Level2 { class Level3 { class Level4 { class Level5<T> { } } } } }\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE, INNER_TYPE, INNER_TYPE, TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test100j_pqtr() throws Exception { this.runConformTest( new String[] { "X.java", "class X {\n" + " Level1.Level2.Level3<@B(1) String>.Level4.Level5<@B(2) String>[][] instance;\n" + "}\n", "Levels.java", "class Level1 { static class Level2 { class Level3<Q> { class Level4 { class Level5<T> { } } } } }\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE, TYPE_ARGUMENT(0)]\n" + " )\n" + " #10 @B(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE, INNER_TYPE, INNER_TYPE, TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test100k_pqtr() throws Exception { this.runConformTest( new String[] { "X.java", "class X {\n" + " Level1.@B(5) Level2.Level3<@B(1) String>.Level4.Level5<@B(2) String>[][] instance;\n" + "}\n", "Levels.java", "class Level1 { static class Level2 { class Level3<Q> { class Level4 { class Level5<T> { } } } } }\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 5 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #10 @B(\n" + " #11 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE, TYPE_ARGUMENT(0)]\n" + " )\n" + " #10 @B(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE, INNER_TYPE, INNER_TYPE, TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test101a_qtr() throws Exception { // QTR (QualifiedTypeReference) this.runConformTest( new String[] { "X.java", "class X {\n" + " com.foo.@B(2) List field2;\n" + "}\n", "List.java", "package com.foo;\n"+ "public class List {}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @B(\n" + " #9 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test101b_qtr() throws Exception { // QTR (QualifiedTypeReference) this.runConformTest( new String[] { "X.java", "class X {\n" + " java.util.Map.@B(2) Entry field;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @B(\n" + " #9 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test101c_qtr() throws Exception { // QTR (QualifiedTypeReference) this.runConformTest( new String[] { "Runner.java", "public class Runner {}\n", "B.java", "package one.two.three;\n" + "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", "X.java", "package one.two.three;\n" + "class X {\n" + " one.two.three.Level1.Level2.@B(2) Level3.Level4.@B(3) Level5 instance;\n" + "}\n", "Level1.java", "package one.two.three;\n" + "public class Level1 { static class Level2 { class Level3 { class Level4 { class Level5 { } } } } }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @one.two.three.B(\n" + " #9 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [INNER_TYPE]\n" + " )\n" + " #8 @one.two.three.B(\n" + " #9 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [INNER_TYPE, INNER_TYPE, INNER_TYPE]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "one" + File.separator + "two" + File.separator + "three" + File.separator + "X.class", "one.two.three.X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test102a_str() throws Exception { // STR (SingleTypeReference) this.runConformTest( new String[] { "X.java", "class X {\n" + " @B(1) X field;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @B(\n" + " #9 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test102b_str() throws Exception { // STR (SingleTypeReference) this.runConformTest( new String[] { "X.java", "class X {\n" + " @B(1) int field;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @B(\n" + " #9 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test103a_atr() throws Exception { // ATR (ArrayTypeReference) this.runConformTest( new String[] { "X.java", "class X {\n" + " @B(1) X[] field;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @B(\n" + " #9 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test103b_atr() throws Exception { // ATR (ArrayTypeReference) this.runConformTest( new String[] { "X.java", "class X {\n" + " X @B(2)[] field;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @B(\n" + " #9 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test103c_atr() throws Exception { // ATR (ArrayTypeReference) this.runConformTest( new String[] { "X.java", "class X {\n" + " X []@B(3)[] field;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @B(\n" + " #9 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test103d_atr() throws Exception { // ATR (ArrayTypeReference) this.runConformTest( new String[] { "X.java", "class X {\n" + " X []@B(3)[][] field;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @B(\n" + " #9 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test103e_atr() throws Exception { // ATR (ArrayTypeReference) this.runConformTest( new String[] { "X.java", "class X {\n" + " @B(1) int []@B(3)[][] field;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @B(\n" + " #9 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, ARRAY]\n" + " )\n" + " #8 @B(\n" + " #9 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test104a_pstr() throws Exception { // PSTR (ParameterizedSingleTypeReference) this.runConformTest( new String[] { "X.java", "class X<T1,T2,T3> {\n" + " @B(1) X<@B(2) String, @B(3) Integer, @B(4) Boolean> field;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n" + " #10 @B(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(0)]\n" + " )\n" + " #10 @B(\n" + " #11 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(1)]\n" + " )\n" + " #10 @B(\n" + " #11 value=(int) 4 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(2)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test104b_pstr() throws Exception { // PSTR (ParameterizedSingleTypeReference) this.runConformTest( new String[] { "X.java", "class X<T1> {\n" + " @B(1) X<@B(2) String> @B(3)[] field;\n" + "}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n" + " #10 @B(\n" + " #11 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n" + " #10 @B(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test105a_aqtr() throws Exception { // AQTR (ArrayQualifiedTypeReference) this.runConformTest( new String[] { "Y.java", "class Y {}", "X.java", "package one.two.three;\n" + "class X<T1> {\n" + " one.two.three.@B(1) List[] field;\n" + "}\n", "List.java", "package one.two.three;\n" + "class List {}\n", "B.java", "package one.two.three;\n" + "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @one.two.three.B(\n" + " #9 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "one" + File.separator + "two" + File.separator + "three" + File.separator +"X.class", "one.two.three.X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test105b_aqtr() throws Exception { // AQTR (ArrayQualifiedTypeReference) this.runConformTest( new String[] { "Y.java", "class Y {}", "X.java", "package one.two.three;\n" + "class X<T1> {\n" + " one.two.three.@B(2) List @B(3)[]@B(4)[] field;\n" + "}\n", "List.java", "package one.two.three;\n" + "class List {}\n", "B.java", "package one.two.three;\n" + "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #8 @one.two.three.B(\n" + " #9 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #8 @one.two.three.B(\n" + " #9 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n" + " #8 @one.two.three.B(\n" + " #9 value=(int) 4 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "one" + File.separator + "two" + File.separator + "three" + File.separator +"X.class", "one.two.three.X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test106a_wtr() throws Exception { // WTR (WildcardTypeReference) this.runConformTest( new String[] { "X.java", "import java.util.List;\n" + "class X<T1> {\n" + " List<? extends @B(1) Number> field;\n" + "}\n", "List.java", "class List {}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(0), WILDCARD]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator +"X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test106b_wtr() throws Exception { // WTR (WildcardTypeReference) this.runConformTest( new String[] { "X.java", "import java.util.List;\n" + "class X<T1> {\n" + " List<? extends @B(1) Number[]> field;\n" + "}\n", "List.java", "class List {}\n", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B { int value() default -1; }\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #10 @B(\n" + " #11 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [TYPE_ARGUMENT(0), WILDCARD, ARRAY]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=409244, [1.8][compiler] Type annotations on redundant casts dropped. public void testAnnotatedRedundantCast() throws Exception { this.runConformTest( new String[] { "X.java", "class X {\n" + " String s = (@NonNull String) \"Hello\";\n" + "}\n", "NonNull.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface NonNull {}\n", }, ""); String expectedOutput = " // Method descriptor #8 ()V\n" + " // Stack: 2, Locals: 1\n" + " X();\n" + " 0 aload_0 [this]\n" + " 1 invokespecial java.lang.Object() [10]\n" + " 4 aload_0 [this]\n" + " 5 ldc <String \"Hello\"> [12]\n" + " 7 checkcast java.lang.String [14]\n" + " 10 putfield X.s : java.lang.String [16]\n" + " 13 return\n" + " Line numbers:\n" + " [pc: 0, line: 1]\n" + " [pc: 4, line: 2]\n" + " [pc: 13, line: 1]\n" + " Local variable table:\n" + " [pc: 0, pc: 14] local: this index: 0 type: X\n" + " RuntimeVisibleTypeAnnotations: \n" + " #23 @NonNull(\n" + " target type = 0x47 CAST\n" + " offset = 7\n" + " type argument index = 0\n" + " )\n" + "}"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=409244, [1.8][compiler] Type annotations on redundant casts dropped. public void testAnnotatedRedundantCast2() throws Exception { this.runConformTest( new String[] { "X.java", "class X {\n" + " String s = (String) \"Hello\";\n" + "}\n", "NonNull.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface NonNull {}\n", }, ""); String expectedOutput = " // Method descriptor #8 ()V\n" + " // Stack: 2, Locals: 1\n" + " X();\n" + " 0 aload_0 [this]\n" + " 1 invokespecial java.lang.Object() [10]\n" + " 4 aload_0 [this]\n" + " 5 ldc <String \"Hello\"> [12]\n" + " 7 putfield X.s : java.lang.String [14]\n" + " 10 return\n" + " Line numbers:\n" + " [pc: 0, line: 1]\n" + " [pc: 4, line: 2]\n" + " [pc: 10, line: 1]\n" + " Local variable table:\n" + " [pc: 0, pc: 11] local: this index: 0 type: X\n" + "}"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test055a_codeblocks_exceptionParameterNestedType() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " public static void main(String[] args) {\n" + " try {\n" + " foo();\n" + " } catch(@B(1) Outer.@B(2) MyException e) {\n" + " e.printStackTrace();\n" + " }\n" + " }\n" + " static void foo() throws Outer.MyException {}\n" + "}\n" + "class Outer {\n" + " class MyException extends Exception {\n" + " private static final long serialVersionUID = 1L;\n" + " }\n" + "}", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B {\n" + " int value() default 0;\n" + "}\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #30 @B(\n" + " #31 value=(int) 1 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " )\n" + " #30 @B(\n" + " #31 value=(int) 2 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " location = [INNER_TYPE]\n" + " )\n" + " \n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test055b_codeblocks_exceptionParameterMultiCatchNestedType() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " public static void main(String[] args) {\n" + " try {\n" + " foo();\n" + " } catch(@B(1) Outer.@B(2) MyException | @B(3) Outer2.@B(4) MyException2 e) {\n" + " e.printStackTrace();\n" + " }\n" + " }\n" + " static void foo() throws Outer.MyException, Outer2.MyException2 {}\n" + "}\n" + "class Outer {\n" + " class MyException extends Exception {\n" + " private static final long serialVersionUID = 1L;\n" + " }\n" + "}\n" + "class Outer2 {\n" + " class MyException2 extends Exception {\n" + " private static final long serialVersionUID = 1L;\n" + " }\n" + "}", "B.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface B {\n" + " int value() default 0;\n" + "}\n", }, ""); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #34 @B(\n" + " #35 value=(int) 1 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " )\n" + " #34 @B(\n" + " #35 value=(int) 2 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " location = [INNER_TYPE]\n" + " )\n" + " #34 @B(\n" + " #35 value=(int) 3 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 1\n" + " )\n" + " #34 @B(\n" + " #35 value=(int) 4 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 1\n" + " location = [INNER_TYPE]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test055c_codeblocks_exceptionParameterMultiCatch() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.Target;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "class Exc1 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "class Exc2 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "class Exc3 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "public class X {\n" + " public static void main(String[] args) {\n" + " try {\n" + " System.out.println(42);\n" + " } catch(Exc1 | @B(1) Exc2 | @B(2) Exc3 t) {\n" + " t.printStackTrace();\n" + " }\n" + " }\n" + "}", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface B {\n" + " int value() default 99;\n" + "}\n", }, "42"); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #45 @B(\n" + " #46 value=(int) 1 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 1\n" + " )\n" + " #45 @B(\n" + " #46 value=(int) 2 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 2\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test055d_codeblocks_exceptionParameterMultiCatch() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.Target;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "class Exc1 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "class Exc2 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "class Exc3 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "public class X {\n" + " public static void main(String[] args) {\n" + " try {\n" + " System.out.println(42);\n" + " } catch(@A(1) @B(2) Exc1 | Exc2 | @A(3) @B(4) Exc3 t) {\n" + " t.printStackTrace();\n" + " }\n" + " }\n" + "}", "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " int value() default 99;\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface B {\n" + " int value() default 99;\n" + "}\n", }, "42"); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #45 @A(\n" + " #46 value=(int) 1 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " )\n" + " #48 @B(\n" + " #46 value=(int) 2 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " )\n" + " #45 @A(\n" + " #46 value=(int) 3 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 2\n" + " )\n" + " #48 @B(\n" + " #46 value=(int) 4 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 2\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test055e_codeblocks_exceptionParameterMultiCatch() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.Target;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "class Exc1 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "class Exc2 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "class Exc3 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "public class X {\n" + " public static void main(String[] args) {\n" + " try {\n" + " System.out.println(42);\n" + " } catch(@A(1) @B(2) Exc1 | Exc2 | @A(3) @B(4) Exc3 t) {\n" + " t.printStackTrace();\n" + " }\n" + " }\n" + "}", "A.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface A {\n" + " int value() default 99;\n" + "}\n", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface B {\n" + " int value() default 99;\n" + "}\n", }, "42"); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #45 @A(\n" + " #46 value=(int) 1 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " )\n" + " #48 @B(\n" + " #46 value=(int) 2 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " )\n" + " #45 @A(\n" + " #46 value=(int) 3 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 2\n" + " )\n" + " #48 @B(\n" + " #46 value=(int) 4 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 2\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void test055f_codeblocks_exceptionParameterComplex() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.Target;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "class Exc1 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "class Exc2 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "class Exc3 extends RuntimeException {" + " private static final long serialVersionUID = 1L;\n" + "}\n"+ "public class X {\n" + " public static void main(String[] args) {\n" + " try {\n" + " System.out.println(42);\n" + " } catch(@B(1) Exc1 | Exc2 | @B(2) Exc3 t) {\n" + " t.printStackTrace();\n" + " }\n" + " try {\n" + " System.out.println(43);\n" + " } catch(@B(1) Exc1 t) {\n" + " t.printStackTrace();\n" + " }\n" + " try {\n" + " System.out.println(44);\n" + " } catch(@B(1) Exc1 | @B(2) Exc2 t) {\n" + " t.printStackTrace();\n" + " }\n" + " }\n" + "}", "B.java", "import java.lang.annotation.Target;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import java.lang.annotation.Retention;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface B {\n" + " int value() default 99;\n" + "}\n", }, "42\n43\n44"); String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + " #47 @B(\n" + " #48 value=(int) 1 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 0\n" + " )\n" + " #47 @B(\n" + " #48 value=(int) 2 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 2\n" + " )\n" + " #47 @B(\n" + " #48 value=(int) 1 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 3\n" + " )\n" + " #47 @B(\n" + " #48 value=(int) 1 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 4\n" + " )\n" + " #47 @B(\n" + " #48 value=(int) 2 (constant type)\n" + " target type = 0x42 EXCEPTION_PARAMETER\n" + " exception table index = 5\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void testBug415911() { runNegativeTest( new String[] { "X.java", "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Target;\n" + "\n" + "@Target(ElementType.TYPE_USE)\n" + "@interface Marker {\n" + "}\n" + "\n" + "public class X {\n" + " @Marker\n" + " foo(String s) {\n" + "\n" + " }\n" + "}\n" }, "----------\n" + "1. ERROR in X.java (at line 10)\n" + " foo(String s) {\n" + " ^^^^^^^^^^^^^\n" + "Return type for the method is missing\n" + "----------\n"); } public void testBug426616() throws Exception { this.runConformTest( new String[] { "X.java", "import java.util.*;\n"+ "import java.lang.annotation.*;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Retention(RUNTIME)\n" + "@Target(TYPE_USE)\n" + "@interface SizeHolder { Size[] value();}\n"+ "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@Repeatable(SizeHolder.class)\n"+ "@interface Size { int max(); }\n"+ "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface Nonnull {}\n"+ "\n"+ "public class X {\n" + " public static void main(String[]argv) {}\n"+ " public static String testArrays() {\n"+ " List<@Size(max = 41) CharSequence>[] @Size(max = 42) [] @Nonnull @Size(max = 43) [][] test = new @Size(max = 44) ArrayList @Size(max = 45) [10][][] @Size(max = 47) @Size(max = 48) [];\n"+ " return (@Size(max = 49) String) test[0][1][2][3].get(0);\n"+ " }\n"+ "}", }, ""); // Javac output // 0: Size(45): NEW, offset=0 // 1: SizeHolder([@Size(max=47),@Size(max=48)]): NEW, offset=0, location=[ARRAY, ARRAY, ARRAY] // 2: Size(44): NEW, offset=0, location=[ARRAY, ARRAY, ARRAY, ARRAY] // 3: Size(49): CAST, offset=6, type_index=0 // 4: Size(42): LOCAL_VARIABLE, {start_pc=6, length=19, index=0}, location=[ARRAY] // 5: NonNull: LOCAL_VARIABLE, {start_pc=6, length=19, index=0}, location=[ARRAY, ARRAY] // 6: Size(43): LOCAL_VARIABLE, {start_pc=6, length=19, index=0}, location=[ARRAY, ARRAY] // 7: Size(41): LOCAL_VARIABLE, {start_pc=6, length=19, index=0}, location=[ARRAY, ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0)] String expectedOutput = " RuntimeVisibleTypeAnnotations: \n" + // X Maps to javac entry (2): location OK, target type OK, offset different, our offset is 2 and not 0 " #33 @Size(\n" + " #34 max=(int) 44 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 2\n" + " location = [ARRAY, ARRAY, ARRAY, ARRAY]\n" + " )\n" + // X Maps to javac entry (0), location OK, target type OK, offset different, our offset is 2 and not 0 " #33 @Size(\n" + " #34 max=(int) 45 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 2\n" + " )\n" + // X Maps to javac entry (1), location OK, target type OK, offset different, our offset is 2 and not 0 " #37 @SizeHolder(\n" + " #38 value=[\n" + " annotation value =\n" + " #33 @Size(\n" + " #34 max=(int) 47 (constant type)\n" + " )\n" + " annotation value =\n" + " #33 @Size(\n" + " #34 max=(int) 48 (constant type)\n" + " )\n" + " ]\n" + " target type = 0x44 NEW\n" + " offset = 2\n" + " location = [ARRAY, ARRAY, ARRAY]\n" + " )\n" + // X Maps to javac entry (3), location OK, target type OK, offset different, our offset is 24 (not 6), type index OK " #33 @Size(\n" + " #34 max=(int) 49 (constant type)\n" + " target type = 0x47 CAST\n" + " offset = 24\n" + " type argument index = 0\n" + " )\n" + // Maps to javac entry (4), location OK, target type OK, lvar diff, slight position difference (we seem to have an extra CHECKCAST) " #33 @Size(\n" + " #34 max=(int) 42 (constant type)\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 6, pc: 28] index: 0\n" + " location = [ARRAY]\n" + " )\n" + // Maps to javac entry (5), location OK, taret type OK, lvar diff, slight position difference (we seem to have an extra CHECKCAST) " #43 @Nonnull(\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 6, pc: 28] index: 0\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + // Maps to javac entry (6), location OK, target type OK, slight position difference (we seem to have an extra CHECKCAST) " #33 @Size(\n" + " #34 max=(int) 43 (constant type)\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 6, pc: 28] index: 0\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + // Maps to javac entry (7), location OK, target type OK, slight position difference (we seem to have an extra CHECKCAST) " #33 @Size(\n" + " #34 max=(int) 41 (constant type)\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 6, pc: 28] index: 0\n" + " location = [ARRAY, ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0)]\n" + " )\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void testBug426616a() throws Exception { this.runConformTest( new String[] { "X.java", "import java.util.*;\n"+ "import java.lang.annotation.*;\n" + "import static java.lang.annotation.ElementType.*;\n" + "import static java.lang.annotation.RetentionPolicy.*;\n" + "@Retention(RUNTIME)\n" + "@Target(TYPE_USE)\n" + "@interface SizeHolder { Size[] value();}\n"+ "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@Repeatable(SizeHolder.class)\n"+ "@interface Size { int max(); }\n"+ "@Target(TYPE_USE)\n" + "@Retention(RUNTIME)\n" + "@interface Nonnull {}\n"+ "\n"+ "public class X {\n" + " List<@Size(max = 41) CharSequence>[] @Size(max = 42) [] @Nonnull @Size(max = 43) [][] test = new @Size(max = 44) ArrayList @Size(max = 45) [10][][] @Size(max = 47) @Size(max = 48) [];\n" + " public static void main(String[]argv) {}\n"+ "}", }, ""); String expectedOutput = " // Field descriptor #6 [[[[Ljava/util/List;\n" + " // Signature: [[[[Ljava/util/List<Ljava/lang/CharSequence;>;\n" + " java.util.List[][][][] test;\n" + " RuntimeVisibleTypeAnnotations: \n" + " #10 @Size(\n" + " #11 max=(int) 42 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n" + " #13 @Nonnull(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #10 @Size(\n" + " #11 max=(int) 43 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #10 @Size(\n" + " #11 max=(int) 41 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, ARRAY, ARRAY, TYPE_ARGUMENT(0)]\n" + " )\n" + " \n" + " // Method descriptor #17 ()V\n" + " // Stack: 2, Locals: 1\n" + " public X();\n" + " 0 aload_0 [this]\n" + " 1 invokespecial java.lang.Object() [19]\n" + " 4 aload_0 [this]\n" + " 5 bipush 10\n" + " 7 anewarray java.util.ArrayList[][][] [21]\n" + " 10 putfield X.test : java.util.List[][][][] [23]\n" + " 13 return\n" + " Line numbers:\n" + " [pc: 0, line: 16]\n" + " [pc: 4, line: 17]\n" + " [pc: 13, line: 16]\n" + " Local variable table:\n" + " [pc: 0, pc: 14] local: this index: 0 type: X\n" + " RuntimeVisibleTypeAnnotations: \n" + " #10 @Size(\n" + " #11 max=(int) 44 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 7\n" + " location = [ARRAY, ARRAY, ARRAY, ARRAY]\n" + " )\n" + " #10 @Size(\n" + " #11 max=(int) 45 (constant type)\n" + " target type = 0x44 NEW\n" + " offset = 7\n" + " )\n" + " #31 @SizeHolder(\n" + " #32 value=[\n" + " annotation value =\n" + " #10 @Size(\n" + " #11 max=(int) 47 (constant type)\n" + " )\n" + " annotation value =\n" + " #10 @Size(\n" + " #11 max=(int) 48 (constant type)\n" + " )\n" + " ]\n" + " target type = 0x44 NEW\n" + " offset = 7\n" + " location = [ARRAY, ARRAY, ARRAY]\n" + " )\n" + " \n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void testTypeVariable() { runNegativeTest( new String[] { "X.java", "public class X<@Missing T> {\n" + "}\n" }, "----------\n" + "1. ERROR in X.java (at line 1)\n" + " public class X<@Missing T> {\n" + " ^^^^^^^\n" + "Missing cannot be resolved to a type\n" + "----------\n"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=417660, [1.8][compiler] Incorrect parsing of Annotations with array dimensions in arguments public void test417660() { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.Documented;\n" + "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Retention;\n" + "import java.lang.annotation.RetentionPolicy;\n" + "import java.lang.annotation.Target;\n" + "public class X {\n" + " int bar(int [] @TakeType(int[].class)[] x) { \n" + " return x[0][0]; \n" + " } \n" + " public static void main(String[] args) {\n" + " System.out.println(new X().bar(new int [][] { { 1234 }}));\n" + " }\n" + "}\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@Documented\n" + "@interface TakeType {\n" + " Class value() default int[].class;\n" + "}\n" }, "1234"); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=417660, [1.8][compiler] Incorrect parsing of Annotations with array dimensions in arguments public void test417660b() { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.Documented;\n" + "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Retention;\n" + "import java.lang.annotation.RetentionPolicy;\n" + "import java.lang.annotation.Target;\n" + "public class X {\n" + " int bar(int [][] @TakeType(int[].class)[][] x @TakeType(int[].class)[]) { \n" + " return x[0][0][0][0][0]; \n" + " } \n" + " public static void main(String[] args) {\n" + " System.out.println(new X().bar(new int [][][][][] { { { { { 1234 } } } } }));\n" + " }\n" + "}\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@Documented\n" + "@interface TakeType {\n" + " Class value() default int[].class;\n" + "}\n" }, "1234"); } public void testAnnotatedExtendedDimensions() throws Exception { this.runConformTest( new String[] { "X.java", "public class X {\n" + " @NonNull String @Nullable [] f @NonNull [] = null;\n" + " static @NonNull String @Nullable [] foo(@NonNull String @Nullable [] p @NonNull []) @NonNull [] {\n" + " p = null;\n" + " @NonNull String @Nullable [] l @NonNull [] = null;\n" + " return p;\n" + " }\n" + "}\n", "NonNull.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface NonNull {}\n", "Nullable.java", "import java.lang.annotation.*;\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@interface Nullable {}\n", }, ""); String expectedOutput = " // Field descriptor #6 [[Ljava/lang/String;\n" + " java.lang.String[][] f;\n" + " RuntimeVisibleTypeAnnotations: \n" + " #8 @NonNull(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #9 @Nullable(\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n" + " #8 @NonNull(\n" + " target type = 0x13 FIELD\n" + " )\n" + " \n" + " // Method descriptor #11 ()V\n" + " // Stack: 2, Locals: 1\n" + " public X();\n" + " 0 aload_0 [this]\n" + " 1 invokespecial java.lang.Object() [13]\n" + " 4 aload_0 [this]\n" + " 5 aconst_null\n" + " 6 putfield X.f : java.lang.String[][] [15]\n" + " 9 return\n" + " Line numbers:\n" + " [pc: 0, line: 1]\n" + " [pc: 4, line: 2]\n" + " [pc: 9, line: 1]\n" + " Local variable table:\n" + " [pc: 0, pc: 10] local: this index: 0 type: X\n" + " \n" + " // Method descriptor #22 ([[Ljava/lang/String;)[[Ljava/lang/String;\n" + " // Stack: 1, Locals: 2\n" + " static java.lang.String[][] foo(java.lang.String[][] p);\n" + " 0 aconst_null\n" + " 1 astore_0 [p]\n" + " 2 aconst_null\n" + " 3 astore_1 [l]\n" + " 4 aload_0 [p]\n" + " 5 areturn\n" + " Line numbers:\n" + " [pc: 0, line: 4]\n" + " [pc: 2, line: 5]\n" + " [pc: 4, line: 6]\n" + " Local variable table:\n" + " [pc: 0, pc: 6] local: p index: 0 type: java.lang.String[][]\n" + " [pc: 4, pc: 6] local: l index: 1 type: java.lang.String[][]\n" + " RuntimeVisibleTypeAnnotations: \n" + " #8 @NonNull(\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 4, pc: 6] index: 1\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #9 @Nullable(\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 4, pc: 6] index: 1\n" + " location = [ARRAY]\n" + " )\n" + " #8 @NonNull(\n" + " target type = 0x40 LOCAL_VARIABLE\n" + " local variable entries:\n" + " [pc: 4, pc: 6] index: 1\n" + " )\n" + " RuntimeVisibleTypeAnnotations: \n" + " #8 @NonNull(\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #9 @Nullable(\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " location = [ARRAY]\n" + " )\n" + " #8 @NonNull(\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " )\n" + " #8 @NonNull(\n" + " target type = 0x14 METHOD_RETURN\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #9 @Nullable(\n" + " target type = 0x14 METHOD_RETURN\n" + " location = [ARRAY]\n" + " )\n" + " #8 @NonNull(\n" + " target type = 0x14 METHOD_RETURN\n" + " )\n" + "}"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=418347, [1.8][compiler] Type annotations dropped during code generation. public void testPQTRArray() throws Exception { this.runConformTest( new String[] { "Outer.java", "public class Outer<K> {\n" + " class Inner<P> {\n" + " }\n" + " public @T(1) Outer<@T(2) String>.@T(3) Inner<@T(4) Integer> @T(5) [] omi @T(6) [];\n" + "}\n" + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface T {\n" + " int value();\n" + "}\n", }, ""); String expectedOutput = " public Outer$Inner[][] omi;\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #10 @T(\n" + " #11 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE]\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 5 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 6 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, TYPE_ARGUMENT(0)]\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 4 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE, TYPE_ARGUMENT(0)]\n" + " )\n" + " \n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "Outer.class", "Outer", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=418347, [1.8][compiler] Type annotations dropped during code generation. public void testPQTRArray2() throws Exception { this.runConformTest( new String[] { "Outer.java", "public class Outer<K1, K2> {\n" + " class Inner<P1, P2> {\n" + " }\n" + " public @T(1) Outer<@T(2) String, @T(3) Inner>.@T(4) Inner<@T(5) Integer, @T(6) Outer.@T(7) Inner> @T(7) [] omi @T(8) [];\n" + "}\n" + "@java.lang.annotation.Target (java.lang.annotation.ElementType.TYPE_USE)\n" + "@interface T {\n" + " int value();\n" + "}\n", }, ""); String expectedOutput = " // Field descriptor #6 [[LOuter$Inner;\n" + " // Signature: [[LOuter<Ljava/lang/String;LOuter$Inner;>.Inner<Ljava/lang/Integer;LOuter$Inner;>;\n" + " public Outer$Inner[][] omi;\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #10 @T(\n" + " #11 value=(int) 1 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY]\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 4 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE]\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 7 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY]\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 8 (constant type)\n" + " target type = 0x13 FIELD\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 2 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, TYPE_ARGUMENT(0)]\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 3 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, TYPE_ARGUMENT(1), INNER_TYPE]\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 5 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE, TYPE_ARGUMENT(0)]\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 6 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE, TYPE_ARGUMENT(1)]\n" + " )\n" + " #10 @T(\n" + " #11 value=(int) 7 (constant type)\n" + " target type = 0x13 FIELD\n" + " location = [ARRAY, ARRAY, INNER_TYPE, TYPE_ARGUMENT(1), INNER_TYPE]\n" + " )\n" + " \n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "Outer.class", "Outer", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=418347, [1.8][compiler] Type annotations dropped during code generation. public void testConstructorResult() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Target;\n" + "@Target(ElementType.TYPE_USE)\n" + "@interface T {\n" + "}\n" + "public class X {\n" + " @T X() {}\n" + " class Y {\n" + " @T Y () {\n" + " }\n" + " }\n" + "}\n", }, ""); String expectedOutput = " // Method descriptor #6 ()V\n" + " // Stack: 1, Locals: 1\n" + " X();\n" + " 0 aload_0 [this]\n" + " 1 invokespecial java.lang.Object() [8]\n" + " 4 return\n" + " Line numbers:\n" + " [pc: 0, line: 7]\n" + " Local variable table:\n" + " [pc: 0, pc: 5] local: this index: 0 type: X\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #15 @T(\n" + " target type = 0x14 METHOD_RETURN\n" + " )\n" + "\n"; String expectedOutForY = " // Method descriptor #8 (LX;)V\n" + " // Stack: 2, Locals: 2\n" + " X$Y(X arg0);\n" + " 0 aload_0 [this]\n" + " 1 aload_1 [arg0]\n" + " 2 putfield X$Y.this$0 : X [10]\n" + " 5 aload_0 [this]\n" + " 6 invokespecial java.lang.Object() [12]\n" + " 9 return\n" + " Line numbers:\n" + " [pc: 0, line: 9]\n" + " [pc: 9, line: 10]\n" + " Local variable table:\n" + " [pc: 0, pc: 10] local: this index: 0 type: X.Y\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #20 @T(\n" + " target type = 0x14 METHOD_RETURN\n" + " location = [INNER_TYPE]\n" + " )\n" + "\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X$Y.class", "Y", expectedOutForY, ClassFileBytesDisassembler.SYSTEM); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=418347, [1.8][compiler] Type annotations dropped during code generation. public void test418347() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.*;\n" + "import static java.lang.annotation.ElementType.*;\n" + "@Target({TYPE_USE}) @interface P { }\n" + "@Target({TYPE_USE}) @interface O { }\n" + "@Target({TYPE_USE}) @interface I { }\n" + "public abstract class X<T> {\n" + " class Y<Q> {\n" + " }\n" + " void foo(@P Y<P> p) {}\n" + "}\n", }, ""); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #24 @P(\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " location = [INNER_TYPE]\n" + " )\n" + "\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=418347, [1.8][compiler] Type annotations dropped during code generation. public void test418347a() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.*;\n" + "import static java.lang.annotation.ElementType.*;\n" + "@Target({TYPE_USE}) @interface P { }\n" + "@Target({TYPE_USE}) @interface O { }\n" + "@Target({TYPE_USE}) @interface I { }\n" + "public abstract class X {\n" + " class Y {\n" + " class Z {}\n" + " }\n" + " void foo(@P X.@O Y.@I Z[] p) {}\n" + "}\n", }, ""); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #19 @P(\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " location = [ARRAY]\n" + " )\n" + " #20 @O(\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " location = [ARRAY, INNER_TYPE]\n" + " )\n" + " #21 @I(\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " location = [ARRAY, INNER_TYPE, INNER_TYPE]\n" + " )\n" + "\n"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=418347, [1.8][compiler] Type annotations dropped during code generation. public void test418347b() throws Exception { this.runConformTest( new String[] { "X.java", "public abstract class X {\n" + " java.util.List [][] l = new java.util.ArrayList @pkg.NonNull [0] @pkg.NonNull[]; \n" + "}\n", "pkg/NonNull.java", "package pkg;\n" + "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Target;\n" + "@Target(ElementType.TYPE_USE)\n" + "public @interface NonNull {\n" + "}\n" }, ""); String expectedOutput = " RuntimeInvisibleTypeAnnotations: \n" + " #21 @pkg.NonNull(\n" + " target type = 0x44 NEW\n" + " offset = 6\n" + " )\n" + " #21 @pkg.NonNull(\n" + " target type = 0x44 NEW\n" + " offset = 6\n" + " location = [ARRAY]\n" + " )\n" + "}"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=419331, [1.8][compiler] Weird error on forward reference to type annotations from type parameter declarations public void testForwardReference() { this.runNegativeTest( false /* skipJavac */, JavacTestOptions.Excuse.JavacHasWarningsEclipseNotConfigured, new String[] { "T.java", "import java.lang.annotation.Annotation;\n" + "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Target;\n" + "\n" + "@R(TC.class)\n" + "@Target(ElementType.TYPE_PARAMETER)\n" + "@interface T {\n" + "}\n" + "\n" + "interface I<@T K> {\n" + "}\n" + "\n" + "@Deprecated\n" + "@interface TC {\n" + "\n" + "}\n" + "\n" + "@Target(ElementType.ANNOTATION_TYPE)\n" + "@interface R {\n" + " Class<? extends Annotation> value();\n" + "}\n", }, ""); } public void testHybridTargets() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Target;\n" + "@Target({ElementType.TYPE_USE, ElementType.PACKAGE})\n" + "@interface T {\n" + "}\n" + "@T\n" + "public class X {\n" + " @T\n" + " X() {}\n" + " @T String x;\n" + " @T \n" + " int foo(@T int p) { \n" + " @T int l;\n" + " return 0;\n" + " }\n" + "}\n", }, ""); String expectedOutput = " // Field descriptor #6 Ljava/lang/String;\n" + " java.lang.String x;\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #8 @T(\n" + " target type = 0x13 FIELD\n" + " )\n" + " \n" + " // Method descriptor #10 ()V\n" + " // Stack: 1, Locals: 1\n" + " X();\n" + " 0 aload_0 [this]\n" + " 1 invokespecial java.lang.Object() [12]\n" + " 4 return\n" + " Line numbers:\n" + " [pc: 0, line: 9]\n" + " Local variable table:\n" + " [pc: 0, pc: 5] local: this index: 0 type: X\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #8 @T(\n" + " target type = 0x14 METHOD_RETURN\n" + " )\n" + " \n" + " // Method descriptor #19 (I)I\n" + " // Stack: 1, Locals: 2\n" + " int foo(int p);\n" + " 0 iconst_0\n" + " 1 ireturn\n" + " Line numbers:\n" + " [pc: 0, line: 14]\n" + " Local variable table:\n" + " [pc: 0, pc: 2] local: this index: 0 type: X\n" + " [pc: 0, pc: 2] local: p index: 1 type: int\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #8 @T(\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " )\n" + " #8 @T(\n" + " target type = 0x14 METHOD_RETURN\n" + " )\n" + "\n" + " RuntimeInvisibleAnnotations: \n" + " #8 @T(\n" + " )\n" + "}"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void testHybridTargets2() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.Target;\n" + "import java.lang.annotation.ElementType;\n" + "@Target({ ElementType.TYPE_USE, ElementType.METHOD })\n" + "@interface SillyAnnotation { }\n" + "public class X {\n" + " @SillyAnnotation\n" + " X(@SillyAnnotation int x) {\n" + " }\n" + " @SillyAnnotation\n" + " void foo(@SillyAnnotation int x) {\n" + " }\n" + " @SillyAnnotation\n" + " String goo(@SillyAnnotation int x) {\n" + " return null;\n" + " }\n" + " @SillyAnnotation\n" + " X field;\n" + "}\n" }, ""); String expectedOutput = " // Field descriptor #6 LX;\n" + " X field;\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #8 @SillyAnnotation(\n" + " target type = 0x13 FIELD\n" + " )\n" + " \n" + " // Method descriptor #10 (I)V\n" + " // Stack: 1, Locals: 2\n" + " X(int x);\n" + " 0 aload_0 [this]\n" + " 1 invokespecial java.lang.Object() [12]\n" + " 4 return\n" + " Line numbers:\n" + " [pc: 0, line: 7]\n" + " [pc: 4, line: 8]\n" + " Local variable table:\n" + " [pc: 0, pc: 5] local: this index: 0 type: X\n" + " [pc: 0, pc: 5] local: x index: 1 type: int\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #8 @SillyAnnotation(\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " )\n" + " #8 @SillyAnnotation(\n" + " target type = 0x14 METHOD_RETURN\n" + " )\n" + " \n" + " // Method descriptor #10 (I)V\n" + " // Stack: 0, Locals: 2\n" + " void foo(int x);\n" + " 0 return\n" + " Line numbers:\n" + " [pc: 0, line: 11]\n" + " Local variable table:\n" + " [pc: 0, pc: 1] local: this index: 0 type: X\n" + " [pc: 0, pc: 1] local: x index: 1 type: int\n" + " RuntimeInvisibleAnnotations: \n" + " #8 @SillyAnnotation(\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #8 @SillyAnnotation(\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " )\n" + " \n" + " // Method descriptor #23 (I)Ljava/lang/String;\n" + " // Stack: 1, Locals: 2\n" + " java.lang.String goo(int x);\n" + " 0 aconst_null\n" + " 1 areturn\n" + " Line numbers:\n" + " [pc: 0, line: 14]\n" + " Local variable table:\n" + " [pc: 0, pc: 2] local: this index: 0 type: X\n" + " [pc: 0, pc: 2] local: x index: 1 type: int\n" + " RuntimeInvisibleAnnotations: \n" + " #8 @SillyAnnotation(\n" + " )\n" + " RuntimeInvisibleTypeAnnotations: \n" + " #8 @SillyAnnotation(\n" + " target type = 0x16 METHOD_FORMAL_PARAMETER\n" + " method parameter index = 0\n" + " )\n" + " #8 @SillyAnnotation(\n" + " target type = 0x14 METHOD_RETURN\n" + " )\n" + "}"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } public void testDeprecated() throws Exception { this.runConformTest( new String[] { "X.java", "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Target;\n" + "@Deprecated\n" + "@Target(ElementType.TYPE_USE)\n" + "@interface X {\n" + " int value() default 0;\n" + "}\n" }, ""); String expectedOutput = "// Compiled from X.java (version 1.8 : 52.0, no super bit, deprecated)\n" + "abstract @interface X extends java.lang.annotation.Annotation {\n" + " Constant pool:\n" + " constant #1 class: #2 X\n" + " constant #2 utf8: \"X\"\n" + " constant #3 class: #4 java/lang/Object\n" + " constant #4 utf8: \"java/lang/Object\"\n" + " constant #5 class: #6 java/lang/annotation/Annotation\n" + " constant #6 utf8: \"java/lang/annotation/Annotation\"\n" + " constant #7 utf8: \"value\"\n" + " constant #8 utf8: \"()I\"\n" + " constant #9 utf8: \"AnnotationDefault\"\n" + " constant #10 integer: 0\n" + " constant #11 utf8: \"SourceFile\"\n" + " constant #12 utf8: \"X.java\"\n" + " constant #13 utf8: \"Deprecated\"\n" + " constant #14 utf8: \"RuntimeVisibleAnnotations\"\n" + " constant #15 utf8: \"Ljava/lang/Deprecated;\"\n" + " constant #16 utf8: \"Ljava/lang/annotation/Target;\"\n" + " constant #17 utf8: \"Ljava/lang/annotation/ElementType;\"\n" + " constant #18 utf8: \"TYPE_USE\"\n" + " \n" + " // Method descriptor #8 ()I\n" + " public abstract int value();\n" + " Annotation Default: \n" + " (int) 0 (constant type)\n" + "\n" + " RuntimeVisibleAnnotations: \n" + " #15 @java.lang.Deprecated(\n" + " )\n" + " #16 @java.lang.annotation.Target(\n" + " #7 value=[\n" + " java.lang.annotation.ElementType.TYPE_USE(enum type #17.#18)\n" + " ]\n" + " )\n" + "}"; checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=421148, [1.8][compiler] Verify error with annotated casts and unused locals. public void test421148() { Map customOptions = getCompilerOptions(); customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT); runConformTest( new String[] { "X.java", "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Target;\n" + "@Target(ElementType.TYPE_USE) @interface T {}\n" + "public class X {\n" + " public static void main(String argv[]) {\n" + " Object o = (@T Object) new Object(); \n" + " System.out.println(\"OK\");\n" + " }\n" + "}\n" }, "OK", customOptions); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=421620, [1.8][compiler] wrong compile error with TYPE_USE annotation on exception public void test421620() { Map customOptions = getCompilerOptions(); customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT); runConformTest( new String[] { "X.java", "import java.lang.annotation.Documented;\n" + "import java.lang.annotation.Retention;\n" + "import java.lang.annotation.Target;\n" + "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.RetentionPolicy;\n" + "class E1 extends Exception {\n" + " private static final long serialVersionUID = 1L;\n" + "}\n" + "\n" + "@Target(ElementType.TYPE_USE)\n" + "@Retention(RetentionPolicy.RUNTIME)\n" + "@Documented\n" + "@interface NonCritical { }\n" + "public class X {\n" + " @NonCritical E1 e1; // looks like this field's type binding is reused\n" + "//wrong error:\n" + "//Cannot use the parameterized type E1 either in catch block or throws clause\n" + " void f1 (int a) throws /*@NonCritical*/ E1 {\n" + " throw new E1();\n" + " }\n" + " void foo() {\n" + " try {\n" + " f1(0);\n" + "//wrong error: Unreachable catch block for E1.\n" + "// This exception is never thrown from the try statement body\n" + " } catch (@NonCritical final RuntimeException | @NonCritical E1 ex) {\n" + " System.out.println(ex);\n" + " }\n" + " }\n" + " public static void main(String[] args) {\n" + " System.out.println(\"OK\");\n" + " }\n" + "}\n" }, "OK", customOptions); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=425599, [1.8][compiler] ISE when trying to compile qualified and annotated class instance creation public void _test425599() { Map customOptions = getCompilerOptions(); customOptions.put(CompilerOptions.OPTION_Store_Annotations, CompilerOptions.ENABLED); runConformTest( new String[] { "X.java", "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Target;\n" + "public class X {\n" + " Object ax = new @A Outer().new Middle<String>();\n" + " public static void main(String args[]) {\n" + " System.out.println(\"OK\");\n" + " }\n" + "}\n" + "@Target(ElementType.TYPE_USE) @interface A {}\n" + "class Outer {\n" + " class Middle<E> {\n" + " class Inner<I> {}\n" + " @A Middle<Object>.@A Inner<Character> ax = new pack.@A Outer().new @A Middle<@A Object>().new @A Inner<@A Character>(null);\n" + " }\n" + "}\n" }, "OK", customOptions); } public void testBug485386() { runConformTest( new String[] { "Test.java", "import java.lang.annotation.*;\n" + "import java.lang.reflect.*;\n" + "\n" + "@Retention(value = RetentionPolicy.RUNTIME)\n" + "@java.lang.annotation.Target(ElementType.TYPE_USE)\n" + "@interface TestAnn1 {\n" + " String value() default \"1\";\n" + "}\n" + "\n" + "public class Test {\n" + "\n" + " class Inner {\n" + " public @TestAnn1() Inner() {\n" + " System.out.println(\"New\");\n" + " }\n" + " }\n" + "\n" + " public void test() throws SecurityException, NoSuchMethodException {\n" + " Executable f = Test.Inner.class.getDeclaredConstructor(Test.class);\n" + " AnnotatedType ae = f.getAnnotatedReturnType();\n" + " Object o = ae.getAnnotation(TestAnn1.class);\n" + " System.out.println(o);\n" + " }\n" + " \n" + " public static void main(String... args) throws Exception {\n" + " new Test().test();\n" + " }\n" + "}\n" }, "@TestAnn1(value=1)"); } public void testBug492322readFromClass() { runConformTest( new String[] { "test1/Base.java", "package test1;\n" + "\n" + "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Target;\n" + "\n" + "@Target(ElementType.TYPE_USE) @interface A2 {}\n" + "@Target(ElementType.TYPE_USE) @interface A3 {}\n" + "@Target(ElementType.TYPE_USE) @interface A4 {}\n" + "@Target(ElementType.TYPE_USE) @interface A5 {}\n" + "@Target(ElementType.TYPE_USE) @interface A6 {}\n" + "@Target(ElementType.TYPE_USE) @interface A7 {}\n" + "@Target(ElementType.TYPE_USE) @interface A8 {}\n" + "@Target(ElementType.TYPE_USE) @interface B1 {}\n" + "@Target(ElementType.TYPE_USE) @interface B2 {}\n" + "@Target(ElementType.TYPE_USE) @interface B3 {}\n" + "@Target(ElementType.TYPE_USE) @interface C1 {}\n" + "@Target(ElementType.TYPE_USE) @interface C2 {}\n" + "\n" + "public abstract class Base {\n" + " static public class Static {\n" + " public class Middle1 {\n" + " public class Middle2<M> {\n" + " public class Middle3 {\n" + " public class GenericInner<T> {\n" + " }\n" + " }\n" + " }\n" + " }\n" + " }\n" + "\n" + " public Object method1(Base.@A2 Static.@A3 Middle1.@A4 Middle2<Object>.@A5 Middle3.@A6 GenericInner<String> nullable) {\n" + " return new Object();\n" + " }\n" + " public Object method2(Base.@A2 Static.@A3 Middle1.@A4 Middle2<@B1 Object>.@A5 Middle3.@A6 GenericInner<@B2 String> @A7 [] @A8 [] nullable) {\n" + " return new Object();\n" + " }\n" + " public Object method3(Base.@A2 Static.@A3 Middle1.@A4 Middle2<@B1 Class<@C1 Object @C2 []> @B2 []>.@A5 Middle3.@A6 GenericInner<@B3 String> @A7 [] @A8 [] nullable) {\n" + " return new Object();\n" + " }\n" + "}\n" + "", } ); // get compiled type via binarytypebinding Requestor requestor = new Requestor(false, null /*no custom requestor*/, false, /* show category */ false /* show warning token*/); Map customOptions = getCompilerOptions(); customOptions.put(CompilerOptions.OPTION_Store_Annotations, CompilerOptions.ENABLED); Compiler compiler = new Compiler(getNameEnvironment(new String[0], null), getErrorHandlingPolicy(), new CompilerOptions(customOptions), requestor, getProblemFactory()); char [][] compoundName = new char [][] { "test1".toCharArray(), "Base".toCharArray()}; ReferenceBinding type = compiler.lookupEnvironment.askForType(compoundName); assertNotNull(type); MethodBinding[] methods1 = type.getMethods("method1".toCharArray()); assertEquals("Base.@A2 Static.@A3 Middle1.@A4 Middle2<Object>.@A5 Middle3.@A6 GenericInner<String>", new String(methods1[0].parameters[0].annotatedDebugName())); MethodBinding[] methods2 = type.getMethods("method2".toCharArray()); assertEquals("Base.@A2 Static.@A3 Middle1.@A4 Middle2<@B1 Object>.@A5 Middle3.@A6 GenericInner<@B2 String> @A7 [] @A8 []", new String(methods2[0].parameters[0].annotatedDebugName())); MethodBinding[] methods3 = type.getMethods("method3".toCharArray()); assertEquals("Base.@A2 Static.@A3 Middle1.@A4 Middle2<@B1 Class<@C1 Object @C2 []> @B2 []>.@A5 Middle3.@A6 GenericInner<@B3 String> @A7 [] @A8 []", new String(methods3[0].parameters[0].annotatedDebugName())); } public void testBug492322readFromClassWithGenericBase() { runConformTest( new String[] { "test1/Base.java", "package test1;\n" + "\n" + "import java.lang.annotation.ElementType;\n" + "import java.lang.annotation.Target;\n" + "\n" + "@Target(ElementType.TYPE_USE) @interface A2 {}\n" + "@Target(ElementType.TYPE_USE) @interface A3 {}\n" + "@Target(ElementType.TYPE_USE) @interface A4 {}\n" + "@Target(ElementType.TYPE_USE) @interface A5 {}\n" + "@Target(ElementType.TYPE_USE) @interface A6 {}\n" + "@Target(ElementType.TYPE_USE) @interface A7 {}\n" + "@Target(ElementType.TYPE_USE) @interface A8 {}\n" + "@Target(ElementType.TYPE_USE) @interface B1 {}\n" + "@Target(ElementType.TYPE_USE) @interface B2 {}\n" + "@Target(ElementType.TYPE_USE) @interface B3 {}\n" + "@Target(ElementType.TYPE_USE) @interface C1 {}\n" + "@Target(ElementType.TYPE_USE) @interface C2 {}\n" + "\n" + "public abstract class Base<B> {\n" + " static public class Static {\n" + " public class Middle1 {\n" + " public class Middle2<M> {\n" + " public class Middle3 {\n" + " public class GenericInner<T> {\n" + " }\n" + " }\n" + " }\n" + " }\n" + " }\n" + "\n" + " public Object method1(Base.@A2 Static.@A3 Middle1.@A4 Middle2<Object>.@A5 Middle3.@A6 GenericInner<String> nullable) {\n" + " return new Object();\n" + " }\n" + " public Object method2(Base.@A2 Static.@A3 Middle1.@A4 Middle2<@B1 Object>.@A5 Middle3.@A6 GenericInner<@B2 String> @A7 [] @A8 [] nullable) {\n" + " return new Object();\n" + " }\n" + " public Object method3(Base.@A2 Static.@A3 Middle1.@A4 Middle2<@B1 Class<@C1 Object @C2 []> @B2 []>.@A5 Middle3.@A6 GenericInner<@B3 String> @A7 [] @A8 [] nullable) {\n" + " return new Object();\n" + " }\n" + "}\n" + "", } ); // get compiled type via binarytypebinding Requestor requestor = new Requestor(false, null /*no custom requestor*/, false, /* show category */ false /* show warning token*/); Map customOptions = getCompilerOptions(); customOptions.put(CompilerOptions.OPTION_Store_Annotations, CompilerOptions.ENABLED); Compiler compiler = new Compiler(getNameEnvironment(new String[0], null), getErrorHandlingPolicy(), new CompilerOptions(customOptions), requestor, getProblemFactory()); char [][] compoundName = new char [][] { "test1".toCharArray(), "Base".toCharArray()}; ReferenceBinding type = compiler.lookupEnvironment.askForType(compoundName); assertNotNull(type); MethodBinding[] methods1 = type.getMethods("method1".toCharArray()); assertEquals("Base.@A2 Static.@A3 Middle1.@A4 Middle2<Object>.@A5 Middle3.@A6 GenericInner<String>", new String(methods1[0].parameters[0].annotatedDebugName())); MethodBinding[] methods2 = type.getMethods("method2".toCharArray()); assertEquals("Base.@A2 Static.@A3 Middle1.@A4 Middle2<@B1 Object>.@A5 Middle3.@A6 GenericInner<@B2 String> @A7 [] @A8 []", new String(methods2[0].parameters[0].annotatedDebugName())); MethodBinding[] methods3 = type.getMethods("method3".toCharArray()); assertEquals("Base.@A2 Static.@A3 Middle1.@A4 Middle2<@B1 Class<@C1 Object @C2 []> @B2 []>.@A5 Middle3.@A6 GenericInner<@B3 String> @A7 [] @A8 []", new String(methods3[0].parameters[0].annotatedDebugName())); } public void testBug492322WithOldBinary() { // bug492322-compiled-with-4.6.jar contains classes compiled with eclipse 4.6: /*- package test1; import java.lang.annotation.ElementType; import java.lang.annotation.Target; @Target(ElementType.TYPE_USE) @interface A2 {} @Target(ElementType.TYPE_USE) @interface A3 {} @Target(ElementType.TYPE_USE) @interface A4 {} @Target(ElementType.TYPE_USE) @interface A5 {} @Target(ElementType.TYPE_USE) @interface A6 {} @Target(ElementType.TYPE_USE) @interface A7 {} @Target(ElementType.TYPE_USE) @interface A8 {} @Target(ElementType.TYPE_USE) @interface B1 {} @Target(ElementType.TYPE_USE) @interface B2 {} @Target(ElementType.TYPE_USE) @interface B3 {} @Target(ElementType.TYPE_USE) @interface B4 {} @Target(ElementType.TYPE_USE) @interface C1 {} @Target(ElementType.TYPE_USE) @interface C2 {} public abstract class Base<B> { static public class Static { public static class Static2<X> { public class Middle1 { public class Middle2<M> { public class Middle3 { public class GenericInner<T> { } } } } } } public Object method1(Static.@A2 Static2<Exception>.@A3 Middle1.@A4 Middle2<Object>.@A5 Middle3.@A6 GenericInner<String> nullable) { return new Object(); } public Object method2(Static.@A2 Static2<@B1 Exception>.@A3 Middle1.@A4 Middle2<@B2 Object>.@A5 Middle3.@A6 GenericInner<@B3 String> @A7 [] @A8 [] nullable) { return new Object(); } public Object method3(Static.@A2 Static2<@B1 Exception>.@A3 Middle1.@A4 Middle2<@B2 Class<@C1 Object @C2 []> @B3 []>.@A5 Middle3.@A6 GenericInner<@B4 String> @A7 [] @A8 [] nullable) { return new Object(); } } */ // get compiled type via binarytypebinding Requestor requestor = new Requestor(false, null /*no custom requestor*/, false, /* show category */ false /* show warning token*/); Map customOptions = getCompilerOptions(); customOptions.put(CompilerOptions.OPTION_Store_Annotations, CompilerOptions.ENABLED); String[] defaultClassPaths = getDefaultClassPaths(); String jarpath = this.getCompilerTestsPluginDirectoryPath() + File.separator + "workspace" + File.separator + "bug492322-compiled-with-4.6.jar"; String[] paths = new String[defaultClassPaths.length + 1]; System.arraycopy(defaultClassPaths, 0, paths, 0, defaultClassPaths.length); paths[defaultClassPaths.length] = jarpath; Compiler compiler = new Compiler(getNameEnvironment(new String[0], paths), getErrorHandlingPolicy(), new CompilerOptions(customOptions), requestor, getProblemFactory()); char [][] compoundName = new char [][] { "test1".toCharArray(), "Base".toCharArray()}; ReferenceBinding type = compiler.lookupEnvironment.askForType(compoundName); assertNotNull(type); MethodBinding[] methods1 = type.getMethods("method1".toCharArray()); assertEquals("Base.Static.@A2 Static2<Exception>.@A3 Middle1.@A4 Middle2<Object>.@A5 Middle3.@A6 GenericInner<String>", new String(methods1[0].parameters[0].annotatedDebugName())); MethodBinding[] methods2 = type.getMethods("method2".toCharArray()); assertEquals("Base.Static.@A2 Static2<@B1 Exception>.@A3 Middle1.@A4 Middle2<@B2 Object>.@A5 Middle3.@A6 GenericInner<@B3 String> @A7 [] @A8 []", new String(methods2[0].parameters[0].annotatedDebugName())); MethodBinding[] methods3 = type.getMethods("method3".toCharArray()); assertEquals("Base.Static.@A2 Static2<@B1 Exception>.@A3 Middle1.@A4 Middle2<@B2 Class<@C1 Object @C2 []> @B3 []>.@A5 Middle3.@A6 GenericInner<@B4 String> @A7 [] @A8 []", new String(methods3[0].parameters[0].annotatedDebugName())); } }