Home | History | Annotate | Download | only in src
      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 
     77   public static void main(String args[]) throws Exception {
     78     check("Inf");
     79     check("NonInf");
     80     check("A");
     81     check("A$B");
     82   }
     83 
     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 
    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 
    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