CSR :
|
|
Relates :
|
|
Relates :
|
Summary ------- Add new accessor methods to `AccessFlag.Location` and correct the historical locations reported by `AccessFlag.SYNTHETIC`. Problem ------- 1. 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. 2. We cannot easily get the `AccessFlag` for a location; it's easy the other way around. 3. `ACC_SYNTHETIC` was added in Java SE Platform 5.0, but current `AccessFlag.SYNTHETIC` behaves as if it was only added in 7. Keeping this inconsistent behavior increases the implementation complexity of the new methods. Solution -------- 1. Add these new methods to `AccessFlag.Location`: - `int flagsMask()` - `int flagsMask(ClassFileFormatVersion)` - `Set<AccessFlag> flags()` - `Set<AccessFlag> flags(ClassFileFormatVersion)` 2. Change the behavior of `AccessFlag.SYNTHETIC` to apply to all of classes, inner classes, methods, and fields from releases 5.0 to 7, to ensure consistency between `AccessFlag` and `AccessFlag.Location`. 3. 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". 4. 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) { + } ```
|