< prev index next >

src/java.base/share/classes/java/lang/reflect/AccessFlag.java

Print this page

171                   if (cffv.compareTo(ClassFileFormatVersion.RELEASE_8) >= 0) {
172                       return Location.SET_FINAL_8;
173                   } else {
174                       return (cffv == ClassFileFormatVersion.RELEASE_0) ?
175                           Location.SET_CLASS_FIELD_METHOD :
176                           Location.SET_CLASS_FIELD_METHOD_INNER_CLASS;
177                   }
178               }
179           }),
180 
181     /**
182      * The access flag {@code ACC_SUPER} with a mask value of {@code
183      * 0x0020}.
184      *
185      * @apiNote
186      * In Java SE 8 and above, the JVM treats the {@code ACC_SUPER}
187      * flag as set in every class file (JVMS {@jvms 4.1}).
188      */
189     SUPER(0x0000_0020, false, Location.SET_CLASS, null),
190 








191     /**
192      * The module flag {@code ACC_OPEN} with a mask value of {@code
193      * 0x0020}.
194      * @see java.lang.module.ModuleDescriptor#isOpen
195      */
196         OPEN(0x0000_0020, false, Location.SET_MODULE,
197              new Function<ClassFileFormatVersion, Set<Location>>() {
198                  @Override
199                  public Set<Location> apply(ClassFileFormatVersion cffv) {
200                      return (cffv.compareTo(ClassFileFormatVersion.RELEASE_9) >= 0 ) ?
201                          Location.SET_MODULE:
202                          Location.EMPTY_SET;}
203              }),
204 
205     /**
206      * The module requires flag {@code ACC_TRANSITIVE} with a mask
207      * value of {@code 0x0020}.
208      * @see java.lang.module.ModuleDescriptor.Requires.Modifier#TRANSITIVE
209      */
210     TRANSITIVE(0x0000_0020, false, Location.SET_MODULE_REQUIRES,
211                new Function<ClassFileFormatVersion, Set<Location>>() {
212                    @Override
213                    public Set<Location> apply(ClassFileFormatVersion cffv) {
214                        return (cffv.compareTo(ClassFileFormatVersion.RELEASE_9) >= 0 ) ?
215                            Location.SET_MODULE_REQUIRES:
216                            Location.EMPTY_SET;}
217                }),
218 
219     /**
220      * The access flag {@code ACC_SYNCHRONIZED}, corresponding to the
221      * source modifier {@link Modifier#SYNCHRONIZED synchronized}, with
222      * a mask value of <code>{@value "0x%04x" Modifier#SYNCHRONIZED}</code>.
223      */
224     SYNCHRONIZED(Modifier.SYNCHRONIZED, true, Location.SET_METHOD, null),
225 
226     /**
227      * The module requires flag {@code ACC_STATIC_PHASE} with a mask
228      * value of {@code 0x0040}.
229      * @see java.lang.module.ModuleDescriptor.Requires.Modifier#STATIC
230      */
231     STATIC_PHASE(0x0000_0040, false, Location.SET_MODULE_REQUIRES,
232                  new Function<ClassFileFormatVersion, Set<Location>>() {
233                      @Override
234                      public Set<Location> apply(ClassFileFormatVersion cffv) {
235                          return (cffv.compareTo(ClassFileFormatVersion.RELEASE_9) >= 0 ) ?
236                              Location.SET_MODULE_REQUIRES:
237                              Location.EMPTY_SET;}
238                  }),
239 
240    /**








241      * The access flag {@code ACC_VOLATILE}, corresponding to the
242      * source modifier {@link Modifier#VOLATILE volatile}, with a mask
243      * value of <code>{@value "0x%04x" Modifier#VOLATILE}</code>.
244      */
245     VOLATILE(Modifier.VOLATILE, true, Location.SET_FIELD, null),
246 
247     /**
248      * The access flag {@code ACC_BRIDGE} with a mask value of
249      * <code>{@value "0x%04x" Modifier#BRIDGE}</code>
250      * @see Method#isBridge()
251      */
252     BRIDGE(Modifier.BRIDGE, false, Location.SET_METHOD,
253            new Function<ClassFileFormatVersion, Set<Location>>() {
254                @Override
255                public Set<Location> apply(ClassFileFormatVersion cffv) {
256                    return (cffv.compareTo(ClassFileFormatVersion.RELEASE_5) >= 0 ) ?
257                        Location.SET_METHOD:
258                        Location.EMPTY_SET;}
259            }),
260 
261     /**
262      * The access flag {@code ACC_TRANSIENT}, corresponding to the
263      * source modifier {@link Modifier#TRANSIENT transient}, with a
264      * mask value of <code>{@value "0x%04x" Modifier#TRANSIENT}</code>.
265      */
266     TRANSIENT(Modifier.TRANSIENT, true, Location.SET_FIELD, null),

