Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8287330: (valhalla) Better modeling of access flags in core reflection
Reviewed-by: mchung
  • Loading branch information
Roger Riggs committed May 25, 2022
1 parent 68ab121 commit 0f7c1c2
Show file tree
Hide file tree
Showing 9 changed files with 759 additions and 16 deletions.
21 changes: 21 additions & 0 deletions src/java.base/share/classes/java/lang/Class.java
Expand Up @@ -36,6 +36,7 @@
import java.io.ObjectStreamField;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.AccessFlag;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
Expand Down Expand Up @@ -1458,6 +1459,7 @@ private Class<?> elementType() {
*
* @return the {@code int} representing the modifiers for this class
* @see java.lang.reflect.Modifier
* @see #accessFlags()
* @see <a
* href="{@docRoot}/java.base/java/lang/reflect/package-summary.html#LanguageJvmModel">Java
* programming language and JVM modeling in core reflection</a>
Expand All @@ -1483,6 +1485,25 @@ private Class<?> elementType() {
*/
native void setSigners(Object[] signers);

/**
* {@return an unmodifiable set of the {@linkplain AccessFlag access
* flags} for this class, possibly empty}
* @see #getModifiers()
* @jvms 4.1 The ClassFile Structure
* @jvms 4.7.6 The InnerClasses Attribute
* @since 20
*/
public Set<AccessFlag> accessFlags() {
// This likely needs some refinement. Exploration of hidden
// classes, array classes. Location.CLASS allows SUPER and
// AccessFlag.MODULE which INNER_CLASS forbids. INNER_CLASS
// allows PRIVATE, PROTECTED, and STATIC, which are not
// allowed on Location.CLASS.
return AccessFlag.maskToAccessFlags(getModifiers(),
(isMemberClass() || isLocalClass() || isAnonymousClass()) ?
AccessFlag.Location.INNER_CLASS :
AccessFlag.Location.CLASS);
}

/**
* If this {@code Class} object represents a local or anonymous
Expand Down
110 changes: 94 additions & 16 deletions src/java.base/share/classes/java/lang/module/ModuleDescriptor.java
Expand Up @@ -29,6 +29,7 @@
import java.io.IOException;
import java.io.PrintStream;
import java.io.UncheckedIOException;
import java.lang.reflect.AccessFlag;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.util.ArrayList;
Expand Down Expand Up @@ -105,7 +106,7 @@ public enum Modifier {
* An open module. An open module does not declare any open packages
* but the resulting module is treated as if all packages are open.
*/
OPEN,
OPEN(AccessFlag.OPEN.mask()),

/**
* An automatic module. An automatic module is treated as if it exports
Expand All @@ -114,19 +115,24 @@ public enum Modifier {
* @apiNote This modifier does not correspond to a module flag in the
* binary form of a module declaration ({@code module-info.class}).
*/
AUTOMATIC,
AUTOMATIC(0 /* no flag per above comment */),

/**
* The module was not explicitly or implicitly declared.
*/
SYNTHETIC,
SYNTHETIC(AccessFlag.SYNTHETIC.mask()),

/**
* The module was implicitly declared.
*/
MANDATED;
}
MANDATED(AccessFlag.MANDATED.mask());

private int mask;
private Modifier(int mask) {
this.mask = mask;
}
private int mask() {return mask;}
}

/**
* <p> A dependence upon a module. </p>
Expand All @@ -152,28 +158,31 @@ public enum Modifier {
* module</i> to have an implicitly declared dependence on the module
* named by the {@code Requires}.
*/
TRANSITIVE,
TRANSITIVE(AccessFlag.TRANSITIVE.mask()),

/**
* The dependence is mandatory in the static phase, during compilation,
* but is optional in the dynamic phase, during execution.
*/
STATIC,
STATIC(AccessFlag.STATIC.mask()),

/**
* The dependence was not explicitly or implicitly declared in the
* source of the module declaration.
*/
SYNTHETIC,
SYNTHETIC(AccessFlag.SYNTHETIC.mask()),

/**
* The dependence was implicitly declared in the source of the module
* declaration.
*/
MANDATED;

