1 /*
  2  * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package com.sun.tools.javac.code;
 27 
 28 import java.util.Collections;
 29 import java.util.EnumSet;
 30 import java.util.Map;
 31 import java.util.Set;
 32 import java.util.concurrent.ConcurrentHashMap;
 33 
 34 import javax.lang.model.element.Modifier;
 35 
 36 import com.sun.tools.javac.util.Assert;
 37 import com.sun.tools.javac.util.StringUtils;
 38 
 39 /** Access flags and other modifiers for Java classes and members.
 40  *
 41  *  <p><b>This is NOT part of any supported API.
 42  *  If you write code that depends on this, you do so at your own risk.
 43  *  This code and its internal interfaces are subject to change or
 44  *  deletion without notice.</b>
 45  */
 46 public class Flags {
 47 
 48     private Flags() {} // uninstantiable
 49 
 50     public static String toString(long flags) {
 51         StringBuilder buf = new StringBuilder();
 52         String sep = "";
 53         for (Flag flag : asFlagSet(flags)) {
 54             buf.append(sep);
 55             buf.append(flag);
 56             sep = " ";
 57         }
 58         return buf.toString();
 59     }
 60 
 61     public static EnumSet<Flag> asFlagSet(long flags) {
 62         EnumSet<Flag> flagSet = EnumSet.noneOf(Flag.class);
 63         for (Flag flag : Flag.values()) {
 64             if ((flags & flag.value) != 0) {
 65                 flagSet.add(flag);
 66                 flags &= ~flag.value;
 67             }
 68         }
 69         Assert.check(flags == 0);
 70         return flagSet;
 71     }
 72 
 73     /* Standard Java flags.
 74      */
 75     public static final int PUBLIC       = 1;
 76     public static final int PRIVATE      = 1<<1;
 77     public static final int PROTECTED    = 1<<2;
 78     public static final int STATIC       = 1<<3;
 79     public static final int FINAL        = 1<<4;
 80     public static final int SYNCHRONIZED = 1<<5;
 81     public static final int VOLATILE     = 1<<6;
 82     public static final int TRANSIENT    = 1<<7;
 83     public static final int NATIVE       = 1<<8;
 84     public static final int INTERFACE    = 1<<9;
 85     public static final int ABSTRACT     = 1<<10;
 86     public static final int STRICTFP     = 1<<11;
 87 
 88     /* Flag that marks a symbol synthetic, added in classfile v49.0. */
 89     public static final int SYNTHETIC    = 1<<12;
 90 
 91     /** Flag that marks attribute interfaces, added in classfile v49.0. */
 92     public static final int ANNOTATION   = 1<<13;
 93 
 94     /** An enumeration type or an enumeration constant, added in
 95      *  classfile v49.0. */
 96     public static final int ENUM         = 1<<14;
 97 
 98     /** Added in SE8, represents constructs implicitly declared in source. */
 99     public static final int MANDATED     = 1<<15;
100 
101     public static final int StandardFlags = 0x0fff;
102 
103     // Because the following access flags are overloaded with other
104     // bit positions, we translate them when reading and writing class
105     // files into unique bits positions: ACC_SYNTHETIC <-> SYNTHETIC,
106     // for example.
107     public static final int ACC_SUPER    = 0x0020;
108     public static final int ACC_BRIDGE   = 0x0040;
109     public static final int ACC_VARARGS  = 0x0080;
110     public static final int ACC_MODULE   = 0x8000;
111 
112     /*****************************************
113      * Internal compiler flags (no bits in the lower 16).
114      *****************************************/
115 
116     /** Flag is set if symbol is deprecated.  See also DEPRECATED_REMOVAL.
117      */
118     public static final int DEPRECATED   = 1<<17;
119 
120     /** Flag is set for a variable symbol if the variable's definition
121      *  has an initializer part.
122      */
123     public static final int HASINIT          = 1<<18;
124 
125     /** Flag is set for compiler-generated anonymous method symbols
126      *  that `own' an initializer block.
127      */
128     public static final int BLOCK            = 1<<20;
129 
130     /** Flag bit 21 is available. (used earlier to tag compiler-generated abstract methods that implement
131      *  an interface method (Miranda methods)).
132      */
133 
134     /** Flag is set for nested classes that do not access instance members
135      *  or `this' of an outer class and therefore don't need to be passed
136      *  a this$n reference.  This value is currently set only for anonymous
137      *  classes in superclass constructor calls.
138      *  todo: use this value for optimizing away this$n parameters in
139      *  other cases.
140      */
141     public static final int NOOUTERTHIS  = 1<<22;
142 
143     /** Flag is set for package symbols if a package has a member or
144      *  directory and therefore exists.
145      */
146     public static final int EXISTS           = 1<<23;
147 
148     /** Flag is set for compiler-generated compound classes
149      *  representing multiple variable bounds
150      */
151     public static final int COMPOUND     = 1<<24;
152 
153     /** Flag is set for class symbols if a class file was found for this class.
154      */
155     public static final int CLASS_SEEN   = 1<<25;
156 
157     /** Flag is set for class symbols if a source file was found for this
158      *  class.
159      */
160     public static final int SOURCE_SEEN  = 1<<26;
161 
162     /* State flags (are reset during compilation).
163      */
164 
165     /** Flag for class symbols is set and later re-set as a lock in
166      *  Enter to detect cycles in the superclass/superinterface
167      *  relations.  Similarly for constructor call cycle detection in
168      *  Attr.
169      */
170     public static final int LOCKED           = 1<<27;
171 
172     /** Flag for class symbols is set and later re-set to indicate that a class
173      *  has been entered but has not yet been attributed.
174      */
175     public static final int UNATTRIBUTED = 1<<28;
176 
177     /** Flag for synthesized default constructors of anonymous classes.
178      */
179     public static final int ANONCONSTR   = 1<<29; //non-class members
180 
181     /**
182      * Flag to indicate the super classes of this ClassSymbol has been attributed.
183      */
184     public static final int SUPER_OWNER_ATTRIBUTED = 1<<29; //ClassSymbols
185 
186     /** Flag for class symbols to indicate it has been checked and found
187      *  acyclic.
188      */
189     public static final int ACYCLIC          = 1<<30;
190 
191     /** Flag that marks bridge methods.
192      */
193     public static final long BRIDGE          = 1L<<31;
194 
195     /** Flag that marks formal parameters.
196      */
197     public static final long PARAMETER   = 1L<<33;
198 
199     /** Flag that marks varargs methods.
200      */
201     public static final long VARARGS   = 1L<<34;
202 
203     /** Flag for annotation type symbols to indicate it has been
204      *  checked and found acyclic.
205      */
206     public static final long ACYCLIC_ANN      = 1L<<35;
207 
208     /** Flag that marks a generated default constructor.
209      */
210     public static final long GENERATEDCONSTR   = 1L<<36;
211 
212     /** Flag that marks a hypothetical method that need not really be
213      *  generated in the binary, but is present in the symbol table to
214      *  simplify checking for erasure clashes - also used for 292 poly sig methods.
215      */
216     public static final long HYPOTHETICAL   = 1L<<37;
217 
218     /**
219      * Flag that marks an internal proprietary class.
220      */
221     public static final long PROPRIETARY = 1L<<38;
222 
223     /**
224      * Flag that marks a multi-catch parameter.
225      */
226     public static final long UNION = 1L<<39;
227 
228     /**
229      * Flags an erroneous TypeSymbol as viable for recovery.
230      * TypeSymbols only.
231      */
232     public static final long RECOVERABLE = 1L<<40;
233 
234     /**
235      * Flag that marks an 'effectively final' local variable.
236      */
237     public static final long EFFECTIVELY_FINAL = 1L<<41;
238 
239     /**
240      * Flag that marks non-override equivalent methods with the same signature,
241      * or a conflicting match binding (BindingSymbol).
242      */
243     public static final long CLASH = 1L<<42;
244 
245     /**
246      * Flag that marks either a default method or an interface containing default methods.
247      */
248     public static final long DEFAULT = 1L<<43;
249 
250     /**
251      * Flag that marks class as auxiliary, ie a non-public class following
252      * the public class in a source file, that could block implicit compilation.
253      */
254     public static final long AUXILIARY = 1L<<44;
255 
256     /**
257      * Flag that marks that a symbol is not available in the current profile
258      */
259     public static final long NOT_IN_PROFILE = 1L<<45;
260 
261     /**
262      * Flag that indicates that an override error has been detected by Check.
263      */
264     public static final long BAD_OVERRIDE = 1L<<45;
265 
266     /**
267      * Flag that indicates a signature polymorphic method (292).
268      */
269     public static final long SIGNATURE_POLYMORPHIC = 1L<<46;
270 
271     /**
272      * Flag that indicates that an inference variable is used in a 'throws' clause.
273      */
274     public static final long THROWS = 1L<<47;
275 
276     /**
277      * Flag that marks potentially ambiguous overloads
278      */
279     public static final long POTENTIALLY_AMBIGUOUS = 1L<<48;
280 
281     /**
282      * Flag that marks a synthetic method body for a lambda expression
283      */
284     public static final long LAMBDA_METHOD = 1L<<49;
285 
286     /**
287      * Flag to control recursion in TransTypes
288      */
289     public static final long TYPE_TRANSLATED = 1L<<50;
290 
291     /**
292      * Flag to indicate class symbol is for module-info
293      */
294     public static final long MODULE = 1L<<51;
295 
296     /**
297      * Flag to indicate the given ModuleSymbol is an automatic module.
298      */
299     public static final long AUTOMATIC_MODULE = 1L<<52; //ModuleSymbols only
300 
301     /**
302      * Flag to indicate the given PackageSymbol contains any non-.java and non-.class resources.
303      */
304     public static final long HAS_RESOURCE = 1L<<52; //PackageSymbols only
305 
306     /**
307      * Flag to indicate the given ParamSymbol has a user-friendly name filled.
308      */
309     public static final long NAME_FILLED = 1L<<52; //ParamSymbols only
310 
311     /**
312      * Flag to indicate the given ModuleSymbol is a system module.
313      */
314     public static final long SYSTEM_MODULE = 1L<<53; //ModuleSymbols only
315 
316     /**
317      * Flag to indicate the given ClassSymbol is a value based.
318      */
319     public static final long VALUE_BASED = 1L<<53; //ClassSymbols only
320 
321     /**
322      * Flag to indicate the given symbol has a @Deprecated annotation.
323      */
324     public static final long DEPRECATED_ANNOTATION = 1L<<54;
325 
326     /**
327      * Flag to indicate the given symbol has been deprecated and marked for removal.
328      */
329     public static final long DEPRECATED_REMOVAL = 1L<<55;
330 
331     /**
332      * Flag to indicate the API element in question is for a preview API.
333      */
334     public static final long PREVIEW_API = 1L<<56; //any Symbol kind
335 
336     /**
337      * Flag for synthesized default constructors of anonymous classes that have an enclosing expression.
338      */
339     public static final long ANONCONSTR_BASED = 1L<<57;
340 
341     /**
342      * Flag that marks finalize block as body-only, should not be copied into catch clauses.
343      * Used to implement try-with-resources.
344      */
345     public static final long BODY_ONLY_FINALIZE = 1L<<17; //blocks only
346 
347     /**
348      * Flag to indicate the API element in question is for a preview API.
349      */
350     public static final long PREVIEW_REFLECTIVE = 1L<<58; //any Symbol kind
351 
352     /**
353      * Flag to indicate the given variable is a match binding variable.
354      */
355     public static final long MATCH_BINDING = 1L<<59;
356 
357     /**
358      * A flag to indicate a match binding variable whose scope extends after the current statement.
359      */
360     public static final long MATCH_BINDING_TO_OUTER = 1L<<60;
361 
362     /**
363      * Flag to indicate that a class is a record. The flag is also used to mark fields that are
364      * part of the state vector of a record and to mark the canonical constructor
365      */
366     public static final long RECORD = 1L<<61; // ClassSymbols, MethodSymbols and VarSymbols
367 
368     /**
369      * Flag to mark a record constructor as a compact one
370      */
371     public static final long COMPACT_RECORD_CONSTRUCTOR = 1L<<51; // MethodSymbols only
372 
373     /**
374      * Flag to mark a record field that was not initialized in the compact constructor
375      */
376     public static final long UNINITIALIZED_FIELD= 1L<<51; // VarSymbols only
377 
378     /** Flag is set for compiler-generated record members, it could be applied to
379      *  accessors and fields
380      */
381     public static final int GENERATED_MEMBER = 1<<24; // MethodSymbols and VarSymbols
382 
383     /**
384      * Flag to indicate sealed class/interface declaration.
385      */
386     public static final long SEALED = 1L<<62; // ClassSymbols
387 
388     /**
389      * Flag to indicate that the class/interface was declared with the non-sealed modifier.
390      */
391     public static final long NON_SEALED = 1L<<63; // ClassSymbols
392 
393 
394     /** Modifier masks.
395      */
396     public static final int
397         AccessFlags                       = PUBLIC | PROTECTED | PRIVATE,
398         LocalClassFlags                   = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC,
399         StaticLocalFlags                  = LocalClassFlags | STATIC | INTERFACE,
400         MemberClassFlags                  = LocalClassFlags | INTERFACE | AccessFlags,
401         MemberStaticClassFlags            = MemberClassFlags | STATIC,
402         ClassFlags                        = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION,
403         InterfaceVarFlags                 = FINAL | STATIC | PUBLIC,
404         VarFlags                          = AccessFlags | FINAL | STATIC |
405                                             VOLATILE | TRANSIENT | ENUM,
406         ConstructorFlags                  = AccessFlags,
407         InterfaceMethodFlags              = ABSTRACT | PUBLIC,
408         MethodFlags                       = AccessFlags | ABSTRACT | STATIC | NATIVE |
409                                             SYNCHRONIZED | FINAL | STRICTFP,
410         RecordMethodFlags                 = AccessFlags | ABSTRACT | STATIC |
411                                             SYNCHRONIZED | FINAL | STRICTFP;
412     public static final long
413         ExtendedStandardFlags             = (long)StandardFlags | DEFAULT | SEALED | NON_SEALED,
414         ExtendedMemberClassFlags          = (long)MemberClassFlags | SEALED | NON_SEALED,
415         ExtendedMemberStaticClassFlags    = (long) MemberStaticClassFlags | SEALED | NON_SEALED,
416         ExtendedClassFlags                = (long)ClassFlags | SEALED | NON_SEALED,
417         ModifierFlags                     = ((long)StandardFlags & ~INTERFACE) | DEFAULT | SEALED | NON_SEALED,
418         InterfaceMethodMask               = ABSTRACT | PRIVATE | STATIC | PUBLIC | STRICTFP | DEFAULT,
419         AnnotationTypeElementMask         = ABSTRACT | PUBLIC,
420         LocalVarFlags                     = FINAL | PARAMETER,
421         ReceiverParamFlags                = PARAMETER;
422 
423     public static Set<Modifier> asModifierSet(long flags) {
424         Set<Modifier> modifiers = modifierSets.get(flags);
425         if (modifiers == null) {
426             modifiers = java.util.EnumSet.noneOf(Modifier.class);
427             if (0 != (flags & PUBLIC))    modifiers.add(Modifier.PUBLIC);
428             if (0 != (flags & PROTECTED)) modifiers.add(Modifier.PROTECTED);
429             if (0 != (flags & PRIVATE))   modifiers.add(Modifier.PRIVATE);
430             if (0 != (flags & ABSTRACT))  modifiers.add(Modifier.ABSTRACT);
431             if (0 != (flags & STATIC))    modifiers.add(Modifier.STATIC);
432             if (0 != (flags & SEALED))    modifiers.add(Modifier.SEALED);
433             if (0 != (flags & NON_SEALED))
434                                           modifiers.add(Modifier.NON_SEALED);
435             if (0 != (flags & FINAL))     modifiers.add(Modifier.FINAL);
436             if (0 != (flags & TRANSIENT)) modifiers.add(Modifier.TRANSIENT);
437             if (0 != (flags & VOLATILE))  modifiers.add(Modifier.VOLATILE);
438             if (0 != (flags & SYNCHRONIZED))
439                                           modifiers.add(Modifier.SYNCHRONIZED);
440             if (0 != (flags & NATIVE))    modifiers.add(Modifier.NATIVE);
441             if (0 != (flags & STRICTFP))  modifiers.add(Modifier.STRICTFP);
442             if (0 != (flags & DEFAULT))   modifiers.add(Modifier.DEFAULT);
443             modifiers = Collections.unmodifiableSet(modifiers);
444             modifierSets.put(flags, modifiers);
445         }
446         return modifiers;
447     }
448 
449     // Cache of modifier sets.
450     private static final Map<Long, Set<Modifier>> modifierSets = new ConcurrentHashMap<>(64);
451 
452     public static boolean isStatic(Symbol symbol) {
453         return (symbol.flags() & STATIC) != 0;
454     }
455 
456     public static boolean isEnum(Symbol symbol) {
457         return (symbol.flags() & ENUM) != 0;
458     }
459 
460     public static boolean isConstant(Symbol.VarSymbol symbol) {
461         return symbol.getConstValue() != null;
462     }
463 
464 
465     public enum Flag {
466         PUBLIC(Flags.PUBLIC),
467         PRIVATE(Flags.PRIVATE),
468         PROTECTED(Flags.PROTECTED),
469         STATIC(Flags.STATIC),
470         FINAL(Flags.FINAL),
471         SYNCHRONIZED(Flags.SYNCHRONIZED),
472         VOLATILE(Flags.VOLATILE),
473         TRANSIENT(Flags.TRANSIENT),
474         NATIVE(Flags.NATIVE),
475         INTERFACE(Flags.INTERFACE),
476         ABSTRACT(Flags.ABSTRACT),
477         DEFAULT(Flags.DEFAULT),
478         STRICTFP(Flags.STRICTFP),
479         BRIDGE(Flags.BRIDGE),
480         SYNTHETIC(Flags.SYNTHETIC),
481         ANNOTATION(Flags.ANNOTATION),
482         DEPRECATED(Flags.DEPRECATED),
483         HASINIT(Flags.HASINIT),
484         BLOCK(Flags.BLOCK),
485         ENUM(Flags.ENUM),
486         MANDATED(Flags.MANDATED),
487         NOOUTERTHIS(Flags.NOOUTERTHIS),
488         EXISTS(Flags.EXISTS),
489         COMPOUND(Flags.COMPOUND),
490         CLASS_SEEN(Flags.CLASS_SEEN),
491         SOURCE_SEEN(Flags.SOURCE_SEEN),
492         LOCKED(Flags.LOCKED),
493         UNATTRIBUTED(Flags.UNATTRIBUTED),
494         ANONCONSTR(Flags.ANONCONSTR),
495         ACYCLIC(Flags.ACYCLIC),
496         PARAMETER(Flags.PARAMETER),
497         VARARGS(Flags.VARARGS),
498         ACYCLIC_ANN(Flags.ACYCLIC_ANN),
499         GENERATEDCONSTR(Flags.GENERATEDCONSTR),
500         HYPOTHETICAL(Flags.HYPOTHETICAL),
501         PROPRIETARY(Flags.PROPRIETARY),
502         UNION(Flags.UNION),
503         EFFECTIVELY_FINAL(Flags.EFFECTIVELY_FINAL),
504         CLASH(Flags.CLASH),
505         AUXILIARY(Flags.AUXILIARY),
506         NOT_IN_PROFILE(Flags.NOT_IN_PROFILE),
507         BAD_OVERRIDE(Flags.BAD_OVERRIDE),
508         SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC),
509         THROWS(Flags.THROWS),
510         LAMBDA_METHOD(Flags.LAMBDA_METHOD),
511         TYPE_TRANSLATED(Flags.TYPE_TRANSLATED),
512         MODULE(Flags.MODULE),
513         AUTOMATIC_MODULE(Flags.AUTOMATIC_MODULE),
514         SYSTEM_MODULE(Flags.SYSTEM_MODULE),
515         DEPRECATED_ANNOTATION(Flags.DEPRECATED_ANNOTATION),
516         DEPRECATED_REMOVAL(Flags.DEPRECATED_REMOVAL),
517         HAS_RESOURCE(Flags.HAS_RESOURCE),
518         POTENTIALLY_AMBIGUOUS(Flags.POTENTIALLY_AMBIGUOUS),
519         ANONCONSTR_BASED(Flags.ANONCONSTR_BASED),
520         NAME_FILLED(Flags.NAME_FILLED),
521         PREVIEW_API(Flags.PREVIEW_API),
522         PREVIEW_REFLECTIVE(Flags.PREVIEW_REFLECTIVE),
523         MATCH_BINDING(Flags.MATCH_BINDING),
524         MATCH_BINDING_TO_OUTER(Flags.MATCH_BINDING_TO_OUTER),
525         RECORD(Flags.RECORD),
526         RECOVERABLE(Flags.RECOVERABLE),
527         SEALED(Flags.SEALED),
528         NON_SEALED(Flags.NON_SEALED) {
529             @Override
530             public String toString() {
531                 return "non-sealed";
532             }
533         };
534 
535         Flag(long flag) {
536             this.value = flag;
537             this.lowercaseName = StringUtils.toLowerCase(name());
538         }
539 
540         @Override
541         public String toString() {
542             return lowercaseName;
543         }
544 
545         final long value;
546         final String lowercaseName;
547     }
548 
549 }