blob: 4fd33536b79c1e6275fc7c917d888ebf8ba44612 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2016 GoPivotal, Inc.
* 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:
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* Bug 407191 - [1.8] Binary access support for type annotations
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
import junit.framework.Test;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
import org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair;
import org.eclipse.jdt.internal.compiler.env.IBinaryField;
import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
import org.eclipse.jdt.internal.compiler.env.IBinaryTypeAnnotation;
@SuppressWarnings({ "rawtypes" })
public class ClassFileReaderTest_1_8 extends AbstractRegressionTest {
static {
}
public static Test suite() {
return buildMinimalComplianceTestSuite(testClass(), F_1_8);
}
public static Class testClass() {
return ClassFileReaderTest_1_8.class;
}
public ClassFileReaderTest_1_8(String name) {
super(name);
}
// Needed to run tests individually from JUnit
protected void setUp() throws Exception {
super.setUp();
this.complianceLevel = ClassFileConstants.JDK1_8;
}
public void test001_classTypeParameter() throws Exception {
String source =
"import java.lang.annotation.*;\n" +
"public class X<@Foo T1,@Bar(iii=99) T2> {}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int iii() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader classFileReader = getInternalClassFile("", "X", "X", source);
IBinaryTypeAnnotation[] typeAnnotations = classFileReader.getTypeAnnotations();
assertEquals(2,typeAnnotations.length);
assertEquals("@LFoo; CLASS_TYPE_PARAMETER(type_parameter_index=0)", printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LBar;(iii=(int)99) CLASS_TYPE_PARAMETER(type_parameter_index=1)", printTypeAnnotation(typeAnnotations[1]));
}
public void test001a_classTypeParameterDifferingRetentions() throws Exception {
String source =
"import java.lang.annotation.*;\n" +
"public class X<@Foo T1,@Bar(iii=99) T2> {}\n" +
"@Retention(RetentionPolicy.RUNTIME)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int iii() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader classFileReader = getInternalClassFile("", "X", "X", source);
IBinaryTypeAnnotation[] typeAnnotations = classFileReader.getTypeAnnotations();
assertEquals(2,typeAnnotations.length);
assertEquals("@LBar;(iii=(int)99) CLASS_TYPE_PARAMETER(type_parameter_index=1)", printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LFoo; CLASS_TYPE_PARAMETER(type_parameter_index=0)", printTypeAnnotation(typeAnnotations[1]));
}
public void test002_methodTypeParameter() throws Exception {
String source =
"import java.lang.annotation.*;\n" +
"public class X {\n" +
" <@Foo T1, @Bar(3) T2> void foo(T1 t1,T2 t2) {}\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int value() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);
IBinaryMethod method = getMethod(cfr,"foo");
assertNotNull(method);
IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
assertNotNull(typeAnnotations);
assertEquals(2,typeAnnotations.length);
assertEquals("@LFoo; METHOD_TYPE_PARAMETER(type_parameter_index=0)",printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LBar;(value=(int)3) METHOD_TYPE_PARAMETER(type_parameter_index=1)",printTypeAnnotation(typeAnnotations[1]));
}
public void test003_classExtends() throws Exception {
this.complianceLevel = ClassFileConstants.JDK1_8;
String source =
"import java.lang.annotation.*;\n" +
"public class X extends @Foo @Bar(iii=34) Object implements java.io.@Bar(iii=1) Serializable {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int iii() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader classFileReader = getInternalClassFile("", "X", "X", source);
IBinaryTypeAnnotation[] typeAnnotations = classFileReader.getTypeAnnotations();
assertEquals(3,typeAnnotations.length);
assertEquals("@LFoo; CLASS_EXTENDS(type_index=-1)", printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LBar;(iii=(int)34) CLASS_EXTENDS(type_index=-1)", printTypeAnnotation(typeAnnotations[1]));
assertEquals("@LBar;(iii=(int)1) CLASS_EXTENDS(type_index=0)", printTypeAnnotation(typeAnnotations[2]));
}
public void test004_classExtends() throws Exception {
String source =
"import java.lang.annotation.*;\n" +
"public class X extends Y<@Foo String,@Bar Integer> implements I<@Foo String> {\n" +
"}\n" +
"class Y<T1, T2> {}\n" +
"interface I<T1> {}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int iii() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader classFileReader = getInternalClassFile("", "X", "X", source);
IBinaryTypeAnnotation[] typeAnnotations = classFileReader.getTypeAnnotations();
assertEquals(3,typeAnnotations.length);
assertEquals("@LFoo; CLASS_EXTENDS(type_index=-1), location=[TYPE_ARGUMENT(0)]", printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LBar; CLASS_EXTENDS(type_index=-1), location=[TYPE_ARGUMENT(1)]", printTypeAnnotation(typeAnnotations[1]));
assertEquals("@LFoo; CLASS_EXTENDS(type_index=0), location=[TYPE_ARGUMENT(0)]", printTypeAnnotation(typeAnnotations[2]));
}
public void test005_classTypeParameterBound() throws Exception {
String source =
"import java.lang.annotation.*;\n" +
"public class X<U, T extends Y<@Foo String @Bar(1)[][]@Bar(2)[]> & @Bar(3) Cloneable> {}\n" +
"class Y<T> {}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int value() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader classFileReader = getInternalClassFile("", "X", "X", source);
IBinaryTypeAnnotation[] typeAnnotations = classFileReader.getTypeAnnotations();
assertEquals(4,typeAnnotations.length);
assertEquals("@LFoo; CLASS_TYPE_PARAMETER_BOUND(type_parameter_index=1, bound_index=0), location=[TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]", printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LBar;(value=(int)1) CLASS_TYPE_PARAMETER_BOUND(type_parameter_index=1, bound_index=0), location=[TYPE_ARGUMENT(0)]", printTypeAnnotation(typeAnnotations[1]));
assertEquals("@LBar;(value=(int)2) CLASS_TYPE_PARAMETER_BOUND(type_parameter_index=1, bound_index=0), location=[TYPE_ARGUMENT(0), ARRAY, ARRAY]", printTypeAnnotation(typeAnnotations[2]));
assertEquals("@LBar;(value=(int)3) CLASS_TYPE_PARAMETER_BOUND(type_parameter_index=1, bound_index=1)", printTypeAnnotation(typeAnnotations[3]));
}
public void test006_methodTypeParameterBound() throws Exception {
String source =
"import java.lang.annotation.*;\n" +
"public class X{\n" +
" <T extends Y<@Foo Z @Bar(1)[][]@Bar(2)[]> & @Bar(3) Cloneable> void foo(T t) {}\n" +
"}\n" +
"class Y<T> {}\n" +
"class Z {}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int value() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);
IBinaryMethod method = getMethod(cfr,"foo");
assertNotNull(method);
IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
assertNotNull(typeAnnotations);
assertEquals(4,typeAnnotations.length);
assertEquals("@LFoo; METHOD_TYPE_PARAMETER_BOUND(type_parameter_index=0, bound_index=0), location=[TYPE_ARGUMENT(0), ARRAY, ARRAY, ARRAY]",printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LBar;(value=(int)1) METHOD_TYPE_PARAMETER_BOUND(type_parameter_index=0, bound_index=0), location=[TYPE_ARGUMENT(0)]", printTypeAnnotation(typeAnnotations[1]));
assertEquals("@LBar;(value=(int)2) METHOD_TYPE_PARAMETER_BOUND(type_parameter_index=0, bound_index=0), location=[TYPE_ARGUMENT(0), ARRAY, ARRAY]", printTypeAnnotation(typeAnnotations[2]));
assertEquals("@LBar;(value=(int)3) METHOD_TYPE_PARAMETER_BOUND(type_parameter_index=0, bound_index=1)", printTypeAnnotation(typeAnnotations[3]));
}
public void test007_field() throws Exception {
String source =
"import java.lang.annotation.*;\n" +
"import java.util.Map;\n" +
"public class X{\n" +
" @Foo Map<@Bar(1) String, @Bar(2) String @Bar(3)[] @Bar(4)[] @Bar(5)[]> field3;\n" +
"}\n" +
"class Y<T> {}\n" +
"class Z {}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int value() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);
IBinaryField field = getField(cfr,"field3");
assertNotNull(field);
IBinaryTypeAnnotation[] typeAnnotations = field.getTypeAnnotations();
assertNotNull(typeAnnotations);
assertEquals(6,typeAnnotations.length);
assertEquals("@LFoo; FIELD",printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LBar;(value=(int)1) FIELD, location=[TYPE_ARGUMENT(0)]", printTypeAnnotation(typeAnnotations[1]));
assertEquals("@LBar;(value=(int)2) FIELD, location=[TYPE_ARGUMENT(1), ARRAY, ARRAY, ARRAY]", printTypeAnnotation(typeAnnotations[2]));
assertEquals("@LBar;(value=(int)3) FIELD, location=[TYPE_ARGUMENT(1)]", printTypeAnnotation(typeAnnotations[3]));
assertEquals("@LBar;(value=(int)4) FIELD, location=[TYPE_ARGUMENT(1), ARRAY]", printTypeAnnotation(typeAnnotations[4]));
assertEquals("@LBar;(value=(int)5) FIELD, location=[TYPE_ARGUMENT(1), ARRAY, ARRAY]", printTypeAnnotation(typeAnnotations[5]));
}
public void test008_methodReturn() throws Exception {
String source =
"import java.lang.annotation.*;\n" +
"import java.util.Map;\n" +
"public class X{\n" +
" @Bar(3) @Foo int foo() {\n" +
" return 1;\n" +
" }\n" +
" @Bar(3) int @Foo [] foo2() {\n" +
" return null;\n" +
" }\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int value() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);
IBinaryMethod method = getMethod(cfr,"foo");
assertNotNull(method);
IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
assertNotNull(typeAnnotations);
assertEquals(2,typeAnnotations.length);
assertEquals("@LBar;(value=(int)3) METHOD_RETURN",printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LFoo; METHOD_RETURN", printTypeAnnotation(typeAnnotations[1]));
method = getMethod(cfr,"foo2");
assertNotNull(method);
typeAnnotations = method.getTypeAnnotations();
assertNotNull(typeAnnotations);
assertEquals(2,typeAnnotations.length);
assertEquals("@LBar;(value=(int)3) METHOD_RETURN, location=[ARRAY]",printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LFoo; METHOD_RETURN", printTypeAnnotation(typeAnnotations[1]));
}
public void test009_methodReceiver() throws Exception {
String source =
"import java.lang.annotation.*;\n" +
"import java.util.Map;\n" +
"public class X{\n" +
" void foo(@Bar(3) X this) {}\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int value() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);
IBinaryMethod method = getMethod(cfr,"foo");
assertNotNull(method);
IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
assertNotNull(typeAnnotations);
assertEquals(1,typeAnnotations.length);
assertEquals("@LBar;(value=(int)3) METHOD_RECEIVER", printTypeAnnotation(typeAnnotations[0]));
}
public void test010_methodFormalParameter() throws Exception {
String source =
"import java.lang.annotation.*;\n" +
"import java.util.Map;\n" +
"public class X{\n" +
" void foo(@Bar(3) String s, @Foo int i) {}\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int value() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);
IBinaryMethod method = getMethod(cfr,"foo");
assertNotNull(method);
IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
assertNotNull(typeAnnotations);
assertEquals(2,typeAnnotations.length);
assertEquals("@LBar;(value=(int)3) METHOD_FORMAL_PARAMETER(method_formal_parameter_index=0)",printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LFoo; METHOD_FORMAL_PARAMETER(method_formal_parameter_index=1)",printTypeAnnotation(typeAnnotations[1]));
}
public void test011_throws() throws Exception {
String source =
"import java.lang.annotation.*;\n" +
"import java.util.Map;\n" +
"public class X{\n" +
" void foo() throws @Foo Exception, @Bar(1) Throwable {}\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int value() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);
IBinaryMethod method = getMethod(cfr,"foo");
assertNotNull(method);
IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
assertNotNull(typeAnnotations);
assertEquals(2,typeAnnotations.length);
assertEquals("@LFoo; THROWS(throws_type_index=0)",printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LBar;(value=(int)1) THROWS(throws_type_index=1)",printTypeAnnotation(typeAnnotations[1]));
}
public void test012_annotationMethodReturn() throws Exception {
String source =
"import java.lang.annotation.*;\n" +
"import java.util.Map;\n" +
"public @interface X{\n" +
" @Bar(3) @Foo int foo();\n" +
" @Bar(3) int @Foo [] foo2();\n" +
" @Bar(7) @Foo String value() default \"aaa\";\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Foo {\n" +
"}\n" +
"@Retention(RetentionPolicy.CLASS)\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface Bar {\n" +
" int value() default -1;\n" +
"}";
org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader cfr = getInternalClassFile("", "X", "X", source);
IBinaryMethod method = getMethod(cfr,"foo");
assertNotNull(method);
IBinaryTypeAnnotation[] typeAnnotations = method.getTypeAnnotations();
assertNotNull(typeAnnotations);
assertEquals(2,typeAnnotations.length);
assertEquals("@LBar;(value=(int)3) METHOD_RETURN",printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LFoo; METHOD_RETURN", printTypeAnnotation(typeAnnotations[1]));
method = getMethod(cfr,"foo2");
assertNotNull(method);
typeAnnotations = method.getTypeAnnotations();
assertNotNull(typeAnnotations);
assertEquals(2,typeAnnotations.length);
assertEquals("@LBar;(value=(int)3) METHOD_RETURN, location=[ARRAY]",printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LFoo; METHOD_RETURN", printTypeAnnotation(typeAnnotations[1]));
method = getMethod(cfr,"value");
assertNotNull(method);
typeAnnotations = method.getTypeAnnotations();
assertNotNull(typeAnnotations);
assertEquals(2,typeAnnotations.length);
assertEquals("@LBar;(value=(int)7) METHOD_RETURN",printTypeAnnotation(typeAnnotations[0]));
assertEquals("@LFoo; METHOD_RETURN", printTypeAnnotation(typeAnnotations[1]));
assertEquals(((org.eclipse.jdt.internal.compiler.impl.Constant)method.getDefaultValue()).stringValue(), "aaa");
}
/**
* Produce a nicely formatted type annotation for testing. Exercises the API for type annotations.
* Output examples:<br>
* <tt>@Foo(id=34) CLASS_EXTENDS, type_index=-1, location=[ARRAY, INNER_TYPE, TYPE_ARGUMENT(0)]</tt><br>
*/
private String printTypeAnnotation(IBinaryTypeAnnotation typeAnnotation) {
StringBuffer sb = new StringBuffer();
// The annotation:
IBinaryAnnotation annotation = typeAnnotation.getAnnotation();
sb.append('@').append(annotation.getTypeName());
IBinaryElementValuePair[] pairs = annotation.getElementValuePairs();
if (pairs.length != 0) {
sb.append('(');
for (int i = 0; i < pairs.length; i++) {
if (i > 0) {
sb.append(',');
}
sb.append(pairs[i].getName()).append('=').append(pairs[i].getValue());
}
sb.append(')');
}
sb.append(' ');
// target type
int targetType = typeAnnotation.getTargetType();
switch (targetType) {
case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER:
sb.append("CLASS_TYPE_PARAMETER(type_parameter_index=").append(typeAnnotation.getTypeParameterIndex()).append(')');
break;
case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER:
sb.append("METHOD_TYPE_PARAMETER(type_parameter_index=").append(typeAnnotation.getTypeParameterIndex()).append(')');
break;
case AnnotationTargetTypeConstants.CLASS_EXTENDS:
sb.append("CLASS_EXTENDS(type_index=").append((short)typeAnnotation.getSupertypeIndex()).append(')');
break;
case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND:
sb.append("CLASS_TYPE_PARAMETER_BOUND(type_parameter_index=").
append(typeAnnotation.getTypeParameterIndex()).
append(", bound_index=").append(typeAnnotation.getBoundIndex()).
append(')');
break;
case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND:
sb.append("METHOD_TYPE_PARAMETER_BOUND(type_parameter_index=").
append(typeAnnotation.getTypeParameterIndex()).
append(", bound_index=").append(typeAnnotation.getBoundIndex()).
append(')');
break;
case AnnotationTargetTypeConstants.FIELD:
sb.append("FIELD");
break;
case AnnotationTargetTypeConstants.METHOD_RETURN:
sb.append("METHOD_RETURN");
break;
case AnnotationTargetTypeConstants.METHOD_RECEIVER:
sb.append("METHOD_RECEIVER");
break;
case AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER :
sb.append("METHOD_FORMAL_PARAMETER(method_formal_parameter_index=").
append(typeAnnotation.getMethodFormalParameterIndex()).append(')');
break;
case AnnotationTargetTypeConstants.THROWS :
sb.append("THROWS(throws_type_index=").
append(typeAnnotation.getThrowsTypeIndex()).append(')');
break;
default: throw new IllegalStateException("nyi "+targetType);
}
// location
int[] typepath = typeAnnotation.getTypePath();
if (typepath != IBinaryTypeAnnotation.NO_TYPE_PATH) {
sb.append(", location=["); //$NON-NLS-1$
for (int i = 0, max = typepath.length; i < max; i += 2) {
if (i > 0) {
sb.append(", "); //$NON-NLS-1$
}
switch (typepath[i]) {
case 0:
sb.append("ARRAY"); //$NON-NLS-1$
break;
case 1:
sb.append("INNER_TYPE"); //$NON-NLS-1$
break;
case 2:
sb.append("WILDCARD"); //$NON-NLS-1$
break;
case 3:
sb.append("TYPE_ARGUMENT(").append(typepath[i+1]).append(')'); //$NON-NLS-1$
break;
}
}
sb.append(']');
}
return sb.toString();
}
private IBinaryMethod getMethod(ClassFileReader cfr,String methodname) {
IBinaryMethod[] methods = cfr.getMethods();
if (methods == null) {
return null;
}
char[] methodnameAsCharArray = methodname.toCharArray();
for (int i = 0, max = methods.length; i < max; i++) {
if (CharOperation.equals(methods[i].getSelector(),methodnameAsCharArray)) {
return methods[i];
}
}
return null;
}
private IBinaryField getField(ClassFileReader cfr,String fieldname) {
IBinaryField[] fields = cfr.getFields();
if (fields == null) {
return null;
}
char[] fieldnameAsCharArray = fieldname.toCharArray();
for (int i = 0, max = fields.length; i < max; i++) {
if (CharOperation.equals(fields[i].getName(),fieldnameAsCharArray)) {
return fields[i];
}
}
return null;
}
}