MANDATED(AccessFlag.MANDATED.mask());
private int mask;
private Modifier(int mask) {
this.mask = mask;
}
private int mask() {return mask;}
}

private final Set<Modifier> mods;
private final String name;
private final Version compiledVersion;
Expand Down Expand Up @@ -203,6 +212,21 @@ public Set<Modifier> modifiers() {
return mods;
}

/**
* {@return an unmodifiable set of the module {@linkplain AccessFlag
* requires flags, possibly empty}}
* @see #modifiers()
* @jvms 4.7.25 The Module Attribute
* @since 20
*/
public Set<AccessFlag> accessFlags() {
int mask = 0;
for (var modifier : mods) {
mask |= modifier.mask();
}
return AccessFlag.maskToAccessFlags(mask, AccessFlag.Location.MODULE_REQUIRES);
}

/**
* Return the module name.
*
Expand Down Expand Up @@ -376,14 +400,19 @@ public enum Modifier {
* The export was not explicitly or implicitly declared in the
* source of the module declaration.
*/
SYNTHETIC,
SYNTHETIC(AccessFlag.SYNTHETIC.mask()),

/**
* The export was implicitly declared in the source of the module
* declaration.
*/
MANDATED;
MANDATED(AccessFlag.MANDATED.mask());

private int mask;
private Modifier(int mask) {
this.mask = mask;
}
private int mask() {return mask;}
}

private final Set<Modifier> mods;
Expand Down Expand Up @@ -417,6 +446,21 @@ public Set<Modifier> modifiers() {
return mods;
}

/**
* {@return an unmodifiable set of the module {@linkplain AccessFlag
* export flags} for this module descriptor, possibly empty}
* @see #modifiers()
* @jvms 4.7.25 The Module Attribute
* @since 20
*/
public Set<AccessFlag> accessFlags() {
int mask = 0;
for (var modifier : mods) {
mask |= modifier.mask();
}
return AccessFlag.maskToAccessFlags(mask, AccessFlag.Location.MODULE_EXPORTS);
}

/**
* Returns {@code true} if this is a qualified export.
*
Expand Down Expand Up @@ -579,14 +623,18 @@ public enum Modifier {
* The open package was not explicitly or implicitly declared in
* the source of the module declaration.
*/
SYNTHETIC,
SYNTHETIC(AccessFlag.SYNTHETIC.mask()),

/**
* The open package was implicitly declared in the source of the
* module declaration.
*/
MANDATED;

MANDATED(AccessFlag.MANDATED.mask());
private int mask;
private Modifier(int mask) {
this.mask = mask;
}
private int mask() {return mask;}
}

private final Set<Modifier> mods;
Expand Down Expand Up @@ -620,6 +668,21 @@ public Set<Modifier> modifiers() {
return mods;
}

/**
* {@return an unmodifiable set of the module {@linkplain AccessFlag
* opens flags}, possibly empty}
* @see #modifiers()
* @jvms 4.7.25 The Module Attribute
* @since 20
*/
public Set<AccessFlag> accessFlags() {
int mask = 0;
for (var modifier : mods) {
mask |= modifier.mask();
}
return AccessFlag.maskToAccessFlags(mask, AccessFlag.Location.MODULE_OPENS);
}

/**
* Returns {@code true} if this is a qualified {@code Opens}.
*
Expand Down Expand Up @@ -1290,6 +1353,21 @@ public Set<Modifier> modifiers() {
return modifiers;
}

/**
* {@return an unmodifiable set of the {@linkplain AccessFlag
* module flags}, possibly empty}
* @see #modifiers()
* @jvms 4.7.25 The Module Attribute
* @since 20
*/
public Set<AccessFlag> accessFlags() {
int mask = 0;
for (var modifier : modifiers) {
mask |= modifier.mask();
}
return AccessFlag.maskToAccessFlags(mask, AccessFlag.Location.MODULE);
}

/**
* <p> Returns {@code true} if this is an open module. </p>
*
Expand Down

0 comments on commit 0f7c1c2

Please sign in to comment.