Home | History | Annotate | Download | only in code
      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      */
    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_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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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