This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch: FYI: PR libgcj/27729


I'm checking this in on the trunk.

This reworks parts of reflection to be a bit closer to Classpath, and
adds real implementations for some of the new 1.5 reflection methods.

While implementing this I noticed that our ACC_INVISIBLE addition
conflicts with a new flag available in 1.5.  So, I changed its
value.

I believe this still remains relatively compatible for a few reasons.
First, invisible methods are not emitted in BC-compiled objects.  They
are only emitted in objects compiled with the C++ ABI.

Second, the only way this flag would be visible would be to a program
running on a newer libgcj using isSynthetic -- but C++-ABI-using
objects would have to be recompiled anyway.

So, I am not bumping the BC ABI version number.

Tested on x86 FC4.

Tom

Index: gcc/java/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	PR libgcj/27729:
	* jcf.h (ACC_INVISIBLE): Changed value.

Index: libjava/ChangeLog
from  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.

Index: gcc/java/jcf.h
===================================================================
--- gcc/java/jcf.h	(revision 114043)
+++ gcc/java/jcf.h	(working copy)
@@ -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 @@
 #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)
 
Index: libjava/java/lang/reflect/Method.java
===================================================================
--- libjava/java/lang/reflect/Method.java	(revision 114043)
+++ libjava/java/lang/reflect/Method.java	(working copy)
@@ -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 @@
 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 @@
  * @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 @@
    * 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 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,9 +93,42 @@
    * @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.
    * @return the type of this method
    */
@@ -139,14 +184,14 @@
   }
 
   /**
-   * 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 @@
    *
    * @return the String representation of the Method
    */
-  public String toString ()
+  public String toString()
   {
     if (parameter_types == null)
       getType ();
@@ -196,6 +241,33 @@
     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 @@
     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 @@
       }
   }
 
-  // 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;
 
Index: libjava/java/lang/reflect/Field.java
===================================================================
--- libjava/java/lang/reflect/Field.java	(revision 114043)
+++ libjava/java/lang/reflect/Field.java	(working copy)
@@ -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 libgcj.
+This file is part of GNU Classpath.
 
-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.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 @@
   // 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 @@
     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 ();
+  /**
+   * 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 Class getType ();
+  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 native int getModifiers ();
-
-  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 @@
   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 @@
 		   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 @@
     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; }
-
 }
Index: libjava/java/lang/reflect/Constructor.java
===================================================================
--- libjava/java/lang/reflect/Constructor.java	(revision 114043)
+++ libjava/java/lang/reflect/Constructor.java	(working copy)
@@ -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.
+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.
 
-This software is copyrighted work licensed under the terms of the
-Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
-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 @@
  * @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 @@
 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 @@
    * 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 @@
    * 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,9 +122,33 @@
    * @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
    * constructor takes no parameters, returns a 0-length array (not null).
    *
@@ -127,14 +192,14 @@
   }
 
   /**
-   * 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 @@
    *
    * @return the String representation of the Constructor
    */
-  public String toString ()
+  public String toString()
   {
     if (parameter_types == null)
       getType ();
@@ -170,6 +235,45 @@
     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,28 +308,80 @@
     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.
   private native void getType ();
 
Index: libjava/java/lang/reflect/natMethod.cc
===================================================================
--- libjava/java/lang/reflect/natMethod.cc	(revision 114043)
+++ libjava/java/lang/reflect/natMethod.cc	(working copy)
@@ -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 @@
 }
 
 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
Index: libjava/java/lang/reflect/natField.cc
===================================================================
--- libjava/java/lang/reflect/natField.cc	(revision 114043)
+++ libjava/java/lang/reflect/natField.cc	(working copy)
@@ -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 @@
 #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 @@
 
   // 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"));
   
Index: libjava/java/lang/reflect/natConstructor.cc
===================================================================
--- libjava/java/lang/reflect/natConstructor.cc	(revision 114043)
+++ libjava/java/lang/reflect/natConstructor.cc	(working copy)
@@ -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 @@
 #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
Index: libjava/java/lang/reflect/Modifier.java
===================================================================
--- libjava/java/lang/reflect/Modifier.java	(revision 114043)
+++ libjava/java/lang/reflect/Modifier.java	(working copy)
@@ -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 @@
   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 @@
   }
 
   /**
+   * 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]