|
1 /* |
|
2 * Copyright (c) 1999, 2014, 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.javac.code; |
|
27 |
|
28 import java.util.Collections; |
|
29 import java.util.EnumSet; |
|
30 import java.util.Map; |
|
31 import java.util.Set; |
|
32 |
|
33 import javax.lang.model.element.Modifier; |
|
34 |
|
35 import com.sun.tools.javac.util.Assert; |
|
36 import com.sun.tools.javac.util.StringUtils; |
|
37 |
|
38 /** Access flags and other modifiers for Java classes and members. |
|
39 * |
|
40 * <p><b>This is NOT part of any supported API. |
|
41 * If you write code that depends on this, you do so at your own risk. |
|
42 * This code and its internal interfaces are subject to change or |
|
43 * deletion without notice.</b> |
|
44 */ |
|
45 public class Flags { |
|
46 |
|
47 private Flags() {} // uninstantiable |
|
48 |
|
49 public static String toString(long flags) { |
|
50 StringBuilder buf = new StringBuilder(); |
|
51 String sep = ""; |
|
52 for (Flag flag : asFlagSet(flags)) { |
|
53 buf.append(sep); |
|
54 buf.append(flag); |
|
55 sep = " "; |
|
56 } |
|
57 return buf.toString(); |
|
58 } |
|
59 |
|
60 public static EnumSet<Flag> asFlagSet(long flags) { |
|
61 EnumSet<Flag> flagSet = EnumSet.noneOf(Flag.class); |
|
62 for (Flag flag : Flag.values()) { |
|
63 if ((flags & flag.value) != 0) { |
|
64 flagSet.add(flag); |
|
65 flags &= ~flag.value; |
|
66 } |
|
67 } |
|
68 Assert.check(flags == 0, "Flags parameter contains unknown flags " + flags); |
|
69 return flagSet; |
|
70 } |
|
71 |
|
72 /* Standard Java flags. |
|
73 */ |
|
74 public static final int PUBLIC = 1; |
|
75 public static final int PRIVATE = 1<<1; |
|
76 public static final int PROTECTED = 1<<2; |
|
77 public static final int STATIC = 1<<3; |
|
78 public static final int FINAL = 1<<4; |
|
79 public static final int SYNCHRONIZED = 1<<5; |
|
80 public static final int VOLATILE = 1<<6; |
|
81 public static final int TRANSIENT = 1<<7; |
|
82 public static final int NATIVE = 1<<8; |
|
83 public static final int INTERFACE = 1<<9; |
|
84 public static final int ABSTRACT = 1<<10; |
|
85 public static final int STRICTFP = 1<<11; |
|
86 |
|
87 /* Flag that marks a symbol synthetic, added in classfile v49.0. */ |
|
88 public static final int SYNTHETIC = 1<<12; |
|
89 |
|
90 /** Flag that marks attribute interfaces, added in classfile v49.0. */ |
|
91 public static final int ANNOTATION = 1<<13; |
|
92 |
|
93 /** An enumeration type or an enumeration constant, added in |
|
94 * classfile v49.0. */ |
|
95 public static final int ENUM = 1<<14; |
|
96 |
|
97 /** Added in SE8, represents constructs implicitly declared in source. */ |
|
98 public static final int MANDATED = 1<<15; |
|
99 |
|
100 public static final int StandardFlags = 0x0fff; |
|
101 |
|
102 // Because the following access flags are overloaded with other |
|
103 // bit positions, we translate them when reading and writing class |
|
104 // files into unique bits positions: ACC_SYNTHETIC <-> SYNTHETIC, |
|
105 // for example. |
|
106 public static final int ACC_SUPER = 0x0020; |
|
107 public static final int ACC_BRIDGE = 0x0040; |
|
108 public static final int ACC_VARARGS = 0x0080; |
|
109 |
|
110 /***************************************** |
|
111 * Internal compiler flags (no bits in the lower 16). |
|
112 *****************************************/ |
|
113 |
|
114 /** Flag is set if symbol is deprecated. |
|
115 */ |
|
116 public static final int DEPRECATED = 1<<17; |
|
117 |
|
118 /** Flag is set for a variable symbol if the variable's definition |
|
119 * has an initializer part. |
|
120 */ |
|
121 public static final int HASINIT = 1<<18; |
|
122 |
|
123 /** Flag is set for compiler-generated anonymous method symbols |
|
124 * that `own' an initializer block. |
|
125 */ |
|
126 public static final int BLOCK = 1<<20; |
|
127 |
|
128 /** Flag is set for compiler-generated abstract methods that implement |
|
129 * an interface method (Miranda methods). |
|
130 */ |
|
131 public static final int IPROXY = 1<<21; |
|
132 |
|
133 /** Flag is set for nested classes that do not access instance members |
|
134 * or `this' of an outer class and therefore don't need to be passed |
|
135 * a this$n reference. This value is currently set only for anonymous |
|
136 * classes in superclass constructor calls and only for pre 1.4 targets. |
|
137 * todo: use this value for optimizing away this$n parameters in |
|
138 * other cases. |
|
139 */ |
|
140 public static final int NOOUTERTHIS = 1<<22; |
|
141 |
|
142 /** Flag is set for package symbols if a package has a member or |
|
143 * directory and therefore exists. |
|
144 */ |
|
145 public static final int EXISTS = 1<<23; |
|
146 |
|
147 /** Flag is set for compiler-generated compound classes |
|
148 * representing multiple variable bounds |
|
149 */ |
|
150 public static final int COMPOUND = 1<<24; |
|
151 |
|
152 /** Flag is set for class symbols if a class file was found for this class. |
|
153 */ |
|
154 public static final int CLASS_SEEN = 1<<25; |
|
155 |
|
156 /** Flag is set for class symbols if a source file was found for this |
|
157 * class. |
|
158 */ |
|
159 public static final int SOURCE_SEEN = 1<<26; |
|
160 |
|
161 /* State flags (are reset during compilation). |
|
162 */ |
|
163 |
|
164 /** Flag for class symbols is set and later re-set as a lock in |
|
165 * Enter to detect cycles in the superclass/superinterface |
|
166 * relations. Similarly for constructor call cycle detection in |
|
167 * Attr. |
|
168 */ |
|
169 public static final int LOCKED = 1<<27; |
|
170 |
|
171 /** Flag for class symbols is set and later re-set to indicate that a class |
|
172 * has been entered but has not yet been attributed. |
|
173 */ |
|
174 public static final int UNATTRIBUTED = 1<<28; |
|
175 |
|
176 /** Flag for synthesized default constructors of anonymous classes. |
|
177 */ |
|
178 public static final int ANONCONSTR = 1<<29; |
|
179 |
|
180 /** Flag for class symbols to indicate it has been checked and found |
|
181 * acyclic. |
|
182 */ |
|
183 public static final int ACYCLIC = 1<<30; |
|
184 |
|
185 /** Flag that marks bridge methods. |
|
186 */ |
|
187 public static final long BRIDGE = 1L<<31; |
|
188 |
|
189 /** Flag that marks formal parameters. |
|
190 */ |
|
191 public static final long PARAMETER = 1L<<33; |
|
192 |
|
193 /** Flag that marks varargs methods. |
|
194 */ |
|
195 public static final long VARARGS = 1L<<34; |
|
196 |
|
197 /** Flag for annotation type symbols to indicate it has been |
|
198 * checked and found acyclic. |
|
199 */ |
|
200 public static final long ACYCLIC_ANN = 1L<<35; |
|
201 |
|
202 /** Flag that marks a generated default constructor. |
|
203 */ |
|
204 public static final long GENERATEDCONSTR = 1L<<36; |
|
205 |
|
206 /** Flag that marks a hypothetical method that need not really be |
|
207 * generated in the binary, but is present in the symbol table to |
|
208 * simplify checking for erasure clashes - also used for 292 poly sig methods. |
|
209 */ |
|
210 public static final long HYPOTHETICAL = 1L<<37; |
|
211 |
|
212 /** |
|
213 * Flag that marks an internal proprietary class. |
|
214 */ |
|
215 public static final long PROPRIETARY = 1L<<38; |
|
216 |
|
217 /** |
|
218 * Flag that marks a multi-catch parameter. |
|
219 */ |
|
220 public static final long UNION = 1L<<39; |
|
221 |
|
222 /** |
|
223 * Flag that marks a special kind of bridge method (the ones that |
|
224 * come from restricted supertype bounds). |
|
225 */ |
|
226 public static final long OVERRIDE_BRIDGE = 1L<<40; |
|
227 |
|
228 /** |
|
229 * Flag that marks an 'effectively final' local variable. |
|
230 */ |
|
231 public static final long EFFECTIVELY_FINAL = 1L<<41; |
|
232 |
|
233 /** |
|
234 * Flag that marks non-override equivalent methods with the same signature. |
|
235 */ |
|
236 public static final long CLASH = 1L<<42; |
|
237 |
|
238 /** |
|
239 * Flag that marks either a default method or an interface containing default methods. |
|
240 */ |
|
241 public static final long DEFAULT = 1L<<43; |
|
242 |
|
243 /** |
|
244 * Flag that marks class as auxiliary, ie a non-public class following |
|
245 * the public class in a source file, that could block implicit compilation. |
|
246 */ |
|
247 public static final long AUXILIARY = 1L<<44; |
|
248 |
|
249 /** |
|
250 * Flag that marks that a symbol is not available in the current profile |
|
251 */ |
|
252 public static final long NOT_IN_PROFILE = 1L<<45; |
|
253 |
|
254 /** |
|
255 * Flag that indicates that an override error has been detected by Check. |
|
256 */ |
|
257 public static final long BAD_OVERRIDE = 1L<<45; |
|
258 |
|
259 /** |
|
260 * Flag that indicates a signature polymorphic method (292). |
|
261 */ |
|
262 public static final long SIGNATURE_POLYMORPHIC = 1L<<46; |
|
263 |
|
264 /** |
|
265 * Flag that indicates that an inference variable is used in a 'throws' clause. |
|
266 */ |
|
267 public static final long THROWS = 1L<<47; |
|
268 |
|
269 /** |
|
270 * Flag that marks potentially ambiguous overloads |
|
271 */ |
|
272 public static final long POTENTIALLY_AMBIGUOUS = 1L<<48; |
|
273 |
|
274 /** |
|
275 * Flag that marks a synthetic method body for a lambda expression |
|
276 */ |
|
277 public static final long LAMBDA_METHOD = 1L<<49; |
|
278 |
|
279 /** |
|
280 * Flag to control recursion in TransTypes |
|
281 */ |
|
282 public static final long TYPE_TRANSLATED = 1L<<50; |
|
283 |
|
284 /** Modifier masks. |
|
285 */ |
|
286 public static final int |
|
287 AccessFlags = PUBLIC | PROTECTED | PRIVATE, |
|
288 LocalClassFlags = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC, |
|
289 MemberClassFlags = LocalClassFlags | INTERFACE | AccessFlags, |
|
290 ClassFlags = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION, |
|
291 InterfaceVarFlags = FINAL | STATIC | PUBLIC, |
|
292 VarFlags = AccessFlags | FINAL | STATIC | |
|
293 VOLATILE | TRANSIENT | ENUM, |
|
294 ConstructorFlags = AccessFlags, |
|
295 InterfaceMethodFlags = ABSTRACT | PUBLIC, |
|
296 MethodFlags = AccessFlags | ABSTRACT | STATIC | NATIVE | |
|
297 SYNCHRONIZED | FINAL | STRICTFP; |
|
298 public static final long |
|
299 ExtendedStandardFlags = (long)StandardFlags | DEFAULT, |
|
300 ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT, |
|
301 InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT, |
|
302 AnnotationTypeElementMask = ABSTRACT | PUBLIC, |
|
303 LocalVarFlags = FINAL | PARAMETER, |
|
304 ReceiverParamFlags = PARAMETER; |
|
305 |
|
306 |
|
307 public static Set<Modifier> asModifierSet(long flags) { |
|
308 Set<Modifier> modifiers = modifierSets.get(flags); |
|
309 if (modifiers == null) { |
|
310 modifiers = java.util.EnumSet.noneOf(Modifier.class); |
|
311 if (0 != (flags & PUBLIC)) modifiers.add(Modifier.PUBLIC); |
|
312 if (0 != (flags & PROTECTED)) modifiers.add(Modifier.PROTECTED); |
|
313 if (0 != (flags & PRIVATE)) modifiers.add(Modifier.PRIVATE); |
|
314 if (0 != (flags & ABSTRACT)) modifiers.add(Modifier.ABSTRACT); |
|
315 if (0 != (flags & STATIC)) modifiers.add(Modifier.STATIC); |
|
316 if (0 != (flags & FINAL)) modifiers.add(Modifier.FINAL); |
|
317 if (0 != (flags & TRANSIENT)) modifiers.add(Modifier.TRANSIENT); |
|
318 if (0 != (flags & VOLATILE)) modifiers.add(Modifier.VOLATILE); |
|
319 if (0 != (flags & SYNCHRONIZED)) |
|
320 modifiers.add(Modifier.SYNCHRONIZED); |
|
321 if (0 != (flags & NATIVE)) modifiers.add(Modifier.NATIVE); |
|
322 if (0 != (flags & STRICTFP)) modifiers.add(Modifier.STRICTFP); |
|
323 if (0 != (flags & DEFAULT)) modifiers.add(Modifier.DEFAULT); |
|
324 modifiers = Collections.unmodifiableSet(modifiers); |
|
325 modifierSets.put(flags, modifiers); |
|
326 } |
|
327 return modifiers; |
|
328 } |
|
329 |
|
330 // Cache of modifier sets. |
|
331 private static final Map<Long, Set<Modifier>> modifierSets = |
|
332 new java.util.concurrent.ConcurrentHashMap<Long, Set<Modifier>>(64); |
|
333 |
|
334 public static boolean isStatic(Symbol symbol) { |
|
335 return (symbol.flags() & STATIC) != 0; |
|
336 } |
|
337 |
|
338 public static boolean isEnum(Symbol symbol) { |
|
339 return (symbol.flags() & ENUM) != 0; |
|
340 } |
|
341 |
|
342 public static boolean isConstant(Symbol.VarSymbol symbol) { |
|
343 return symbol.getConstValue() != null; |
|
344 } |
|
345 |
|
346 |
|
347 public enum Flag { |
|
348 PUBLIC(Flags.PUBLIC), |
|
349 PRIVATE(Flags.PRIVATE), |
|
350 PROTECTED(Flags.PROTECTED), |
|
351 STATIC(Flags.STATIC), |
|
352 FINAL(Flags.FINAL), |
|
353 SYNCHRONIZED(Flags.SYNCHRONIZED), |
|
354 VOLATILE(Flags.VOLATILE), |
|
355 TRANSIENT(Flags.TRANSIENT), |
|
356 NATIVE(Flags.NATIVE), |
|
357 INTERFACE(Flags.INTERFACE), |
|
358 ABSTRACT(Flags.ABSTRACT), |
|
359 DEFAULT(Flags.DEFAULT), |
|
360 STRICTFP(Flags.STRICTFP), |
|
361 BRIDGE(Flags.BRIDGE), |
|
362 SYNTHETIC(Flags.SYNTHETIC), |
|
363 ANNOTATION(Flags.ANNOTATION), |
|
364 DEPRECATED(Flags.DEPRECATED), |
|
365 HASINIT(Flags.HASINIT), |
|
366 BLOCK(Flags.BLOCK), |
|
367 ENUM(Flags.ENUM), |
|
368 MANDATED(Flags.MANDATED), |
|
369 IPROXY(Flags.IPROXY), |
|
370 NOOUTERTHIS(Flags.NOOUTERTHIS), |
|
371 EXISTS(Flags.EXISTS), |
|
372 COMPOUND(Flags.COMPOUND), |
|
373 CLASS_SEEN(Flags.CLASS_SEEN), |
|
374 SOURCE_SEEN(Flags.SOURCE_SEEN), |
|
375 LOCKED(Flags.LOCKED), |
|
376 UNATTRIBUTED(Flags.UNATTRIBUTED), |
|
377 ANONCONSTR(Flags.ANONCONSTR), |
|
378 ACYCLIC(Flags.ACYCLIC), |
|
379 PARAMETER(Flags.PARAMETER), |
|
380 VARARGS(Flags.VARARGS), |
|
381 ACYCLIC_ANN(Flags.ACYCLIC_ANN), |
|
382 GENERATEDCONSTR(Flags.GENERATEDCONSTR), |
|
383 HYPOTHETICAL(Flags.HYPOTHETICAL), |
|
384 PROPRIETARY(Flags.PROPRIETARY), |
|
385 UNION(Flags.UNION), |
|
386 OVERRIDE_BRIDGE(Flags.OVERRIDE_BRIDGE), |
|
387 EFFECTIVELY_FINAL(Flags.EFFECTIVELY_FINAL), |
|
388 CLASH(Flags.CLASH), |
|
389 AUXILIARY(Flags.AUXILIARY), |
|
390 NOT_IN_PROFILE(Flags.NOT_IN_PROFILE), |
|
391 BAD_OVERRIDE(Flags.BAD_OVERRIDE), |
|
392 SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC), |
|
393 THROWS(Flags.THROWS), |
|
394 LAMBDA_METHOD(Flags.LAMBDA_METHOD), |
|
395 TYPE_TRANSLATED(Flags.TYPE_TRANSLATED); |
|
396 |
|
397 Flag(long flag) { |
|
398 this.value = flag; |
|
399 this.lowercaseName = StringUtils.toLowerCase(name()); |
|
400 } |
|
401 |
|
402 @Override |
|
403 public String toString() { |
|
404 return lowercaseName; |
|
405 } |
|
406 |
|
407 final long value; |
|
408 final String lowercaseName; |
|
409 } |
|
410 |
|
411 } |