Home | History | Annotate | Download | only in sourcer
      1 /*
      2  * Copyright (C) 2009 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.mkstubs.sourcer;
     18 
     19 import org.objectweb.asm.Opcodes;
     20 
     21 /**
     22  * Source generator for the access fields of methods, fields and classes.
     23  * <p/>
     24  * Given an integer access field and a type ({@link #IS_CLASS}, {@link #IS_FIELD} or
     25  * {@link #IS_METHOD}), the {@link #write(int, int)} method can generate a string
     26  * desribing the access modifiers for a Java source.
     27  */
     28 class AccessSourcer {
     29 
     30     private final Output mOutput;
     31 
     32     public static int IS_CLASS  = 1;
     33     public static int IS_FIELD  = 2;
     34     public static int IS_METHOD = 4;
     35 
     36     private enum Flag {
     37         ACC_PUBLIC(Opcodes.ACC_PUBLIC               , IS_CLASS | IS_FIELD | IS_METHOD),
     38         ACC_PRIVATE(Opcodes.ACC_PRIVATE             , IS_CLASS | IS_FIELD | IS_METHOD),
     39         ACC_PROTECTED(Opcodes.ACC_PROTECTED         , IS_CLASS | IS_FIELD | IS_METHOD),
     40         ACC_STATIC(Opcodes.ACC_STATIC               , IS_FIELD | IS_METHOD),
     41         ACC_FINAL(Opcodes.ACC_FINAL                 , IS_CLASS | IS_FIELD | IS_METHOD),
     42         ACC_SUPER(Opcodes.ACC_SUPER                 , IS_CLASS),
     43         ACC_SYNCHRONIZED(Opcodes.ACC_SYNCHRONIZED   , IS_METHOD),
     44         ACC_VOLATILE(Opcodes.ACC_VOLATILE           , IS_FIELD),
     45         ACC_BRIDGE(Opcodes.ACC_BRIDGE               , IS_METHOD),
     46         ACC_VARARGS(Opcodes.ACC_VARARGS             , IS_METHOD),
     47         ACC_TRANSIENT(Opcodes.ACC_TRANSIENT         , IS_FIELD),
     48         ACC_NATIVE(Opcodes.ACC_NATIVE               , IS_METHOD),
     49         ACC_INTERFACE(Opcodes.ACC_INTERFACE         , IS_CLASS),
     50         ACC_ABSTRACT(Opcodes.ACC_ABSTRACT           , IS_CLASS | IS_METHOD),
     51         ACC_STRICT(Opcodes.ACC_STRICT               , IS_METHOD),
     52         ACC_SYNTHETIC(Opcodes.ACC_SYNTHETIC         , IS_CLASS | IS_FIELD | IS_METHOD),
     53         ACC_ANNOTATION(Opcodes.ACC_ANNOTATION       , IS_CLASS),
     54         ACC_ENUM(Opcodes.ACC_ENUM                   , IS_CLASS),
     55         ACC_DEPRECATED(Opcodes.ACC_DEPRECATED       , IS_CLASS | IS_FIELD | IS_METHOD)
     56         ;
     57 
     58         private final int mValue;
     59         private final int mFilter;
     60 
     61         Flag(int value, int filter) {
     62             mValue = value;
     63             mFilter = filter;
     64         }
     65 
     66         public int getValue() {
     67             return mValue;
     68         }
     69 
     70         public int getFilter() {
     71             return mFilter;
     72         }
     73 
     74         /** Transforms "ACC_PUBLIC" into "public" */
     75         @Override
     76         public String toString() {
     77             return super.toString().substring(4).toLowerCase();
     78         }
     79     }
     80 
     81 
     82     public AccessSourcer(Output output) {
     83         mOutput = output;
     84     }
     85 
     86     /**
     87      * Generates a list of access keywords, e.g. "public final".
     88      * <p/>
     89      * It is up to the caller to filter extra keywords that should not be generated,
     90      * e.g. {@link Flag#ACC_SYNTHETIC}.
     91      *
     92      * @param access The access mode, e.g. 33 or 18
     93      * @param filter One of {@link #IS_CLASS}, {@link #IS_FIELD} or {@link #IS_METHOD}, which
     94      *        indicates the validity context.
     95      */
     96     public void write(int access, int filter) {
     97 
     98         boolean need_sep = false;
     99 
    100         for (Flag f : Flag.values()) {
    101             if ((f.getFilter() & filter) != 0 && (access & f.getValue()) != 0) {
    102                 if (need_sep) {
    103                     mOutput.write(" ");
    104                 }
    105                 mOutput.write(f.toString());
    106                 need_sep = true;
    107             }
    108         }
    109 
    110     }
    111 }
    112