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