-
Type:
CSR
-
Resolution: Approved
-
Priority:
P4
-
Component/s: core-libs
-
None
-
source, behavioral
-
low
-
-
Java API
-
SE
Summary
Add new accessor methods to AccessFlag.Location and correct the historical locations reported by AccessFlag.SYNTHETIC.
Problem
- In the ClassFile API and other locations, we often mention about IllegalArgumentException caused by the mismatch of masks for access flags, but we never provided a way to easily detect if a mask has mismatch.
- We cannot easily get the
AccessFlagfor a location; it's easy the other way around. ACC_SYNTHETICwas added in Java SE Platform 5.0, but currentAccessFlag.SYNTHETICbehaves as if it was only added in 7. Keeping this inconsistent behavior increases the implementation complexity of the new methods.
Solution
- Add these new methods to
AccessFlag.Location:
int flagsMask()int flagsMask(ClassFileFormatVersion)Set<AccessFlag> flags()Set<AccessFlag> flags(ClassFileFormatVersion)
-
Change the behavior of
AccessFlag.SYNTHETICto apply to all of classes, inner classes, methods, and fields from releases 5.0 to 7, to ensure consistency betweenAccessFlagandAccessFlag.Location. -
Document that historical locations may return empty if the flag does not exist, and the no-CFFV version is for the current version, which is more accurate than "latest".
-
Reimplement maskToAccessFlags withe the location-based information, making it align with the immutable collections in this process (UOE, null hostility)
Specification
@@ -425,31 +307,31 @@ public Set<Location> apply(ClassFileFormatVersion cffv) {
/**
- * {@return the corresponding integer mask for the access flag}
+ * {@return the corresponding mask for the access flag} The mask has
+ * exactly one bit set and is in the range of {@code char}.
*/
public int mask() {
}
/**
- * {@return whether or not the flag has a directly corresponding
+ * {@return whether or not this flag has a directly corresponding
* modifier in the Java programming language}
*/
public boolean sourceModifier() {
@@ -458,7 +339,7 @@ public boolean sourceModifier() {
/**
- * {@return kinds of constructs the flag can be applied to in the
- * latest class file format version}
+ * {@return locations this flag can be applied to in the current class file
+ * format version}
+ * <p>
+ * This method returns an empty set if this flag is not defined in
+ * the current class file format version.
*/
public Set<Location> locations() {
return locations;
@@ -467,16 +348,15 @@ public Set<Location> locations() {
/**
- * {@return kinds of constructs the flag can be applied to in the
- * given class file format version}
+ * {@return locations this flag can be applied to in the given class file
+ * format version}
+ * <p>
+ * This method returns an empty set if this flag is not defined in
+ * the given {@code cffv}.
+ *
* @param cffv the class file format version to use
* @throws NullPointerException if the parameter is {@code null}
*/
public Set<Location> locations(ClassFileFormatVersion cffv) {
}
/**
@@ -516,57 +418,129 @@ public static Set<AccessFlag> maskToAccessFlags(int mask, Location location) {
public enum Location {
/**
* Class location.
- * @jvms 4.1 The ClassFile Structure
+ *
+ * @see Class#accessFlags()
+ * @see ClassModel#flags()
+ * @jvms 4.1 The {@code ClassFile} Structure
*/
CLASS,
/**
* Field location.
+ *
+ * @see Field#accessFlags()
+ * @see FieldModel#flags()
* @jvms 4.5 Fields
*/
FIELD,
/**
* Method location.
+ *
+ * @see Executable#accessFlags()
+ * @see MethodModel#flags()
* @jvms 4.6 Methods
*/
METHOD,
/**
* Inner class location.
- * @jvms 4.7.6 The InnerClasses Attribute
+ *
+ * @see Class#accessFlags()
+ * @see InnerClassInfo#flags()
+ * @jvms 4.7.6 The {@code InnerClasses} Attribute
*/
INNER_CLASS,
/**
* Method parameter location.
- * @jvms 4.7.24 The MethodParameters Attribute
+ *
+ * @see Parameter#accessFlags()
+ * @see MethodParameterInfo#flags()
+ * @jvms 4.7.24 The {@code MethodParameters} Attribute
*/
METHOD_PARAMETER,
/**
- * Module location
- * @jvms 4.7.25 The Module Attribute
+ * Module location.
+ *
+ * @see ModuleDescriptor#accessFlags()
+ * @see ModuleAttribute#moduleFlags()
+ * @jvms 4.7.25 The {@code Module} Attribute
*/
MODULE,
/**
- * Module requires location
- * @jvms 4.7.25 The Module Attribute
+ * Module requires location.
+ *
+ * @see ModuleDescriptor.Requires#accessFlags()
+ * @see ModuleRequireInfo#requiresFlags()
+ * @jvms 4.7.25 The {@code Module} Attribute
*/
MODULE_REQUIRES,
/**
- * Module exports location
- * @jvms 4.7.25 The Module Attribute
+ * Module exports location.
+ *
+ * @see ModuleDescriptor.Exports#accessFlags()
+ * @see ModuleExportInfo#exportsFlags()
+ * @jvms 4.7.25 The {@code Module} Attribute
*/
MODULE_EXPORTS,
/**
- * Module opens location
- * @jvms 4.7.25 The Module Attribute
+ * Module opens location.
+ *
+ * @see ModuleDescriptor.Opens#accessFlags()
+ * @see ModuleOpenInfo#opensFlags()
+ * @jvms 4.7.25 The {@code Module} Attribute
*/
MODULE_OPENS;
// Repeated sets of locations used by AccessFlag constants
private static final Set<Location> EMPTY_SET = Set.of();
@@ -618,37 +572,218 @@ public enum Location {
+
+ /**
+ * {@return the union of masks of all access flags defined for
+ * this location in the current class file format version}
+ * <p>
+ * This method returns {@code 0} if this location does not exist in
+ * the current class file format version.
+ *
+ * @since 25
+ */
+ public int flagsMask() {
+ return flagsMask;
+ }
+
+ /**
+ * {@return the union of masks of all access flags defined for
+ * this location in the given class file format version}
+ * <p>
+ * This method returns {@code 0} if this location does not exist in
+ * the given {@code cffv}.
+ *
+ * @param cffv the class file format version
+ * @throws NullPointerException if {@code cffv} is {@code null}
+ * @since 25
+ */
+ public int flagsMask(ClassFileFormatVersion cffv) {
+ }
+
+ /**
+ * {@return the set of access flags defined for this location in the
+ * current class file format version} The set is immutable.
+ * <p>
+ * This method returns an empty set if this location does not exist
+ * in the current class file format version.
+ *
+ * @since 25
+ */
+ public Set<AccessFlag> flags() {
+ }
+
+ /**
+ * {@return the set of access flags defined for this location in the
+ * given class file format version} The set is immutable.
+ * <p>
+ * This method returns an empty set if this location does not exist
+ * in the given {@code cffv}.
+ *
+ * @param cffv the class file format version
+ * @throws NullPointerException if {@code cffv} is {@code null}
+ * @since 25
+ */
+ public Set<AccessFlag> flags(ClassFileFormatVersion cffv) {
+ }
- csr of
-
JDK-8347471 Provide valid flags and mask in AccessFlag.Location
-
- Resolved
-
- relates to
-
JDK-8281660 Better modeling of access flags in core reflection
-
- Closed
-
-
JDK-8297741 AccessFlag.maskToAccessFlags should be specific to class file version
-
- Closed
-