blob: e21b789cc7dc2b8f33b7781ca7cde34d3760e44e [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
17// These classes are to check the additional flags for inner classes.
18class A {
19 private static class B {
20 }
21 protected static interface C {
22 }
23}
24
25public 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}