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