473     public Set<Location> locations(ClassFileFormatVersion cffv) {
474         Objects.requireNonNull(cffv);
475         if (cffvToLocations == null) {
476             return locations;
477         } else {
478             return cffvToLocations.apply(cffv);
479         }
480     }
481 
482     /**
483      * {@return an unmodifiable set of access flags for the given mask value
484      * appropriate for the location in question}
485      *
486      * @param mask bit mask of access flags
487      * @param location context to interpret mask value
488      * @throws IllegalArgumentException if the mask contains bit
489      * positions not support for the location in question
490      */
491     public static Set<AccessFlag> maskToAccessFlags(int mask, Location location) {
492         Set<AccessFlag> result = java.util.EnumSet.noneOf(AccessFlag.class);

493         for (var accessFlag : LocationToFlags.locationToFlags.get(location)) {
494             int accessMask = accessFlag.mask();
495             if ((mask &  accessMask) != 0) {
496                 result.add(accessFlag);
497                 mask = mask & ~accessMask;
498             }
499         }
500         if (mask != 0) {
501             throw new IllegalArgumentException("Unmatched bit position 0x" +
502                                                Integer.toHexString(mask) +
503                                                " for location " + location);
504         }
505         return Collections.unmodifiableSet(result);
506     }
507 
508     /**
509      * A location within a class file where flags can be applied.
510      *
511      * Note that since these locations represent class file structures
512      * rather than language structures many language structures, such
513      * as constructors and interfaces, are <em>not</em> present.
514      * @since 20
515      */
516     public enum Location {
517         /**
518          * Class location.
519          * @jvms 4.1 The ClassFile Structure
520          */
521         CLASS,
522 

606               Set.of(CLASS, FIELD, METHOD,
607                      INNER_CLASS, METHOD_PARAMETER);
608         private static final Set<Location> SET_SYNTHETIC_9 =
609               // Added as an access flag in 7
610               Set.of(CLASS, FIELD, METHOD,
611                      INNER_CLASS,
612                      METHOD_PARAMETER, // Added in 8
613                      // Module-related items added in 9
614                      MODULE, MODULE_REQUIRES,
615                      MODULE_EXPORTS, MODULE_OPENS);
616         private static final Set<Location> SET_MANDATED_9 =
617             Set.of(METHOD_PARAMETER, // From 8
618                    // Starting in 9
619                    MODULE, MODULE_REQUIRES,
620                    MODULE_EXPORTS, MODULE_OPENS);
621     }
622 
623     private static class LocationToFlags {
624         private static Map<Location, Set<AccessFlag>> locationToFlags =
625             Map.ofEntries(entry(Location.CLASS,
626                                 Set.of(PUBLIC, FINAL, SUPER,
627                                        INTERFACE, ABSTRACT,
628                                        SYNTHETIC, ANNOTATION,
629                                        ENUM, AccessFlag.MODULE)),
630                           entry(Location.FIELD,
631                                 Set.of(PUBLIC, PRIVATE, PROTECTED,
632                                        STATIC, FINAL, VOLATILE,
633                                        TRANSIENT, SYNTHETIC, ENUM)),
634                           entry(Location.METHOD,
635                                 Set.of(PUBLIC, PRIVATE, PROTECTED,
636                                        STATIC, FINAL, SYNCHRONIZED,
637                                        BRIDGE, VARARGS, NATIVE,
638                                        ABSTRACT, STRICT, SYNTHETIC)),
639                           entry(Location.INNER_CLASS,
640                                 Set.of(PUBLIC, PRIVATE, PROTECTED,
641                                        STATIC, FINAL, INTERFACE, ABSTRACT,
642                                        SYNTHETIC, ANNOTATION, ENUM)),
643                           entry(Location.METHOD_PARAMETER,
644                                 Set.of(FINAL, SYNTHETIC, MANDATED)),
645                           entry(Location.MODULE,
646                                 Set.of(OPEN, SYNTHETIC, MANDATED)),
647                           entry(Location.MODULE_REQUIRES,
648                                 Set.of(TRANSITIVE, STATIC_PHASE, SYNTHETIC, MANDATED)),
649                           entry(Location.MODULE_EXPORTS,
650                                 Set.of(SYNTHETIC, MANDATED)),
651                           entry(Location.MODULE_OPENS,
652                                 Set.of(SYNTHETIC, MANDATED)));
653     }
654 }

