|
1 /* |
|
2 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package com.sun.tools.classfile; |
|
27 |
|
28 import java.io.IOException; |
|
29 import java.util.LinkedHashSet; |
|
30 import java.util.Set; |
|
31 |
|
32 /** |
|
33 * See JVMS, sections 4.2, 4.6, 4.7. |
|
34 * |
|
35 * <p><b>This is NOT part of any supported API. |
|
36 * If you write code that depends on this, you do so at your own risk. |
|
37 * This code and its internal interfaces are subject to change or |
|
38 * deletion without notice.</b> |
|
39 */ |
|
40 public class AccessFlags { |
|
41 public static final int ACC_PUBLIC = 0x0001; // class, inner, field, method |
|
42 public static final int ACC_PRIVATE = 0x0002; // inner, field, method |
|
43 public static final int ACC_PROTECTED = 0x0004; // inner, field, method |
|
44 public static final int ACC_STATIC = 0x0008; // inner, field, method |
|
45 public static final int ACC_FINAL = 0x0010; // class, inner, field, method |
|
46 public static final int ACC_SUPER = 0x0020; // class |
|
47 public static final int ACC_SYNCHRONIZED = 0x0020; // method |
|
48 public static final int ACC_VOLATILE = 0x0040; // field |
|
49 public static final int ACC_BRIDGE = 0x0040; // method |
|
50 public static final int ACC_TRANSIENT = 0x0080; // field |
|
51 public static final int ACC_VARARGS = 0x0080; // method |
|
52 public static final int ACC_NATIVE = 0x0100; // method |
|
53 public static final int ACC_INTERFACE = 0x0200; // class, inner |
|
54 public static final int ACC_ABSTRACT = 0x0400; // class, inner, method |
|
55 public static final int ACC_STRICT = 0x0800; // method |
|
56 public static final int ACC_SYNTHETIC = 0x1000; // class, inner, field, method |
|
57 public static final int ACC_ANNOTATION = 0x2000; // class, inner |
|
58 public static final int ACC_ENUM = 0x4000; // class, inner, field |
|
59 public static final int ACC_MANDATED = 0x8000; // class, inner, field, method |
|
60 |
|
61 public static enum Kind { Class, InnerClass, Field, Method} |
|
62 |
|
63 AccessFlags(ClassReader cr) throws IOException { |
|
64 this(cr.readUnsignedShort()); |
|
65 } |
|
66 |
|
67 public AccessFlags(int flags) { |
|
68 this.flags = flags; |
|
69 } |
|
70 |
|
71 public AccessFlags ignore(int mask) { |
|
72 return new AccessFlags(flags & ~mask); |
|
73 } |
|
74 |
|
75 public boolean is(int mask) { |
|
76 return (flags & mask) != 0; |
|
77 } |
|
78 |
|
79 public int byteLength() { |
|
80 return 2; |
|
81 } |
|
82 |
|
83 private static final int[] classModifiers = { |
|
84 ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT |
|
85 }; |
|
86 |
|
87 private static final int[] classFlags = { |
|
88 ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_INTERFACE, ACC_ABSTRACT, |
|
89 ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM |
|
90 }; |
|
91 |
|
92 public Set<String> getClassModifiers() { |
|
93 int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags); |
|
94 return getModifiers(f, classModifiers, Kind.Class); |
|
95 } |
|
96 |
|
97 public Set<String> getClassFlags() { |
|
98 return getFlags(classFlags, Kind.Class); |
|
99 } |
|
100 |
|
101 private static final int[] innerClassModifiers = { |
|
102 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, |
|
103 ACC_ABSTRACT |
|
104 }; |
|
105 |
|
106 private static final int[] innerClassFlags = { |
|
107 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SUPER, |
|
108 ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM |
|
109 }; |
|
110 |
|
111 public Set<String> getInnerClassModifiers() { |
|
112 int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags); |
|
113 return getModifiers(f, innerClassModifiers, Kind.InnerClass); |
|
114 } |
|
115 |
|
116 public Set<String> getInnerClassFlags() { |
|
117 return getFlags(innerClassFlags, Kind.InnerClass); |
|
118 } |
|
119 |
|
120 private static final int[] fieldModifiers = { |
|
121 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, |
|
122 ACC_VOLATILE, ACC_TRANSIENT |
|
123 }; |
|
124 |
|
125 private static final int[] fieldFlags = { |
|
126 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, |
|
127 ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM |
|
128 }; |
|
129 |
|
130 public Set<String> getFieldModifiers() { |
|
131 return getModifiers(fieldModifiers, Kind.Field); |
|
132 } |
|
133 |
|
134 public Set<String> getFieldFlags() { |
|
135 return getFlags(fieldFlags, Kind.Field); |
|
136 } |
|
137 |
|
138 private static final int[] methodModifiers = { |
|
139 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, |
|
140 ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT |
|
141 }; |
|
142 |
|
143 private static final int[] methodFlags = { |
|
144 ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, |
|
145 ACC_SYNCHRONIZED, ACC_BRIDGE, ACC_VARARGS, ACC_NATIVE, ACC_ABSTRACT, |
|
146 ACC_STRICT, ACC_SYNTHETIC |
|
147 }; |
|
148 |
|
149 public Set<String> getMethodModifiers() { |
|
150 return getModifiers(methodModifiers, Kind.Method); |
|
151 } |
|
152 |
|
153 public Set<String> getMethodFlags() { |
|
154 return getFlags(methodFlags, Kind.Method); |
|
155 } |
|
156 |
|
157 private Set<String> getModifiers(int[] modifierFlags, Kind t) { |
|
158 return getModifiers(flags, modifierFlags, t); |
|
159 } |
|
160 |
|
161 private static Set<String> getModifiers(int flags, int[] modifierFlags, Kind t) { |
|
162 Set<String> s = new LinkedHashSet<>(); |
|
163 for (int m: modifierFlags) { |
|
164 if ((flags & m) != 0) |
|
165 s.add(flagToModifier(m, t)); |
|
166 } |
|
167 return s; |
|
168 } |
|
169 |
|
170 private Set<String> getFlags(int[] expectedFlags, Kind t) { |
|
171 Set<String> s = new LinkedHashSet<>(); |
|
172 int f = flags; |
|
173 for (int e: expectedFlags) { |
|
174 if ((f & e) != 0) { |
|
175 s.add(flagToName(e, t)); |
|
176 f = f & ~e; |
|
177 } |
|
178 } |
|
179 while (f != 0) { |
|
180 int bit = Integer.highestOneBit(f); |
|
181 s.add("0x" + Integer.toHexString(bit)); |
|
182 f = f & ~bit; |
|
183 } |
|
184 return s; |
|
185 } |
|
186 |
|
187 private static String flagToModifier(int flag, Kind t) { |
|
188 switch (flag) { |
|
189 case ACC_PUBLIC: |
|
190 return "public"; |
|
191 case ACC_PRIVATE: |
|
192 return "private"; |
|
193 case ACC_PROTECTED: |
|
194 return "protected"; |
|
195 case ACC_STATIC: |
|
196 return "static"; |
|
197 case ACC_FINAL: |
|
198 return "final"; |
|
199 case ACC_SYNCHRONIZED: |
|
200 return "synchronized"; |
|
201 case 0x80: |
|
202 return (t == Kind.Field ? "transient" : null); |
|
203 case ACC_VOLATILE: |
|
204 return "volatile"; |
|
205 case ACC_NATIVE: |
|
206 return "native"; |
|
207 case ACC_ABSTRACT: |
|
208 return "abstract"; |
|
209 case ACC_STRICT: |
|
210 return "strictfp"; |
|
211 case ACC_MANDATED: |
|
212 return "mandated"; |
|
213 default: |
|
214 return null; |
|
215 } |
|
216 } |
|
217 |
|
218 private static String flagToName(int flag, Kind t) { |
|
219 switch (flag) { |
|
220 case ACC_PUBLIC: |
|
221 return "ACC_PUBLIC"; |
|
222 case ACC_PRIVATE: |
|
223 return "ACC_PRIVATE"; |
|
224 case ACC_PROTECTED: |
|
225 return "ACC_PROTECTED"; |
|
226 case ACC_STATIC: |
|
227 return "ACC_STATIC"; |
|
228 case ACC_FINAL: |
|
229 return "ACC_FINAL"; |
|
230 case 0x20: |
|
231 return (t == Kind.Class ? "ACC_SUPER" : "ACC_SYNCHRONIZED"); |
|
232 case 0x40: |
|
233 return (t == Kind.Field ? "ACC_VOLATILE" : "ACC_BRIDGE"); |
|
234 case 0x80: |
|
235 return (t == Kind.Field ? "ACC_TRANSIENT" : "ACC_VARARGS"); |
|
236 case ACC_NATIVE: |
|
237 return "ACC_NATIVE"; |
|
238 case ACC_INTERFACE: |
|
239 return "ACC_INTERFACE"; |
|
240 case ACC_ABSTRACT: |
|
241 return "ACC_ABSTRACT"; |
|
242 case ACC_STRICT: |
|
243 return "ACC_STRICT"; |
|
244 case ACC_SYNTHETIC: |
|
245 return "ACC_SYNTHETIC"; |
|
246 case ACC_ANNOTATION: |
|
247 return "ACC_ANNOTATION"; |
|
248 case ACC_ENUM: |
|
249 return "ACC_ENUM"; |
|
250 case ACC_MANDATED: |
|
251 return "ACC_MANDATED"; |
|
252 default: |
|
253 return null; |
|
254 } |
|
255 } |
|
256 |
|
257 public final int flags; |
|
258 } |