| /******************************************************************************* |
| * 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.print(\"Annotations on superclass of \"+clazz.getName() +\"\\n\");\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.print(\"Annotations on superinterfaces of \"+clazz.getName() +\"\\n\");\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.print(\">\\n\");\n"+ |
| " }\n"+ |
| " public static String toStringAnno(Annotation anno) {\n"+ |
| " String s = anno.toString();\n"+ |
| " s = s.replace(\"\\\"\", \"\");\n" + |
| " s = s.replace(\"'\", \"\");\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.print(header+t+\":no annotations\\n\"); 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.print(\"\\n\");\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=" + decorateAnnotationValueLiteral("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())); |
| } |
| } |
| |