| /* |
| * Copyright (C) 2007 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.jack.dx.rop.code; |
| |
| import com.android.jack.dx.util.Hex; |
| |
| /** |
| * Constants used as "access flags" in various places in classes, and |
| * related utilities. Although, at the rop layer, flags are generally |
| * ignored, this is the layer of communication, and as such, this |
| * package is where these definitions belong. The flag definitions are |
| * identical to Java access flags, but {@code ACC_SUPER} isn't |
| * used at all in translated code, and {@code ACC_SYNCHRONIZED} |
| * is only used in a very limited way. |
| */ |
| public final class AccessFlags { |
| /** public member / class */ |
| public static final int ACC_PUBLIC = 0x0001; |
| |
| /** private member */ |
| public static final int ACC_PRIVATE = 0x0002; |
| |
| /** protected member */ |
| public static final int ACC_PROTECTED = 0x0004; |
| |
| /** static member */ |
| public static final int ACC_STATIC = 0x0008; |
| |
| /** final member / class */ |
| public static final int ACC_FINAL = 0x0010; |
| |
| /** |
| * synchronized method; only valid in dex files for {@code native} |
| * methods |
| */ |
| public static final int ACC_SYNCHRONIZED = 0x0020; |
| |
| /** |
| * class with new-style {@code invokespecial} for superclass |
| * method access |
| */ |
| public static final int ACC_SUPER = 0x0020; |
| |
| /** volatile field */ |
| public static final int ACC_VOLATILE = 0x0040; |
| |
| /** bridge method (generated) */ |
| public static final int ACC_BRIDGE = 0x0040; |
| |
| /** transient field */ |
| public static final int ACC_TRANSIENT = 0x0080; |
| |
| /** varargs method */ |
| public static final int ACC_VARARGS = 0x0080; |
| |
| /** native method */ |
| public static final int ACC_NATIVE = 0x0100; |
| |
| /** "class" is in fact an public static final interface */ |
| public static final int ACC_INTERFACE = 0x0200; |
| |
| /** abstract method / class */ |
| public static final int ACC_ABSTRACT = 0x0400; |
| |
| /** |
| * method with strict floating point ({@code strictfp}) |
| * behavior |
| */ |
| public static final int ACC_STRICT = 0x0800; |
| |
| /** synthetic member */ |
| public static final int ACC_SYNTHETIC = 0x1000; |
| |
| /** class is an annotation type */ |
| public static final int ACC_ANNOTATION = 0x2000; |
| |
| /** |
| * class is an enumerated type; field is an element of an enumerated |
| * type |
| */ |
| public static final int ACC_ENUM = 0x4000; |
| |
| /** method is a constructor */ |
| public static final int ACC_CONSTRUCTOR = 0x10000; |
| |
| /** |
| * method was declared {@code synchronized}; has no effect on |
| * execution (other than inspecting this flag, per se) |
| */ |
| public static final int ACC_DECLARED_SYNCHRONIZED = 0x20000; |
| |
| /** flags defined on classes */ |
| public static final int CLASS_FLAGS = ACC_PUBLIC | ACC_FINAL | ACC_SUPER | ACC_INTERFACE |
| | ACC_ABSTRACT | ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM; |
| |
| /** flags defined on inner classes */ |
| public static final int INNER_CLASS_FLAGS = ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC |
| | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT | ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM; |
| |
| /** flags defined on fields */ |
| public static final int FIELD_FLAGS = ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC |
| | ACC_FINAL | ACC_VOLATILE | ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM; |
| |
| /** flags defined on methods */ |
| public static final int METHOD_FLAGS = ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC |
| | ACC_FINAL | ACC_SYNCHRONIZED | ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE | ACC_ABSTRACT |
| | ACC_STRICT | ACC_SYNTHETIC | ACC_CONSTRUCTOR | ACC_DECLARED_SYNCHRONIZED; |
| |
| /** indicates conversion of class flags */ |
| private static final int CONV_CLASS = 1; |
| |
| /** indicates conversion of field flags */ |
| private static final int CONV_FIELD = 2; |
| |
| /** indicates conversion of method flags */ |
| private static final int CONV_METHOD = 3; |
| |
| /** |
| * This class is uninstantiable. |
| */ |
| private AccessFlags() { |
| // This space intentionally left blank. |
| } |
| |
| /** |
| * Returns a human-oriented string representing the given access flags, |
| * as defined on classes (not fields or methods). |
| * |
| * @param flags the flags |
| * @return {@code non-null;} human-oriented string |
| */ |
| public static String classString(int flags) { |
| return humanHelper(flags, CLASS_FLAGS, CONV_CLASS); |
| } |
| |
| /** |
| * Returns a human-oriented string representing the given access flags, |
| * as defined on inner classes. |
| * |
| * @param flags the flags |
| * @return {@code non-null;} human-oriented string |
| */ |
| public static String innerClassString(int flags) { |
| return humanHelper(flags, INNER_CLASS_FLAGS, CONV_CLASS); |
| } |
| |
| /** |
| * Returns a human-oriented string representing the given access flags, |
| * as defined on fields (not classes or methods). |
| * |
| * @param flags the flags |
| * @return {@code non-null;} human-oriented string |
| */ |
| public static String fieldString(int flags) { |
| return humanHelper(flags, FIELD_FLAGS, CONV_FIELD); |
| } |
| |
| /** |
| * Returns a human-oriented string representing the given access flags, |
| * as defined on methods (not classes or fields). |
| * |
| * @param flags the flags |
| * @return {@code non-null;} human-oriented string |
| */ |
| public static String methodString(int flags) { |
| return humanHelper(flags, METHOD_FLAGS, CONV_METHOD); |
| } |
| |
| /** |
| * Returns whether the flag {@code ACC_PUBLIC} is on in the given |
| * flags. |
| * |
| * @param flags the flags to check |
| * @return the value of the {@code ACC_PUBLIC} flag |
| */ |
| public static boolean isPublic(int flags) { |
| return (flags & ACC_PUBLIC) != 0; |
| } |
| |
| /** |
| * Returns whether the flag {@code ACC_PROTECTED} is on in the given |
| * flags. |
| * |
| * @param flags the flags to check |
| * @return the value of the {@code ACC_PROTECTED} flag |
| */ |
| public static boolean isProtected(int flags) { |
| return (flags & ACC_PROTECTED) != 0; |
| } |
| |
| /** |
| * Returns whether the flag {@code ACC_PRIVATE} is on in the given |
| * flags. |
| * |
| * @param flags the flags to check |
| * @return the value of the {@code ACC_PRIVATE} flag |
| */ |
| public static boolean isPrivate(int flags) { |
| return (flags & ACC_PRIVATE) != 0; |
| } |
| |
| /** |
| * Returns whether the flag {@code ACC_STATIC} is on in the given |
| * flags. |
| * |
| * @param flags the flags to check |
| * @return the value of the {@code ACC_STATIC} flag |
| */ |
| public static boolean isStatic(int flags) { |
| return (flags & ACC_STATIC) != 0; |
| } |
| |
| /** |
| * Returns whether the flag {@code ACC_CONSTRUCTOR} is on in |
| * the given flags. |
| * |
| * @param flags the flags to check |
| * @return the value of the {@code ACC_CONSTRUCTOR} flag |
| */ |
| public static boolean isConstructor(int flags) { |
| return (flags & ACC_CONSTRUCTOR) != 0; |
| } |
| |
| /** |
| * Returns whether the flag {@code ACC_INTERFACE} is on in |
| * the given flags. |
| * |
| * @param flags the flags to check |
| * @return the value of the {@code ACC_INTERFACE} flag |
| */ |
| public static boolean isInterface(int flags) { |
| return (flags & ACC_INTERFACE) != 0; |
| } |
| |
| /** |
| * Returns whether the flag {@code ACC_SYNCHRONIZED} is on in |
| * the given flags. |
| * |
| * @param flags the flags to check |
| * @return the value of the {@code ACC_SYNCHRONIZED} flag |
| */ |
| public static boolean isSynchronized(int flags) { |
| return (flags & ACC_SYNCHRONIZED) != 0; |
| } |
| |
| /** |
| * Returns whether the flag {@code ACC_ABSTRACT} is on in the given |
| * flags. |
| * |
| * @param flags the flags to check |
| * @return the value of the {@code ACC_ABSTRACT} flag |
| */ |
| public static boolean isAbstract(int flags) { |
| return (flags & ACC_ABSTRACT) != 0; |
| } |
| |
| /** |
| * Returns whether the flag {@code ACC_NATIVE} is on in the given |
| * flags. |
| * |
| * @param flags the flags to check |
| * @return the value of the {@code ACC_NATIVE} flag |
| */ |
| public static boolean isNative(int flags) { |
| return (flags & ACC_NATIVE) != 0; |
| } |
| |
| /** |
| * Returns whether the flag {@code ACC_ANNOTATION} is on in the given |
| * flags. |
| * |
| * @param flags the flags to check |
| * @return the value of the {@code ACC_ANNOTATION} flag |
| */ |
| public static boolean isAnnotation(int flags) { |
| return (flags & ACC_ANNOTATION) != 0; |
| } |
| |
| /** |
| * Returns whether the flag {@code ACC_DECLARED_SYNCHRONIZED} is |
| * on in the given flags. |
| * |
| * @param flags the flags to check |
| * @return the value of the {@code ACC_DECLARED_SYNCHRONIZED} flag |
| */ |
| public static boolean isDeclaredSynchronized(int flags) { |
| return (flags & ACC_DECLARED_SYNCHRONIZED) != 0; |
| } |
| |
| /** |
| * Returns whether the flag {@code ACC_ENUM} is on in the given flags. |
| * |
| * @param flags the flags to check |
| * @return the value of the {@code ACC_ENUM} flag |
| */ |
| public static boolean isEnum(int flags) { |
| return (flags & ACC_ENUM) != 0; |
| } |
| |
| /** |
| * Helper to return a human-oriented string representing the given |
| * access flags. |
| * |
| * @param flags the defined flags |
| * @param mask mask for the "defined" bits |
| * @param what what the flags represent (one of {@code CONV_*}) |
| * @return {@code non-null;} human-oriented string |
| */ |
| private static String humanHelper(int flags, int mask, int what) { |
| StringBuffer sb = new StringBuffer(80); |
| int extra = flags & ~mask; |
| |
| flags &= mask; |
| |
| if ((flags & ACC_PUBLIC) != 0) { |
| sb.append("|public"); |
| } |
| if ((flags & ACC_PRIVATE) != 0) { |
| sb.append("|private"); |
| } |
| if ((flags & ACC_PROTECTED) != 0) { |
| sb.append("|protected"); |
| } |
| if ((flags & ACC_STATIC) != 0) { |
| sb.append("|static"); |
| } |
| if ((flags & ACC_FINAL) != 0) { |
| sb.append("|final"); |
| } |
| if ((flags & ACC_SYNCHRONIZED) != 0) { |
| if (what == CONV_CLASS) { |
| sb.append("|super"); |
| } else { |
| sb.append("|synchronized"); |
| } |
| } |
| if ((flags & ACC_VOLATILE) != 0) { |
| if (what == CONV_METHOD) { |
| sb.append("|bridge"); |
| } else { |
| sb.append("|volatile"); |
| } |
| } |
| if ((flags & ACC_TRANSIENT) != 0) { |
| if (what == CONV_METHOD) { |
| sb.append("|varargs"); |
| } else { |
| sb.append("|transient"); |
| } |
| } |
| if ((flags & ACC_NATIVE) != 0) { |
| sb.append("|native"); |
| } |
| if ((flags & ACC_INTERFACE) != 0) { |
| sb.append("|interface"); |
| } |
| if ((flags & ACC_ABSTRACT) != 0) { |
| sb.append("|abstract"); |
| } |
| if ((flags & ACC_STRICT) != 0) { |
| sb.append("|strictfp"); |
| } |
| if ((flags & ACC_SYNTHETIC) != 0) { |
| sb.append("|synthetic"); |
| } |
| if ((flags & ACC_ANNOTATION) != 0) { |
| sb.append("|annotation"); |
| } |
| if ((flags & ACC_ENUM) != 0) { |
| sb.append("|enum"); |
| } |
| if ((flags & ACC_CONSTRUCTOR) != 0) { |
| sb.append("|constructor"); |
| } |
| if ((flags & ACC_DECLARED_SYNCHRONIZED) != 0) { |
| sb.append("|declared_synchronized"); |
| } |
| |
| if ((extra != 0) || (sb.length() == 0)) { |
| sb.append('|'); |
| sb.append(Hex.u2(extra)); |
| } |
| |
| return sb.substring(1); |
| } |
| } |