Home | History | Annotate | Download | only in src2
      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 
     69   public static void main(String args[]) throws Exception {
     70     check("Inf");
     71     check("NonInf");
     72     check("A");
     73     check("A$B");
     74   }
     75 
     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 
    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 
    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