blob: 62e65a8fbecd8fe5a89dcc6855901f6bd81d60ca [file] [log] [blame]
Andreas Gampe7fc8f902014-08-25 15:05:04 -07001/*
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
Andreas Gampe7fc8f902014-08-25 15:05:04 -070017public 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}