1 /* 2 * Copyright (c) 2007, 2008, 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.classfile; 27 28 import java.io.IOException; 29 import java.util.LinkedHashSet; 30 import java.util.Set; 31 32 /** 33 * See JVMS, sections 4.2, 4.6, 4.7. 34 * 35 * <p><b>This is NOT part of any supported API. 36 * If 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 AccessFlags { 41 public static final int ACC_PUBLIC = 0x0001; // class, inner, field, method 42 public static final int ACC_PRIVATE = 0x0002; // inner, field, method 43 public static final int ACC_PROTECTED = 0x0004; // inner, field, method 44 public static final int ACC_STATIC = 0x0008; // inner, field, method 45 public static final int ACC_FINAL = 0x0010; // class, inner, field, method 46 public static final int ACC_SUPER = 0x0020; // class 47 public static final int ACC_SYNCHRONIZED = 0x0020; // method 48 public static final int ACC_VOLATILE = 0x0040; // field 49 public static final int ACC_BRIDGE = 0x0040; // method 50 public static final int ACC_TRANSIENT = 0x0080; // field 51 public static final int ACC_VARARGS = 0x0080; // method 52 public static final int ACC_NATIVE = 0x0100; // method 53 public static final int ACC_INTERFACE = 0x0200; // class, inner 54 public static final int ACC_ABSTRACT = 0x0400; // class, inner, method 55 public static final int ACC_STRICT = 0x0800; // method 56 public static final int ACC_SYNTHETIC = 0x1000; // class, inner, field, method 57 public static final int ACC_ANNOTATION = 0x2000; // class, inner 58 public static final int ACC_ENUM = 0x4000; // class, inner, field 59 public static final int ACC_MANDATED = 0x8000; // class, inner, field, method 60 61 public static enum Kind { Class, InnerClass, Field, Method}; 62 63 AccessFlags(ClassReader cr) throws IOException { 64 this(cr.readUnsignedShort()); 65 } 66 67 public AccessFlags(int flags) { 68 this.flags = flags; 69 } 70 71 public AccessFlags ignore(int mask) { 72 return new AccessFlags(flags & ~mask); 73 } 74 75 public boolean is(int mask) { 76 return (flags & mask) != 0; 77 } 78 79 public int byteLength() { 80 return 2; 81 } 82 83 private static final int[] classModifiers = { 84 ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT 85 }; 86 87 private static final int[] classFlags = { 88 ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_INTERFACE, ACC_ABSTRACT, 89 ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM 90 }; 91 92 public Set<String> getClassModifiers() { 93 int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags); 94 return getModifiers(f, classModifiers, Kind.Class); 95 } 96 97 public Set<String> getClassFlags() { 98 return getFlags(classFlags, Kind.Class); 99 } 100 101 private static final int[] innerClassModifiers = { 102 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, 103 ACC_ABSTRACT 104 }; 105 106 private static final int[] innerClassFlags = { 107 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SUPER, 108 ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM 109 }; 110 111 public Set<String> getInnerClassModifiers() { 112 int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags); 113 return getModifiers(f, innerClassModifiers, Kind.InnerClass); 114 } 115 116 public Set<String> getInnerClassFlags() { 117 return getFlags(innerClassFlags, Kind.InnerClass); 118 } 119 120 private static final int[] fieldModifiers = { 121 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, 122 ACC_VOLATILE, ACC_TRANSIENT 123 }; 124 125 private static final int[] fieldFlags = { 126 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, 127 ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM 128 }; 129 130 public Set<String> getFieldModifiers() { 131 return getModifiers(fieldModifiers, Kind.Field); 132 } 133 134 public Set<String> getFieldFlags() { 135 return getFlags(fieldFlags, Kind.Field); 136 } 137 138 private static final int[] methodModifiers = { 139 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, 140 ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT 141 }; 142 143 private static final int[] methodFlags = { 144 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, 145 ACC_SYNCHRONIZED, ACC_BRIDGE, ACC_VARARGS, ACC_NATIVE, ACC_ABSTRACT, 146 ACC_STRICT, ACC_SYNTHETIC 147 }; 148 149 public Set<String> getMethodModifiers() { 150 return getModifiers(methodModifiers, Kind.Method); 151 } 152 153 public Set<String> getMethodFlags() { 154 return getFlags(methodFlags, Kind.Method); 155 } 156 157 private Set<String> getModifiers(int[] modifierFlags, Kind t) { 158 return getModifiers(flags, modifierFlags, t); 159 } 160 161 private static Set<String> getModifiers(int flags, int[] modifierFlags, Kind t) { 162 Set<String> s = new LinkedHashSet<String>(); 163 for (int m: modifierFlags) { 164 if ((flags & m) != 0) 165 s.add(flagToModifier(m, t)); 166 } 167 return s; 168 } 169 170 private Set<String> getFlags(int[] expectedFlags, Kind t) { 171 Set<String> s = new LinkedHashSet<String>(); 172 int f = flags; 173 for (int e: expectedFlags) { 174 if ((f & e) != 0) { 175 s.add(flagToName(e, t)); 176 f = f & ~e; 177 } 178 } 179 while (f != 0) { 180 int bit = Integer.highestOneBit(f); 181 s.add("0x" + Integer.toHexString(bit)); 182 f = f & ~bit; 183 } 184 return s; 185 } 186 187 private static String flagToModifier(int flag, Kind t) { 188 switch (flag) { 189 case ACC_PUBLIC: 190 return "public"; 191 case ACC_PRIVATE: 192 return "private"; 193 case ACC_PROTECTED: 194 return "protected"; 195 case ACC_STATIC: 196 return "static"; 197 case ACC_FINAL: 198 return "final"; 199 case ACC_SYNCHRONIZED: 200 return "synchronized"; 201 case 0x80: 202 return (t == Kind.Field ? "transient" : null); 203 case ACC_VOLATILE: 204 return "volatile"; 205 case ACC_NATIVE: 206 return "native"; 207 case ACC_ABSTRACT: 208 return "abstract"; 209 case ACC_STRICT: 210 return "strictfp"; 211 case ACC_MANDATED: 212 return "mandated"; 213 default: 214 return null; 215 } 216 } 217 218 private static String flagToName(int flag, Kind t) { 219 switch (flag) { 220 case ACC_PUBLIC: 221 return "ACC_PUBLIC"; 222 case ACC_PRIVATE: 223 return "ACC_PRIVATE"; 224 case ACC_PROTECTED: 225 return "ACC_PROTECTED"; 226 case ACC_STATIC: 227 return "ACC_STATIC"; 228 case ACC_FINAL: 229 return "ACC_FINAL"; 230 case 0x20: 231 return (t == Kind.Class ? "ACC_SUPER" : "ACC_SYNCHRONIZED"); 232 case 0x40: 233 return (t == Kind.Field ? "ACC_VOLATILE" : "ACC_BRIDGE"); 234 case 0x80: 235 return (t == Kind.Field ? "ACC_TRANSIENT" : "ACC_VARARGS"); 236 case ACC_NATIVE: 237 return "ACC_NATIVE"; 238 case ACC_INTERFACE: 239 return "ACC_INTERFACE"; 240 case ACC_ABSTRACT: 241 return "ACC_ABSTRACT"; 242 case ACC_STRICT: 243 return "ACC_STRICT"; 244 case ACC_SYNTHETIC: 245 return "ACC_SYNTHETIC"; 246 case ACC_ANNOTATION: 247 return "ACC_ANNOTATION"; 248 case ACC_ENUM: 249 return "ACC_ENUM"; 250 case ACC_MANDATED: 251 return "ACC_MANDATED"; 252 default: 253 return null; 254 } 255 } 256 257 public final int flags; 258 }