1 /* 2 * Copyright (C) 2014 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 // These classes are to check the additional flags for inner classes. 18 class A { 19 private static class B { 20 } 21 protected static interface C { 22 } 23 } 24 25 public class Main { 26 public final static int INTERFACE_DEFINED_BITS = 27 0x0001 | // public, may be set. 28 0x0002 | // private, may be flagged by inner class. 29 0x0004 | // protected, may be flagged by inner class. 30 0x0008 | // static, may be flagged by inner class. 31 0x0010 | // final, must not be set. 32 0x0020 | // super, must not be set. 33 0x0200 | // interface, must be set. 34 0x0400 | // abstract, must be set. 35 0x1000 | // synthetic, may be set. 36 0x2000 | // annotation, may be set (annotation implies interface) 37 0x4000 ; // enum, must not be set. 38 39 public final static int CLASS_DEFINED_BITS = 40 0x0001 | // public, may be set. 41 0x0002 | // private, may be flagged by inner class. 42 0x0004 | // protected, may be flagged by inner class. 43 0x0008 | // static, may be flagged by inner class. 44 0x0010 | // final, may be set. 45 0x0020 | // super, may be set. 46 0x0200 | // interface, must not be set. 47 0x0400 | // abstract, may be set. 48 0x1000 | // synthetic, may be set. 49 0x2000 | // annotation, must not be set. 50 0x4000 ; // enum, may be set. 51 52 public final static int FIELD_DEFINED_BITS = 53 0x0001 | // public 54 0x0002 | // private 55 0x0004 | // protected 56 0x0008 | // static 57 0x0010 | // final 58 0x0040 | // volatile 59 0x0080 | // transient 60 0x1000 | // synthetic 61 0x4000 ; // enum 62 63 public final static int METHOD_DEFINED_BITS = 64 0x0001 | // public 65 0x0002 | // private 66 0x0004 | // protected 67 0x0008 | // static 68 0x0010 | // final 69 0x0020 | // synchronized 70 0x0040 | // bridge 71 0x0080 | // varargs 72 0x0100 | // native 73 0x0400 | // abstract 74 0x0800 | // strictfp 75 0x1000 ; // synthetic 76 main(String args[])77 public static void main(String args[]) throws Exception { 78 check("Inf"); 79 check("NonInf"); 80 check("A"); 81 check("A$B"); 82 } 83 check(String className)84 private static void check(String className) throws Exception { 85 Class<?> clazz = Class.forName(className); 86 if (className.equals("Inf")) { 87 if (!clazz.isInterface()) { 88 throw new RuntimeException("Expected an interface."); 89 } 90 int undefinedBits = 0xFFFF ^ INTERFACE_DEFINED_BITS; 91 if ((clazz.getModifiers() & undefinedBits) != 0) { 92 System.out.println("Clazz.getModifiers(): " + Integer.toBinaryString(clazz.getModifiers())); 93 System.out.println("INTERFACE_DEF_BITS: " + Integer.toBinaryString(INTERFACE_DEFINED_BITS)); 94 throw new RuntimeException("Undefined bits for an interface: " + className); 95 } 96 } else { 97 if (clazz.isInterface()) { 98 throw new RuntimeException("Expected a class."); 99 } 100 int undefinedBits = 0xFFFF ^ CLASS_DEFINED_BITS; 101 if ((clazz.getModifiers() & undefinedBits) != 0) { 102 System.out.println("Clazz.getModifiers(): " + Integer.toBinaryString(clazz.getModifiers())); 103 System.out.println("CLASS_DEF_BITS: " + Integer.toBinaryString(CLASS_DEFINED_BITS)); 104 throw new RuntimeException("Undefined bits for a class: " + className); 105 } 106 } 107 108 // Check fields. 109 for (java.lang.reflect.Field f : clazz.getDeclaredFields()) { 110 String name = f.getName(); 111 int undefinedBits = 0xFFFF ^ FIELD_DEFINED_BITS; 112 if ((f.getModifiers() & undefinedBits) != 0) { 113 System.out.println("f.getModifiers(): " + Integer.toBinaryString(f.getModifiers())); 114 System.out.println("FIELD_DEF_BITS: " + Integer.toBinaryString(FIELD_DEFINED_BITS)); 115 throw new RuntimeException("Unexpected field bits: " + name); 116 } 117 if (name.equals("I")) { 118 // Interface field, just check generically. 119 } else { 120 // Check the name, see that the corresponding bit is set. 121 int bitmask = getFieldMask(name); 122 if ((bitmask & f.getModifiers()) == 0) { 123 throw new RuntimeException("Expected field bit not set."); 124 } 125 } 126 } 127 128 // Check methods. 129 for (java.lang.reflect.Method m : clazz.getDeclaredMethods()) { 130 String name = m.getName(); 131 int undefinedBits = 0xFFFF ^ METHOD_DEFINED_BITS; 132 if ((m.getModifiers() & undefinedBits) != 0) { 133 System.out.println("m.getModifiers(): " + Integer.toBinaryString(m.getModifiers())); 134 System.out.println("METHOD_DEF_BITS: " + Integer.toBinaryString(METHOD_DEFINED_BITS)); 135 throw new RuntimeException("Unexpected method bits: " + name); 136 } 137 // Check the name, see that the corresponding bit is set. 138 int bitmask = getMethodMask(name); 139 if ((bitmask & m.getModifiers()) == 0) { 140 throw new RuntimeException("Expected method bit not set."); 141 } 142 } 143 } 144 getFieldMask(String name)145 private static int getFieldMask(String name) { 146 int index = name.indexOf("Field"); 147 if (index > 0) { 148 String shortS = name.substring(0, index); 149 if (shortS.equals("public")) { 150 return 0x0001; 151 } 152 if (shortS.equals("private")) { 153 return 0x0002; 154 } 155 if (shortS.equals("protected")) { 156 return 0x0004; 157 } 158 if (shortS.equals("static")) { 159 return 0x0008; 160 } 161 if (shortS.equals("transient")) { 162 return 0x0080; 163 } 164 if (shortS.equals("volatile")) { 165 return 0x0040; 166 } 167 if (shortS.equals("final")) { 168 return 0x0010; 169 } 170 } 171 throw new RuntimeException("Unexpected field name " + name); 172 } 173 getMethodMask(String name)174 private static int getMethodMask(String name) { 175 int index = name.indexOf("Method"); 176 if (index > 0) { 177 String shortS = name.substring(0, index); 178 if (shortS.equals("public")) { 179 return 0x0001; 180 } 181 if (shortS.equals("private")) { 182 return 0x0002; 183 } 184 if (shortS.equals("protected")) { 185 return 0x0004; 186 } 187 if (shortS.equals("static")) { 188 return 0x0008; 189 } 190 if (shortS.equals("synchronized")) { 191 return 0x0020; 192 } 193 if (shortS.equals("varargs")) { 194 return 0x0080; 195 } 196 if (shortS.equals("final")) { 197 return 0x0010; 198 } 199 if (shortS.equals("native")) { 200 return 0x0100; 201 } 202 if (shortS.equals("abstract")) { 203 return 0x0400; 204 } 205 if (shortS.equals("strictfp")) { 206 return 0x0800; 207 } 208 } 209 throw new RuntimeException("Unexpected method name " + name); 210 } 211 } 212