I'm posting this for comment.

This is the patch to change Method/Field/Constructor to have a
'getModifiersInternal' method, which returns the un-masked modifiers
as read from the .class file.  This lets us implement the new
1.5 reflection predicates such as isSynthetic.

I made this patch against the generics branch, so it probably won't
apply cleanly to the trunk without a little tweaking.  But there is
nothing actually generics-specific in this patch, and I would like to
commit it to the trunk.

Note that we could also do something similar to this for Class.  I
think we ought to but I'd prefer to do it as a separate patch.

The VMs will need some changes as soon as this goes in, because it
adds an abstract method to Member.  This means that a VM's copy of
(e.g.) Field will not compile until it is updated.  This is why I'm
not simply checking it in.

Tom

2006-03-05  Tom Tromey  <[EMAIL PROTECTED]>

        * vm/reference/java/lang/reflect/Method.java (METHOD_MODIFIERS):
        New constant.
        (getModifiersInternal): Renamed from getModifiers.
        (getModifiers): New method.
        (isBridge): Likewise.
        (isSynthetic): Likewise.
        (isVarArgs): Likewise.
        * vm/reference/java/lang/reflect/Field.java (FIELD_MODIFIERS):
        New constant.
        (getModifiersInternal): Renamed from getModifiers.
        (getModifiers): New method.
        (isSynthetic): Likewise.
        (isEnumConstant): Likewise.
        * vm/reference/java/lang/reflect/Constructor.java
        (getModifiersInternal): Renamed from getModifiers.
        (getModifiers): New method
        (CONSTRUCTOR_MODIFIERS): New constant.
        (isSynthetic): New method.
        (isVarArgs): Likewise.
        * java/lang/reflect/Member.java (isSynthetic): New method.

Index: java/lang/reflect/Member.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/reflect/Member.java,v
retrieving revision 1.6.2.3
diff -u -r1.6.2.3 Member.java
--- java/lang/reflect/Member.java       20 Sep 2005 18:46:29 -0000      1.6.2.3
+++ java/lang/reflect/Member.java       15 Mar 2006 16:37:30 -0000
@@ -97,4 +97,13 @@
    * @see Modifier
    */
   int getModifiers();
+
+  /**
+   * Return true if this member is synthetic, meaning that it was
+   * created by the compiler and does not appear in the user's
+   * source code.
+   * @return true if the member is synthetic
+   * @since 1.5
+   */
+  boolean isSynthetic();
 }
Index: java/lang/reflect/Modifier.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/reflect/Modifier.java,v
retrieving revision 1.8.2.4
diff -u -r1.8.2.4 Modifier.java
--- java/lang/reflect/Modifier.java     13 Jan 2006 13:25:57 -0000      1.8.2.4
+++ java/lang/reflect/Modifier.java     15 Mar 2006 16:37:30 -0000
@@ -158,6 +158,26 @@
   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;
+
+  /**
    * Check whether the given modifier is abstract.
    * @param mod the modifier.
    * @return <code>true</code> if abstract, <code>false</code> otherwise.
Index: vm/reference/java/lang/reflect/Constructor.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/vm/reference/java/lang/reflect/Constructor.java,v
retrieving revision 1.11.2.10
diff -u -r1.11.2.10 Constructor.java
--- vm/reference/java/lang/reflect/Constructor.java     2 Mar 2006 09:34:06 
-0000       1.11.2.10
+++ vm/reference/java/lang/reflect/Constructor.java     15 Mar 2006 16:37:40 
-0000
@@ -81,6 +82,9 @@
   private Class<T> clazz;
   private int slot;
   
+  private static final int CONSTRUCTOR_MODIFIERS
+    = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
+
   /**
    * This class is uninstantiable except from native code.
    */
@@ -114,6 +118,13 @@
   }
 
   /**
+   * 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.
@@ -121,7 +132,31 @@
    * @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
Index: vm/reference/java/lang/reflect/Field.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/vm/reference/java/lang/reflect/Field.java,v
retrieving revision 1.9.2.4
diff -u -r1.9.2.4 Field.java
--- vm/reference/java/lang/reflect/Field.java   1 Oct 2005 10:02:47 -0000       
1.9.2.4
+++ vm/reference/java/lang/reflect/Field.java   15 Mar 2006 16:37:40 -0000
@@ -80,6 +81,11 @@
   private String name;
   private int slot;
 
+  private static final int FIELD_MODIFIERS
+    = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
+      | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
+      | Modifier.VOLATILE;
+
   /**
    * This class is uninstantiable except natively.
    */
@@ -110,6 +116,12 @@
   }
 
   /**
+   * 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,
@@ -118,7 +130,29 @@
    * @return an integer representing the modifiers to this Member
    * @see Modifier
    */
-  public native int getModifiers();
+  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.
Index: vm/reference/java/lang/reflect/Method.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/vm/reference/java/lang/reflect/Method.java,v
retrieving revision 1.12.2.8
diff -u -r1.12.2.8 Method.java
--- vm/reference/java/lang/reflect/Method.java  2 Mar 2006 09:34:06 -0000       
1.12.2.8
+++ vm/reference/java/lang/reflect/Method.java  15 Mar 2006 16:37:40 -0000
@@ -81,6 +82,11 @@
   String name;
   int slot;
 
+  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.
    */
@@ -111,6 +117,12 @@
   }
 
   /**
+   * 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,
@@ -119,7 +131,40 @@
    * @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.

Reply via email to