1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.dx.rop.code; 18 19import com.android.dx.util.Hex; 20 21/** 22 * Constants used as "access flags" in various places in classes, and 23 * related utilities. Although, at the rop layer, flags are generally 24 * ignored, this is the layer of communication, and as such, this 25 * package is where these definitions belong. The flag definitions are 26 * identical to Java access flags, but {@code ACC_SUPER} isn't 27 * used at all in translated code, and {@code ACC_SYNCHRONIZED} 28 * is only used in a very limited way. 29 */ 30public final class AccessFlags { 31 /** public member / class */ 32 public static final int ACC_PUBLIC = 0x0001; 33 34 /** private member */ 35 public static final int ACC_PRIVATE = 0x0002; 36 37 /** protected member */ 38 public static final int ACC_PROTECTED = 0x0004; 39 40 /** static member */ 41 public static final int ACC_STATIC = 0x0008; 42 43 /** final member / class */ 44 public static final int ACC_FINAL = 0x0010; 45 46 /** 47 * synchronized method; only valid in dex files for {@code native} 48 * methods 49 */ 50 public static final int ACC_SYNCHRONIZED = 0x0020; 51 52 /** 53 * class with new-style {@code invokespecial} for superclass 54 * method access 55 */ 56 public static final int ACC_SUPER = 0x0020; 57 58 /** volatile field */ 59 public static final int ACC_VOLATILE = 0x0040; 60 61 /** bridge method (generated) */ 62 public static final int ACC_BRIDGE = 0x0040; 63 64 /** transient field */ 65 public static final int ACC_TRANSIENT = 0x0080; 66 67 /** varargs method */ 68 public static final int ACC_VARARGS = 0x0080; 69 70 /** native method */ 71 public static final int ACC_NATIVE = 0x0100; 72 73 /** "class" is in fact an public static final interface */ 74 public static final int ACC_INTERFACE = 0x0200; 75 76 /** abstract method / class */ 77 public static final int ACC_ABSTRACT = 0x0400; 78 79 /** 80 * method with strict floating point ({@code strictfp}) 81 * behavior 82 */ 83 public static final int ACC_STRICT = 0x0800; 84 85 /** synthetic member */ 86 public static final int ACC_SYNTHETIC = 0x1000; 87 88 /** class is an annotation type */ 89 public static final int ACC_ANNOTATION = 0x2000; 90 91 /** 92 * class is an enumerated type; field is an element of an enumerated 93 * type 94 */ 95 public static final int ACC_ENUM = 0x4000; 96 97 /** method is a constructor */ 98 public static final int ACC_CONSTRUCTOR = 0x10000; 99 100 /** 101 * method was declared {@code synchronized}; has no effect on 102 * execution (other than inspecting this flag, per se) 103 */ 104 public static final int ACC_DECLARED_SYNCHRONIZED = 0x20000; 105 106 /** flags defined on classes */ 107 public static final int CLASS_FLAGS = 108 ACC_PUBLIC | ACC_FINAL | ACC_SUPER | ACC_INTERFACE | ACC_ABSTRACT | 109 ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM; 110 111 /** flags defined on inner classes */ 112 public static final int INNER_CLASS_FLAGS = 113 ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL | 114 ACC_INTERFACE | ACC_ABSTRACT | ACC_SYNTHETIC | ACC_ANNOTATION | 115 ACC_ENUM; 116 117 /** flags defined on fields */ 118 public static final int FIELD_FLAGS = 119 ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL | 120 ACC_VOLATILE | ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM; 121 122 /** flags defined on methods */ 123 public static final int METHOD_FLAGS = 124 ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL | 125 ACC_SYNCHRONIZED | ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE | 126 ACC_ABSTRACT | ACC_STRICT | ACC_SYNTHETIC | ACC_CONSTRUCTOR | 127 ACC_DECLARED_SYNCHRONIZED; 128 129 /** indicates conversion of class flags */ 130 private static final int CONV_CLASS = 1; 131 132 /** indicates conversion of field flags */ 133 private static final int CONV_FIELD = 2; 134 135 /** indicates conversion of method flags */ 136 private static final int CONV_METHOD = 3; 137 138 /** 139 * This class is uninstantiable. 140 */ 141 private AccessFlags() { 142 // This space intentionally left blank. 143 } 144 145 /** 146 * Returns a human-oriented string representing the given access flags, 147 * as defined on classes (not fields or methods). 148 * 149 * @param flags the flags 150 * @return {@code non-null;} human-oriented string 151 */ 152 public static String classString(int flags) { 153 return humanHelper(flags, CLASS_FLAGS, CONV_CLASS); 154 } 155 156 /** 157 * Returns a human-oriented string representing the given access flags, 158 * as defined on inner classes. 159 * 160 * @param flags the flags 161 * @return {@code non-null;} human-oriented string 162 */ 163 public static String innerClassString(int flags) { 164 return humanHelper(flags, INNER_CLASS_FLAGS, CONV_CLASS); 165 } 166 167 /** 168 * Returns a human-oriented string representing the given access flags, 169 * as defined on fields (not classes or methods). 170 * 171 * @param flags the flags 172 * @return {@code non-null;} human-oriented string 173 */ 174 public static String fieldString(int flags) { 175 return humanHelper(flags, FIELD_FLAGS, CONV_FIELD); 176 } 177 178 /** 179 * Returns a human-oriented string representing the given access flags, 180 * as defined on methods (not classes or fields). 181 * 182 * @param flags the flags 183 * @return {@code non-null;} human-oriented string 184 */ 185 public static String methodString(int flags) { 186 return humanHelper(flags, METHOD_FLAGS, CONV_METHOD); 187 } 188 189 /** 190 * Returns whether the flag {@code ACC_PUBLIC} is on in the given 191 * flags. 192 * 193 * @param flags the flags to check 194 * @return the value of the {@code ACC_PUBLIC} flag 195 */ 196 public static boolean isPublic(int flags) { 197 return (flags & ACC_PUBLIC) != 0; 198 } 199 200 /** 201 * Returns whether the flag {@code ACC_PROTECTED} is on in the given 202 * flags. 203 * 204 * @param flags the flags to check 205 * @return the value of the {@code ACC_PROTECTED} flag 206 */ 207 public static boolean isProtected(int flags) { 208 return (flags & ACC_PROTECTED) != 0; 209 } 210 211 /** 212 * Returns whether the flag {@code ACC_PRIVATE} is on in the given 213 * flags. 214 * 215 * @param flags the flags to check 216 * @return the value of the {@code ACC_PRIVATE} flag 217 */ 218 public static boolean isPrivate(int flags) { 219 return (flags & ACC_PRIVATE) != 0; 220 } 221 222 /** 223 * Returns whether the flag {@code ACC_STATIC} is on in the given 224 * flags. 225 * 226 * @param flags the flags to check 227 * @return the value of the {@code ACC_STATIC} flag 228 */ 229 public static boolean isStatic(int flags) { 230 return (flags & ACC_STATIC) != 0; 231 } 232 233 /** 234 * Returns whether the flag {@code ACC_SYNCHRONIZED} is on in 235 * the given flags. 236 * 237 * @param flags the flags to check 238 * @return the value of the {@code ACC_SYNCHRONIZED} flag 239 */ 240 public static boolean isSynchronized(int flags) { 241 return (flags & ACC_SYNCHRONIZED) != 0; 242 } 243 244 /** 245 * Returns whether the flag {@code ACC_ABSTRACT} is on in the given 246 * flags. 247 * 248 * @param flags the flags to check 249 * @return the value of the {@code ACC_ABSTRACT} flag 250 */ 251 public static boolean isAbstract(int flags) { 252 return (flags & ACC_ABSTRACT) != 0; 253 } 254 255 /** 256 * Returns whether the flag {@code ACC_NATIVE} is on in the given 257 * flags. 258 * 259 * @param flags the flags to check 260 * @return the value of the {@code ACC_NATIVE} flag 261 */ 262 public static boolean isNative(int flags) { 263 return (flags & ACC_NATIVE) != 0; 264 } 265 266 /** 267 * Returns whether the flag {@code ACC_ANNOTATION} is on in the given 268 * flags. 269 * 270 * @param flags the flags to check 271 * @return the value of the {@code ACC_ANNOTATION} flag 272 */ 273 public static boolean isAnnotation(int flags) { 274 return (flags & ACC_ANNOTATION) != 0; 275 } 276 277 /** 278 * Returns whether the flag {@code ACC_DECLARED_SYNCHRONIZED} is 279 * on in the given flags. 280 * 281 * @param flags the flags to check 282 * @return the value of the {@code ACC_DECLARED_SYNCHRONIZED} flag 283 */ 284 public static boolean isDeclaredSynchronized(int flags) { 285 return (flags & ACC_DECLARED_SYNCHRONIZED) != 0; 286 } 287 288 /** 289 * Helper to return a human-oriented string representing the given 290 * access flags. 291 * 292 * @param flags the defined flags 293 * @param mask mask for the "defined" bits 294 * @param what what the flags represent (one of {@code CONV_*}) 295 * @return {@code non-null;} human-oriented string 296 */ 297 private static String humanHelper(int flags, int mask, int what) { 298 StringBuffer sb = new StringBuffer(80); 299 int extra = flags & ~mask; 300 301 flags &= mask; 302 303 if ((flags & ACC_PUBLIC) != 0) { 304 sb.append("|public"); 305 } 306 if ((flags & ACC_PRIVATE) != 0) { 307 sb.append("|private"); 308 } 309 if ((flags & ACC_PROTECTED) != 0) { 310 sb.append("|protected"); 311 } 312 if ((flags & ACC_STATIC) != 0) { 313 sb.append("|static"); 314 } 315 if ((flags & ACC_FINAL) != 0) { 316 sb.append("|final"); 317 } 318 if ((flags & ACC_SYNCHRONIZED) != 0) { 319 if (what == CONV_CLASS) { 320 sb.append("|super"); 321 } else { 322 sb.append("|synchronized"); 323 } 324 } 325 if ((flags & ACC_VOLATILE) != 0) { 326 if (what == CONV_METHOD) { 327 sb.append("|bridge"); 328 } else { 329 sb.append("|volatile"); 330 } 331 } 332 if ((flags & ACC_TRANSIENT) != 0) { 333 if (what == CONV_METHOD) { 334 sb.append("|varargs"); 335 } else { 336 sb.append("|transient"); 337 } 338 } 339 if ((flags & ACC_NATIVE) != 0) { 340 sb.append("|native"); 341 } 342 if ((flags & ACC_INTERFACE) != 0) { 343 sb.append("|interface"); 344 } 345 if ((flags & ACC_ABSTRACT) != 0) { 346 sb.append("|abstract"); 347 } 348 if ((flags & ACC_STRICT) != 0) { 349 sb.append("|strictfp"); 350 } 351 if ((flags & ACC_SYNTHETIC) != 0) { 352 sb.append("|synthetic"); 353 } 354 if ((flags & ACC_ANNOTATION) != 0) { 355 sb.append("|annotation"); 356 } 357 if ((flags & ACC_ENUM) != 0) { 358 sb.append("|enum"); 359 } 360 if ((flags & ACC_CONSTRUCTOR) != 0) { 361 sb.append("|constructor"); 362 } 363 if ((flags & ACC_DECLARED_SYNCHRONIZED) != 0) { 364 sb.append("|declared_synchronized"); 365 } 366 367 if ((extra != 0) || (sb.length() == 0)) { 368 sb.append('|'); 369 sb.append(Hex.u2(extra)); 370 } 371 372 return sb.substring(1); 373 } 374} 375