Skip to content

Commit de74671

Browse files
committed
8266670: Better modeling of access flags in core reflection
Reviewed-by: mchung, rriggs, asotona
1 parent a5c25d8 commit de74671

File tree

14 files changed

+1480
-16
lines changed

14 files changed

+1480
-16
lines changed

src/java.base/share/classes/java/lang/Class.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.io.ObjectStreamField;
3737
import java.lang.reflect.AnnotatedElement;
3838
import java.lang.reflect.AnnotatedType;
39+
import java.lang.reflect.AccessFlag;
3940
import java.lang.reflect.Array;
4041
import java.lang.reflect.Constructor;
4142
import java.lang.reflect.Executable;
@@ -1312,6 +1313,7 @@ private Class<?> elementType() {
13121313
*
13131314
* @return the {@code int} representing the modifiers for this class
13141315
* @see java.lang.reflect.Modifier
1316+
* @see #accessFlags()
13151317
* @see <a
13161318
* href="{@docRoot}/java.base/java/lang/reflect/package-summary.html#LanguageJvmModel">Java
13171319
* programming language and JVM modeling in core reflection</a>
@@ -1322,6 +1324,39 @@ private Class<?> elementType() {
13221324
@IntrinsicCandidate
13231325
public native int getModifiers();
13241326

1327+
/**
1328+
* {@return an unmodifiable set of the {@linkplain AccessFlag access
1329+
* flags} for this class, possibly empty}
1330+
*
1331+
* <p> If the underlying class is an array class, then its
1332+
* {@code PUBLIC}, {@code PRIVATE} and {@code PROTECTED}
1333+
* access flags are the same as those of its component type. If this
1334+
* {@code Class} object represents a primitive type or void, the
1335+
* {@code PUBLIC} access flag is present, and the
1336+
* {@code PROTECTED} and {@code PRIVATE} access flags are always
1337+
* absent. If this {@code Class} object represents an array class, a
1338+
* primitive type or void, then the {@code FINAL} access flag is always
1339+
* present and the interface access flag is always
1340+
* absent. The values of its other access flags are not determined
1341+
* by this specification.
1342+
*
1343+
* @see #getModifiers()
1344+
* @jvms 4.1 The ClassFile Structure
1345+
* @jvms 4.7.6 The InnerClasses Attribute
1346+
* @since 20
1347+
*/
1348+
public Set<AccessFlag> accessFlags() {
1349+
// This likely needs some refinement. Exploration of hidden
1350+
// classes, array classes. Location.CLASS allows SUPER and
1351+
// AccessFlag.MODULE which INNER_CLASS forbids. INNER_CLASS
1352+
// allows PRIVATE, PROTECTED, and STATIC, which are not
1353+
// allowed on Location.CLASS.
1354+
return AccessFlag.maskToAccessFlags(getModifiers(),
1355+
(isMemberClass() || isLocalClass() ||
1356+
isAnonymousClass() || isArray()) ?
1357+
AccessFlag.Location.INNER_CLASS :
1358+
AccessFlag.Location.CLASS);
1359+
}
13251360

13261361
/**
13271362
* Gets the signers of this class.

src/java.base/share/classes/java/lang/module/ModuleDescriptor.java

Lines changed: 94 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.io.IOException;
3030
import java.io.PrintStream;
3131
import java.io.UncheckedIOException;
32+
import java.lang.reflect.AccessFlag;
3233
import java.nio.ByteBuffer;
3334
import java.nio.file.Path;
3435
import java.util.ArrayList;
@@ -105,7 +106,7 @@ public enum Modifier {
105106
* An open module. An open module does not declare any open packages
106107
* but the resulting module is treated as if all packages are open.
107108
*/
108-
OPEN,
109+
OPEN(AccessFlag.OPEN.mask()),
109110

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

119120
/**
120121
* The module was not explicitly or implicitly declared.
121122
*/
122-
SYNTHETIC,
123+
SYNTHETIC(AccessFlag.SYNTHETIC.mask()),
123124

124125
/**
125126
* The module was implicitly declared.
126127
*/
127-
MANDATED;
128-
}
128+
MANDATED(AccessFlag.MANDATED.mask());
129129

130+
private final int mask;
131+
private Modifier(int mask) {
132+
this.mask = mask;
133+
}
134+
private int mask() {return mask;}
135+
}
130136

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

157163
/**
158164
* The dependence is mandatory in the static phase, during compilation,
159165
* but is optional in the dynamic phase, during execution.
160166
*/
161-
STATIC,
167+
STATIC(AccessFlag.STATIC_PHASE.mask()),
162168

163169
/**
164170
* The dependence was not explicitly or implicitly declared in the
165171
* source of the module declaration.
166172
*/
167-
SYNTHETIC,
173+
SYNTHETIC(AccessFlag.SYNTHETIC.mask()),
168174

