From: Andy Clement Date: Fri, 24 May 2013 23:45:27 +0000 (-0700) Subject: Java8 support: methodparameters, typeannotations X-Git-Tag: AS_BETA_JAVA8_CREATED~7 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=0a01bd478349676a87a6afaa71a77a04de3f27a4;p=aspectj.git Java8 support: methodparameters, typeannotations Can read/write MethodParameters attribute. Can read/write type annotation attributes. --- diff --git a/bcel-builder/src/org/aspectj/apache/bcel/Constants.java b/bcel-builder/src/org/aspectj/apache/bcel/Constants.java index 2604d8e54..4499284c2 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/Constants.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/Constants.java @@ -59,8 +59,8 @@ import org.aspectj.apache.bcel.generic.Type; /** * Constants for the project, mostly defined in the JVM specification. * - * @version $Id: Constants.java,v 1.7 2011/09/28 01:14:54 aclement Exp $ * @author M. Dahm + * @author Andy Clement */ public interface Constants { // Major and minor version of the code @@ -76,6 +76,10 @@ public interface Constants { public final static short MINOR_1_5 = 0; public final static short MAJOR_1_6 = 50; public final static short MINOR_1_6 = 0; + public final static short MAJOR_1_7 = 51; + public final static short MINOR_1_7 = 0; + public final static short MAJOR_1_8 = 52; + public final static short MINOR_1_8 = 0; // Defaults public final static short MAJOR = MAJOR_1_1; public final static short MINOR = MINOR_1_1; @@ -609,13 +613,20 @@ public interface Constants { public static final byte ATTR_ENCLOSING_METHOD = 17; public static final byte ATTR_ANNOTATION_DEFAULT = 18; public static final byte ATTR_BOOTSTRAPMETHODS = 19; - - public static final short KNOWN_ATTRIBUTES = 20; - - public static final String[] ATTRIBUTE_NAMES = { "SourceFile", "ConstantValue", "Code", "Exceptions", "LineNumberTable", - "LocalVariableTable", "InnerClasses", "Synthetic", "Deprecated", "PMGClass", "Signature", "StackMap", - "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", "RuntimeVisibleParameterAnnotations", - "RuntimeInvisibleParameterAnnotations", "LocalVariableTypeTable", "EnclosingMethod", "AnnotationDefault","BootstrapMethods" }; + public static final byte ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = 20; + public static final byte ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = 21; + public static final byte ATTR_METHOD_PARAMETERS = 22; + + public static final short KNOWN_ATTRIBUTES = 23; + + public static final String[] ATTRIBUTE_NAMES = { + "SourceFile", "ConstantValue", "Code", "Exceptions", "LineNumberTable", "LocalVariableTable", + "InnerClasses", "Synthetic", "Deprecated", "PMGClass", "Signature", "StackMap", + "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", "RuntimeVisibleParameterAnnotations", + "RuntimeInvisibleParameterAnnotations", "LocalVariableTypeTable", "EnclosingMethod", + "AnnotationDefault","BootstrapMethods", "RuntimeVisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations", + "MethodParameters" + }; /** * Constants used in the StackMap attribute. diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java index 939fa36be..817628295 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java @@ -64,6 +64,7 @@ import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos; import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos; /** * Abstract super class for Attribute objects. Currently the ConstantValue, SourceFile, Code, @@ -159,6 +160,10 @@ public abstract class Attribute implements Cloneable, Node, Serializable { return new EnclosingMethod(idx, len, file, cpool); case Constants.ATTR_BOOTSTRAPMETHODS: return new BootstrapMethods(idx,len,file,cpool); + case Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS: + return new RuntimeVisTypeAnnos(idx, len, file, cpool); + case Constants.ATTR_METHOD_PARAMETERS: + return new MethodParameters(idx, len, file, cpool); default: throw new IllegalStateException(); } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java index c411cb5d6..9280083a8 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/ClassVisitor.java @@ -2,8 +2,10 @@ package org.aspectj.apache.bcel.classfile; import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisTypeAnnos; import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos; /* ==================================================================== * The Apache Software License, Version 1.1 @@ -151,7 +153,13 @@ public interface ClassVisitor { public void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisParamAnnos obj); + public void visitRuntimeVisibleTypeAnnotations(RuntimeVisTypeAnnos obj); + + public void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisTypeAnnos obj); + public void visitAnnotationDefault(AnnotationDefault obj); public void visitLocalVariableTypeTable(LocalVariableTypeTable obj); + + public void visitMethodParameters(MethodParameters methodParameters); } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Method.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Method.java index d354b7fe1..46aeac845 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Method.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Method.java @@ -1,5 +1,3 @@ -package org.aspectj.apache.bcel.classfile; - /* ==================================================================== * The Apache Software License, Version 1.1 * @@ -53,6 +51,8 @@ package org.aspectj.apache.bcel.classfile; * information on the Apache Software Foundation, please see * . */ +package org.aspectj.apache.bcel.classfile; + import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java index af442522d..9a0a42909 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/AnnotationGen.java @@ -1,5 +1,5 @@ /* ******************************************************************* - * Copyright (c) 2004 IBM Corporation + * Copyright (c) 2004, 2013 IBM Corporation * * All rights reserved. * This program and the accompanying materials are made available @@ -127,13 +127,16 @@ public class AnnotationGen { public String toShortString() { StringBuffer s = new StringBuffer(); - s.append("@" + getTypeName() + "("); - for (int i = 0; i < pairs.size(); i++) { - s.append(pairs.get(i)); - if (i + 1 < pairs.size()) - s.append(","); + s.append("@").append(getTypeName()); + if (pairs.size()!=0) { + s.append("("); + for (int i = 0; i < pairs.size(); i++) { + s.append(pairs.get(i)); + if (i + 1 < pairs.size()) + s.append(","); + } + s.append(")"); } - s.append(")"); return s.toString(); } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java index 511afe2b1..06f7c7273 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/ElementValue.java @@ -1,5 +1,5 @@ /* ******************************************************************* - * Copyright (c) 2004 IBM + * Copyright (c) 2004, 2013 IBM, VMware * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java index a6b6534df..05c83a6ee 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeAnnos.java @@ -1,3 +1,14 @@ +/* ******************************************************************* + * Copyright (c) 2004, 2013 IBM, VMware + * 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 - initial implementation {date} + * ******************************************************************/ package org.aspectj.apache.bcel.classfile.annotation; import java.io.ByteArrayInputStream; diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java index a2ab520d3..a6b2e529f 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisAnnos.java @@ -1,3 +1,14 @@ +/* ******************************************************************* + * Copyright (c) 2004, 2013 IBM, VMware + * 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 - initial implementation {date} + * ******************************************************************/ package org.aspectj.apache.bcel.classfile.annotation; import java.io.DataInputStream; diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java index b5d7bb119..cb2eb8d7a 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeInvisParamAnnos.java @@ -1,3 +1,14 @@ +/* ******************************************************************* + * Copyright (c) 2004, 2013 IBM, VMware + * 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 - initial implementation {date} + * ******************************************************************/ package org.aspectj.apache.bcel.classfile.annotation; import java.io.DataInputStream; diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java index 4bd8644c5..ad92c9fce 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeParamAnnos.java @@ -1,3 +1,14 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * 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 - initial implementation {date} + * ******************************************************************/ package org.aspectj.apache.bcel.classfile.annotation; import java.io.ByteArrayInputStream; @@ -12,7 +23,7 @@ import org.aspectj.apache.bcel.classfile.ConstantPool; public abstract class RuntimeParamAnnos extends Attribute { - private List /*Annotation[]*/ parameterAnnotations; + private List parameterAnnotations; private boolean visible; diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisAnnos.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisAnnos.java index aa3f49eac..3b07cccc7 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisAnnos.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisAnnos.java @@ -1,3 +1,14 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * 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 - initial implementation {date} + * ******************************************************************/ package org.aspectj.apache.bcel.classfile.annotation; import java.io.DataInputStream; diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisParamAnnos.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisParamAnnos.java index ccd1aa7d2..b47d8aac1 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisParamAnnos.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/annotation/RuntimeVisParamAnnos.java @@ -1,3 +1,14 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM + * 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 - initial implementation {date} + * ******************************************************************/ package org.aspectj.apache.bcel.classfile.annotation; import java.io.DataInputStream; diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java index 2689aae04..3311c5386 100644 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java +++ b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/BcelTestCase.java @@ -1,5 +1,5 @@ /* ******************************************************************* - * Copyright (c) 2004 IBM + * Copyright (c) 2004, 2013 IBM, VMware * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 @@ -20,6 +20,7 @@ import junit.framework.TestCase; import org.aspectj.apache.bcel.classfile.Attribute; import org.aspectj.apache.bcel.classfile.ConstantPool; +import org.aspectj.apache.bcel.classfile.Field; import org.aspectj.apache.bcel.classfile.JavaClass; import org.aspectj.apache.bcel.classfile.Method; import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; @@ -47,6 +48,11 @@ public class BcelTestCase extends TestCase { return repos.loadClass(clazzname); } + protected JavaClass getClassFromJava8Jar(String clazzname) throws ClassNotFoundException { + SyntheticRepository repos = createRepos("java8testcode.jar"); + return repos.loadClass(clazzname); + } + protected Method getMethod(JavaClass cl, String methodname) { Method[] methods = cl.getMethods(); for (int i = 0; i < methods.length; i++) { @@ -58,6 +64,17 @@ public class BcelTestCase extends TestCase { return null; } + protected Field getField(JavaClass cl, String fieldname) { + Field[] fields = cl.getFields(); + for (int i = 0; i < fields.length; i++) { + Field f = fields[i]; + if (f.getName().equals(fieldname)) { + return f; + } + } + return null; + } + protected boolean wipe(String name) { return new File("testdata" + File.separator + name).delete(); } @@ -148,5 +165,14 @@ public class BcelTestCase extends TestCase { elements.add(nvGen); return new AnnotationGen(t, elements, visibility, cp); } + + public Attribute getAttribute(Attribute[] attrs, byte tag) { + for (Attribute attr: attrs) { + if (attr.getTag() == tag) { + return attr; + } + } + return null; + } } diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java index dcb36432f..df4c2a401 100644 --- a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java +++ b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/TypeAnnotationsTest.java @@ -1,5 +1,5 @@ /* ******************************************************************* - * Copyright (c) 2004 IBM + * Copyright (c) 2013 VMware * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 @@ -9,27 +9,366 @@ * Contributors: * Andy Clement - initial implementation * ******************************************************************/ - package org.aspectj.apache.bcel.classfile.tests; +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.Field; import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; -import org.aspectj.apache.bcel.generic.ClassGen; - +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeTypeAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos; +import org.aspectj.apache.bcel.classfile.annotation.TypeAnnotationGen; public class TypeAnnotationsTest extends BcelTestCase { - protected void setUp() throws Exception { super.setUp(); } - public void testMarkerAnnotationsOnTypes() throws ClassNotFoundException { - JavaClass clazz = getClassFromJar("MarkedType"); - ClassGen cg = new ClassGen(clazz); - AnnotationGen[] annotations = cg.getAnnotations(); - assertTrue("Should be a MarkerAnnotation and a MarkerAnnotationInvisible - but found: "+annotations.length,annotations.length==2); + public Attribute getAttribute(Attribute[] attrs, byte tag) { + for (Attribute attr: attrs) { + if (attr.getTag() == tag) { + return attr; + } + } + return null; } + public void testClassTypeParameter() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnClassTypeParameter"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(jc.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(2,tas.length); + checkTypeAnnotationClassTypeParameter(tas[0],0,"@Anno"); + checkTypeAnnotationClassTypeParameter(tas[1],1,"@Anno(value=2)"); + } + + public void testMethodTypeParameter() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodTypeParameter"); + Method m = getMethod(jc, "m"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(m.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(1,tas.length); + checkTypeAnnotationMethodTypeParameter(tas[0],0,"@Anno"); + } + + public void testSuperinterface() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnSuperinterface1"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(jc.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(1,tas.length); + TypeAnnotationGen ta = tas[0]; + checkTypeAnnotationClassExtends(ta, 0, "@Anno"); + } + + public void testSupertypes() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnSupertypes"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(jc.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(3,tas.length); + checkTypeAnnotationClassExtends(tas[0],-1,"@Anno(value=1)"); + checkTypeAnnotationClassExtends(tas[1],0,"@Anno"); + checkTypeAnnotationClassExtends(tas[2],1,"@Anno(value=2)"); + } + + public void testClassTypeParameterBound() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnClassTypeParameterBound"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(jc.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(3,tas.length); + checkTypeAnnotationClassTypeParameterBound(tas[0],0,0,"@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + checkTypeAnnotationClassTypeParameterBound(tas[1],0,1,"@Anno(value=2)"); + checkTypePath(tas[1],TypeAnnotationGen.NO_TYPE_PATH); + checkTypeAnnotationClassTypeParameterBound(tas[2],0,1,"@Anno(value=3)"); + checkTypePath(tas[2],new int[]{TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT,0}); + } + + public void testMethodTypeParameterBound() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodTypeParameterBound"); + Method m = getMethod(jc, "m"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(m.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(3,tas.length); + checkTypeAnnotationMethodTypeParameterBound(tas[0],0,0,"@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + checkTypeAnnotationMethodTypeParameterBound(tas[1],0,1,"@Anno(value=2)"); + checkTypePath(tas[1],TypeAnnotationGen.NO_TYPE_PATH); + checkTypeAnnotationMethodTypeParameterBound(tas[2],0,1,"@Anno(value=3)"); + checkTypePath(tas[2],new int[]{TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT,1}); + } + + public void testField() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnField"); + Field f = getField(jc,"f1"); + RuntimeVisTypeAnnos rvta = (RuntimeVisTypeAnnos)getAttribute(f.getAttributes(), Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + assertTrue(rvta.areVisible()); + TypeAnnotationGen[] tas = rvta.getTypeAnnotations(); + assertEquals(1,tas.length); + checkTypeAnnotationField(tas[0],"@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + + tas = getTypeAnnotations(getField(jc,"f2"),true); + checkTypeAnnotationField(tas[0],"@Anno"); + checkTypePath(tas[0],new int[]{TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT,0}); + + tas = getTypeAnnotations(getField(jc,"f3"),true); + checkTypeAnnotationField(tas[0],"@Anno"); + checkTypePath(tas[0],new int[]{TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0}); + + tas = getTypeAnnotations(getField(jc,"f4"),true); + checkTypeAnnotationField(tas[0],"@Anno"); + checkTypePath(tas[0],new int[]{ + TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0, + TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_TYPE_ARGUMENT,0 + }); + } + + public void testMethodReturn() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodReturn"); + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m"), true); + checkTypeAnnotationMethodReturn(tas[0],"@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + } + + public void testMethodReceiver() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodReceiver"); + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m"), true); + checkTypeAnnotationMethodReceiver(tas[0],"@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + } + + public void testMethodFormalParameter() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnMethodFormalParameter"); + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m"), true); + checkTypeAnnotationMethodFormalParameter(tas[0],0, "@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + } + + public void testThrows() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnThrows"); + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m"), true); + checkTypeAnnotationThrows(tas[0],0, "@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + checkTypeAnnotationThrows(tas[1],1, "@Anno(value=2)"); + checkTypePath(tas[1],TypeAnnotationGen.NO_TYPE_PATH); + } + + public void testLocalVariable() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnLocalVariable"); + // TODO I think the attribute should be on the code for the method, not the method + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); + assertEquals(1,tas.length); + checkTypeAnnotationLocalVariable(tas[0],new int[]{11,8,1}, "@Anno"); + } + + public void testResourceVariable() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnResourceVariable"); + // TODO I think the attribute should be on the code for the method, not the method + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); + assertEquals(2,tas.length); + checkTypeAnnotationResourceVariable(tas[0],new int[]{17,204,1}, "@Anno"); + checkTypeAnnotationResourceVariable(tas[1],new int[]{36,114,3}, "@Anno(value=99)"); + } + + public void testExceptionParameter() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnExceptionParameter"); + // TODO I think the attribute should be on the code for the method, not the method + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); + assertEquals(2,tas.length); + checkTypeAnnotationExceptionParameter(tas[0],0, "@Anno(value=99)"); + checkTypeAnnotationExceptionParameter(tas[1],0, "@Anno"); + } + + public void testInstanceOf() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnInstanceOf"); + // TODO I think the attribute should be on the code for the method, not the method + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); + assertEquals(2,tas.length); + checkTypeAnnotationInstanceOf(tas[0],3, "@Anno(value=1)"); + checkTypeAnnotationInstanceOf(tas[1],18, "@Anno(value=1)"); + } + + public void testNew() throws Exception { + JavaClass jc = getClassFromJava8Jar("TypeAnnoOnNew"); + // TODO I think the attribute should be on the code for the method, not the method + TypeAnnotationGen[] tas = getTypeAnnotations(getMethod(jc,"m").getAttributes(), true); + assertEquals(4,tas.length); + checkTypeAnnotationNew(tas[0],0, "@Anno"); + checkTypePath(tas[0],TypeAnnotationGen.NO_TYPE_PATH); + + // TODO type path bugs in javac b90 according to the spec + checkTypeAnnotationNew(tas[1],8, "@Anno(value=2)"); + checkTypePath(tas[1],new int[]{ + TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0 + }); + checkTypeAnnotationNew(tas[2],13, "@Anno(value=4)"); + checkTypePath(tas[2],TypeAnnotationGen.NO_TYPE_PATH); + checkTypeAnnotationNew(tas[3],13, "@Anno(value=3)"); + checkTypePath(tas[3],new int[]{ + TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0, + TypeAnnotationGen.TYPE_PATH_ENTRY_KIND_ARRAY,0 + }); + } + + + // --- + private TypeAnnotationGen[] getTypeAnnotations(Attribute[] attrs, boolean visible) { + RuntimeTypeAnnos rvta = (RuntimeTypeAnnos)getAttribute(attrs, visible?Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS:Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS); + return rvta.getTypeAnnotations(); + } + + private TypeAnnotationGen[] getTypeAnnotations(Method m, boolean visible) { + RuntimeTypeAnnos rvta = (RuntimeTypeAnnos)getAttribute(m.getAttributes(), visible?Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS:Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS); + return rvta.getTypeAnnotations(); + } + + private TypeAnnotationGen[] getTypeAnnotations(Field f, boolean visible) { + RuntimeTypeAnnos rvta = (RuntimeTypeAnnos)getAttribute(f.getAttributes(), visible?Constants.ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS:Constants.ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS); + return rvta.getTypeAnnotations(); + } + + private void checkTypePath(TypeAnnotationGen ta, int[] expectedTypePath) { + int[] typepath = ta.getTypePath(); + if (expectedTypePath==TypeAnnotationGen.NO_TYPE_PATH || expectedTypePath==null) { + if (typepath!=TypeAnnotationGen.NO_TYPE_PATH) { + fail("Expected no type path but was "+ta.getTypePathString()); + } + } else { + assertEquals(expectedTypePath.length, typepath.length); + for (int i=0;i. */ +package org.aspectj.apache.bcel.verifier; import org.aspectj.apache.bcel.classfile.AnnotationDefault; import org.aspectj.apache.bcel.classfile.BootstrapMethods; @@ -87,6 +86,7 @@ import org.aspectj.apache.bcel.classfile.LocalVariable; import org.aspectj.apache.bcel.classfile.LocalVariableTable; import org.aspectj.apache.bcel.classfile.LocalVariableTypeTable; import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.classfile.MethodParameters; import org.aspectj.apache.bcel.classfile.Signature; import org.aspectj.apache.bcel.classfile.SourceFile; import org.aspectj.apache.bcel.classfile.StackMap; @@ -96,8 +96,10 @@ import org.aspectj.apache.bcel.classfile.Unknown; import org.aspectj.apache.bcel.classfile.ClassVisitor; import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisAnnos; import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisParamAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisTypeAnnos; import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisAnnos; import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisParamAnnos; +import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisTypeAnnos; /** * Visitor with empty method bodies, can be extended and used in conjunction with the @@ -158,5 +160,9 @@ public class EmptyClassVisitor implements ClassVisitor { public void visitAnnotationDefault(AnnotationDefault attribute) {} public void visitLocalVariableTypeTable(LocalVariableTypeTable obj) {} + // J8SUPPORT: + public void visitRuntimeVisibleTypeAnnotations(RuntimeVisTypeAnnos attribute) {} + public void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisTypeAnnos attribute) {} + public void visitMethodParameters(MethodParameters attribute) {} }