< prev index next >

test/jdk/java/lang/reflect/AccessFlag/VersionedLocationsTest.java

Print this page

 35 import java.util.Set;
 36 
 37 /*
 38  * There are several patterns of access flag applicability. First, an
 39  * access flag can be applied to the same set of locations for each
 40  * class file format version. This is "invariant" usage. Second, an
 41  * access flag can be defined for version N, therefore inapplicable
 42  * for earlier versions, and then applied to the same locations for
 43  * all subsequent versions. This is "step" usage. Finally, an access
 44  * flag to have a more complicated pattern, having multiple steps of
 45  * being allowed at more locations or even having locations removed if
 46  * the access flag is retired.
 47  *
 48  * List of access flags and how they are tested:
 49  *
 50  * PUBLIC       step
 51  * PRIVATE      step
 52  * PROTECTED    step
 53  * STATIC       step
 54  * FINAL        two-step
 55  * SUPER        invariant
 56  * OPEN         step
 57  * TRANSITIVE   step
 58  * SYNCHRONIZED invariant
 59  * STATIC_PHASE step
 60  * VOLATILE     invariant
 61  * BRIDGE       step
 62  * TRANSIENT    invariant
 63  * VARARGS      step
 64  * NATIVE       invariant
 65  * INTERFACE    step
 66  * ABSTRACT     step
 67  * STRICT       other
 68  * SYNTHETIC    other (three-step)
 69  * ANNOTATION   step
 70  * ENUM         step
 71  * MANDATED     two-step
 72  * MODULE       step
 73  */
 74 
 75 public class VersionedLocationsTest {
 76     public static void main(String... args) throws Exception {
 77         testInvariantAccessFlags();
 78         testStepFunctionAccessFlags();
 79         testTwoStepAccessFlags();
 80         testSynthetic();
 81         testStrict();
 82         testLatestMatch();
 83         testFlagVersionConsistency();
 84         testLocationMaskFlagConsistency();
 85     }
 86 
 87     /**
 88      * Invariant access flags have the same set of locations for each
 89      * class file format version.
 90      */
 91     private static void testInvariantAccessFlags() {
 92         Set<AccessFlag> invariantAccessFlags =
 93             Set.of(SUPER, SYNCHRONIZED, VOLATILE, TRANSIENT, NATIVE);
 94         for(var accessFlag : invariantAccessFlags) {
 95             Set<AccessFlag.Location> expected = accessFlag.locations();
 96 
 97             for(var cffv : ClassFileFormatVersion.values()) {
 98                 compareLocations(accessFlag.locations(), accessFlag, cffv);
 99             }
100         }
101     }
102 
103     private static void testStepFunctionAccessFlags() {
104         StepFunctionTC[] testCases = {
105             new StepFunctionTC(PUBLIC,
106                                removeInnerClass(PUBLIC.locations()),
107                                ClassFileFormatVersion.RELEASE_1),
108 
109             new StepFunctionTC(PRIVATE,
110                                removeInnerClass(PRIVATE.locations()),
111                                ClassFileFormatVersion.RELEASE_1),
112 
113             new StepFunctionTC(PROTECTED,
114                                removeInnerClass(PROTECTED.locations()),
115                                ClassFileFormatVersion.RELEASE_1),
116 
117             new StepFunctionTC(STATIC,
118                                removeInnerClass(STATIC.locations()),
119                                ClassFileFormatVersion.RELEASE_1),
120 




121             new StepFunctionTC(OPEN,
122                                Set.of(),
123                                ClassFileFormatVersion.RELEASE_9),
124 
125             new StepFunctionTC(TRANSITIVE,
126                                Set.of(),
127                                ClassFileFormatVersion.RELEASE_9),
128 
129             new StepFunctionTC(STATIC_PHASE,
130                                Set.of(),
131                                ClassFileFormatVersion.RELEASE_9),
132 
133             new StepFunctionTC(BRIDGE,
134                                Set.of(),
135                                ClassFileFormatVersion.RELEASE_5),
136 
137             new StepFunctionTC(VARARGS,
138                                Set.of(),
139                                ClassFileFormatVersion.RELEASE_5),
140 

277 
278     private static void testLatestMatch() {
279         // Verify accessFlag.locations() and
280         // accessFlag.locations(ClassFileFormatVersion.latest()) are
281         // consistent
282         var LATEST = ClassFileFormatVersion.latest();
283         for (var accessFlag : AccessFlag.values()) {
284             var locationSet = accessFlag.locations();
285             var locationLatestSet = accessFlag.locations(LATEST);
286             if (!locationSet.equals(locationLatestSet)) {
287                 throw new RuntimeException("Unequal location sets for " + accessFlag);
288             }
289         }
290     }
291 
292     private static void testFlagVersionConsistency() {
293         for (var flag : AccessFlag.values()) {
294             for (var location : AccessFlag.Location.values()) {
295                 if (location.flags().contains(flag) != flag.locations().contains(location)) {
296                     throw new RuntimeException(String.format("AccessFlag and Location inconsistency:" +
297                             "flag %s and location %s are inconsistent for the latest version"));
298                 }
299             }
300         }
301         for (var cffv : ClassFileFormatVersion.values()) {
302             for (var flag : AccessFlag.values()) {
303                 for (var location : AccessFlag.Location.values()) {
304                     if (location.flags(cffv).contains(flag) != flag.locations(cffv).contains(location)) {
305                         throw new RuntimeException(String.format("AccessFlag and Location inconsistency:" +
306                                 "flag %s and location %s are inconsistent for class file version %s"));
307                     }
308                 }
309             }
310         }
311     }
312 
313     private static void testLocationMaskFlagConsistency() {
314         for (var location : AccessFlag.Location.values()) {
315             if (!flagsAndMaskMatch(location.flags(), location.flagsMask())) {
316                 throw new RuntimeException(String.format("Flags and mask mismatch for %s", location));
317             }
318             for (var cffv : ClassFileFormatVersion.values()) {
319                 if (!flagsAndMaskMatch(location.flags(cffv), location.flagsMask(cffv))) {
320                     throw new RuntimeException(String.format("Flags and mask mismatch for %s in %s", location, cffv));
321                 }
322             }
323         }
324     }
325 
326     private static boolean flagsAndMaskMatch(Set<AccessFlag> flags, int mask) {

 35 import java.util.Set;
 36 
 37 /*
 38  * There are several patterns of access flag applicability. First, an
 39  * access flag can be applied to the same set of locations for each
 40  * class file format version. This is "invariant" usage. Second, an
 41  * access flag can be defined for version N, therefore inapplicable
 42  * for earlier versions, and then applied to the same locations for
 43  * all subsequent versions. This is "step" usage. Finally, an access
 44  * flag to have a more complicated pattern, having multiple steps of
 45  * being allowed at more locations or even having locations removed if
 46  * the access flag is retired.
 47  *
 48  * List of access flags and how they are tested:
 49  *
 50  * PUBLIC       step
 51  * PRIVATE      step
 52  * PROTECTED    step
 53  * STATIC       step
 54  * FINAL        two-step
 55  * SUPER        step
 56  * OPEN         step
 57  * TRANSITIVE   step
 58  * SYNCHRONIZED invariant
 59  * STATIC_PHASE step
 60  * VOLATILE     invariant
 61  * BRIDGE       step
 62  * TRANSIENT    invariant
 63  * VARARGS      step
 64  * NATIVE       invariant
 65  * INTERFACE    step
 66  * ABSTRACT     step
 67  * STRICT       other
 68  * SYNTHETIC    other (three-step)
 69  * ANNOTATION   step
 70  * ENUM         step
 71  * MANDATED     two-step
 72  * MODULE       step
 73  */
 74 
 75 public class VersionedLocationsTest {
 76     public static void main(String... args) throws Exception {
 77         testInvariantAccessFlags();
 78         testStepFunctionAccessFlags();
 79         testTwoStepAccessFlags();
 80         testSynthetic();
 81         testStrict();
 82         testLatestMatch();
 83         testFlagVersionConsistency();
 84         testLocationMaskFlagConsistency();
 85     }
 86 
 87     /**
 88      * Invariant access flags have the same set of locations for each
 89      * class file format version.
 90      */
 91     private static void testInvariantAccessFlags() {
 92         Set<AccessFlag> invariantAccessFlags =
 93             Set.of(SYNCHRONIZED, VOLATILE, TRANSIENT, NATIVE);
 94         for(var accessFlag : invariantAccessFlags) {
 95             Set<AccessFlag.Location> expected = accessFlag.locations();
 96 
 97             for(var cffv : ClassFileFormatVersion.values()) {
 98                 compareLocations(accessFlag.locations(), accessFlag, cffv);
 99             }
100         }
101     }
102 
103     private static void testStepFunctionAccessFlags() {
104         StepFunctionTC[] testCases = {
105             new StepFunctionTC(PUBLIC,
106                                removeInnerClass(PUBLIC.locations()),
107                                ClassFileFormatVersion.RELEASE_1),
108 
109             new StepFunctionTC(PRIVATE,
110                                removeInnerClass(PRIVATE.locations()),
111                                ClassFileFormatVersion.RELEASE_1),
112 
113             new StepFunctionTC(PROTECTED,
114                                removeInnerClass(PROTECTED.locations()),
115                                ClassFileFormatVersion.RELEASE_1),
116 
117             new StepFunctionTC(STATIC,
118                                removeInnerClass(STATIC.locations()),
119                                ClassFileFormatVersion.RELEASE_1),
120 
121             new StepFunctionTC(SUPER,
122                                Set.of(AccessFlag.Location.CLASS),
123                                ClassFileFormatVersion.RELEASE_22),
124 
125             new StepFunctionTC(OPEN,
126                                Set.of(),
127                                ClassFileFormatVersion.RELEASE_9),
128 
129             new StepFunctionTC(TRANSITIVE,
130                                Set.of(),
131                                ClassFileFormatVersion.RELEASE_9),
132 
133             new StepFunctionTC(STATIC_PHASE,
134                                Set.of(),
135                                ClassFileFormatVersion.RELEASE_9),
136 
137             new StepFunctionTC(BRIDGE,
138                                Set.of(),
139                                ClassFileFormatVersion.RELEASE_5),
140 
141             new StepFunctionTC(VARARGS,
142                                Set.of(),
143                                ClassFileFormatVersion.RELEASE_5),
144 

281 
282     private static void testLatestMatch() {
283         // Verify accessFlag.locations() and
284         // accessFlag.locations(ClassFileFormatVersion.latest()) are
285         // consistent
286         var LATEST = ClassFileFormatVersion.latest();
287         for (var accessFlag : AccessFlag.values()) {
288             var locationSet = accessFlag.locations();
289             var locationLatestSet = accessFlag.locations(LATEST);
290             if (!locationSet.equals(locationLatestSet)) {
291                 throw new RuntimeException("Unequal location sets for " + accessFlag);
292             }
293         }
294     }
295 
296     private static void testFlagVersionConsistency() {
297         for (var flag : AccessFlag.values()) {
298             for (var location : AccessFlag.Location.values()) {
299                 if (location.flags().contains(flag) != flag.locations().contains(location)) {
300                     throw new RuntimeException(String.format("AccessFlag and Location inconsistency:" +
301                             "flag %s and location %s are inconsistent for the latest version", flag, location));
302                 }
303             }
304         }
305         for (var cffv : ClassFileFormatVersion.values()) {
306             for (var flag : AccessFlag.values()) {
307                 for (var location : AccessFlag.Location.values()) {
308                     if (location.flags(cffv).contains(flag) != flag.locations(cffv).contains(location)) {
309                         throw new RuntimeException(String.format("AccessFlag and Location inconsistency:" +
310                                 "flag %s and location %s are inconsistent for class file version %s", flag, location, cffv));
311                     }
312                 }
313             }
314         }
315     }
316 
317     private static void testLocationMaskFlagConsistency() {
318         for (var location : AccessFlag.Location.values()) {
319             if (!flagsAndMaskMatch(location.flags(), location.flagsMask())) {
320                 throw new RuntimeException(String.format("Flags and mask mismatch for %s", location));
321             }
322             for (var cffv : ClassFileFormatVersion.values()) {
323                 if (!flagsAndMaskMatch(location.flags(cffv), location.flagsMask(cffv))) {
324                     throw new RuntimeException(String.format("Flags and mask mismatch for %s in %s", location, cffv));
325                 }
326             }
327         }
328     }
329 
330     private static boolean flagsAndMaskMatch(Set<AccessFlag> flags, int mask) {
< prev index next >