aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2006-05-24 17:21:52 +0000
committerTom Tromey <tromey@gcc.gnu.org>2006-05-24 17:21:52 +0000
commit5aca4c41f72573edb4c22736ac46ff3abf7d625a (patch)
tree146a4086fddb5d1c805267e25f1a64634a5ae1a9
parentf32f60c997d57ba70a977804cdfb07068557033f (diff)
downloadgcc-5aca4c41f72573edb4c22736ac46ff3abf7d625a.zip
gcc-5aca4c41f72573edb4c22736ac46ff3abf7d625a.tar.gz
gcc-5aca4c41f72573edb4c22736ac46ff3abf7d625a.tar.bz2
re PR libgcj/27729 (Field, Method and Constructor need isSynthetic() implemetation)
gcc/java: PR libgcj/27729: * jcf.h (ACC_INVISIBLE): Changed value. libjava: PR libgcj/27729: * java/lang/reflect/natField.cc (getAddr): Added parens. * java/lang/reflect/natConstructor.cc (getModifiersInternal): Renamed. Don't mask flags. * java/lang/reflect/Constructor.java (CONSTRUCTOR_MODIFIERS): New constant. (getModifiersInternal): Renamed. (getModifiers): Rewrote. (isSynthetic, isVarArgs): New methods. (hashCode): Rewrote. (addTypeParameters, toGenericString): New methods. (getTypeParameters): Rewrote. (getSignature): New method. (getGenericParameterTypes, getGenericExceptionTypes): Likewise. * java/lang/reflect/natMethod.cc (getModifiersInternal): Renamed. Don't mask flags. * java/lang/reflect/natField.cc (getModifiersInternal): Renamed. Don't mask flags. * java/lang/reflect/Modifier.java (BRIDGE, VARARGS, SYNTHETIC, ENUM): New constants. (INVISIBLE): Changed value. * java/lang/reflect/Method.java: Mostly merged with Classpath. (getModifiersInternal): Renamed. (getModifiers): Rewrote. (isBridge, isSynthetic, isVarArgs): New methods. (toGenericString): Likewise. (getTypeParameters): Likewise. (getSignature): Likewise. (getGenericExceptionTypes, getGenericParameterTypes, getGenericReturnType): Likewise. (METHOD_MODIFIERS): New constant. * java/lang/reflect/Field.java: Mostly merged with Classpath. Added javadoc everywhere. (getModifiersInternal): Renamed. (getModifiers, isSynthetic, isEnumConstant): Rewrote. (toGenericString): New method. (getGenericType, getSignature): Likewise. (FIELD_MODIFIERS): New constant. From-SVN: r114046
-rw-r--r--gcc/java/ChangeLog5
-rw-r--r--gcc/java/jcf.h6
-rw-r--r--libjava/ChangeLog41
-rw-r--r--libjava/java/lang/reflect/Constructor.java204
-rw-r--r--libjava/java/lang/reflect/Field.java707
-rw-r--r--libjava/java/lang/reflect/Method.java210
-rw-r--r--libjava/java/lang/reflect/Modifier.java36
-rw-r--r--libjava/java/lang/reflect/natConstructor.cc7
-rw-r--r--libjava/java/lang/reflect/natField.cc8
-rw-r--r--libjava/java/lang/reflect/natMethod.cc7
10 files changed, 1068 insertions, 163 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index fbdb9a0..8f2af57 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,8 @@
+2006-05-24 Tom Tromey <tromey@redhat.com>
+
+ PR libgcj/27729:
+ * jcf.h (ACC_INVISIBLE): Changed value.
+
2006-05-24 Andrew Haley <aph@redhat.com>
PR java/27754
diff --git a/gcc/java/jcf.h b/gcc/java/jcf.h
index 87c7a6e..9c6bc8e 100644
--- a/gcc/java/jcf.h
+++ b/gcc/java/jcf.h
@@ -1,5 +1,5 @@
/* Utility macros to read Java(TM) .class files and byte codes.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
Free Software Foundation, Inc.
This file is part of GCC.
@@ -231,8 +231,8 @@ typedef struct JCF GTY(()) {
#define ACC_ABSTRACT 0x0400
#define ACC_STRICT 0x0800
/* "Invisible" refers to Miranda methods inserted into an abstract
- #class. It is also used in the runtime. */
-#define ACC_INVISIBLE 0x1000
+ class. It is also used in the runtime. */
+#define ACC_INVISIBLE 0x8000
#define ACC_VISIBILITY (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED)
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index f66b766..4643064 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,5 +1,46 @@
2006-05-24 Tom Tromey <tromey@redhat.com>
+ PR libgcj/27729:
+ * java/lang/reflect/natField.cc (getAddr): Added parens.
+ * java/lang/reflect/natConstructor.cc (getModifiersInternal):
+ Renamed. Don't mask flags.
+ * java/lang/reflect/Constructor.java (CONSTRUCTOR_MODIFIERS): New
+ constant.
+ (getModifiersInternal): Renamed.
+ (getModifiers): Rewrote.
+ (isSynthetic, isVarArgs): New methods.
+ (hashCode): Rewrote.
+ (addTypeParameters, toGenericString): New methods.
+ (getTypeParameters): Rewrote.
+ (getSignature): New method.
+ (getGenericParameterTypes, getGenericExceptionTypes): Likewise.
+ * java/lang/reflect/natMethod.cc (getModifiersInternal):
+ Renamed. Don't mask flags.
+ * java/lang/reflect/natField.cc (getModifiersInternal): Renamed.
+ Don't mask flags.
+ * java/lang/reflect/Modifier.java (BRIDGE, VARARGS, SYNTHETIC,
+ ENUM): New constants.
+ (INVISIBLE): Changed value.
+ * java/lang/reflect/Method.java: Mostly merged with Classpath.
+ (getModifiersInternal): Renamed.
+ (getModifiers): Rewrote.
+ (isBridge, isSynthetic, isVarArgs): New methods.
+ (toGenericString): Likewise.
+ (getTypeParameters): Likewise.
+ (getSignature): Likewise.
+ (getGenericExceptionTypes, getGenericParameterTypes,
+ getGenericReturnType): Likewise.
+ (METHOD_MODIFIERS): New constant.
+ * java/lang/reflect/Field.java: Mostly merged with Classpath.
+ Added javadoc everywhere.
+ (getModifiersInternal): Renamed.
+ (getModifiers, isSynthetic, isEnumConstant): Rewrote.
+ (toGenericString): New method.
+ (getGenericType, getSignature): Likewise.
+ (FIELD_MODIFIERS): New constant.
+
+2006-05-24 Tom Tromey <tromey@redhat.com>
+
PR libgcj/27731:
* java/lang/natMath.cc (cbrt, cosh, expm1, hypot, log1p, sinh,
tanh): New methods.
diff --git a/libjava/java/lang/reflect/Constructor.java b/libjava/java/lang/reflect/Constructor.java
index b789fb1..68b2d39 100644
--- a/libjava/java/lang/reflect/Constructor.java
+++ b/libjava/java/lang/reflect/Constructor.java
@@ -1,15 +1,46 @@
-// Constructor.java - Represents a constructor for a class.
+/* java.lang.reflect.Constructor - reflection of Java constructors
+ Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
-/* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation
+This file is part of GNU Classpath.
- This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
+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.reflect.MethodSignatureParser;
+
/**
* The Constructor class represents a constructor of a class. It also allows
* dynamic creation of an object, via reflection. Invocation on Constructor
@@ -37,8 +68,8 @@ package java.lang.reflect;
* @author Tom Tromey <tromey@redhat.com>
* @see Member
* @see Class
- * @see java.lang.Class#getConstructor(Object[])
- * @see java.lang.Class#getDeclaredConstructor(Object[])
+ * @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
@@ -47,6 +78,9 @@ package java.lang.reflect;
public final class Constructor extends AccessibleObject
implements Member, GenericDeclaration
{
+ private static final int CONSTRUCTOR_MODIFIERS
+ = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
+
/**
* This class is uninstantiable except from native code.
*/
@@ -58,7 +92,7 @@ public final class Constructor extends AccessibleObject
* Gets the class that declared this constructor.
* @return the class that declared this member
*/
- public Class getDeclaringClass ()
+ public Class getDeclaringClass()
{
return declaringClass;
}
@@ -68,12 +102,19 @@ public final class Constructor extends AccessibleObject
* it was declared in).
* @return the name of this constructor
*/
- public String getName ()
+ public String getName()
{
return declaringClass.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.
@@ -81,7 +122,31 @@ public final class Constructor extends AccessibleObject
* @return an integer representing the modifiers to this Member
* @see Modifier
*/
- public native int getModifiers ();
+ 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
@@ -127,14 +192,14 @@ public final class Constructor extends AccessibleObject
}
/**
- * Get the hash code for the Constructor.
+ * 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 ()
{
- // FIXME.
- return getName().hashCode() + declaringClass.getName().hashCode();
+ return declaringClass.getName().hashCode();
}
/**
@@ -147,7 +212,7 @@ public final class Constructor extends AccessibleObject
*
* @return the String representation of the Constructor
*/
- public String toString ()
+ public String toString()
{
if (parameter_types == null)
getType ();
@@ -170,6 +235,45 @@ public final class Constructor extends AccessibleObject
return b.toString();
}
+ /* FIXME[GENERICS]: Add X extends GenericDeclaration and TypeVariable<X> */
+ static void addTypeParameters(StringBuilder sb, TypeVariable[] 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>
@@ -204,26 +308,78 @@ public final class Constructor extends AccessibleObject
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException;
- // FIXME - Write a real implementation
- public boolean isSynthetic() { return false; }
-
/**
* 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 class has no type
+ * An array of size zero is returned if this constructor has no type
* variables.
*
- * @return the type variables associated with this class.
+ * @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
*/
- /* FIXME[GENERICS]: Should be TypeVariable<Method>[] */
+ /* FIXME[GENERICS]: Add <Constructor<T>> */
public TypeVariable[] getTypeParameters()
{
- // FIXME - write a real implementation
- return new TypeVariable[0];
+ 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 String getSignature()
+ {
+ // FIXME: libgcj doesn't record this information yet.
+ return null;
+ }
+
+ /**
+ * 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();
}
// Update cached values from method descriptor in class.
diff --git a/libjava/java/lang/reflect/Field.java b/libjava/java/lang/reflect/Field.java
index 10884c1..134ff13 100644
--- a/libjava/java/lang/reflect/Field.java
+++ b/libjava/java/lang/reflect/Field.java
@@ -1,23 +1,85 @@
-/* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation
+/* java.lang.reflect.Field - reflection of Java fields
+ Copyright (C) 1998, 2001, 2005, 2006 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. */
- This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
package java.lang.reflect;
+import gnu.java.lang.ClassHelper;
+
+import gnu.java.lang.reflect.FieldSignatureParser;
+
/**
+ * The Field class represents a member variable of a class. It also allows
+ * dynamic access to a member, via reflection. This works for both
+ * static and instance fields. Operations on Field objects know how to
+ * do widening conversions, but throw {@link IllegalArgumentException} if
+ * a narrowing conversion would be necessary. You can query for information
+ * on this Field regardless of location, but get and set 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>
* @author Per Bothner <bothner@cygnus.com>
- * @date September 1998; February 1999.
+ * @see Member
+ * @see Class
+ * @see Class#getField(String)
+ * @see Class#getDeclaredField(String)
+ * @see Class#getFields()
+ * @see Class#getDeclaredFields()
+ * @since 1.1
+ * @status updated to 1.4
*/
-
-public final class Field extends AccessibleObject implements Member
+public final class Field
+ extends AccessibleObject implements Member
{
private Class declaringClass;
-
- // This is filled in by getName.
private String name;
// Offset in bytes from the start of declaringClass's fields array.
@@ -26,12 +88,87 @@ public final class Field extends AccessibleObject implements Member
// The Class (or primitive TYPE) of this field.
private Class type;
+ private static final int FIELD_MODIFIERS
+ = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
+ | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
+ | Modifier.VOLATILE;
+
// This is instantiated by Class sometimes, but it uses C++ and
// avoids the Java protection check.
Field ()
{
}
+ /**
+ * Gets the class that declared this field, or the class where this field
+ * is a non-inherited member.
+ * @return the class that declared this member
+ */
+ public Class getDeclaringClass()
+ {
+ return declaringClass;
+ }
+
+ /**
+ * Gets the name of this field.
+ * @return the name of this field
+ */
+ public native String getName();
+
+ /**
+ * Return the raw modifiers for this field.
+ * @return the field's modifiers
+ */
+ private native int getModifiersInternal();
+
+ /**
+ * Gets the modifiers this field uses. Use the <code>Modifier</code>
+ * class to interpret the values. A field can only have a subset of the
+ * following modifiers: public, private, protected, static, final,
+ * transient, and volatile.
+ *
+ * @return an integer representing the modifiers to this Member
+ * @see Modifier
+ */
+ public int getModifiers()
+ {
+ return getModifiersInternal() & FIELD_MODIFIERS;
+ }
+
+ /**
+ * Return true if this field is synthetic, false otherwise.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this field represents an enum constant,
+ * false otherwise.
+ * @since 1.5
+ */
+ public boolean isEnumConstant()
+ {
+ return (getModifiersInternal() & Modifier.ENUM) != 0;
+ }
+
+ /**
+ * Gets the type of this field.
+ * @return the type of this field
+ */
+ public native Class getType();
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Fields are semantically equivalent if they have the same declaring
+ * class, name, and type. Since you can't creat a Field 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 fld)
{
if (! (fld instanceof Field))
@@ -40,75 +177,281 @@ public final class Field extends AccessibleObject implements Member
return declaringClass == f.declaringClass && offset == f.offset;
}
- public Class getDeclaringClass ()
+ /**
+ * Get the hash code for the Field. The Field hash code is the hash code
+ * of its name XOR'd with the hash code of its class name.
+ *
+ * @return the hash code for the object.
+ */
+ public int hashCode()
{
- return declaringClass;
+ return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
}
- public native String getName ();
-
- public native Class getType ();
+ /**
+ * Get a String representation of the Field. A Field's String
+ * representation is "&lt;modifiers&gt; &lt;type&gt;
+ * &lt;class&gt;.&lt;fieldname&gt;".<br> Example:
+ * <code>public transient boolean gnu.parse.Parser.parseComplete</code>
+ *
+ * @return the String representation of the Field
+ */
+ public String toString ()
+ {
+ StringBuffer sbuf = new StringBuffer ();
+ int mods = getModifiers();
+ if (mods != 0)
+ {
+ Modifier.toString(mods, sbuf);
+ sbuf.append(' ');
+ }
+ Method.appendClassName (sbuf, getType ());
+ sbuf.append(' ');
+ Method.appendClassName (sbuf, getDeclaringClass());
+ sbuf.append('.');
+ sbuf.append(getName());
+ return sbuf.toString();
+ }
- public native int getModifiers ();
+ public String toGenericString()
+ {
+ StringBuilder sb = new StringBuilder(64);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ sb.append(getGenericType()).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
+ sb.append(getName());
+ return sb.toString();
+ }
- public int hashCode()
+ /**
+ * Get the value of this Field. If it is primitive, it will be wrapped
+ * in the appropriate wrapper type (boolean = java.lang.Boolean).<p>
+ *
+ * If the field is static, <code>o</code> will be ignored. Otherwise, if
+ * <code>o</code> is null, you get a <code>NullPointerException</code>,
+ * and if it is incompatible with the declaring class of the field, you
+ * get an <code>IllegalArgumentException</code>.<p>
+ *
+ * Next, if this Field enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not access this field in similar compiled code. If the field
+ * is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the field is accessed, and primitives are wrapped (but not
+ * necessarily in new objects). This method accesses the field of the
+ * declaring class, even if the instance passed in belongs to a subclass
+ * which declares another field to hide this one.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if <code>o</code> is not an instance of
+ * the class or interface declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #getBoolean(Object)
+ * @see #getByte(Object)
+ * @see #getChar(Object)
+ * @see #getShort(Object)
+ * @see #getInt(Object)
+ * @see #getLong(Object)
+ * @see #getFloat(Object)
+ * @see #getDouble(Object)
+ */
+ public Object get(Object obj)
+ throws IllegalAccessException
{
- return (declaringClass.hashCode() ^ offset);
+ return get(null, obj);
}
- public boolean getBoolean (Object obj)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Get the value of this boolean Field. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a boolean field of
+ * <code>o</code>, or if <code>o</code> is not an instance of the
+ * declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public boolean getBoolean(Object obj)
+ throws IllegalAccessException
{
return getBoolean(null, obj);
}
- public char getChar (Object obj)
- throws IllegalArgumentException, IllegalAccessException
+
+ /**
+ * Get the value of this byte Field. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte field of
+ * <code>o</code>, or if <code>o</code> is not an instance of the
+ * declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public byte getByte(Object obj)
+ throws IllegalAccessException
{
- return getChar(null, obj);
+ return getByte(null, obj);
}
- public byte getByte (Object obj)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Get the value of this Field as a char. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a char field of
+ * <code>o</code>, or if <code>o</code> is not an instance
+ * of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public char getChar(Object obj)
+ throws IllegalAccessException
{
- return getByte(null, obj);
+ return getChar(null, obj);
}
- public short getShort (Object obj)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Get the value of this Field as a short. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte or short
+ * field of <code>o</code>, or if <code>o</code> is not an instance
+ * of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public short getShort(Object obj)
+ throws IllegalAccessException
{
return getShort(null, obj);
}
- public int getInt (Object obj)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Get the value of this Field as an int. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, or
+ * int field of <code>o</code>, or if <code>o</code> is not an
+ * instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public int getInt(Object obj)
+ throws IllegalAccessException
{
return getInt(null, obj);
}
- public long getLong (Object obj)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Get the value of this Field as a long. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * or long field of <code>o</code>, or if <code>o</code> is not an
+ * instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public long getLong(Object obj)
+ throws IllegalAccessException
{
return getLong(null, obj);
}
- public float getFloat (Object obj)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Get the value of this Field as a float. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * long, or float field of <code>o</code>, or if <code>o</code> is
+ * not an instance of the declaring class of this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public float getFloat(Object obj)
+ throws IllegalAccessException
{
return getFloat(null, obj);
}
- public double getDouble (Object obj)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Get the value of this Field as a double. If the field is static,
+ * <code>o</code> will be ignored.
+ *
+ * @param o the object to get the value of this Field from
+ * @return the value of the Field
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, char, int,
+ * long, float, or double field of <code>o</code>, or if
+ * <code>o</code> is not an instance of the declaring class of this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #get(Object)
+ */
+ public double getDouble(Object obj)
+ throws IllegalAccessException
{
return getDouble(null, obj);
}
- public Object get (Object obj)
- throws IllegalArgumentException, IllegalAccessException
- {
- return get(null, obj);
- }
-
private native boolean getBoolean (Class caller, Object obj)
throws IllegalArgumentException, IllegalAccessException;
@@ -136,52 +479,268 @@ public final class Field extends AccessibleObject implements Member
private native Object get (Class caller, Object obj)
throws IllegalArgumentException, IllegalAccessException;
- public void setByte (Object obj, byte b)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Set the value of this Field. If it is a primitive field, the value
+ * will be unwrapped from the passed object (boolean = java.lang.Boolean).<p>
+ *
+ * If the field is static, <code>o</code> will be ignored. Otherwise, if
+ * <code>o</code> is null, you get a <code>NullPointerException</code>,
+ * and if it is incompatible with the declaring class of the field, you
+ * get an <code>IllegalArgumentException</code>.<p>
+ *
+ * Next, if this Field enforces access control, your runtime context is
+ * evaluated, and you may have an <code>IllegalAccessException</code> if
+ * you could not access this field in similar compiled code. This also
+ * occurs whether or not there is access control if the field is final.
+ * If the field is primitive, and unwrapping your argument fails, you will
+ * get an <code>IllegalArgumentException</code>; likewise, this error
+ * happens if <code>value</code> cannot be cast to the correct object type.
+ * If the field is static, and its class is uninitialized, you trigger class
+ * initialization, which may end in a
+ * <code>ExceptionInInitializerError</code>.<p>
+ *
+ * Finally, the field is set with the widened value. This method accesses
+ * the field of the declaring class, even if the instance passed in belongs
+ * to a subclass which declares another field to hide this one.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if <code>value</code> cannot be
+ * converted by a widening conversion to the underlying type of
+ * the Field, or if <code>o</code> is not an instance of the class
+ * declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #setBoolean(Object, boolean)
+ * @see #setByte(Object, byte)
+ * @see #setChar(Object, char)
+ * @see #setShort(Object, short)
+ * @see #setInt(Object, int)
+ * @see #setLong(Object, long)
+ * @see #setFloat(Object, float)
+ * @see #setDouble(Object, double)
+ */
+ public void set(Object object, Object value)
+ throws IllegalAccessException
+ {
+ set(null, object, value);
+ }
+
+ /**
+ * Set this boolean Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a boolean field, or if
+ * <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setBoolean(Object obj, boolean b)
+ throws IllegalAccessException
+ {
+ setBoolean(null, obj, b, true);
+ }
+
+ /**
+ * Set this byte Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a byte, short, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setByte(Object obj, byte b)
+ throws IllegalAccessException
{
setByte(null, obj, b, true);
}
- public void setShort (Object obj, short s)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Set this char Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a char, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setChar(Object obj, char c)
+ throws IllegalAccessException
+ {
+ setChar(null, obj, c, true);
+ }
+
+ /**
+ * Set this short Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a short, int, long,
+ * float, or double field, or if <code>o</code> is not an instance
+ * of the class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setShort(Object obj, short s)
+ throws IllegalAccessException
{
setShort(null, obj, s, true);
}
- public void setInt (Object obj, int i)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Set this int Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not an int, long, float, or
+ * double field, or if <code>o</code> is not an instance of the
+ * class declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setInt(Object obj, int i)
+ throws IllegalAccessException
{
setInt(null, obj, i, true);
}
- public void setLong (Object obj, long l)
+ /**
+ * Set this long Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a long, float, or double
+ * field, or if <code>o</code> is not an instance of the class
+ * declaring this field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
setLong(null, obj, l, true);
}
- public void setFloat (Object obj, float f)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Set this float Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a float or long field, or
+ * if <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setFloat(Object obj, float f)
+ throws IllegalAccessException
{
setFloat(null, obj, f, true);
}
- public void setDouble (Object obj, double d)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Set this double Field. If the field is static, <code>o</code> will be
+ * ignored.
+ *
+ * @param o the object to set this Field on
+ * @param value the value to set this Field to
+ * @throws IllegalAccessException if you could not normally access this field
+ * (i.e. it is not public)
+ * @throws IllegalArgumentException if this is not a double field, or if
+ * <code>o</code> is not an instance of the class declaring this
+ * field
+ * @throws NullPointerException if <code>o</code> is null and this field
+ * requires an instance
+ * @throws ExceptionInInitializerError if accessing a static field triggered
+ * class initialization, which then failed
+ * @see #set(Object, Object)
+ */
+ public void setDouble(Object obj, double d)
+ throws IllegalAccessException
{
setDouble(null, obj, d, true);
}
- public void setChar (Object obj, char c)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Return the generic type of the field. If the field type is not a generic
+ * type, the method returns the same as <code>getType()</code>.
+ *
+ * @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 getGenericType()
{
- setChar(null, obj, c, true);
+ String signature = getSignature();
+ if (signature == null)
+ return getType();
+ FieldSignatureParser p = new FieldSignatureParser(getDeclaringClass(),
+ signature);
+ return p.getFieldType();
}
- public void setBoolean (Object obj, boolean b)
- throws IllegalArgumentException, IllegalAccessException
+ /**
+ * Return the String in the Signature attribute for this field. If there
+ * is no Signature attribute, return null.
+ */
+ private String getSignature()
{
- setBoolean(null, obj, b, true);
+ // FIXME: libgcj doesn't record Signature attributes yet.
+ return null;
}
native void setByte (Class caller, Object obj, byte b, boolean checkFinal)
@@ -214,12 +773,6 @@ public final class Field extends AccessibleObject implements Member
boolean checkFinal)
throws IllegalArgumentException, IllegalAccessException;
- public void set (Object object, Object value)
- throws IllegalArgumentException, IllegalAccessException
- {
- set(null, object, value);
- }
-
private void set (Class caller, Object object, Object value)
throws IllegalArgumentException, IllegalAccessException
{
@@ -245,26 +798,4 @@ public final class Field extends AccessibleObject implements Member
else
throw new IllegalArgumentException();
}
-
- public String toString ()
- {
- StringBuffer sbuf = new StringBuffer ();
- int mods = getModifiers();
- if (mods != 0)
- {
- Modifier.toString(mods, sbuf);
- sbuf.append(' ');
- }
- Method.appendClassName (sbuf, getType ());
- sbuf.append(' ');
- Method.appendClassName (sbuf, getDeclaringClass());
- sbuf.append('.');
- sbuf.append(getName());
- return sbuf.toString();
- }
-
- // FIXME - Write a real implementations
- public boolean isSynthetic() { return false; }
- public boolean isEnumConstant() { return false; }
-
}
diff --git a/libjava/java/lang/reflect/Method.java b/libjava/java/lang/reflect/Method.java
index a5047f5..3142d64 100644
--- a/libjava/java/lang/reflect/Method.java
+++ b/libjava/java/lang/reflect/Method.java
@@ -1,6 +1,6 @@
// Method.java - Represent method of class or interface.
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006 Free Software Foundation
This file is part of libgcj.
@@ -11,6 +11,7 @@ details. */
package java.lang.reflect;
import gnu.gcj.RawData;
+import gnu.java.lang.reflect.MethodSignatureParser;
/**
* The Method class represents a member method of a class. It also allows
@@ -39,16 +40,21 @@ import gnu.gcj.RawData;
* @author Tom Tromey <tromey@redhat.com>
* @see Member
* @see Class
- * @see java.lang.Class#getMethod(String,Object[])
- * @see java.lang.Class#getDeclaredMethod(String,Object[])
+ * @see java.lang.Class#getMethod(String,Class[])
+ * @see java.lang.Class#getDeclaredMethod(String,Class[])
* @see java.lang.Class#getMethods()
* @see java.lang.Class#getDeclaredMethods()
* @since 1.1
* @status updated to 1.4
*/
-public final class Method extends AccessibleObject
- implements Member, GenericDeclaration
+public final class Method
+ extends AccessibleObject implements Member, GenericDeclaration
{
+ private static final int METHOD_MODIFIERS
+ = Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE
+ | Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC
+ | Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED;
+
/**
* This class is uninstantiable.
*/
@@ -61,7 +67,7 @@ public final class Method extends AccessibleObject
* is a non-inherited member.
* @return the class that declared this member
*/
- public Class getDeclaringClass ()
+ public Class getDeclaringClass()
{
return declaringClass;
}
@@ -73,6 +79,12 @@ public final class Method extends AccessibleObject
public native String getName ();
/**
+ * Return the raw modifiers for this method.
+ * @return the method's modifiers
+ */
+ private native int getModifiersInternal();
+
+ /**
* Gets the modifiers this method uses. Use the <code>Modifier</code>
* class to interpret the values. A method can only have a subset of the
* following modifiers: public, private, protected, abstract, static,
@@ -81,7 +93,40 @@ public final class Method extends AccessibleObject
* @return an integer representing the modifiers to this Member
* @see Modifier
*/
- public native int getModifiers ();
+ public int getModifiers()
+ {
+ return getModifiersInternal() & METHOD_MODIFIERS;
+ }
+
+ /**
+ * Return true if this method is a bridge method. A bridge method
+ * is generated by the compiler in some situations involving
+ * generics and inheritance.
+ * @since 1.5
+ */
+ public boolean isBridge()
+ {
+ return (getModifiersInternal() & Modifier.BRIDGE) != 0;
+ }
+
+ /**
+ * Return true if this method is synthetic, false otherwise.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this is a varargs method, that is if
+ * the method takes a variable number of arguments.
+ * @since 1.5
+ */
+ public boolean isVarArgs()
+ {
+ return (getModifiersInternal() & Modifier.VARARGS) != 0;
+ }
/**
* Gets the return type of this method.
@@ -139,14 +184,14 @@ public final class Method extends AccessibleObject
}
/**
- * Get the hash code for the Method.
+ * Get the hash code for the Method. The Method hash code is the hash code
+ * of its name XOR'd with the hash code of its class name.
*
* @return the hash code for the object
*/
- public int hashCode ()
+ public int hashCode()
{
- // FIXME.
- return getName().hashCode() + declaringClass.getName().hashCode();
+ return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
}
/**
@@ -158,7 +203,7 @@ public final class Method extends AccessibleObject
*
* @return the String representation of the Method
*/
- public String toString ()
+ public String toString()
{
if (parameter_types == null)
getType ();
@@ -196,6 +241,33 @@ public final class Method extends AccessibleObject
return b.toString();
}
+ public String toGenericString()
+ {
+ // 128 is a reasonable buffer initial size for constructor
+ StringBuilder sb = new StringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ Constructor.addTypeParameters(sb, getTypeParameters());
+ sb.append(getGenericReturnType()).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
+ sb.append(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();
+ }
+
/**
* Invoke the method. Arguments are automatically unwrapped and widened,
* and the result is automatically wrapped, if needed.<p>
@@ -241,6 +313,98 @@ public final class Method extends AccessibleObject
throws IllegalAccessException, IllegalArgumentException,
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 class has no type
+ * variables.
+ *
+ * @return the type variables associated with this class.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ /* FIXME[GENERICS]: Should be TypeVariable<Method>[] */
+ public TypeVariable[] 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 method. If there
+ * is no Signature attribute, return null.
+ */
+ private String getSignature()
+ {
+ // FIXME: libgcj doesn't record this information yet.
+ return null;
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the exception types declared by this method, in declaration order.
+ * An array of size zero is returned if this method declares no
+ * exceptions.
+ *
+ * @return the exception types declared by this method.
+ * @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 method, in declaration order.
+ * An array of size zero is returned if this method takes no
+ * parameters.
+ *
+ * @return a list of the types of the method'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();
+ }
+
+ /**
+ * Returns the return type of this method.
+ *
+ * @return the return type of this method
+ * @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 getGenericReturnType()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getReturnType();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericReturnType();
+ }
+
private native void getType ();
// Append a class name to a string buffer. We try to print the
@@ -263,28 +427,6 @@ public final class Method extends AccessibleObject
}
}
- // FIXME - Write a real implementation
- public boolean isSynthetic() { return false; }
-
- /**
- * 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 class has no type
- * variables.
- *
- * @return the type variables associated with this class.
- * @throws GenericSignatureFormatError if the generic signature does
- * not conform to the format specified in the Virtual Machine
- * specification, version 3.
- * @since 1.5
- */
- /* FIXME[GENERICS]: Should be TypeVariable<Method>[] */
- public TypeVariable[] getTypeParameters()
- {
- // FIXME - write a real implementation
- return new TypeVariable[0];
- }
-
// Declaring class.
private Class declaringClass;
diff --git a/libjava/java/lang/reflect/Modifier.java b/libjava/java/lang/reflect/Modifier.java
index 662dfe3..f9a9ca2 100644
--- a/libjava/java/lang/reflect/Modifier.java
+++ b/libjava/java/lang/reflect/Modifier.java
@@ -1,5 +1,5 @@
/* java.lang.reflect.Modifier
- Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -158,10 +158,30 @@ public class Modifier
static final int ALL_FLAGS = 0xfff;
/**
+ * Flag indicating a bridge method.
+ */
+ static final int BRIDGE = 0x40;
+
+ /**
+ * Flag indicating a varargs method.
+ */
+ static final int VARARGS = 0x80;
+
+ /**
+ * Flag indicating a synthetic member.
+ */
+ static final int SYNTHETIC = 0x1000;
+
+ /**
+ * Flag indicating an enum constant or an enum class.
+ */
+ static final int ENUM = 0x4000;
+
+ /**
* GCJ-LOCAL: This access flag is set on methods we declare
* internally but which must not be visible to reflection.
*/
- static final int INVISIBLE = 0x1000;
+ static final int INVISIBLE = 0x8000;
/**
* GCJ-LOCAL: This access flag is set on interpreted classes.
@@ -303,6 +323,18 @@ public class Modifier
}
/**
+ * Package helper method that can take a StringBuilder.
+ * @param mod the modifier
+ * @param r the StringBuilder to which the String representation is appended
+ * @return r, with information appended
+ */
+ static StringBuilder toString(int mod, StringBuilder r)
+ {
+ r.append(toString(mod, new StringBuffer()));
+ return r;
+ }
+
+ /**
* Package helper method that can take a StringBuffer.
* @param mod the modifier
* @param r the StringBuffer to which the String representation is appended
diff --git a/libjava/java/lang/reflect/natConstructor.cc b/libjava/java/lang/reflect/natConstructor.cc
index f4d9590..35cf7f8 100644
--- a/libjava/java/lang/reflect/natConstructor.cc
+++ b/libjava/java/lang/reflect/natConstructor.cc
@@ -1,6 +1,6 @@
// natConstructor.cc - Native code for Constructor class.
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2006 Free Software Foundation
This file is part of libgcj.
@@ -24,10 +24,9 @@ details. */
#include <gcj/method.h>
jint
-java::lang::reflect::Constructor::getModifiers ()
+java::lang::reflect::Constructor::getModifiersInternal ()
{
- // Ignore all unknown flags.
- return _Jv_FromReflectedConstructor (this)->accflags & Modifier::ALL_FLAGS;
+ return _Jv_FromReflectedConstructor (this)->accflags;
}
void
diff --git a/libjava/java/lang/reflect/natField.cc b/libjava/java/lang/reflect/natField.cc
index 33a5717..ae68639 100644
--- a/libjava/java/lang/reflect/natField.cc
+++ b/libjava/java/lang/reflect/natField.cc
@@ -1,6 +1,6 @@
// natField.cc - Implementation of java.lang.reflect.Field native methods.
-/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006 Free Software Foundation
This file is part of libgcj.
@@ -30,9 +30,9 @@ details. */
#include <java/lang/Character.h>
jint
-java::lang::reflect::Field::getModifiers ()
+java::lang::reflect::Field::getModifiersInternal ()
{
- return _Jv_FromReflectedField (this)->getModifiers ();
+ return _Jv_FromReflectedField (this)->flags;
}
jstring
@@ -72,7 +72,7 @@ getAddr (java::lang::reflect::Field* field, jclass caller, jobject obj,
// Setting a final field is usually not allowed.
if (checkFinal
- && field->getModifiers() & java::lang::reflect::Modifier::FINAL)
+ && (field->getModifiers() & java::lang::reflect::Modifier::FINAL))
throw new java::lang::IllegalAccessException(JvNewStringUTF
("Field is final"));
diff --git a/libjava/java/lang/reflect/natMethod.cc b/libjava/java/lang/reflect/natMethod.cc
index 94bc49b..eb7170a 100644
--- a/libjava/java/lang/reflect/natMethod.cc
+++ b/libjava/java/lang/reflect/natMethod.cc
@@ -1,6 +1,6 @@
// natMethod.cc - Native code for Method class.
-/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003, 2004, 2005 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003, 2004, 2005, 2006 Free Software Foundation
This file is part of libgcj.
@@ -183,10 +183,9 @@ java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
}
jint
-java::lang::reflect::Method::getModifiers ()
+java::lang::reflect::Method::getModifiersInternal ()
{
- // Ignore all unknown flags.
- return _Jv_FromReflectedMethod (this)->accflags & Modifier::ALL_FLAGS;
+ return _Jv_FromReflectedMethod (this)->accflags;
}
jstring