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