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