169175
/**
170176
* The dependence was implicitly declared in the source of the module
171177
* declaration.
172178
*/
173-
MANDATED;
174-
179+
MANDATED(AccessFlag.MANDATED.mask());
180+
private final int mask;
181+
private Modifier(int mask) {
182+
this.mask = mask;
183+
}
184+
private int mask() {return mask;}
175185
}
176-
177186
private final Set<Modifier> mods;
178187
private final String name;
179188
private final Version compiledVersion;
@@ -203,6 +212,21 @@ public Set<Modifier> modifiers() {
203212
return mods;
204213
}
205214

215+
/**
216+
* {@return an unmodifiable set of the module {@linkplain AccessFlag
217+
* requires flags, possibly empty}}
218+
* @see #modifiers()
219+
* @jvms 4.7.25 The Module Attribute
220+
* @since 20
221+
*/
222+
public Set<AccessFlag> accessFlags() {
223+
int mask = 0;
224+
for (var modifier : mods) {
225+
mask |= modifier.mask();
226+
}
227+
return AccessFlag.maskToAccessFlags(mask, AccessFlag.Location.MODULE_REQUIRES);
228+
}
229+
206230
/**
207231
* Return the module name.
208232
*
@@ -376,14 +400,19 @@ public enum Modifier {
376400
* The export was not explicitly or implicitly declared in the
377401
* source of the module declaration.
378402
*/
379-
SYNTHETIC,
403+
SYNTHETIC(AccessFlag.SYNTHETIC.mask()),
380404

381405
/**
382406
* The export was implicitly declared in the source of the module
383407
* declaration.
384408
*/
385-
MANDATED;
409+
MANDATED(AccessFlag.MANDATED.mask());
386410

411+
private final int mask;
412+
private Modifier(int mask) {
413+
this.mask = mask;
414+
}
415+
private int mask() {return mask;}
387416
}
388417

389418
private final Set<Modifier> mods;
@@ -417,6 +446,21 @@ public Set<Modifier> modifiers() {
417446
return mods;
418447
}
419448

449+
/**
450+
* {@return an unmodifiable set of the module {@linkplain AccessFlag
451+
* export flags} for this module descriptor, possibly empty}
452+
* @see #modifiers()
453+
* @jvms 4.7.25 The Module Attribute
454+
* @since 20
455+
*/
456+
public Set<AccessFlag> accessFlags() {
457+
int mask = 0;
458+
for (var modifier : mods) {
459+
mask |= modifier.mask();
460+
}
461+
return AccessFlag.maskToAccessFlags(mask, AccessFlag.Location.MODULE_EXPORTS);
462+
}
463+
420464
/**
421465
* Returns {@code true} if this is a qualified export.
422466
*
@@ -579,14 +623,18 @@ public enum Modifier {
579623
* The open package was not explicitly or implicitly declared in
580624
* the source of the module declaration.
581625
*/
582-
SYNTHETIC,
626+
SYNTHETIC(AccessFlag.SYNTHETIC.mask()),
583627

584628
/**
585629
* The open package was implicitly declared in the source of the
586630
* module declaration.
587631
*/
588-
MANDATED;
589-
632+
MANDATED(AccessFlag.MANDATED.mask());
633+
private final int mask;
634+
private Modifier(int mask) {
635+
this.mask = mask;
636+
}
637+
private int mask() {return mask;}
590638
}
591639

592640
private final Set<Modifier> mods;
@@ -620,6 +668,21 @@ public Set<Modifier> modifiers() {
620668
return mods;
621669
}
622670

671+
/**
672+
* {@return an unmodifiable set of the module {@linkplain AccessFlag
673+
* opens flags}, possibly empty}
674+
* @see #modifiers()
675+
* @jvms 4.7.25 The Module Attribute
676+
* @since 20
677+
*/
678+
public Set<AccessFlag> accessFlags() {
679+
int mask = 0;
680+
for (var modifier : mods) {
681+
mask |= modifier.mask();
682+
}
683+
return AccessFlag.maskToAccessFlags(mask, AccessFlag.Location.MODULE_OPENS);
684+
}
685+
623686
/**
624687
* Returns {@code true} if this is a qualified {@code Opens}.
625688
*
@@ -1290,6 +1353,21 @@ public Set<Modifier> modifiers() {
12901353
return modifiers;
12911354
}
12921355

1356+
/**
1357+
* {@return an unmodifiable set of the {@linkplain AccessFlag
1358+
* module flags}, possibly empty}
1359+
* @see #modifiers()
1360+
* @jvms 4.7.25 The Module Attribute
1361+
* @since 20
1362+
*/
1363+
public Set<AccessFlag> accessFlags() {
1364+
int mask = 0;
1365+
for (var modifier : modifiers) {
1366+
mask |= modifier.mask();
1367+
}
1368+
return AccessFlag.maskToAccessFlags(mask, AccessFlag.Location.MODULE);
1369+
}
1370+
12931371
/**
12941372
* <p> Returns {@code true} if this is an open module. </p>
12951373
*

0 commit comments

Comments
 (0)