Flags.java revision 3655:535f80a0a2fd
1/*
2 * Copyright (c) 1999, 2015, 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
26package com.sun.tools.javac.code;
27
28import java.util.Collections;
29import java.util.EnumSet;
30import java.util.Map;
31import java.util.Set;
32import java.util.concurrent.ConcurrentHashMap;
33
34import javax.lang.model.element.Modifier;
35
36import com.sun.tools.javac.util.Assert;
37import 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 */
46public 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.
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;
180
181    /** Flag for class symbols to indicate it has been checked and found
182     *  acyclic.
183     */
184    public static final int ACYCLIC          = 1<<30;
185
186    /** Flag that marks bridge methods.
187     */
188    public static final long BRIDGE          = 1L<<31;
189
190    /** Flag that marks formal parameters.
191     */
192    public static final long PARAMETER   = 1L<<33;
193
194    /** Flag that marks varargs methods.
195     */
196    public static final long VARARGS   = 1L<<34;
197
198    /** Flag for annotation type symbols to indicate it has been
199     *  checked and found acyclic.
200     */
201    public static final long ACYCLIC_ANN      = 1L<<35;
202
203    /** Flag that marks a generated default constructor.
204     */
205    public static final long GENERATEDCONSTR   = 1L<<36;
206
207    /** Flag that marks a hypothetical method that need not really be
208     *  generated in the binary, but is present in the symbol table to
209     *  simplify checking for erasure clashes - also used for 292 poly sig methods.
210     */
211    public static final long HYPOTHETICAL   = 1L<<37;
212
213    /**
214     * Flag that marks an internal proprietary class.
215     */
216    public static final long PROPRIETARY = 1L<<38;
217
218    /**
219     * Flag that marks a multi-catch parameter.
220     */
221    public static final long UNION = 1L<<39;
222
223    // Flag bit (1L << 40) is available.
224
225    /**
226     * Flag that marks an 'effectively final' local variable.
227     */
228    public static final long EFFECTIVELY_FINAL = 1L<<41;
229
230    /**
231     * Flag that marks non-override equivalent methods with the same signature.
232     */
233    public static final long CLASH = 1L<<42;
234
235    /**
236     * Flag that marks either a default method or an interface containing default methods.
237     */
238    public static final long DEFAULT = 1L<<43;
239
240    /**
241     * Flag that marks class as auxiliary, ie a non-public class following
242     * the public class in a source file, that could block implicit compilation.
243     */
244    public static final long AUXILIARY = 1L<<44;
245
246    /**
247     * Flag that marks that a symbol is not available in the current profile
248     */
249    public static final long NOT_IN_PROFILE = 1L<<45;
250
251    /**
252     * Flag that indicates that an override error has been detected by Check.
253     */
254    public static final long BAD_OVERRIDE = 1L<<45;
255
256    /**
257     * Flag that indicates a signature polymorphic method (292).
258     */
259    public static final long SIGNATURE_POLYMORPHIC = 1L<<46;
260
261    /**
262     * Flag that indicates that an inference variable is used in a 'throws' clause.
263     */
264    public static final long THROWS = 1L<<47;
265
266    /**
267     * Flag that marks potentially ambiguous overloads
268     */
269    public static final long POTENTIALLY_AMBIGUOUS = 1L<<48;
270
271    /**
272     * Flag that marks a synthetic method body for a lambda expression
273     */
274    public static final long LAMBDA_METHOD = 1L<<49;
275
276    /**
277     * Flag to control recursion in TransTypes
278     */
279    public static final long TYPE_TRANSLATED = 1L<<50;
280
281    /**
282     * Flag to indicate class symbol is for module-info
283     */
284    public static final long MODULE = 1L<<51;
285
286    /**
287     * Flag to indicate the given ModuleSymbol is an automatic module.
288     */
289    public static final long AUTOMATIC_MODULE = 1L<<52;
290
291    /**
292     * Flag to indicate the given ModuleSymbol is a system module.
293     */
294    public static final long SYSTEM_MODULE = 1L<<53;
295
296    /** Modifier masks.
297     */
298    public static final int
299        AccessFlags           = PUBLIC | PROTECTED | PRIVATE,
300        LocalClassFlags       = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC,
301        MemberClassFlags      = LocalClassFlags | INTERFACE | AccessFlags,
302        ClassFlags            = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION,
303        InterfaceVarFlags     = FINAL | STATIC | PUBLIC,
304        VarFlags              = AccessFlags | FINAL | STATIC |
305                                VOLATILE | TRANSIENT | ENUM,
306        ConstructorFlags      = AccessFlags,
307        InterfaceMethodFlags  = ABSTRACT | PUBLIC,
308        MethodFlags           = AccessFlags | ABSTRACT | STATIC | NATIVE |
309                                SYNCHRONIZED | FINAL | STRICTFP;
310    public static final long
311        ExtendedStandardFlags       = (long)StandardFlags | DEFAULT,
312        ModifierFlags               = ((long)StandardFlags & ~INTERFACE) | DEFAULT,
313        InterfaceMethodMask         = ABSTRACT | PRIVATE | STATIC | PUBLIC | STRICTFP | DEFAULT,
314        AnnotationTypeElementMask   = ABSTRACT | PUBLIC,
315        LocalVarFlags               = FINAL | PARAMETER,
316        ReceiverParamFlags          = PARAMETER;
317
318
319    public static Set<Modifier> asModifierSet(long flags) {
320        Set<Modifier> modifiers = modifierSets.get(flags);
321        if (modifiers == null) {
322            modifiers = java.util.EnumSet.noneOf(Modifier.class);
323            if (0 != (flags & PUBLIC))    modifiers.add(Modifier.PUBLIC);
324            if (0 != (flags & PROTECTED)) modifiers.add(Modifier.PROTECTED);
325            if (0 != (flags & PRIVATE))   modifiers.add(Modifier.PRIVATE);
326            if (0 != (flags & ABSTRACT))  modifiers.add(Modifier.ABSTRACT);
327            if (0 != (flags & STATIC))    modifiers.add(Modifier.STATIC);
328            if (0 != (flags & FINAL))     modifiers.add(Modifier.FINAL);
329            if (0 != (flags & TRANSIENT)) modifiers.add(Modifier.TRANSIENT);
330            if (0 != (flags & VOLATILE))  modifiers.add(Modifier.VOLATILE);
331            if (0 != (flags & SYNCHRONIZED))
332                                          modifiers.add(Modifier.SYNCHRONIZED);
333            if (0 != (flags & NATIVE))    modifiers.add(Modifier.NATIVE);
334            if (0 != (flags & STRICTFP))  modifiers.add(Modifier.STRICTFP);
335            if (0 != (flags & DEFAULT))   modifiers.add(Modifier.DEFAULT);
336            modifiers = Collections.unmodifiableSet(modifiers);
337            modifierSets.put(flags, modifiers);
338        }
339        return modifiers;
340    }
341
342    // Cache of modifier sets.
343    private static final Map<Long, Set<Modifier>> modifierSets = new ConcurrentHashMap<>(64);
344
345    public static boolean isStatic(Symbol symbol) {
346        return (symbol.flags() & STATIC) != 0;
347    }
348
349    public static boolean isEnum(Symbol symbol) {
350        return (symbol.flags() & ENUM) != 0;
351    }
352
353    public static boolean isConstant(Symbol.VarSymbol symbol) {
354        return symbol.getConstValue() != null;
355    }
356
357
358    public enum Flag {
359        PUBLIC(Flags.PUBLIC),
360        PRIVATE(Flags.PRIVATE),
361        PROTECTED(Flags.PROTECTED),
362        STATIC(Flags.STATIC),
363        FINAL(Flags.FINAL),
364        SYNCHRONIZED(Flags.SYNCHRONIZED),
365        VOLATILE(Flags.VOLATILE),
366        TRANSIENT(Flags.TRANSIENT),
367        NATIVE(Flags.NATIVE),
368        INTERFACE(Flags.INTERFACE),
369        ABSTRACT(Flags.ABSTRACT),
370        DEFAULT(Flags.DEFAULT),
371        STRICTFP(Flags.STRICTFP),
372        BRIDGE(Flags.BRIDGE),
373        SYNTHETIC(Flags.SYNTHETIC),
374        ANNOTATION(Flags.ANNOTATION),
375        DEPRECATED(Flags.DEPRECATED),
376        HASINIT(Flags.HASINIT),
377        BLOCK(Flags.BLOCK),
378        ENUM(Flags.ENUM),
379        MANDATED(Flags.MANDATED),
380        NOOUTERTHIS(Flags.NOOUTERTHIS),
381        EXISTS(Flags.EXISTS),
382        COMPOUND(Flags.COMPOUND),
383        CLASS_SEEN(Flags.CLASS_SEEN),
384        SOURCE_SEEN(Flags.SOURCE_SEEN),
385        LOCKED(Flags.LOCKED),
386        UNATTRIBUTED(Flags.UNATTRIBUTED),
387        ANONCONSTR(Flags.ANONCONSTR),
388        ACYCLIC(Flags.ACYCLIC),
389        PARAMETER(Flags.PARAMETER),
390        VARARGS(Flags.VARARGS),
391        ACYCLIC_ANN(Flags.ACYCLIC_ANN),
392        GENERATEDCONSTR(Flags.GENERATEDCONSTR),
393        HYPOTHETICAL(Flags.HYPOTHETICAL),
394        PROPRIETARY(Flags.PROPRIETARY),
395        UNION(Flags.UNION),
396        EFFECTIVELY_FINAL(Flags.EFFECTIVELY_FINAL),
397        CLASH(Flags.CLASH),
398        AUXILIARY(Flags.AUXILIARY),
399        NOT_IN_PROFILE(Flags.NOT_IN_PROFILE),
400        BAD_OVERRIDE(Flags.BAD_OVERRIDE),
401        SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC),
402        THROWS(Flags.THROWS),
403        LAMBDA_METHOD(Flags.LAMBDA_METHOD),
404        TYPE_TRANSLATED(Flags.TYPE_TRANSLATED),
405        MODULE(Flags.MODULE);
406
407        Flag(long flag) {
408            this.value = flag;
409            this.lowercaseName = StringUtils.toLowerCase(name());
410        }
411
412        @Override
413        public String toString() {
414            return lowercaseName;
415        }
416
417        final long value;
418        final String lowercaseName;
419    }
420
421}
422