171                   if (cffv.compareTo(ClassFileFormatVersion.RELEASE_8) >= 0) {
172                       return Location.SET_FINAL_8;
173                   } else {
174                       return (cffv == ClassFileFormatVersion.RELEASE_0) ?
175                           Location.SET_CLASS_FIELD_METHOD :
176                           Location.SET_CLASS_FIELD_METHOD_INNER_CLASS;
177                   }
178               }
179           }),
180 
181     /**
182      * The access flag {@code ACC_SUPER} with a mask value of {@code
183      * 0x0020}.
184      *
185      * @apiNote
186      * In Java SE 8 and above, the JVM treats the {@code ACC_SUPER}
187      * flag as set in every class file (JVMS {@jvms 4.1}).
188      */
189     SUPER(0x0000_0020, false, Location.SET_CLASS, null),
190 
191     /**
192      * The access flag {@code ACC_IDENTITY}, corresponding to the
193      * source modifier {@link Modifier#IDENTITY identity}, with a mask
194      * value of <code>{@value "0x%04x" Modifier#IDENTITY}</code>.
195      * @jvms 4.1 -B. Class access and property modifiers
196      */
197     IDENTITY(Modifier.IDENTITY, true, Location.SET_CLASS_INNER_CLASS, null),
198 
199     /**
200      * The module flag {@code ACC_OPEN} with a mask value of {@code
201      * 0x0020}.
202      * @see java.lang.module.ModuleDescriptor#isOpen
203      */
204     OPEN(0x0000_0020, false, Location.SET_MODULE,
205          new Function<ClassFileFormatVersion, Set<Location>>() {
206              @Override
207              public Set<Location> apply(ClassFileFormatVersion cffv) {
208                  return (cffv.compareTo(ClassFileFormatVersion.RELEASE_9) >= 0 ) ?
209                      Location.SET_MODULE:
210                      Location.EMPTY_SET;}
211          }),
212 
213     /**
214      * The module requires flag {@code ACC_TRANSITIVE} with a mask
215      * value of {@code 0x0020}.
216      * @see java.lang.module.ModuleDescriptor.Requires.Modifier#TRANSITIVE
217      */
218     TRANSITIVE(0x0000_0020, false, Location.SET_MODULE_REQUIRES,
219                new Function<ClassFileFormatVersion, Set<Location>>() {
220                    @Override
221                    public Set<Location> apply(ClassFileFormatVersion cffv) {
222                        return (cffv.compareTo(ClassFileFormatVersion.RELEASE_9) >= 0 ) ?
223                            Location.SET_MODULE_REQUIRES:
224                            Location.EMPTY_SET;}
225                }),
226 
227     /**
228      * The access flag {@code ACC_SYNCHRONIZED}, corresponding to the
229      * source modifier {@link Modifier#SYNCHRONIZED synchronized}, with
230      * a mask value of <code>{@value "0x%04x" Modifier#SYNCHRONIZED}</code>.
231      */
232     SYNCHRONIZED(Modifier.SYNCHRONIZED, true, Location.SET_METHOD, null),
233 
234     /**
235      * The module requires flag {@code ACC_STATIC_PHASE} with a mask
236      * value of {@code 0x0040}.
237      * @see java.lang.module.ModuleDescriptor.Requires.Modifier#STATIC
238      */
239     STATIC_PHASE(0x0000_0040, false, Location.SET_MODULE_REQUIRES,
240                  new Function<ClassFileFormatVersion, Set<Location>>() {
241                      @Override
242                      public Set<Location> apply(ClassFileFormatVersion cffv) {
243                          return (cffv.compareTo(ClassFileFormatVersion.RELEASE_9) >= 0 ) ?
244                              Location.SET_MODULE_REQUIRES:
245                              Location.EMPTY_SET;}
246                  }),
247 
248     /**
249      * The access flag {@code ACC_VALUE}, corresponding to the
250      * source modifier {@link Modifier#VALUE value}, with a mask
251      * value of <code>{@value "0x%04x" Modifier#VALUE}</code>.
252      * @jvms 4.1 -B. Class access and property modifiers
253      */
254     VALUE(Modifier.VALUE, true, Set.of(Location.CLASS, Location.INNER_CLASS), null),
255 
256     /**
257      * The access flag {@code ACC_VOLATILE}, corresponding to the
258      * source modifier {@link Modifier#VOLATILE volatile}, with a mask
259      * value of <code>{@value "0x%04x" Modifier#VOLATILE}</code>.
260      */
261     VOLATILE(Modifier.VOLATILE, true, Location.SET_FIELD, null),

