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 Flag(int value, int filter)61 Flag(int value, int filter) { 62 mValue = value; 63 mFilter = filter; 64 } 65 getValue()66 public int getValue() { 67 return mValue; 68 } 69 getFilter()70 public int getFilter() { 71 return mFilter; 72 } 73 74 /** Transforms "ACC_PUBLIC" into "public" */ 75 @Override toString()76 public String toString() { 77 return super.toString().substring(4).toLowerCase(); 78 } 79 } 80 81 AccessSourcer(Output output)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 */ write(int access, int filter)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