| 1 | /* | 
| 2 |  * Copyright 1999-2006 Sun Microsystems, Inc.  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.  Sun designates this | 
| 8 |  * particular file as subject to the "Classpath" exception as provided | 
| 9 |  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | 
| 22 |  * CA 95054 USA or visit www.sun.com if you need additional information or | 
| 23 |  * have any questions. | 
| 24 |  */ | 
| 25 |   | 
| 26 | package com.sun.tools.javac.code; | 
| 27 |   | 
| 28 | import java.util.Collections; | 
| 29 | import java.util.Map; | 
| 30 | import java.util.Set; | 
| 31 | import javax.lang.model.element.Modifier; | 
| 32 |   | 
| 33 | /** Access flags and other modifiers for Java classes and members. | 
| 34 |  * | 
| 35 |  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If | 
| 36 |  *  you write code that depends on this, you do so at your own risk. | 
| 37 |  *  This code and its internal interfaces are subject to change or | 
| 38 |  *  deletion without notice.</b> | 
| 39 |  */ | 
| 40 | public class Flags { | 
| 41 |   | 
| 42 |     private Flags() {} // uninstantiable | 
| 43 |   | 
| 44 |     public static String toString(long flags) { | 
| 45 |         StringBuffer buf = new StringBuffer(); | 
| 46 |         if ((flags&PUBLIC) != 0) buf.append("public "); | 
| 47 |         if ((flags&PRIVATE) != 0) buf.append("private "); | 
| 48 |         if ((flags&PROTECTED) != 0) buf.append("protected "); | 
| 49 |         if ((flags&STATIC) != 0) buf.append("static "); | 
| 50 |         if ((flags&FINAL) != 0) buf.append("final "); | 
| 51 |         if ((flags&SYNCHRONIZED) != 0) buf.append("synchronized "); | 
| 52 |         if ((flags&VOLATILE) != 0) buf.append("volatile "); | 
| 53 |         if ((flags&TRANSIENT) != 0) buf.append("transient "); | 
| 54 |         if ((flags&NATIVE) != 0) buf.append("native "); | 
| 55 |         if ((flags&INTERFACE) != 0) buf.append("interface "); | 
| 56 |         if ((flags&ABSTRACT) != 0) buf.append("abstract "); | 
| 57 |         if ((flags&STRICTFP) != 0) buf.append("strictfp "); | 
| 58 |         if ((flags&BRIDGE) != 0) buf.append("bridge "); | 
| 59 |         if ((flags&SYNTHETIC) != 0) buf.append("synthetic "); | 
| 60 |         if ((flags&DEPRECATED) != 0) buf.append("deprecated "); | 
| 61 |         if ((flags&HASINIT) != 0) buf.append("hasinit "); | 
| 62 |         if ((flags&ENUM) != 0) buf.append("enum "); | 
| 63 |         if ((flags&IPROXY) != 0) buf.append("iproxy "); | 
| 64 |         if ((flags&NOOUTERTHIS) != 0) buf.append("noouterthis "); | 
| 65 |         if ((flags&EXISTS) != 0) buf.append("exists "); | 
| 66 |         if ((flags&COMPOUND) != 0) buf.append("compound "); | 
| 67 |         if ((flags&CLASS_SEEN) != 0) buf.append("class_seen "); | 
| 68 |         if ((flags&SOURCE_SEEN) != 0) buf.append("source_seen "); | 
| 69 |         if ((flags&LOCKED) != 0) buf.append("locked "); | 
| 70 |         if ((flags&UNATTRIBUTED) != 0) buf.append("unattributed "); | 
| 71 |         if ((flags&ANONCONSTR) != 0) buf.append("anonconstr "); | 
| 72 |         if ((flags&ACYCLIC) != 0) buf.append("acyclic "); | 
| 73 |         if ((flags&PARAMETER) != 0) buf.append("parameter "); | 
| 74 |         if ((flags&VARARGS) != 0) buf.append("varargs "); | 
| 75 |         return buf.toString(); | 
| 76 |     } | 
| 77 |   | 
| 78 |     /* Standard Java flags. | 
| 79 |      */ | 
| 80 |     public static final int PUBLIC       = 1<<0; | 
| 81 |     public static final int PRIVATE      = 1<<1; | 
| 82 |     public static final int PROTECTED    = 1<<2; | 
| 83 |     public static final int STATIC       = 1<<3; | 
| 84 |     public static final int FINAL        = 1<<4; | 
| 85 |     public static final int SYNCHRONIZED = 1<<5; | 
| 86 |     public static final int VOLATILE     = 1<<6; | 
| 87 |     public static final int TRANSIENT    = 1<<7; | 
| 88 |     public static final int NATIVE       = 1<<8; | 
| 89 |     public static final int INTERFACE    = 1<<9; | 
| 90 |     public static final int ABSTRACT     = 1<<10; | 
| 91 |     public static final int STRICTFP     = 1<<11; | 
| 92 |   | 
| 93 |     /* Flag that marks a symbol synthetic, added in classfile v49.0. */ | 
| 94 |     public static final int SYNTHETIC    = 1<<12; | 
| 95 |   | 
| 96 |     /** Flag that marks attribute interfaces, added in classfile v49.0. */ | 
| 97 |     public static final int ANNOTATION   = 1<<13; | 
| 98 |   | 
| 99 |     /** An enumeration type or an enumeration constant, added in | 
| 100 |      *  classfile v49.0. */ | 
| 101 |     public static final int ENUM         = 1<<14; | 
| 102 |   | 
| 103 |     public static final int StandardFlags = 0x0fff; | 
| 104 |   | 
| 105 |     // Because the following access flags are overloaded with other | 
| 106 |     // bit positions, we translate them when reading and writing class | 
| 107 |     // files into unique bits positions: ACC_SYNTHETIC <-> SYNTHETIC, | 
| 108 |     // for example. | 
| 109 |     public static final int ACC_SUPER    = 0x0020; | 
| 110 |     public static final int ACC_BRIDGE   = 0x0040; | 
| 111 |     public static final int ACC_VARARGS  = 0x0080; | 
| 112 |   | 
| 113 |     /***************************************** | 
| 114 |      * Internal compiler flags (no bits in the lower 16). | 
| 115 |      *****************************************/ | 
| 116 |   | 
| 117 |     /** Flag is set if symbol is deprecated. | 
| 118 |      */ | 
| 119 |     public static final int DEPRECATED   = 1<<17; | 
| 120 |   | 
| 121 |     /** Flag is set for a variable symbol if the variable's definition | 
| 122 |      *  has an initializer part. | 
| 123 |      */ | 
| 124 |     public static final int HASINIT          = 1<<18; | 
| 125 |   | 
| 126 |     /** Flag is set for compiler-generated anonymous method symbols | 
| 127 |      *  that `own' an initializer block. | 
| 128 |      */ | 
| 129 |     public static final int BLOCK            = 1<<20; | 
| 130 |   | 
| 131 |     /** Flag is set for compiler-generated abstract methods that implement | 
| 132 |      *  an interface method (Miranda methods). | 
| 133 |      */ | 
| 134 |     public static final int IPROXY           = 1<<21; | 
| 135 |   | 
| 136 |     /** Flag is set for nested classes that do not access instance members | 
| 137 |      *  or `this' of an outer class and therefore don't need to be passed | 
| 138 |      *  a this$n reference.  This flag is currently set only for anonymous | 
| 139 |      *  classes in superclass constructor calls and only for pre 1.4 targets. | 
| 140 |      *  todo: use this flag for optimizing away this$n parameters in | 
| 141 |      *  other cases. | 
| 142 |      */ | 
| 143 |     public static final int NOOUTERTHIS  = 1<<22; | 
| 144 |   | 
| 145 |     /** Flag is set for package symbols if a package has a member or | 
| 146 |      *  directory and therefore exists. | 
| 147 |      */ | 
| 148 |     public static final int EXISTS           = 1<<23; | 
| 149 |   | 
| 150 |     /** Flag is set for compiler-generated compound classes | 
| 151 |      *  representing multiple variable bounds | 
| 152 |      */ | 
| 153 |     public static final int COMPOUND     = 1<<24; | 
| 154 |   | 
| 155 |     /** Flag is set for class symbols if a class file was found for this class. | 
| 156 |      */ | 
| 157 |     public static final int CLASS_SEEN   = 1<<25; | 
| 158 |   | 
| 159 |     /** Flag is set for class symbols if a source file was found for this | 
| 160 |      *  class. | 
| 161 |      */ | 
| 162 |     public static final int SOURCE_SEEN  = 1<<26; | 
| 163 |   | 
| 164 |     /* State flags (are reset during compilation). | 
| 165 |      */ | 
| 166 |   | 
| 167 |     /** Flag for class symbols is set and later re-set as a lock in | 
| 168 |      *  Enter to detect cycles in the superclass/superinterface | 
| 169 |      *  relations.  Similarly for constructor call cycle detection in | 
| 170 |      *  Attr. | 
| 171 |      */ | 
| 172 |     public static final int LOCKED           = 1<<27; | 
| 173 |   | 
| 174 |     /** Flag for class symbols is set and later re-set to indicate that a class | 
| 175 |      *  has been entered but has not yet been attributed. | 
| 176 |      */ | 
| 177 |     public static final int UNATTRIBUTED = 1<<28; | 
| 178 |   | 
| 179 |     /** Flag for synthesized default constructors of anonymous classes. | 
| 180 |      */ | 
| 181 |     public static final int ANONCONSTR   = 1<<29; | 
| 182 |   | 
| 183 |     /** Flag for class symbols to indicate it has been checked and found | 
| 184 |      *  acyclic. | 
| 185 |      */ | 
| 186 |     public static final int ACYCLIC          = 1<<30; | 
| 187 |   | 
| 188 |     /** Flag that marks bridge methods. | 
| 189 |      */ | 
| 190 |     public static final long BRIDGE          = 1L<<31; | 
| 191 |   | 
| 192 |     /** Flag that marks formal parameters. | 
| 193 |      */ | 
| 194 |     public static final long PARAMETER   = 1L<<33; | 
| 195 |   | 
| 196 |     /** Flag that marks varargs methods. | 
| 197 |      */ | 
| 198 |     public static final long VARARGS   = 1L<<34; | 
| 199 |   | 
| 200 |     /** Flag for annotation type symbols to indicate it has been | 
| 201 |      *  checked and found acyclic. | 
| 202 |      */ | 
| 203 |     public static final long ACYCLIC_ANN      = 1L<<35; | 
| 204 |   | 
| 205 |     /** Flag that marks a generated default constructor. | 
| 206 |      */ | 
| 207 |     public static final long GENERATEDCONSTR   = 1L<<36; | 
| 208 |   | 
| 209 |     /** Flag that marks a hypothetical method that need not really be | 
| 210 |      *  generated in the binary, but is present in the symbol table to | 
| 211 |      *  simplify checking for erasure clashes. | 
| 212 |      */ | 
| 213 |     public static final long HYPOTHETICAL   = 1L<<37; | 
| 214 |   | 
| 215 |     /** | 
| 216 |      * Flag that marks a Sun proprietary class. | 
| 217 |      */ | 
| 218 |     public static final long PROPRIETARY = 1L<<38; | 
| 219 |   | 
| 220 |     /** Modifier masks. | 
| 221 |      */ | 
| 222 |     public static final int | 
| 223 |         AccessFlags           = PUBLIC | PROTECTED | PRIVATE, | 
| 224 |         LocalClassFlags       = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC, | 
| 225 |         MemberClassFlags      = LocalClassFlags | INTERFACE | AccessFlags, | 
| 226 |         ClassFlags            = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION, | 
| 227 |         InterfaceVarFlags     = FINAL | STATIC | PUBLIC, | 
| 228 |         VarFlags              = AccessFlags | FINAL | STATIC | | 
| 229 |                                 VOLATILE | TRANSIENT | ENUM, | 
| 230 |         ConstructorFlags      = AccessFlags, | 
| 231 |         InterfaceMethodFlags  = ABSTRACT | PUBLIC, | 
| 232 |         MethodFlags           = AccessFlags | ABSTRACT | STATIC | NATIVE | | 
| 233 |                                 SYNCHRONIZED | FINAL | STRICTFP; | 
| 234 |     public static final long | 
| 235 |         LocalVarFlags         = FINAL | PARAMETER; | 
| 236 |   | 
| 237 |     public static Set<Modifier> asModifierSet(long flags) { | 
| 238 |         Set<Modifier> modifiers = modifierSets.get(flags); | 
| 239 |         if (modifiers == null) { | 
| 240 |             modifiers = java.util.EnumSet.noneOf(Modifier.class); | 
| 241 |             if (0 != (flags & PUBLIC))    modifiers.add(Modifier.PUBLIC); | 
| 242 |             if (0 != (flags & PROTECTED)) modifiers.add(Modifier.PROTECTED); | 
| 243 |             if (0 != (flags & PRIVATE))   modifiers.add(Modifier.PRIVATE); | 
| 244 |             if (0 != (flags & ABSTRACT))  modifiers.add(Modifier.ABSTRACT); | 
| 245 |             if (0 != (flags & STATIC))    modifiers.add(Modifier.STATIC); | 
| 246 |             if (0 != (flags & FINAL))     modifiers.add(Modifier.FINAL); | 
| 247 |             if (0 != (flags & TRANSIENT)) modifiers.add(Modifier.TRANSIENT); | 
| 248 |             if (0 != (flags & VOLATILE))  modifiers.add(Modifier.VOLATILE); | 
| 249 |             if (0 != (flags & SYNCHRONIZED)) | 
| 250 |                                           modifiers.add(Modifier.SYNCHRONIZED); | 
| 251 |             if (0 != (flags & NATIVE))    modifiers.add(Modifier.NATIVE); | 
| 252 |             if (0 != (flags & STRICTFP))  modifiers.add(Modifier.STRICTFP); | 
| 253 |             modifiers = Collections.unmodifiableSet(modifiers); | 
| 254 |             modifierSets.put(flags, modifiers); | 
| 255 |         } | 
| 256 |         return modifiers; | 
| 257 |     } | 
| 258 |   | 
| 259 |     // Cache of modifier sets. | 
| 260 |     private static Map<Long, Set<Modifier>> modifierSets = | 
| 261 |         new java.util.concurrent.ConcurrentHashMap<Long, Set<Modifier>>(64); | 
| 262 |   | 
| 263 |     public static boolean isStatic(Symbol symbol) { | 
| 264 |         return (symbol.flags() & STATIC) != 0; | 
| 265 |     } | 
| 266 |   | 
| 267 |     public static boolean isEnum(Symbol symbol) { | 
| 268 |         return (symbol.flags() & ENUM) != 0; | 
| 269 |     } | 
| 270 |   | 
| 271 |     public static boolean isConstant(Symbol.VarSymbol symbol) { | 
| 272 |         return symbol.getConstValue() != null; | 
| 273 |     } | 
| 274 | } |