(java.lang.annotation.Annotation): Added import.
(java.util.Map): Added import.
(sun.refelct.annotation.AnnotationParser): Added import.
(declaredAnnotations): Added field (inspired by OpenJDK).
(getAnnotation): Added method.
(getDeclaredAnnotations): Added method.
(declaredAnnotations): Added method (inspired by OpenJDK).
(getParameterAnnotations): Added method.
* src/lib/gnu/java/lang/reflect/Field.java
(java.lang.annotation.Annotation): Added import.
(java.util.Map): Added import.
(sun.refelct.annotation.AnnotationParser): Added import.
(declaredAnnotations): Added field (inspired by OpenJDK).
(getAnnotation): Added method.
(getDeclaredAnnotations): Added method.
(declaredAnnotations): Added method (inspired by OpenJDK).
* src/lib/gnu/java/lang/reflect/Constructor.java:
Copied file from GNU Classpath.
(java.lang.annotation.Annotation): Added import.
(java.util.Map): Added import.
(sun.refelct.annotation.AnnotationParser): Added import.
(declaredAnnotations): Added field (inspired by OpenJDK).
(getAnnotation): Added method.
(getDeclaredAnnotations): Added method.
(declaredAnnotations): Added method (inspired by OpenJDK).
(getParameterAnnotations): Added method.
* src/lib/gnu/sun/reflect/generics/parser/SignatureFormatError.java:
Removed.
* src/lib/gnu/sun/reflect/generics/parser/SignatureParser.java:
Removed. I figured out which class of GNU Classpath to use to replace
this self written class.
* src/lib/gnu/sun/reflect/annotation/AnnotationParser.java:
Added a few comments.
(sun.reflect.generics.parser.SignatureParser): Removed import.
(sun.reflect.generics.parser.SignatureFormatError): Removed import.
(gnu.java.lang.reflect.FieldSignatureParser): Added import.
(parseParameterAnnotations): Added method.
(parseSig): Changed method so it uses GNU Classpaths FieldSignatureParser.
* src/lib/Makefile.am
(VM_JAVA_FILES): Added $(top_srcdir)/src/lib/gnu/java/lang/reflect/Constructor.java
(VM_CLASS_FILES): Added classes/java/lang/reflect/Constructor.class
* src/native/vm/java_lang_Class.c
[WITH_CLASSPATH_GNU] [ENABLE_ANNOTATIONS]
(_Jv_java_lang_Class_getDeclaredAnnotations): Cache methodinfo for
sun.reflect.annotation.AnnotationParser.parseAnnotationsIntoArray.
* src/native/vm/gnu/java_lang_reflect_Method.c
[ENABLE_ANNOTATIONS] (native/vm/reflect.h): Added include.
[ENABLE_ANNOTATIONS] (declaredAnnotations): Added method.
[ENABLE_ANNOTATIONS] (getParameterAnnotations): Added method.
[ENABLE_ANNOTATIONS] (Java_java_lang_reflect_Method_getDefaultValue):
Cache methodinfo for sun.reflect.annotation.AnnotationParser.parseDefaultValue.
[ENABLE_ANNOTATIONS] (Java_java_lang_reflect_Method_declaredAnnotations): Added.
[ENABLE_ANNOTATIONS] (Java_java_lang_reflect_Method_getParameterAnnotations): Added.
* src/native/vm/gnu/java_lang_reflect_Field.c
[ENABLE_ANNOTATIONS] (native/include/sun_reflect_ConstantPool.h): Added include.
[ENABLE_ANNOTATIONS] (native/vm/reflect.h): Added include.
[ENABLE_ANNOTATIONS] (declaredAnnotations): Added method.
[ENABLE_ANNOTATIONS] (Java_java_lang_reflect_Field_declaredAnnotations): Added.
* src/native/vm/gnu/java_lang_reflect_Constructor.c
[ENABLE_ANNOTATIONS] (vm/vm.h): Added include.
[ENABLE_ANNOTATIONS] (native/include/sun_reflect_ConstantPool.h): Added include.
[ENABLE_ANNOTATIONS] (native/vm/reflect.h): Added include.
[ENABLE_ANNOTATIONS] (declaredAnnotations): Added method.
[ENABLE_ANNOTATIONS] (getParameterAnnotations): Added method.
[ENABLE_ANNOTATIONS] (Java_java_lang_reflect_Constructor_declaredAnnotations): Added.
[ENABLE_ANNOTATIONS] (Java_java_lang_reflect_Constructor_getParameterAnnotations): Added.
* src/native/vm/reflect.c
[WITH_CLASSPATH_GNU] [ENABLE_ANNOTATIONS] (vm/vm.h): Added include.
[WITH_CLASSPATH_GNU] [ENABLE_ANNOTATIONS] (native/include/sun_reflect_ConstantPool.h): Added include.
[WITH_CLASSPATH_GNU] [ENABLE_ANNOTATIONS] (reflect_get_declaredannotatios): Added.
[WITH_CLASSPATH_GNU] [ENABLE_ANNOTATIONS] (reflect_get_parameterannotations): Added.
* src/native/vm/reflect.h
[WITH_CLASSPATH_GNU] [ENABLE_ANNOTATIONS] (reflect_get_declaredannotatios): Added.
[WITH_CLASSPATH_GNU] [ENABLE_ANNOTATIONS] (reflect_get_parameterannotations): Added.
* src/native/vm/sun/jvm.c
(JVM_GetDeclaredClasses): Implemented (needed by a testcase of mine).
* src/vmcore/method.c (method_get_parametercount): Added.
This function gets the parameter count of a method (not counting the
this pointer of non-static methods). Returns -1 in case of an error.
* src/vmcore/method.h (method_get_parametercount): Added.
## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
## 02110-1301, USA.
##
-## $Id: Makefile.am 8252 2007-08-01 22:47:17Z twisti $
+## $Id: Makefile.am 8262 2007-08-06 12:44:01Z panzi $
## Process this file with automake to produce Makefile.in
$(top_srcdir)/src/lib/gnu/java/lang/VMString.java \
$(top_srcdir)/src/lib/gnu/java/lang/VMThread.java \
$(top_srcdir)/src/lib/gnu/java/lang/VMThrowable.java \
+ $(top_srcdir)/src/lib/gnu/java/lang/reflect/Constructor.java \
$(top_srcdir)/src/lib/gnu/java/lang/reflect/Field.java \
$(top_srcdir)/src/lib/gnu/java/lang/reflect/Method.java \
$(top_srcdir)/src/lib/gnu/java/security/VMAccessController.java \
classes/java/lang/VMString.class \
classes/java/lang/VMThread.class \
classes/java/lang/VMThrowable.class \
+ classes/java/lang/reflect/Constructor.class \
classes/java/lang/reflect/Field.class \
classes/java/lang/reflect/Method.class \
classes/java/security/VMAccessController.class \
$(top_srcdir)/src/lib/gnu/sun/reflect/annotation/TypeNotPresentExceptionProxy.java \
$(top_srcdir)/src/lib/gnu/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java \
$(top_srcdir)/src/lib/gnu/sun/reflect/ConstantPool.java \
- $(top_srcdir)/src/lib/gnu/sun/reflect/generics/parser/SignatureFormatError.java \
- $(top_srcdir)/src/lib/gnu/sun/reflect/generics/parser/SignatureParser.java \
$(top_srcdir)/src/lib/gnu/sun/reflect/annotation/AnnotationType.java \
$(top_srcdir)/src/lib/gnu/sun/reflect/annotation/AnnotationParser.java
classes/sun/reflect/annotation/TypeNotPresentExceptionProxy.class \
classes/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.class \
classes/sun/reflect/ConstantPool.class \
- classes/sun/reflect/generics/parser/SignatureFormatError.class \
- classes/sun/reflect/generics/parser/SignatureParser.class \
classes/sun/reflect/annotation/AnnotationType.class \
classes/sun/reflect/annotation/AnnotationParser.class
endif
--- /dev/null
+/* java.lang.reflect.Constructor - reflection of Java constructors
+ Copyright (C) 1998, 2001, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.java.lang.ClassHelper;
+
+import gnu.java.lang.reflect.MethodSignatureParser;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import java.util.Arrays;
+
+/**
+ * The Constructor class represents a constructor of a class. It also allows
+ * dynamic creation of an object, via reflection. Invocation on Constructor
+ * objects knows how to do widening conversions, but throws
+ * {@link IllegalArgumentException} if a narrowing conversion would be
+ * necessary. You can query for information on this Constructor regardless
+ * of location, but construction access may be limited by Java language
+ * access controls. If you can't do it in the compiler, you can't normally
+ * do it here either.<p>
+ *
+ * <B>Note:</B> This class returns and accepts types as Classes, even
+ * primitive types; there are Class types defined that represent each
+ * different primitive type. They are <code>java.lang.Boolean.TYPE,
+ * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class,
+ * byte.class</code>, etc. These are not to be confused with the
+ * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are
+ * real classes.<p>
+ *
+ * Also note that this is not a serializable class. It is entirely feasible
+ * to make it serializable using the Externalizable interface, but this is
+ * on Sun, not me.
+ *
+ * @author John Keiser
+ * @author Eric Blake <ebb9@email.byu.edu>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getConstructor(Class[])
+ * @see java.lang.Class#getDeclaredConstructor(Class[])
+ * @see java.lang.Class#getConstructors()
+ * @see java.lang.Class#getDeclaredConstructors()
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Constructor<T>
+ extends AccessibleObject
+ implements GenericDeclaration, Member
+{
+ private Class<T> clazz;
+ private int slot;
+ private byte[] annotations = null;
+ private byte[] parameterAnnotations = null;
+ private transient Map<Class, Annotation> declaredAnnotations = null;
+
+ private static final int CONSTRUCTOR_MODIFIERS
+ = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
+
+ private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
+ new Annotation[0];
+
+ /**
+ * This class is uninstantiable except from native code.
+ */
+ private Constructor(Class declaringClass,int slot)
+ {
+ this.clazz = declaringClass;
+ this.slot = slot;
+ }
+
+ private Constructor()
+ {
+ }
+
+ /**
+ * Gets the class that declared this constructor.
+ * @return the class that declared this member
+ */
+ public Class<T> getDeclaringClass()
+ {
+ return clazz;
+ }
+
+ /**
+ * Gets the name of this constructor (the non-qualified name of the class
+ * it was declared in).
+ * @return the name of this constructor
+ */
+ public String getName()
+ {
+ return getDeclaringClass().getName();
+ }
+
+ /**
+ * Return the raw modifiers for this constructor. In particular
+ * this will include the synthetic and varargs bits.
+ * @return the constructor's modifiers
+ */
+ private native int getModifiersInternal();
+
+ /**
+ * Gets the modifiers this constructor uses. Use the <code>Modifier</code>
+ * class to interpret the values. A constructor can only have a subset of the
+ * following modifiers: public, private, protected.
+ *
+ * @return an integer representing the modifiers to this Member
+ * @see Modifier
+ */
+ public int getModifiers()
+ {
+ return getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
+ }
+
+ /**
+ * Return true if this constructor is synthetic, false otherwise.
+ * A synthetic member is one which is created by the compiler,
+ * and which does not appear in the user's source code.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this is a varargs constructor, that is if
+ * the constructor takes a variable number of arguments.
+ * @since 1.5
+ */
+ public boolean isVarArgs()
+ {
+ return (getModifiersInternal() & Modifier.VARARGS) != 0;
+ }
+
+ /**
+ * Get the parameter list for this constructor, in declaration order. If the
+ * constructor takes no parameters, returns a 0-length array (not null).
+ *
+ * @return a list of the types of the constructor's parameters
+ */
+ public native Class<?>[] getParameterTypes();
+
+ /**
+ * Get the exception types this constructor says it throws, in no particular
+ * order. If the constructor has no throws clause, returns a 0-length array
+ * (not null).
+ *
+ * @return a list of the types in the constructor's throws clause
+ */
+ public native Class<?>[] getExceptionTypes();
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Constructors are semantically equivalent if they have the same
+ * declaring class and the same parameter list. This ignores different
+ * exception clauses, but since you can't create a Method except through the
+ * VM, this is just the == relation.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not.
+ */
+ public boolean equals(Object o)
+ {
+ if (!(o instanceof Constructor))
+ return false;
+ Constructor that = (Constructor)o;
+ if (this.getDeclaringClass() != that.getDeclaringClass())
+ return false;
+ if (!Arrays.equals(this.getParameterTypes(), that.getParameterTypes()))
+ return false;
+ return true;
+ }
+
+ /**
+ * Get the hash code for the Constructor. The Constructor hash code is the
+ * hash code of the declaring class's name.
+ *
+ * @return the hash code for the object
+ */
+ public int hashCode()
+ {
+ return getDeclaringClass().getName().hashCode();
+ }
+
+ /**
+ * Get a String representation of the Constructor. A Constructor's String
+ * representation is "<modifier> <classname>(<paramtypes>)
+ * throws <exceptions>", where everything after ')' is omitted if
+ * there are no exceptions.<br> Example:
+ * <code>public java.io.FileInputStream(java.lang.Runnable)
+ * throws java.io.FileNotFoundException</code>
+ *
+ * @return the String representation of the Constructor
+ */
+ public String toString()
+ {
+ // 128 is a reasonable buffer initial size for constructor
+ StringBuilder sb = new StringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ sb.append(getDeclaringClass().getName()).append('(');
+ Class[] c = getParameterTypes();
+ if (c.length > 0)
+ {
+ sb.append(ClassHelper.getUserName(c[0]));
+ for (int i = 1; i < c.length; i++)
+ sb.append(',').append(ClassHelper.getUserName(c[i]));
+ }
+ sb.append(')');
+ c = getExceptionTypes();
+ if (c.length > 0)
+ {
+ sb.append(" throws ").append(c[0].getName());
+ for (int i = 1; i < c.length; i++)
+ sb.append(',').append(c[i].getName());
+ }
+ return sb.toString();
+ }
+
+ static <X extends GenericDeclaration>
+ void addTypeParameters(StringBuilder sb, TypeVariable<X>[] typeArgs)
+ {
+ if (typeArgs.length == 0)
+ return;
+ sb.append('<');
+ for (int i = 0; i < typeArgs.length; ++i)
+ {
+ if (i > 0)
+ sb.append(',');
+ sb.append(typeArgs[i]);
+ }
+ sb.append("> ");
+ }
+
+ public String toGenericString()
+ {
+ StringBuilder sb = new StringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ addTypeParameters(sb, getTypeParameters());
+ sb.append(getDeclaringClass().getName()).append('(');
+ Type[] types = getGenericParameterTypes();
+ if (types.length > 0)
+ {
+ sb.append(types[0]);
+ for (int i = 1; i < types.length; ++i)
+ sb.append(',').append(types[i]);
+ }
+ sb.append(')');
+ types = getGenericExceptionTypes();
+ if (types.length > 0)
+ {
+ sb.append(" throws ").append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Create a new instance by invoking the constructor. Arguments are
+ * automatically unwrapped and widened, if needed.<p>
+ *
+ * If this class is abstract, you will get an
+ * <code>InstantiationException</code>. If the constructor takes 0
+ * arguments, you may use null or a 0-length array for <code>args</code>.<p>
+ *
+ * If this Constructor enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not create this object in similar compiled code. If the class
+ * is uninitialized, you trigger class initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Then, the constructor is invoked. If it completes normally, the return
+ * value will be the new object. If it completes abruptly, the exception is
+ * wrapped in an <code>InvocationTargetException</code>.
+ *
+ * @param args the arguments to the constructor
+ * @return the newly created object
+ * @throws IllegalAccessException if the constructor could not normally be
+ * called by the Java code (i.e. it is not public)
+ * @throws IllegalArgumentException if the number of arguments is incorrect;
+ * or if the arguments types are wrong even with a widening
+ * conversion
+ * @throws InstantiationException if the class is abstract
+ * @throws InvocationTargetException if the constructor throws an exception
+ * @throws ExceptionInInitializerError if construction triggered class
+ * initialization, which then failed
+ */
+ public T newInstance(Object... args)
+ throws InstantiationException, IllegalAccessException,
+ InvocationTargetException
+ {
+ return constructNative(args, clazz, slot);
+ }
+
+ private native T constructNative(Object[] args, Class declaringClass,
+ int slot)
+ throws InstantiationException, IllegalAccessException,
+ InvocationTargetException;
+
+ /**
+ * Returns an array of <code>TypeVariable</code> objects that represents
+ * the type variables declared by this constructor, in declaration order.
+ * An array of size zero is returned if this constructor has no type
+ * variables.
+ *
+ * @return the type variables associated with this constructor.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public TypeVariable<Constructor<T>>[] getTypeParameters()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return new TypeVariable[0];
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getTypeParameters();
+ }
+
+ /**
+ * Return the String in the Signature attribute for this constructor. If there
+ * is no Signature attribute, return null.
+ */
+ private native String getSignature();
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the exception types declared by this constructor, in declaration order.
+ * An array of size zero is returned if this constructor declares no
+ * exceptions.
+ *
+ * @return the exception types declared by this constructor.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericExceptionTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getExceptionTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericExceptionTypes();
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the parameter list for this constructor, in declaration order.
+ * An array of size zero is returned if this constructor takes no
+ * parameters.
+ *
+ * @return a list of the types of the constructor's parameters
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericParameterTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getParameterTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericParameterTypes();
+ }
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+ if (annotationClass == null)
+ throw new NullPointerException();
+
+ return (T)declaredAnnotations().get(annotationClass);
+ }
+
+ /**
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations() {
+ return declaredAnnotations().values().toArray(EMPTY_ANNOTATIONS_ARRAY);
+ }
+
+ private synchronized native Map<Class, Annotation> declaredAnnotations();
+
+ /**
+ * Returns an array of arrays that represent the annotations on the formal
+ * parameters, in declaration order, of the method represented by
+ * this <tt>Method</tt> object. (Returns an array of length zero if the
+ * underlying method is parameterless. If the method has one or more
+ * parameters, a nested array of length zero is returned for each parameter
+ * with no annotations.) The annotation objects contained in the returned
+ * arrays are serializable. The caller of this method is free to modify
+ * the returned arrays; it will have no effect on the arrays returned to
+ * other callers.
+ *
+ * @return an array of arrays that represent the annotations on the formal
+ * parameters, in declaration order, of the method represented by this
+ * Method object
+ * @since 1.5
+ */
+ public native Annotation[][] getParameterAnnotations();
+}
import gnu.java.lang.reflect.FieldSignatureParser;
+import java.lang.annotation.Annotation;
+import java.util.Map;
+
+
/**
* The Field class represents a member variable of a class. It also allows
* dynamic access to a member, via reflection. This works for both
private Class clazz;
private String name;
private int slot;
- private byte[] annotations;
+ private byte[] annotations = null;
+ private transient Map<Class, Annotation> declaredAnnotations = null;
private static final int FIELD_MODIFIERS
= Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
| Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
| Modifier.VOLATILE;
+ private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
+ new Annotation[0];
+
/**
* This class is uninstantiable except natively.
*/
* is no Signature attribute, return null.
*/
private native String getSignature();
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+ if (annotationClass == null)
+ throw new NullPointerException();
+
+ return (T)declaredAnnotations().get(annotationClass);
+ }
+
+ /**
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations() {
+ return declaredAnnotations().values().toArray(EMPTY_ANNOTATIONS_ARRAY);
+ }
+
+ private synchronized native Map<Class, Annotation> declaredAnnotations();
}
import gnu.java.lang.reflect.MethodSignatureParser;
+import java.lang.annotation.Annotation;
+import java.util.Map;
import java.util.Arrays;
/**
Class clazz;
String name;
int slot;
- private byte[] annotations;
- private byte[] parameterAnnotations;
- private byte[] annotationDefault;
+ private byte[] annotations = null;
+ private byte[] parameterAnnotations = null;
+ private byte[] annotationDefault = null;
+ private transient Map<Class, Annotation> declaredAnnotations = null;
private static final int METHOD_MODIFIERS
= Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE
| Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC
| Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED;
+ private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
+ new Annotation[0];
+
/**
* This class is uninstantiable.
*/
* @since 1.5
*/
public native Object getDefaultValue();
+
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+ if (annotationClass == null)
+ throw new NullPointerException();
+
+ return (T)declaredAnnotations().get(annotationClass);
+ }
+
+ /**
+ * @since 1.5
+ */
+ public Annotation[] getDeclaredAnnotations() {
+ return declaredAnnotations().values().toArray(EMPTY_ANNOTATIONS_ARRAY);
+ }
+
+ private synchronized native Map<Class, Annotation> declaredAnnotations();
+
+ /**
+ * Returns an array of arrays that represent the annotations on the formal
+ * parameters, in declaration order, of the method represented by
+ * this <tt>Method</tt> object. (Returns an array of length zero if the
+ * underlying method is parameterless. If the method has one or more
+ * parameters, a nested array of length zero is returned for each parameter
+ * with no annotations.) The annotation objects contained in the returned
+ * arrays are serializable. The caller of this method is free to modify
+ * the returned arrays; it will have no effect on the arrays returned to
+ * other callers.
+ *
+ * @return an array of arrays that represent the annotations on the formal
+ * parameters, in declaration order, of the method represented by this
+ * Method object
+ * @since 1.5
+ */
+ public native Annotation[][] getParameterAnnotations();
}
import java.lang.reflect.*;
import sun.reflect.ConstantPool;
-import sun.reflect.generics.parser.SignatureFormatError;
-import sun.reflect.generics.parser.SignatureParser;
+import gnu.java.lang.reflect.FieldSignatureParser;
-/*
-import sun.reflect.generics.tree.TypeSignature;
-import sun.reflect.generics.factory.GenericsFactory;
-import sun.reflect.generics.factory.CoreReflectionFactory;
-import sun.reflect.generics.visitor.Reifier;
-import sun.reflect.generics.scope.ClassScope;
-*/
/**
* Parser for Java programming language annotations. Translates
* @since 1.5
*/
public class AnnotationParser {
+ /**
+ * Parses the annotations described by the passed byte array.
+ * But return Annotation[] so I don't have to do this in C.
+ *
+ * @author Mathias Panzenböck
+ *
+ * @throws AnnotationFormatError if an annotation is found to be
+ * malformed.
+ */
+ public static Annotation[] parseAnnotationsIntoArray(
+ byte[] rawAnnotations,
+ ConstantPool constPool,
+ Class container) {
+ Map<Class, Annotation> annotations = parseAnnotations(rawAnnotations, constPool, container);
+ return annotations.values().toArray(EMPTY_ANNOTATIONS_ARRAY);
+ }
+
+ /**
+ * Parses parameter annotations.
+ *
+ * @author Mathias Panzenböck
+ *
+ * @throws AnnotationFormatError if an annotation is found to be
+ * malformed.
+ */
+ public static Annotation[][] parseParameterAnnotations(
+ byte[] parameterAnnotations,
+ ConstantPool constPool,
+ Class container,
+ int numParameters) {
+ if (parameterAnnotations == null)
+ return new Annotation[numParameters][0];
+
+ Annotation[][] result = parseParameterAnnotations(
+ parameterAnnotations, constPool, container);
+
+ if (result.length != numParameters)
+ throw new AnnotationFormatError(
+ "Parameter annotations don't match number of parameters (count was " +
+ result.length + " but should be " + numParameters + ").");
+ return result;
+ }
+
+ /**
+ * Parses the annotation default value of the supplied method.
+ * This method is basically copied from OpenJDKs
+ * java.lang.reflect.Method.getAnnotationDefault()
+ *
+ * @author Mathias Panzenböck
+ *
+ * @throws AnnotationFormatError if an annotation is found to be
+ * malformed.
+ */
+ public static Object parseAnnotationDefault(Method method,
+ byte[] annotationDefault,
+ ConstantPool constPool) {
+ if (annotationDefault == null)
+ return null;
+
+ Class memberType = AnnotationType.invocationHandlerReturnType(
+ method.getReturnType());
+
+ Object result = AnnotationParser.parseMemberValue(
+ memberType, ByteBuffer.wrap(annotationDefault),
+ constPool, method.getDeclaringClass());
+
+ if (result instanceof sun.reflect.annotation.ExceptionProxy)
+ throw new AnnotationFormatError("Invalid default: " + method);
+
+ return result;
+ }
+
/**
* Parses the annotations described by the specified byte array.
* resolving constant references in the specified constant pool.
throw new AnnotationFormatError(e);
}
}
-
- /**
- * Parses the annotations described by the specified byte array.
- * But return Annotation[] so I don't have to do this in C.
- * @author Mathias Panzenböck
- */
- public static Annotation[] parseAnnotationsIntoArray(
- byte[] rawAnnotations,
- ConstantPool constPool,
- Class container) {
- Map<Class, Annotation> annotations = parseAnnotations(rawAnnotations, constPool, container);
- Annotation[] result = new Annotation[annotations.size()];
- int i = 0;
-
- for (Annotation annotation : annotations.values()) {
- result[i] = annotation;
- ++ i;
- }
-
- return result;
- }
private static Map<Class, Annotation> parseAnnotations2(
byte[] rawAnnotations,
new AnnotationInvocationHandler(type, memberValues));
}
- /**
- * Parses the annotation default value of the supplied method.
- * This method is basically copied from
- * java.lang.reflect.Method.getAnnotationDefault()
- *
- * @author Mathias Panzenböck
- */
- public static Object parseAnnotationDefault(Method method,
- byte[] annotationDefault,
- ConstantPool constPool,
- Class container) {
- if (annotationDefault == null)
- return null;
- Class memberType = AnnotationType.invocationHandlerReturnType(
- method.getReturnType());
- Object result = AnnotationParser.parseMemberValue(
- memberType, ByteBuffer.wrap(annotationDefault),
- constPool, container);
- if (result instanceof sun.reflect.annotation.ExceptionProxy)
- throw new AnnotationFormatError("Invalid default: " + method);
- return result;
- }
-
/**
* Parses the annotation member value at the current position in the
* specified byte buffer, resolving constant references in the specified
}
}
+ /**
+ * Parses a return type signature and returns the according Class object.
+ */
private static Class<?> parseSig(String sig, Class container) {
- try {
- return new SignatureParser(sig, container.getClassLoader()).getType();
- }
- catch(SignatureFormatError e) {
- throw new AnnotationFormatError(
- "Invalid type siganture in annotation: " + sig, e);
- }
- catch(ClassNotFoundException e) {
- throw new AnnotationFormatError(
- "Class described by this type siganture was not found: " + sig, e);
- }
+ if (sig.equals("V")) {
+ return void.class;
+ }
+ else {
+ return toClass(new FieldSignatureParser(container, sig).getFieldType());
+ }
}
- /*
- private static Class<?> parseSig(String sig, Class container) {
- if (sig.equals("V")) return void.class;
- SignatureParser parser = SignatureParser.make();
- TypeSignature typeSig = parser.parseTypeSig(sig);
- GenericsFactory factory = CoreReflectionFactory.make(container, ClassScope.make(container));
- Reifier reify = Reifier.make(factory);
- typeSig.accept(reify);
- Type result = reify.getResult();
- return toClass(result);
- }
- static Class toClass(Type o) {
+ static Class<?> toClass(Type o) {
if (o instanceof GenericArrayType)
return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
0)
.getClass();
- return (Class)o;
+ return (Class<?>)o;
}
- */
/**
* Parses the enum constant member value at the current position in the
+++ /dev/null
-package sun.reflect.generics.parser;
-
-public class SignatureFormatError extends Exception {
- private static final long serialVersionUID = -1151912353615858866L;
-
- public SignatureFormatError() {
- super("illegal type signature");
- }
-
- public SignatureFormatError(String signature) {
- super("illegal type signature: \"" + signature + "\"");
- }
-
- public SignatureFormatError(Throwable cause) {
- super("illegal type signature", cause);
- }
-
- public SignatureFormatError(String signature, Throwable cause) {
- super("illegal type signature: \"" + signature + "\"", cause);
- }
-}
+++ /dev/null
-package sun.reflect.generics.parser;
-
-import java.lang.reflect.Array;
-
-public class SignatureParser {
- private int index = 0;
- private String signature;
- private ClassLoader classLoader;
- private Class<?> type = null;
-
- public SignatureParser(String signature, ClassLoader classLoader)
- throws SignatureFormatError, ClassNotFoundException {
- this.signature = signature;
- this.classLoader = classLoader;
-
- try {
- type = parseSignature();
- }
- catch(IndexOutOfBoundsException e) {
- throw new SignatureFormatError(signature, e);
- }
-
- if (index != signature.length())
- throw new SignatureFormatError(signature);
- }
-
- public SignatureParser(String signature)
- throws SignatureFormatError, ClassNotFoundException {
- this(signature, ClassLoader.getSystemClassLoader());
- }
-
- public Class<?> getType() {
- return type;
- }
-
- private Class<?> parseSignature()
- throws SignatureFormatError, ClassNotFoundException {
- Class<?> type = null;
- char ch = signature.charAt(index);
-
- switch (ch) {
- case 'L':
- int endIndex = signature.indexOf(';', ++index);
-
- if (endIndex == -1) {
- throw new SignatureFormatError(signature);
- }
-
- type = Class.forName(signature.substring(index, endIndex
- ).replace('/', '.'), true, classLoader);
- index = endIndex + 1;
- break;
- case '[':
- /* ignore optional array size */
- do {
- ch = signature.charAt(++ index);
- } while (ch >= '0' && ch <= '9');
- type = Array.newInstance(parseSignature(), 0).getClass();
- break;
- default:
- type = getPrimitiveClassForSignature(ch);
- ++ index;
- }
-
- return type;
- }
-
- private Class<?> getPrimitiveClassForSignature(char typeCode)
- throws SignatureFormatError {
- switch (typeCode) {
- case 'B': return byte.class;
- case 'C': return char.class;
- case 'D': return double.class;
- case 'F': return float.class;
- case 'I': return int.class;
- case 'J': return long.class;
- case 'S': return short.class;
- case 'Z': return boolean.class;
- case 'V': return void.class;
- }
-
- throw new SignatureFormatError(signature);
- }
-}
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: java_lang_reflect_Constructor.c 8123 2007-06-20 23:50:55Z michi $
+ $Id: java_lang_reflect_Constructor.c 8262 2007-08-06 12:44:01Z panzi $
*/
#include <assert.h>
#include <stdlib.h>
+#if defined(ENABLE_ANNOTATIONS)
+#include "vm/vm.h"
+#endif
+
#include "vm/types.h"
#include "native/jni.h"
#include "native/include/java_lang_String.h"
#include "native/include/java_lang_reflect_Constructor.h"
+#if defined(ENABLE_ANNOTATIONS)
+#include "native/include/sun_reflect_ConstantPool.h"
+#include "native/vm/reflect.h"
+#endif
+
#include "native/vm/java_lang_reflect_Constructor.h"
#include "vmcore/utf8.h"
/* native methods implemented by this file ************************************/
static JNINativeMethod methods[] = {
- { "getModifiersInternal", "()I", (void *) (ptrint) &_Jv_java_lang_reflect_Constructor_getModifiers },
- { "getParameterTypes", "()[Ljava/lang/Class;", (void *) (ptrint) &_Jv_java_lang_reflect_Constructor_getParameterTypes },
- { "getExceptionTypes", "()[Ljava/lang/Class;", (void *) (ptrint) &_Jv_java_lang_reflect_Constructor_getExceptionTypes },
- { "constructNative", "([Ljava/lang/Object;Ljava/lang/Class;I)Ljava/lang/Object;", (void *) (ptrint) &Java_java_lang_reflect_Constructor_constructNative },
- { "getSignature", "()Ljava/lang/String;", (void *) (ptrint) &_Jv_java_lang_reflect_Constructor_getSignature },
+ { "getModifiersInternal", "()I", (void *) (ptrint) &_Jv_java_lang_reflect_Constructor_getModifiers },
+ { "getParameterTypes", "()[Ljava/lang/Class;", (void *) (ptrint) &_Jv_java_lang_reflect_Constructor_getParameterTypes },
+ { "getExceptionTypes", "()[Ljava/lang/Class;", (void *) (ptrint) &_Jv_java_lang_reflect_Constructor_getExceptionTypes },
+ { "constructNative", "([Ljava/lang/Object;Ljava/lang/Class;I)Ljava/lang/Object;", (void *) (ptrint) &Java_java_lang_reflect_Constructor_constructNative },
+ { "getSignature", "()Ljava/lang/String;", (void *) (ptrint) &_Jv_java_lang_reflect_Constructor_getSignature },
+#if defined(ENABLE_ANNOTATIONS)
+ { "declaredAnnotations", "()Ljava/util/Map;", (void *) (ptrint) &Java_java_lang_reflect_Constructor_declaredAnnotations },
+ { "getParameterAnnotations", "()[[Ljava/lang/annotation/Annotation;", (void *) (ptrint) &Java_java_lang_reflect_Constructor_getParameterAnnotations },
+#endif
};
}
+#if defined(ENABLE_ANNOTATIONS)
+/*
+ * Class: java/lang/reflect/Constructor
+ * Method: declaredAnnotations
+ * Signature: ()Ljava/util/Map;
+ */
+JNIEXPORT struct java_util_Map* JNICALL Java_java_lang_reflect_Constructor_declaredAnnotations(JNIEnv *env, struct java_lang_reflect_Constructor* this)
+{
+ java_objectheader *o = (java_objectheader*)this;
+
+ if (this == NULL) {
+ exceptions_throw_nullpointerexception();
+ return NULL;
+ }
+
+ return reflect_get_declaredannotatios(&(this->declaredAnnotations), this->annotations, this->clazz, o->vftbl->class);
+}
+
+
+/*
+ * Class: java/lang/reflect/Constructor
+ * Method: getParameterAnnotations
+ * Signature: ()[[Ljava/lang/annotation/Annotation;
+ */
+JNIEXPORT java_objectarray* JNICALL Java_java_lang_reflect_Constructor_getParameterAnnotations(JNIEnv *env, struct java_lang_reflect_Constructor* this)
+{
+ java_objectheader *o = (java_objectheader*)this;
+
+ if (this == NULL) {
+ exceptions_throw_nullpointerexception();
+ return NULL;
+ }
+
+ return reflect_get_parameterannotations((java_objectheader*)this->parameterAnnotations, this->slot, this->clazz, o->vftbl->class);
+}
+#endif
+
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: java_lang_reflect_Field.c 8132 2007-06-22 11:15:47Z twisti $
+ $Id: java_lang_reflect_Field.c 8262 2007-08-06 12:44:01Z panzi $
*/
#include "native/include/java_lang_reflect_Field.h"
+#if defined(ENABLE_ANNOTATIONS)
+#include "native/include/sun_reflect_ConstantPool.h"
+#include "native/vm/reflect.h"
+#endif
+
#include "vm/access.h"
#include "vm/builtin.h"
#include "vm/exceptions.h"
{ "setFloat", "(Ljava/lang/Object;F)V", (void *) (intptr_t) &Java_java_lang_reflect_Field_setFloat },
{ "setDouble", "(Ljava/lang/Object;D)V", (void *) (intptr_t) &Java_java_lang_reflect_Field_setDouble },
{ "getSignature", "()Ljava/lang/String;", (void *) (intptr_t) &Java_java_lang_reflect_Field_getSignature },
+#if defined(ENABLE_ANNOTATIONS)
+ { "declaredAnnotations", "()Ljava/util/Map;", (void *) (intptr_t) &Java_java_lang_reflect_Field_declaredAnnotations },
+#endif
};
}
+#if defined(ENABLE_ANNOTATIONS)
+/*
+ * Class: java/lang/reflect/Field
+ * Method: declaredAnnotations
+ * Signature: ()Ljava/util/Map;
+ */
+JNIEXPORT struct java_util_Map* JNICALL Java_java_lang_reflect_Field_declaredAnnotations(JNIEnv *env, struct java_lang_reflect_Field* this)
+{
+ java_objectheader *o = (java_objectheader*)this;
+
+ if (this == NULL) {
+ exceptions_throw_nullpointerexception();
+ return NULL;
+ }
+
+ return reflect_get_declaredannotatios(&(this->declaredAnnotations), this->annotations, this->clazz, o->vftbl->class);
+}
+#endif
+
+
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: java_lang_reflect_Method.c 8249 2007-07-31 12:59:03Z panzi $
+ $Id: java_lang_reflect_Method.c 8262 2007-08-06 12:44:01Z panzi $
*/
#if defined(ENABLE_ANNOTATIONS)
#include "native/include/sun_reflect_ConstantPool.h"
+#include "native/vm/reflect.h"
#endif
#include "native/include/java_lang_reflect_Method.h"
/* native methods implemented by this file ************************************/
static JNINativeMethod methods[] = {
- { "getModifiersInternal", "()I", (void *) (ptrint) &Java_java_lang_reflect_Method_getModifiersInternal },
- { "getReturnType", "()Ljava/lang/Class;", (void *) (ptrint) &Java_java_lang_reflect_Method_getReturnType },
- { "getParameterTypes", "()[Ljava/lang/Class;", (void *) (ptrint) &Java_java_lang_reflect_Method_getParameterTypes },
- { "getExceptionTypes", "()[Ljava/lang/Class;", (void *) (ptrint) &Java_java_lang_reflect_Method_getExceptionTypes },
- { "invokeNative", "(Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Class;I)Ljava/lang/Object;", (void *) (ptrint) &Java_java_lang_reflect_Method_invokeNative },
- { "getSignature", "()Ljava/lang/String;", (void *) (ptrint) &Java_java_lang_reflect_Method_getSignature },
+ { "getModifiersInternal", "()I", (void *) (ptrint) &Java_java_lang_reflect_Method_getModifiersInternal },
+ { "getReturnType", "()Ljava/lang/Class;", (void *) (ptrint) &Java_java_lang_reflect_Method_getReturnType },
+ { "getParameterTypes", "()[Ljava/lang/Class;", (void *) (ptrint) &Java_java_lang_reflect_Method_getParameterTypes },
+ { "getExceptionTypes", "()[Ljava/lang/Class;", (void *) (ptrint) &Java_java_lang_reflect_Method_getExceptionTypes },
+ { "invokeNative", "(Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Class;I)Ljava/lang/Object;", (void *) (ptrint) &Java_java_lang_reflect_Method_invokeNative },
+ { "getSignature", "()Ljava/lang/String;", (void *) (ptrint) &Java_java_lang_reflect_Method_getSignature },
#if defined(ENABLE_ANNOTATIONS)
- { "getDefaultValue", "()Ljava/lang/Object;", (void *) (ptrint) &Java_java_lang_reflect_Method_getDefaultValue },
+ { "getDefaultValue", "()Ljava/lang/Object;", (void *) (ptrint) &Java_java_lang_reflect_Method_getDefaultValue },
+ { "declaredAnnotations", "()Ljava/util/Map;", (void *) (ptrint) &Java_java_lang_reflect_Method_declaredAnnotations },
+ { "getParameterAnnotations", "()[[Ljava/lang/annotation/Annotation;", (void *) (ptrint) &Java_java_lang_reflect_Method_getParameterAnnotations },
#endif
};
*/
JNIEXPORT struct java_lang_Object* JNICALL Java_java_lang_reflect_Method_getDefaultValue(JNIEnv *env, struct java_lang_reflect_Method* this)
{
- methodinfo *m = NULL;
- utf *utf_parseAnnotationDefault = NULL;
- utf *utf_desc = NULL;
+ static methodinfo *m_parseAnnotationDefault = NULL;
+ utf *utf_parseAnnotationDefault = NULL;
+ utf *utf_desc = NULL;
sun_reflect_ConstantPool *constantPool = NULL;
+ java_objectheader *o = (java_objectheader*)this;
if (this == NULL) {
exceptions_throw_nullpointerexception();
constantPool->constantPoolOop = (java_lang_Object*)this->clazz;
- utf_parseAnnotationDefault = utf_new_char("parseAnnotationDefault");
- utf_desc = utf_new_char(
- "(Ljava/lang/reflect/Method;[BLsun/reflect/ConstantPool;Ljava/lang/Class;)Ljava/lang/Object;");
+ /* only resolve the method the first time */
+ if (m_parseAnnotationDefault == NULL) {
+ utf_parseAnnotationDefault = utf_new_char("parseAnnotationDefault");
+ utf_desc = utf_new_char(
+ "(Ljava/lang/reflect/Method;[BLsun/reflect/ConstantPool;)"
+ "Ljava/lang/Object;");
+
+ if (utf_parseAnnotationDefault == NULL || utf_desc == NULL) {
+ /* out of memory */
+ return NULL;
+ }
+
+ m_parseAnnotationDefault = class_resolveclassmethod(
+ class_sun_reflect_annotation_AnnotationParser,
+ utf_parseAnnotationDefault,
+ utf_desc,
+ o->vftbl->class,
+ true);
+
+ if (m_parseAnnotationDefault == NULL)
+ {
+ /* method not found */
+ return NULL;
+ }
+ }
- if (utf_parseAnnotationDefault == NULL || utf_desc == NULL) {
- /* out of memory */
+ return (java_lang_Object*)vm_call_method(
+ m_parseAnnotationDefault, NULL,
+ this, this->annotationDefault, constantPool);
+}
+
+
+/*
+ * Class: java/lang/reflect/Method
+ * Method: declaredAnnotations
+ * Signature: ()Ljava/util/Map;
+ */
+JNIEXPORT struct java_util_Map* JNICALL Java_java_lang_reflect_Method_declaredAnnotations(JNIEnv *env, struct java_lang_reflect_Method* this)
+{
+ java_objectheader *o = (java_objectheader*)this;
+
+ if (this == NULL) {
+ exceptions_throw_nullpointerexception();
return NULL;
}
- m = class_resolveclassmethod(
- class_sun_reflect_annotation_AnnotationParser,
- utf_parseAnnotationDefault,
- utf_desc,
- ((java_objectheader*)this)->vftbl->class,
- true);
+ return reflect_get_declaredannotatios(&(this->declaredAnnotations), this->annotations, this->clazz, o->vftbl->class);
+}
+
- if (m == NULL)
- {
- /* method not found */
+/*
+ * Class: java/lang/reflect/Method
+ * Method: getParameterAnnotations
+ * Signature: ()[[Ljava/lang/annotation/Annotation;
+ */
+JNIEXPORT java_objectarray* JNICALL Java_java_lang_reflect_Method_getParameterAnnotations(JNIEnv *env, struct java_lang_reflect_Method* this)
+{
+ java_objectheader *o = (java_objectheader*)this;
+
+ if (this == NULL) {
+ exceptions_throw_nullpointerexception();
return NULL;
}
- return (java_lang_Object*)vm_call_method(m, NULL, this, this->annotationDefault, constantPool, this->clazz);
+ return reflect_get_parameterannotations((java_objectheader*)this->parameterAnnotations, this->slot, this->clazz, o->vftbl->class);
}
#endif
+
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: java_lang_Class.c 8249 2007-07-31 12:59:03Z panzi $
+ $Id: java_lang_Class.c 8262 2007-08-06 12:44:01Z panzi $
*/
*/
java_objectarray *_Jv_java_lang_Class_getDeclaredAnnotations(java_lang_Class* klass)
{
- classinfo *c = (classinfo*)klass;
- methodinfo *m = NULL;
- utf *utf_parseAnnotationsIntoArray = NULL;
- utf *utf_desc = NULL;
- java_bytearray *annotations = NULL;
+ classinfo *c = (classinfo*)klass;
+ static methodinfo *m_parseAnnotationsIntoArray = NULL;
+ utf *utf_parseAnnotationsIntoArray = NULL;
+ utf *utf_desc = NULL;
+ java_bytearray *annotations = NULL;
sun_reflect_ConstantPool *constantPool = NULL;
+ uint32_t size = 0;
if (c == NULL) {
exceptions_throw_nullpointerexception();
}
if (c->annotations != NULL) {
- uint32_t size = c->annotations->size;
+ size = c->annotations->size;
annotations = builtin_newarray_byte(size);
- if(annotations != NULL)
- {
+ if(annotations != NULL) {
MCOPY(annotations->data, c->annotations->data, uint8_t, size);
}
}
constantPool->constantPoolOop = (java_lang_Object*)klass;
- utf_parseAnnotationsIntoArray = utf_new_char("parseAnnotationsIntoArray");
- utf_desc = utf_new_char(
- "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;");
+ /* only resolve the method the first time */
+ if (m_parseAnnotationsIntoArray == NULL) {
+ utf_parseAnnotationsIntoArray = utf_new_char("parseAnnotationsIntoArray");
+ utf_desc = utf_new_char(
+ "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
+ "[Ljava/lang/annotation/Annotation;");
- if (utf_parseAnnotationsIntoArray == NULL || utf_desc == NULL) {
- /* out of memory */
- return NULL;
- }
+ if (utf_parseAnnotationsIntoArray == NULL || utf_desc == NULL) {
+ /* out of memory */
+ return NULL;
+ }
- m = class_resolveclassmethod(
- class_sun_reflect_annotation_AnnotationParser,
- utf_parseAnnotationsIntoArray,
- utf_desc,
- class_java_lang_Class,
- true);
+ m_parseAnnotationsIntoArray = class_resolveclassmethod(
+ class_sun_reflect_annotation_AnnotationParser,
+ utf_parseAnnotationsIntoArray,
+ utf_desc,
+ class_java_lang_Class,
+ true);
- if (m == NULL) {
- /* method not found */
- return NULL;
+ if (m_parseAnnotationsIntoArray == NULL) {
+ /* method not found */
+ return NULL;
+ }
}
- return vm_call_method(m, NULL, annotations, constantPool, klass);
+ return vm_call_method(
+ m_parseAnnotationsIntoArray, NULL,
+ annotations, constantPool, klass);
}
#endif
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: reflect.c 8249 2007-07-31 12:59:03Z panzi $
+ $Id: reflect.c 8262 2007-08-06 12:44:01Z panzi $
*/
#if defined(ENABLE_ANNOTATIONS)
#include "mm/memory.h"
+
+#if defined(WITH_CLASSPATH_GNU)
+#include "vm/vm.h"
+
+#include "native/include/sun_reflect_ConstantPool.h"
+#endif
#endif
#include "native/jni.h"
java_objectheader *o;
java_lang_reflect_Constructor *rc;
int32_t slot;
- java_bytearray *annotations = NULL;
- java_bytearray *parameterAnnotations = NULL;
- annotation_bytearray_t *ba = NULL;
+ java_bytearray *annotations = NULL;
+ java_bytearray *parameterAnnotations = NULL;
+ annotation_bytearray_t *ba = NULL;
#if defined(ENABLE_ANNOTATIONS)
/* get annotations */
java_objectheader *o;
java_lang_reflect_Field *rf;
int32_t slot;
- java_bytearray *annotations = NULL;
- annotation_bytearray_t *ba = NULL;
+ java_bytearray *annotations = NULL;
+ annotation_bytearray_t *ba = NULL;
#if defined(ENABLE_ANNOTATIONS)
/* get annotations */
java_objectheader *o;
java_lang_reflect_Method *rm;
int32_t slot;
- java_bytearray *annotations = NULL;
- java_bytearray *parameterAnnotations = NULL;
- java_bytearray *annotationDefault = NULL;
- annotation_bytearray_t *ba = NULL;
+ java_bytearray *annotations = NULL;
+ java_bytearray *parameterAnnotations = NULL;
+ java_bytearray *annotationDefault = NULL;
+ annotation_bytearray_t *ba = NULL;
#if defined(ENABLE_ANNOTATIONS)
/* get annotations */
}
+#if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
+/* reflect_get_declaredannotatios *********************************************
+
+ Returnes a java.util.Map<Class, Annotation> of the declared
+ annotations. Only calls the AnnotationParser if the declared
+ annotations are not yet parsed.
+
+*******************************************************************************/
+
+struct java_util_Map* reflect_get_declaredannotatios(
+ struct java_util_Map **declaredAnnotations,
+ java_bytearray *annotations,
+ java_lang_Class *declaringClass,
+ classinfo *referer)
+{
+ static methodinfo *m_parseAnnotations = NULL;
+ utf *utf_parseAnnotations = NULL;
+ utf *utf_desc = NULL;
+ sun_reflect_ConstantPool *constantPool = NULL;
+
+ if (*declaredAnnotations == NULL) {
+ constantPool =
+ (sun_reflect_ConstantPool*)native_new_and_init(
+ class_sun_reflect_ConstantPool);
+
+ if(constantPool == NULL) {
+ /* out of memory */
+ return NULL;
+ }
+
+ constantPool->constantPoolOop = (java_lang_Object*)declaringClass;
+
+ /* only resolve the method the first time */
+ if (m_parseAnnotations == NULL) {
+ utf_parseAnnotations = utf_new_char("parseAnnotations");
+ utf_desc = utf_new_char(
+ "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
+ "Ljava/util/Map;");
+
+ if (utf_parseAnnotations == NULL || utf_desc == NULL) {
+ /* out of memory */
+ return NULL;
+ }
+
+ m_parseAnnotations = class_resolveclassmethod(
+ class_sun_reflect_annotation_AnnotationParser,
+ utf_parseAnnotations,
+ utf_desc,
+ referer,
+ true);
+
+ if (m_parseAnnotations == NULL) {
+ /* method not found */
+ return NULL;
+ }
+ }
+
+ *declaredAnnotations =
+ (struct java_util_Map*)vm_call_method(
+ m_parseAnnotations, NULL, annotations,
+ constantPool, declaringClass);
+ }
+
+ return *declaredAnnotations;
+}
+
+
+/* reflect_get_parameterannotations *******************************************
+
+ Parses and returns the parameter annotations of a method.
+
+*******************************************************************************/
+
+java_objectarray* reflect_get_parameterannotations(
+ java_objectheader *parameterAnnotations,
+ int32_t slot,
+ java_lang_Class *declaringClass,
+ classinfo *referer)
+{
+ /* This method in java would be basically the following.
+ * We don't do it in java because we don't want to make a
+ * public method with wich you can get a ConstantPool, because
+ * with that you could read any kind of constants (even private
+ * ones).
+ *
+ * ConstantPool constPool = new ConstantPool();
+ * constPool.constantPoolOop = getDeclaringClass();
+ * return sun.reflect.AnnotationParser.parseParameterAnnotations(
+ * parameterAnnotations,
+ * constPool,
+ * getDeclaringClass(),
+ * getParameterTypes().length);
+ */
+ static methodinfo *m_parseParameterAnnotations = NULL;
+ utf *utf_parseParameterAnnotations = NULL;
+ utf *utf_desc = NULL;
+ sun_reflect_ConstantPool *constantPool = NULL;
+ classinfo *c = NULL;
+ methodinfo *m = NULL;
+ int32_t numParameters = -1;
+
+ /* get parameter count */
+
+ c = (classinfo *)declaringClass;
+ m = &(c->methods[slot]);
+
+ numParameters = method_get_parametercount(m);
+
+ if (numParameters < 0) {
+ /* error parsing descriptor */
+ return NULL;
+ }
+
+ /* get ConstantPool */
+
+ constantPool =
+ (sun_reflect_ConstantPool*)native_new_and_init(
+ class_sun_reflect_ConstantPool);
+
+ if(constantPool == NULL) {
+ /* out of memory */
+ return NULL;
+ }
+
+ constantPool->constantPoolOop = (java_lang_Object*)declaringClass;
+
+ /* only resolve the method the first time */
+ if (m_parseParameterAnnotations == NULL) {
+ utf_parseParameterAnnotations = utf_new_char("parseParameterAnnotations");
+ utf_desc = utf_new_char(
+ "([BLsun/reflect/ConstantPool;Ljava/lang/Class;I)"
+ "[[Ljava/lang/annotation/Annotation;");
+
+ if (utf_parseParameterAnnotations == NULL || utf_desc == NULL) {
+ /* out of memory */
+ return NULL;
+ }
+
+ /* get parser method */
+
+ m_parseParameterAnnotations = class_resolveclassmethod(
+ class_sun_reflect_annotation_AnnotationParser,
+ utf_parseParameterAnnotations,
+ utf_desc,
+ referer,
+ true);
+
+ if (m_parseParameterAnnotations == NULL)
+ {
+ /* method not found */
+ return NULL;
+ }
+ }
+
+ return (java_objectarray*)vm_call_method(
+ m_parseParameterAnnotations, NULL, parameterAnnotations,
+ constantPool, declaringClass, numParameters);
+}
+#endif
+
+
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: reflect.h 8172 2007-06-30 14:14:52Z twisti $
+ $Id: reflect.h 8262 2007-08-06 12:44:01Z panzi $
*/
java_lang_reflect_Field *reflect_field_new(fieldinfo *f);
java_lang_reflect_Method *reflect_method_new(methodinfo *m);
+#if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
+struct java_util_Map* reflect_get_declaredannotatios(
+ struct java_util_Map **declaredAnnotations,
+ java_bytearray *annotations,
+ java_lang_Class *declaringClass,
+ classinfo *referer);
+
+java_objectarray* reflect_get_parameterannotations(
+ java_objectheader *parameterAnnotations,
+ int32_t slot,
+ java_lang_Class *declaringClass,
+ classinfo *referer);
+#endif
/*
* These are local overrides for various environment variables in Emacs.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: jvm.c 8256 2007-08-05 10:58:21Z twisti $
+ $Id: jvm.c 8262 2007-08-06 12:44:01Z panzi $
*/
jobjectArray JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass)
{
- log_println("JVM_GetDeclaredClasses: IMPLEMENT ME!");
+ java_lang_Class *c = (java_lang_Class*)ofClass;
+
+ TRACEJVMCALLS("JVM_GetDeclaredClasses: ofClass=%p", ofClass);
+
+ if(c == NULL) {
+ exceptions_throw_nullpointerexception();
+ return NULL;
+ }
+
+ return (jobjectArray)_Jv_java_lang_Class_getDeclaredClasses(c, false);
}
return NULL;
}
- return rf->annotations;
+ return (jbyteArray)rf->annotations;
}
return NULL;
}
- return rm->annotations;
+ return (jbyteArray)rm->annotations;
}
return NULL;
}
- return rm->annotationDefault;
+ return (jbyteArray)rm->annotationDefault;
}
return NULL;
}
- return rm->parameterAnnotations;
+ return (jbyteArray)rm->parameterAnnotations;
}
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
+ $Id$
*/
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: method.c 8249 2007-07-31 12:59:03Z panzi $
+ $Id: method.c 8262 2007-08-06 12:44:01Z panzi $
*/
}
+/* method_get_parametercount **************************************************
+
+ Use the descriptor of a method to determine the number of parameters
+ of the method. The this pointer of non-static methods is not counted.
+
+ Returns -1 on error.
+
+*******************************************************************************/
+
+int32_t method_get_parametercount(methodinfo *m)
+{
+ methoddesc *md;
+ int32_t paramcount = 0;
+
+ md = m->parseddesc;
+
+ /* is the descriptor fully parsed? */
+
+ if (m->parseddesc->params == NULL) {
+ if (!descriptor_params_from_paramtypes(md, m->flags)) {
+ return -1;
+ }
+ }
+
+ paramcount = md->paramcount;
+
+ /* skip `this' pointer */
+
+ if (!(m->flags & ACC_STATIC)) {
+ --paramcount;
+ }
+
+ return paramcount;
+}
+
+
/* method_get_parametertypearray ***********************************************
Use the descriptor of a method to generate a java.lang.Class array
{
methoddesc *md;
typedesc *paramtypes;
- s4 paramcount;
- java_objectarray *oa;
- s4 i;
+ int32_t paramcount;
+ java_objectarray *oa;
+ int32_t i;
classinfo *c;
md = m->parseddesc;
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: method.h 8249 2007-07-31 12:59:03Z panzi $
+ $Id: method.h 8262 2007-08-06 12:44:01Z panzi $
*/
methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m);
+int32_t method_get_parametercount(methodinfo *m);
java_objectarray *method_get_parametertypearray(methodinfo *m);
java_objectarray *method_get_exceptionarray(methodinfo *m);
classinfo *method_returntype_get(methodinfo *m);