1 /* 2 * Copyright (c) 1999, 2023, 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 import java.util.concurrent.ConcurrentHashMap; 33 import java.util.stream.Collectors; 34 35 import javax.lang.model.element.Modifier; 36 37 import com.sun.tools.javac.util.Assert; 38 import com.sun.tools.javac.util.StringUtils; 39 40 /** Access flags and other modifiers for Java classes and members. 41 * 42 * <p><b>This is NOT part of any supported API. 43 * If you write code that depends on this, you do so at your own risk. 44 * This code and its internal interfaces are subject to change or 45 * deletion without notice.</b> 46 */ 47 public class Flags { 48 49 private Flags() {} // uninstantiable 50 51 public static String toString(long flags) { 52 StringBuilder buf = new StringBuilder(); 53 String sep = ""; 54 for (Flag flag : asFlagSet(flags)) { 55 buf.append(sep); 56 buf.append(flag); 57 sep = " "; 58 } 59 return buf.toString(); 60 } 61 62 public static EnumSet<Flag> asFlagSet(long flags) { 63 EnumSet<Flag> flagSet = EnumSet.noneOf(Flag.class); 64 for (Flag flag : Flag.values()) { 65 if ((flags & flag.value) != 0) { 66 flagSet.add(flag); 67 flags &= ~flag.value; 68 } 69 } 70 Assert.check(flags == 0); 71 return flagSet; 72 } 73 74 /* Standard Java flags. 75 */ 76 public static final int PUBLIC = 1; 77 public static final int PRIVATE = 1<<1; 78 public static final int PROTECTED = 1<<2; 79 public static final int STATIC = 1<<3; 80 public static final int FINAL = 1<<4; 81 public static final int SYNCHRONIZED = 1<<5; 82 public static final int VOLATILE = 1<<6; 83 public static final int TRANSIENT = 1<<7; 84 public static final int NATIVE = 1<<8; 85 public static final int INTERFACE = 1<<9; 86 public static final int ABSTRACT = 1<<10; 87 public static final int STRICTFP = 1<<11; 88 89 /* Flag that marks a symbol synthetic, added in classfile v49.0. */ 90 public static final int SYNTHETIC = 1<<12; 91 92 /** Flag that marks attribute interfaces, added in classfile v49.0. */ 93 public static final int ANNOTATION = 1<<13; 94 95 /** An enumeration type or an enumeration constant, added in 96 * classfile v49.0. */ 97 public static final int ENUM = 1<<14; 98 99 /** Added in SE8, represents constructs implicitly declared in source. */ 100 public static final int MANDATED = 1<<15; 101 102 public static final int StandardFlags = 0x0fff; 103 104 // Because the following access flags are overloaded with other 105 // bit positions, we translate them when reading and writing class 106 // files into unique bits positions: ACC_SYNTHETIC <-> SYNTHETIC, 107 // for example. 108 public static final int ACC_SUPER = 0x0020; 109 public static final int ACC_BRIDGE = 0x0040; 110 public static final int ACC_VARARGS = 0x0080; 111 public static final int ACC_MODULE = 0x8000; 112 113 /* *************************************** 114 * Internal compiler flags (no bits in the lower 16). 115 *****************************************/ 116 117 /** Flag is set if symbol is deprecated. See also DEPRECATED_REMOVAL. 118 */ 119 public static final int DEPRECATED = 1<<17; 120 121 /** Flag is set for a variable symbol if the variable's definition 122 * has an initializer part. 123 */ 124 public static final int HASINIT = 1<<18; 125 126 /** Class is an implicitly declared top level class. 127 */ 128 public static final int IMPLICIT_CLASS = 1<<19; 129 130 /** Flag is set for compiler-generated anonymous method symbols 131 * that `own' an initializer block. 132 */ 133 public static final int BLOCK = 1<<20; 134 135 /** Flag is set for ClassSymbols that are being compiled from source. 136 */ 137 public static final int FROM_SOURCE = 1<<21; //ClassSymbols 138 139 /** Flag is set for nested classes that do not access instance members 140 * or `this' of an outer class and therefore don't need to be passed 141 * a this$n reference. This value is currently set only for anonymous 142 * classes in superclass constructor calls. 143 * todo: use this value for optimizing away this$n parameters in 144 * other cases. 145 */ 146 public static final int NOOUTERTHIS = 1<<22; 147 148 /** Flag is set for package symbols if a package has a member or 149 * directory and therefore exists. 150 */ 151 public static final int EXISTS = 1<<23; 152 153 /** Flag is set for compiler-generated compound classes 154 * representing multiple variable bounds 155 */ 156 public static final int COMPOUND = 1<<24; 157 158 /** Flag is set for class symbols if a class file was found for this class. 159 */ 160 public static final int CLASS_SEEN = 1<<25; 161 162 /** Flag is set for class symbols if a source file was found for this 163 * class. 164 */ 165 public static final int SOURCE_SEEN = 1<<26; 166 167 /* State flags (are reset during compilation). 168 */ 169 170 /** Flag for class symbols is set and later re-set as a lock in 171 * Enter to detect cycles in the superclass/superinterface 172 * relations. Similarly for constructor call cycle detection in 173 * Attr. 174 */ 175 public static final int LOCKED = 1<<27; 176 177 /** Flag for class symbols is set and later re-set to indicate that a class 178 * has been entered but has not yet been attributed. 179 */ 180 public static final int UNATTRIBUTED = 1<<28; 181 182 /** Flag for synthesized default constructors of anonymous classes. 183 */ 184 public static final int ANONCONSTR = 1<<29; //non-class members 185 186 /** 187 * Flag to indicate the superclasses of this ClassSymbol has been attributed. 188 */ 189 public static final int SUPER_OWNER_ATTRIBUTED = 1<<29; //ClassSymbols 190 191 /** Flag for class symbols to indicate it has been checked and found 192 * acyclic. 193 */ 194 public static final int ACYCLIC = 1<<30; 195 196 /** Flag that marks bridge methods. 197 */ 198 public static final long BRIDGE = 1L<<31; 199 200 /** Flag that marks formal parameters. 201 */ 202 public static final long PARAMETER = 1L<<33; 203 204 /** Flag that marks varargs methods. 205 */ 206 public static final long VARARGS = 1L<<34; 207 208 /** Flag for annotation type symbols to indicate it has been 209 * checked and found acyclic. 210 */ 211 public static final long ACYCLIC_ANN = 1L<<35; 212 213 /** Flag that marks a generated default constructor. 214 */ 215 public static final long GENERATEDCONSTR = 1L<<36; 216 217 /** Flag that marks a hypothetical method that need not really be 218 * generated in the binary, but is present in the symbol table to 219 * simplify checking for erasure clashes - also used for 292 poly sig methods. 220 */ 221 public static final long HYPOTHETICAL = 1L<<37; 222 223 /** 224 * Flag that marks an internal proprietary class. 225 */ 226 public static final long PROPRIETARY = 1L<<38; 227 228 /** 229 * Flag that marks a multi-catch parameter. 230 */ 231 public static final long UNION = 1L<<39; 232 233 /** 234 * Flags an erroneous TypeSymbol as viable for recovery. 235 * TypeSymbols only. 236 */ 237 public static final long RECOVERABLE = 1L<<40; 238 239 /** 240 * Flag that marks an 'effectively final' local variable. 241 */ 242 public static final long EFFECTIVELY_FINAL = 1L<<41; 243 244 /** 245 * Flag that marks non-override equivalent methods with the same signature, 246 * or a conflicting match binding (BindingSymbol). 247 */ 248 public static final long CLASH = 1L<<42; 249 250 /** 251 * Flag that marks either a default method or an interface containing default methods. 252 */ 253 public static final long DEFAULT = 1L<<43; 254 255 /** 256 * Flag that marks class as auxiliary, ie a non-public class following 257 * the public class in a source file, that could block implicit compilation. 258 */ 259 public static final long AUXILIARY = 1L<<44; 260 261 /** 262 * Flag that marks that a symbol is not available in the current profile 263 */ 264 public static final long NOT_IN_PROFILE = 1L<<45; 265 266 /** 267 * Flag that indicates that an override error has been detected by Check. 268 */ 269 public static final long BAD_OVERRIDE = 1L<<45; 270 271 /** 272 * Flag that indicates a signature polymorphic method (292). 273 */ 274 public static final long SIGNATURE_POLYMORPHIC = 1L<<46; 275 276 /** 277 * Flag that indicates that an inference variable is used in a 'throws' clause. 278 */ 279 public static final long THROWS = 1L<<47; 280 281 /* 282 * Currently available: Bit 48. 283 */ 284 285 /** 286 * Flag that marks a synthetic method body for a lambda expression 287 */ 288 public static final long LAMBDA_METHOD = 1L<<49; //MethodSymbols only 289 290 /** 291 * Flag that marks a synthetic local capture field in a local/anon class 292 */ 293 public static final long LOCAL_CAPTURE_FIELD = 1L<<49; //VarSymbols only 294 295 /** 296 * Flag to control recursion in TransTypes 297 */ 298 public static final long TYPE_TRANSLATED = 1L<<50; 299 300 /** 301 * Flag to indicate class symbol is for module-info 302 */ 303 public static final long MODULE = 1L<<51; 304 305 /** 306 * Flag to indicate the given ModuleSymbol is an automatic module. 307 */ 308 public static final long AUTOMATIC_MODULE = 1L<<52; //ModuleSymbols only 309 310 /** 311 * Flag to indicate the given PackageSymbol contains any non-.java and non-.class resources. 312 */ 313 public static final long HAS_RESOURCE = 1L<<52; //PackageSymbols only 314 315 /** 316 * Flag to indicate the given ParamSymbol has a user-friendly name filled. 317 */ 318 public static final long NAME_FILLED = 1L<<52; //ParamSymbols only 319 320 /** 321 * Flag to indicate the given ModuleSymbol is a system module. 322 */ 323 public static final long SYSTEM_MODULE = 1L<<53; //ModuleSymbols only 324 325 /** 326 * Flag to indicate the given ClassSymbol is a value based. 327 */ 328 public static final long VALUE_BASED = 1L<<53; //ClassSymbols only 329 330 /** 331 * Flag to indicate the given symbol has a @Deprecated annotation. 332 */ 333 public static final long DEPRECATED_ANNOTATION = 1L<<54; 334 335 /** 336 * Flag to indicate the given symbol has been deprecated and marked for removal. 337 */ 338 public static final long DEPRECATED_REMOVAL = 1L<<55; 339 340 /** 341 * Flag to indicate the API element in question is for a preview API. 342 */ 343 public static final long PREVIEW_API = 1L<<56; //any Symbol kind 344 345 /** 346 * Flag for synthesized default constructors of anonymous classes that have an enclosing expression. 347 */ 348 public static final long ANONCONSTR_BASED = 1L<<57; 349 350 /** 351 * Flag that marks finalize block as body-only, should not be copied into catch clauses. 352 * Used to implement try-with-resources. 353 */ 354 public static final long BODY_ONLY_FINALIZE = 1L<<17; //blocks only 355 356 /** 357 * Flag to indicate the API element in question is for a preview API. 358 */ 359 public static final long PREVIEW_REFLECTIVE = 1L<<58; //any Symbol kind 360 361 /** 362 * Flag to indicate the given variable is a match binding variable. 363 */ 364 public static final long MATCH_BINDING = 1L<<59; 365 366 /** 367 * A flag to indicate a match binding variable whose scope extends after the current statement. 368 */ 369 public static final long MATCH_BINDING_TO_OUTER = 1L<<60; 370 371 /** 372 * Flag to indicate that a class is a record. The flag is also used to mark fields that are 373 * part of the state vector of a record and to mark the canonical constructor 374 */ 375 public static final long RECORD = 1L<<61; // ClassSymbols, MethodSymbols and VarSymbols 376 377 /** 378 * Flag to mark a record constructor as a compact one 379 */ 380 public static final long COMPACT_RECORD_CONSTRUCTOR = 1L<<51; // MethodSymbols only 381 382 /** 383 * Flag to mark a record field that was not initialized in the compact constructor 384 */ 385 public static final long UNINITIALIZED_FIELD= 1L<<51; // VarSymbols only 386 387 /** Flag is set for compiler-generated record members, it could be applied to 388 * accessors and fields 389 */ 390 public static final int GENERATED_MEMBER = 1<<24; // MethodSymbols and VarSymbols 391 392 /** 393 * Flag to indicate sealed class/interface declaration. 394 */ 395 public static final long SEALED = 1L<<62; // ClassSymbols 396 397 /** 398 * Flag to indicate restricted method declaration. 399 */ 400 public static final long RESTRICTED = 1L<<62; // MethodSymbols 401 402 /** 403 * Flag to indicate that the class/interface was declared with the non-sealed modifier. 404 */ 405 public static final long NON_SEALED = 1L<<63; // ClassSymbols 406 407 /** 408 * Describe modifier flags as they might appear in source code, i.e., 409 * separated by spaces and in the order suggested by JLS 8.1.1. 410 */ 411 public static String toSource(long flags) { 412 return asModifierSet(flags).stream() 413 .map(Modifier::toString) 414 .collect(Collectors.joining(" ")); 415 } 416 417 /** Modifier masks. 418 */ 419 public static final int 420 AccessFlags = PUBLIC | PROTECTED | PRIVATE, 421 LocalClassFlags = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC, 422 StaticLocalFlags = LocalClassFlags | STATIC | INTERFACE, 423 MemberClassFlags = LocalClassFlags | INTERFACE | AccessFlags, 424 MemberStaticClassFlags = MemberClassFlags | STATIC, 425 ClassFlags = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION, 426 InterfaceVarFlags = FINAL | STATIC | PUBLIC, 427 VarFlags = AccessFlags | FINAL | STATIC | 428 VOLATILE | TRANSIENT | ENUM, 429 ConstructorFlags = AccessFlags, 430 InterfaceMethodFlags = ABSTRACT | PUBLIC, 431 MethodFlags = AccessFlags | ABSTRACT | STATIC | NATIVE | 432 SYNCHRONIZED | FINAL | STRICTFP, 433 RecordMethodFlags = AccessFlags | ABSTRACT | STATIC | 434 SYNCHRONIZED | FINAL | STRICTFP; 435 public static final long 436 ExtendedStandardFlags = (long)StandardFlags | DEFAULT | SEALED | NON_SEALED, 437 ExtendedMemberClassFlags = (long)MemberClassFlags | SEALED | NON_SEALED, 438 ExtendedMemberStaticClassFlags = (long) MemberStaticClassFlags | SEALED | NON_SEALED, 439 ExtendedClassFlags = (long)ClassFlags | SEALED | NON_SEALED, 440 ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT | SEALED | NON_SEALED, 441 InterfaceMethodMask = ABSTRACT | PRIVATE | STATIC | PUBLIC | STRICTFP | DEFAULT, 442 AnnotationTypeElementMask = ABSTRACT | PUBLIC, 443 LocalVarFlags = FINAL | PARAMETER, 444 ReceiverParamFlags = PARAMETER; 445 446 public static Set<Modifier> asModifierSet(long flags) { 447 Set<Modifier> modifiers = modifierSets.get(flags); 448 if (modifiers == null) { 449 modifiers = java.util.EnumSet.noneOf(Modifier.class); 450 if (0 != (flags & PUBLIC)) modifiers.add(Modifier.PUBLIC); 451 if (0 != (flags & PROTECTED)) modifiers.add(Modifier.PROTECTED); 452 if (0 != (flags & PRIVATE)) modifiers.add(Modifier.PRIVATE); 453 if (0 != (flags & ABSTRACT)) modifiers.add(Modifier.ABSTRACT); 454 if (0 != (flags & STATIC)) modifiers.add(Modifier.STATIC); 455 if (0 != (flags & SEALED)) modifiers.add(Modifier.SEALED); 456 if (0 != (flags & NON_SEALED)) 457 modifiers.add(Modifier.NON_SEALED); 458 if (0 != (flags & FINAL)) modifiers.add(Modifier.FINAL); 459 if (0 != (flags & TRANSIENT)) modifiers.add(Modifier.TRANSIENT); 460 if (0 != (flags & VOLATILE)) modifiers.add(Modifier.VOLATILE); 461 if (0 != (flags & SYNCHRONIZED)) 462 modifiers.add(Modifier.SYNCHRONIZED); 463 if (0 != (flags & NATIVE)) modifiers.add(Modifier.NATIVE); 464 if (0 != (flags & STRICTFP)) modifiers.add(Modifier.STRICTFP); 465 if (0 != (flags & DEFAULT)) modifiers.add(Modifier.DEFAULT); 466 modifiers = Collections.unmodifiableSet(modifiers); 467 modifierSets.put(flags, modifiers); 468 } 469 return modifiers; 470 } 471 472 // Cache of modifier sets. 473 private static final Map<Long, Set<Modifier>> modifierSets = new ConcurrentHashMap<>(64); 474 475 public static boolean isStatic(Symbol symbol) { 476 return (symbol.flags() & STATIC) != 0; 477 } 478 479 public static boolean isEnum(Symbol symbol) { 480 return (symbol.flags() & ENUM) != 0; 481 } 482 483 public static boolean isConstant(Symbol.VarSymbol symbol) { 484 return symbol.getConstValue() != null; 485 } 486 487 488 public enum Flag { 489 PUBLIC(Flags.PUBLIC), 490 PRIVATE(Flags.PRIVATE), 491 PROTECTED(Flags.PROTECTED), 492 STATIC(Flags.STATIC), 493 FINAL(Flags.FINAL), 494 SYNCHRONIZED(Flags.SYNCHRONIZED), 495 VOLATILE(Flags.VOLATILE), 496 TRANSIENT(Flags.TRANSIENT), 497 NATIVE(Flags.NATIVE), 498 INTERFACE(Flags.INTERFACE), 499 ABSTRACT(Flags.ABSTRACT), 500 DEFAULT(Flags.DEFAULT), 501 STRICTFP(Flags.STRICTFP), 502 BRIDGE(Flags.BRIDGE), 503 SYNTHETIC(Flags.SYNTHETIC), 504 ANNOTATION(Flags.ANNOTATION), 505 DEPRECATED(Flags.DEPRECATED), 506 HASINIT(Flags.HASINIT), 507 IMPLICIT_CLASS(Flags.IMPLICIT_CLASS), 508 BLOCK(Flags.BLOCK), 509 FROM_SOURCE(Flags.FROM_SOURCE), 510 ENUM(Flags.ENUM), 511 MANDATED(Flags.MANDATED), 512 NOOUTERTHIS(Flags.NOOUTERTHIS), 513 EXISTS(Flags.EXISTS), 514 COMPOUND(Flags.COMPOUND), 515 CLASS_SEEN(Flags.CLASS_SEEN), 516 SOURCE_SEEN(Flags.SOURCE_SEEN), 517 LOCKED(Flags.LOCKED), 518 UNATTRIBUTED(Flags.UNATTRIBUTED), 519 ANONCONSTR(Flags.ANONCONSTR), 520 ACYCLIC(Flags.ACYCLIC), 521 PARAMETER(Flags.PARAMETER), 522 VARARGS(Flags.VARARGS), 523 ACYCLIC_ANN(Flags.ACYCLIC_ANN), 524 GENERATEDCONSTR(Flags.GENERATEDCONSTR), 525 HYPOTHETICAL(Flags.HYPOTHETICAL), 526 PROPRIETARY(Flags.PROPRIETARY), 527 UNION(Flags.UNION), 528 EFFECTIVELY_FINAL(Flags.EFFECTIVELY_FINAL), 529 CLASH(Flags.CLASH), 530 AUXILIARY(Flags.AUXILIARY), 531 NOT_IN_PROFILE(Flags.NOT_IN_PROFILE), 532 BAD_OVERRIDE(Flags.BAD_OVERRIDE), 533 SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC), 534 THROWS(Flags.THROWS), 535 LAMBDA_METHOD(Flags.LAMBDA_METHOD), 536 TYPE_TRANSLATED(Flags.TYPE_TRANSLATED), 537 MODULE(Flags.MODULE), 538 AUTOMATIC_MODULE(Flags.AUTOMATIC_MODULE), 539 SYSTEM_MODULE(Flags.SYSTEM_MODULE), 540 DEPRECATED_ANNOTATION(Flags.DEPRECATED_ANNOTATION), 541 DEPRECATED_REMOVAL(Flags.DEPRECATED_REMOVAL), 542 HAS_RESOURCE(Flags.HAS_RESOURCE), 543 // Bit 48 is currently available 544 ANONCONSTR_BASED(Flags.ANONCONSTR_BASED), 545 NAME_FILLED(Flags.NAME_FILLED), 546 PREVIEW_API(Flags.PREVIEW_API), 547 PREVIEW_REFLECTIVE(Flags.PREVIEW_REFLECTIVE), 548 MATCH_BINDING(Flags.MATCH_BINDING), 549 MATCH_BINDING_TO_OUTER(Flags.MATCH_BINDING_TO_OUTER), 550 RECORD(Flags.RECORD), 551 RECOVERABLE(Flags.RECOVERABLE), 552 SEALED(Flags.SEALED), 553 NON_SEALED(Flags.NON_SEALED) { 554 @Override 555 public String toString() { 556 return "non-sealed"; 557 } 558 }; 559 560 Flag(long flag) { 561 this.value = flag; 562 this.lowercaseName = StringUtils.toLowerCase(name()); 563 } 564 565 @Override 566 public String toString() { 567 return lowercaseName; 568 } 569 570 final long value; 571 final String lowercaseName; 572 } 573 574 }