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.