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 17 package com.android.dx.rop.code; 18 19 import 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 */ 30 public 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 */ AccessFlags()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 */ classString(int flags)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 */ innerClassString(int flags)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 */ fieldString(int flags)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 */ methodString(int flags)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 */ isPublic(int flags)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 */ isProtected(int flags)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 */ isPrivate(int flags)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 */ isStatic(int flags)229 public static boolean isStatic(int flags) { 230 return (flags & ACC_STATIC) != 0; 231 } 232 233 /** 234 * Returns whether the flag {@code ACC_CONSTRUCTOR} is on in 235 * the given flags. 236 * 237 * @param flags the flags to check 238 * @return the value of the {@code ACC_CONSTRUCTOR} flag 239 */ isConstructor(int flags)240 public static boolean isConstructor(int flags) { 241 return (flags & ACC_CONSTRUCTOR) != 0; 242 } 243 244 /** 245 * Returns whether the flag {@code ACC_INTERFACE} is on in 246 * the given flags. 247 * 248 * @param flags the flags to check 249 * @return the value of the {@code ACC_INTERFACE} flag 250 */ isInterface(int flags)251 public static boolean isInterface(int flags) { 252 return (flags & ACC_INTERFACE) != 0; 253 } 254 255 /** 256 * Returns whether the flag {@code ACC_SYNCHRONIZED} is on in 257 * the given flags. 258 * 259 * @param flags the flags to check 260 * @return the value of the {@code ACC_SYNCHRONIZED} flag 261 */ isSynchronized(int flags)262 public static boolean isSynchronized(int flags) { 263 return (flags & ACC_SYNCHRONIZED) != 0; 264 } 265 266 /** 267 * Returns whether the flag {@code ACC_ABSTRACT} is on in the given 268 * flags. 269 * 270 * @param flags the flags to check 271 * @return the value of the {@code ACC_ABSTRACT} flag 272 */ isAbstract(int flags)273 public static boolean isAbstract(int flags) { 274 return (flags & ACC_ABSTRACT) != 0; 275 } 276 277 /** 278 * Returns whether the flag {@code ACC_NATIVE} is on in the given 279 * flags. 280 * 281 * @param flags the flags to check 282 * @return the value of the {@code ACC_NATIVE} flag 283 */ isNative(int flags)284 public static boolean isNative(int flags) { 285 return (flags & ACC_NATIVE) != 0; 286 } 287 288 /** 289 * Returns whether the flag {@code ACC_ANNOTATION} is on in the given 290 * flags. 291 * 292 * @param flags the flags to check 293 * @return the value of the {@code ACC_ANNOTATION} flag 294 */ isAnnotation(int flags)295 public static boolean isAnnotation(int flags) { 296 return (flags & ACC_ANNOTATION) != 0; 297 } 298 299 /** 300 * Returns whether the flag {@code ACC_DECLARED_SYNCHRONIZED} is 301 * on in the given flags. 302 * 303 * @param flags the flags to check 304 * @return the value of the {@code ACC_DECLARED_SYNCHRONIZED} flag 305 */ isDeclaredSynchronized(int flags)306 public static boolean isDeclaredSynchronized(int flags) { 307 return (flags & ACC_DECLARED_SYNCHRONIZED) != 0; 308 } 309 310 /** 311 * Returns whether the flag {@code ACC_ENUM} is on in the given flags. 312 * 313 * @param flags the flags to check 314 * @return the value of the {@code ACC_ENUM} flag 315 */ isEnum(int flags)316 public static boolean isEnum(int flags) { 317 return (flags & ACC_ENUM) != 0; 318 } 319 320 /** 321 * Helper to return a human-oriented string representing the given 322 * access flags. 323 * 324 * @param flags the defined flags 325 * @param mask mask for the "defined" bits 326 * @param what what the flags represent (one of {@code CONV_*}) 327 * @return {@code non-null;} human-oriented string 328 */ humanHelper(int flags, int mask, int what)329 private static String humanHelper(int flags, int mask, int what) { 330 StringBuilder sb = new StringBuilder(80); 331 int extra = flags & ~mask; 332 333 flags &= mask; 334 335 if ((flags & ACC_PUBLIC) != 0) { 336 sb.append("|public"); 337 } 338 if ((flags & ACC_PRIVATE) != 0) { 339 sb.append("|private"); 340 } 341 if ((flags & ACC_PROTECTED) != 0) { 342 sb.append("|protected"); 343 } 344 if ((flags & ACC_STATIC) != 0) { 345 sb.append("|static"); 346 } 347 if ((flags & ACC_FINAL) != 0) { 348 sb.append("|final"); 349 } 350 if ((flags & ACC_SYNCHRONIZED) != 0) { 351 if (what == CONV_CLASS) { 352 sb.append("|super"); 353 } else { 354 sb.append("|synchronized"); 355 } 356 } 357 if ((flags & ACC_VOLATILE) != 0) { 358 if (what == CONV_METHOD) { 359 sb.append("|bridge"); 360 } else { 361 sb.append("|volatile"); 362 } 363 } 364 if ((flags & ACC_TRANSIENT) != 0) { 365 if (what == CONV_METHOD) { 366 sb.append("|varargs"); 367 } else { 368 sb.append("|transient"); 369 } 370 } 371 if ((flags & ACC_NATIVE) != 0) { 372 sb.append("|native"); 373 } 374 if ((flags & ACC_INTERFACE) != 0) { 375 sb.append("|interface"); 376 } 377 if ((flags & ACC_ABSTRACT) != 0) { 378 sb.append("|abstract"); 379 } 380 if ((flags & ACC_STRICT) != 0) { 381 sb.append("|strictfp"); 382 } 383 if ((flags & ACC_SYNTHETIC) != 0) { 384 sb.append("|synthetic"); 385 } 386 if ((flags & ACC_ANNOTATION) != 0) { 387 sb.append("|annotation"); 388 } 389 if ((flags & ACC_ENUM) != 0) { 390 sb.append("|enum"); 391 } 392 if ((flags & ACC_CONSTRUCTOR) != 0) { 393 sb.append("|constructor"); 394 } 395 if ((flags & ACC_DECLARED_SYNCHRONIZED) != 0) { 396 sb.append("|declared_synchronized"); 397 } 398 399 if ((extra != 0) || (sb.length() == 0)) { 400 sb.append('|'); 401 sb.append(Hex.u2(extra)); 402 } 403 404 return sb.substring(1); 405 } 406 } 407