262     /**
263      * The access flag {@code ACC_BRIDGE} with a mask value of
264      * <code>{@value "0x%04x" Modifier#BRIDGE}</code>
265      * @see Method#isBridge()
266      */
267     BRIDGE(Modifier.BRIDGE, false, Location.SET_METHOD,
268            new Function<ClassFileFormatVersion, Set<Location>>() {
269                @Override
270                public Set<Location> apply(ClassFileFormatVersion cffv) {
271                    return (cffv.compareTo(ClassFileFormatVersion.RELEASE_5) >= 0 ) ?
272                        Location.SET_METHOD:
273                        Location.EMPTY_SET;}
274            }),
275 
276     /**
277      * The access flag {@code ACC_TRANSIENT}, corresponding to the
278      * source modifier {@link Modifier#TRANSIENT transient}, with a
279      * mask value of <code>{@value "0x%04x" Modifier#TRANSIENT}</code>.
280      */
281     TRANSIENT(Modifier.TRANSIENT, true, Location.SET_FIELD, null),

488     public Set<Location> locations(ClassFileFormatVersion cffv) {
489         Objects.requireNonNull(cffv);
490         if (cffvToLocations == null) {
491             return locations;
492         } else {
493             return cffvToLocations.apply(cffv);
494         }
495     }
496 
497     /**
498      * {@return an unmodifiable set of access flags for the given mask value
499      * appropriate for the location in question}
500      *
501      * @param mask bit mask of access flags
502      * @param location context to interpret mask value
503      * @throws IllegalArgumentException if the mask contains bit
504      * positions not support for the location in question
505      */
506     public static Set<AccessFlag> maskToAccessFlags(int mask, Location location) {
507         Set<AccessFlag> result = java.util.EnumSet.noneOf(AccessFlag.class);
508         int unmatchedFlags = mask;
509         for (var accessFlag : LocationToFlags.locationToFlags.get(location)) {
510             int accessMask = accessFlag.mask();
511             if ((mask &  accessMask) != 0) {
512                 result.add(accessFlag);
513                 unmatchedFlags = unmatchedFlags & ~accessMask;
514             }
515         }
516         if (unmatchedFlags != 0) {
517             throw new IllegalArgumentException("Unmatched bit position 0x" +
518                                                Integer.toHexString(unmatchedFlags) +
519                                                " for location " + location);
520         }
521         return Collections.unmodifiableSet(result);
522     }
523 
524     /**
525      * A location within a class file where flags can be applied.
526      *
527      * Note that since these locations represent class file structures
528      * rather than language structures many language structures, such
529      * as constructors and interfaces, are <em>not</em> present.
530      * @since 20
531      */
532     public enum Location {
533         /**
534          * Class location.
535          * @jvms 4.1 The ClassFile Structure
536          */
537         CLASS,
538 

622               Set.of(CLASS, FIELD, METHOD,
623                      INNER_CLASS, METHOD_PARAMETER);
624         private static final Set<Location> SET_SYNTHETIC_9 =
625               // Added as an access flag in 7
626               Set.of(CLASS, FIELD, METHOD,
627                      INNER_CLASS,
628                      METHOD_PARAMETER, // Added in 8
629                      // Module-related items added in 9
630                      MODULE, MODULE_REQUIRES,
631                      MODULE_EXPORTS, MODULE_OPENS);
632         private static final Set<Location> SET_MANDATED_9 =
633             Set.of(METHOD_PARAMETER, // From 8
634                    // Starting in 9
635                    MODULE, MODULE_REQUIRES,
636                    MODULE_EXPORTS, MODULE_OPENS);
637     }
638 
639     private static class LocationToFlags {
640         private static Map<Location, Set<AccessFlag>> locationToFlags =
641             Map.ofEntries(entry(Location.CLASS,
642                                 Set.of(PUBLIC, FINAL, SUPER, IDENTITY, VALUE,
643                                        INTERFACE, ABSTRACT,
644                                        SYNTHETIC, ANNOTATION,
645                                        ENUM, AccessFlag.MODULE)),
646                           entry(Location.FIELD,
647                                 Set.of(PUBLIC, PRIVATE, PROTECTED,
648                                        STATIC, FINAL, VOLATILE,
649                                        TRANSIENT, SYNTHETIC, ENUM)),
650                           entry(Location.METHOD,
651                                 Set.of(PUBLIC, PRIVATE, PROTECTED,
652                                        STATIC, FINAL, SYNCHRONIZED,
653                                        BRIDGE, VARARGS, NATIVE,
654                                        ABSTRACT, STRICT, SYNTHETIC)),
655                           entry(Location.INNER_CLASS,
656                                 Set.of(PUBLIC, PRIVATE, PROTECTED, IDENTITY, VALUE,
657                                        STATIC, FINAL, INTERFACE, ABSTRACT,
658                                        SYNTHETIC, ANNOTATION, ENUM)),
659                           entry(Location.METHOD_PARAMETER,
660                                 Set.of(FINAL, SYNTHETIC, MANDATED)),
661                           entry(Location.MODULE,
662                                 Set.of(OPEN, SYNTHETIC, MANDATED)),
663                           entry(Location.MODULE_REQUIRES,
664                                 Set.of(TRANSITIVE, STATIC_PHASE, SYNTHETIC, MANDATED)),
665                           entry(Location.MODULE_EXPORTS,
666                                 Set.of(SYNTHETIC, MANDATED)),
667                           entry(Location.MODULE_OPENS,
668                                 Set.of(SYNTHETIC, MANDATED)));
669     }
670 }
< prev index next >