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; 300 301 /** 302 * Flag to control recursion in TransTypes 303 */ 304 public static final long TYPE_TRANSLATED = 1L<<50; 305 306 /** 307 * Flag to indicate class symbol is for module-info 308 */ 309 public static final long MODULE = 1L<<51; 310 311 /** 312 * Flag to indicate the given ModuleSymbol is an automatic module. 313 */ 314 public static final long AUTOMATIC_MODULE = 1L<<52; //ModuleSymbols only 315 316 /** 317 * Flag to indicate the given PackageSymbol contains any non-.java and non-.class resources. 318 */ 319 public static final long HAS_RESOURCE = 1L<<52; //PackageSymbols only 320 321 /** 322 * Flag to indicate the given ParamSymbol has a user-friendly name filled. 323 */ 324 public static final long NAME_FILLED = 1L<<52; //ParamSymbols only 325 326 /** 327 * Flag to indicate the given ModuleSymbol is a system module. 328 */ 329 public static final long SYSTEM_MODULE = 1L<<53; //ModuleSymbols only 330 331 /** 332 * Flag to indicate the given ClassSymbol is a value based. 333 */ 334 public static final long VALUE_BASED = 1L<<53; //ClassSymbols only 335 336 /** 337 * Flag to indicate the given ClassSymbol is a value based. 338 */ 339 public static final long MIGRATED_VALUE_CLASS = 1L<<57; //ClassSymbols only 340 341 /** 342 * Flag to indicate the given symbol has a @Deprecated annotation. 343 */ 344 public static final long DEPRECATED_ANNOTATION = 1L<<54; 345 346 /** 347 * Flag to indicate the given symbol has been deprecated and marked for removal. 348 */ 349 public static final long DEPRECATED_REMOVAL = 1L<<55; 350 351 /** 352 * Flag to indicate the API element in question is for a preview API. 353 */ 354 public static final long PREVIEW_API = 1L<<56; //any Symbol kind 355 356 /** 357 * Flag for synthesized default constructors of anonymous classes that have an enclosing expression. 358 */ 359 public static final long ANONCONSTR_BASED = 1L<<57; 360 361 /** 362 * Flag that marks finalize block as body-only, should not be copied into catch clauses. 363 * Used to implement try-with-resources. 364 */ 365 public static final long BODY_ONLY_FINALIZE = 1L<<17; //blocks only 366 367 /** 368 * Flag to indicate the API element in question is for a preview API. 369 */ 370 public static final long PREVIEW_REFLECTIVE = 1L<<58; //any Symbol kind 371 372 /** 373 * Flag to indicate the given variable is a match binding variable. 374 */ 375 public static final long MATCH_BINDING = 1L<<59; 376 377 /** 378 * A flag to indicate a match binding variable whose scope extends after the current statement. 379 */ 380 public static final long MATCH_BINDING_TO_OUTER = 1L<<60; 381 382 /** 383 * Flag to indicate that a class is a record. The flag is also used to mark fields that are 384 * part of the state vector of a record and to mark the canonical constructor 385 */ 386 public static final long RECORD = 1L<<61; // ClassSymbols, MethodSymbols and VarSymbols 387 388 /** 389 * Flag to mark a record constructor as a compact one 390 */ 391 public static final long COMPACT_RECORD_CONSTRUCTOR = 1L<<51; // MethodSymbols only 392 393 /** 394 * Flag to mark a record field that was not initialized in the compact constructor 395 */ 396 public static final long UNINITIALIZED_FIELD= 1L<<51; // VarSymbols only 397 398 /** Flag is set for compiler-generated record members, it could be applied to 399 * accessors and fields 400 */ 401 public static final int GENERATED_MEMBER = 1<<24; // MethodSymbols and VarSymbols 402 403 /** 404 * Flag to indicate sealed class/interface declaration. 405 */ 406 public static final long SEALED = 1L<<62; // ClassSymbols 407 408 /** 409 * Flag to indicate restricted method declaration. 410 */ 411 public static final long RESTRICTED = 1L<<62; // MethodSymbols 412 413 /** 414 * Flag to indicate that the class/interface was declared with the non-sealed modifier. 415 */ 416 public static final long NON_SEALED = 1L<<63; // ClassSymbols 417 418 /** 419 * Flag to indicate that a field is strict 420 */ 421 public static final long STRICT = 1L<<53; // VarSymbols 422 423 /** 424 * Describe modifier flags as they might appear in source code, i.e., 425 * separated by spaces and in the order suggested by JLS 8.1.1. 426 */ 427 public static String toSource(long flags) { 428 return asModifierSet(flags).stream() 429 .map(Modifier::toString) 430 .collect(Collectors.joining(" ")); 431 } 432 433 /** Modifier masks. 434 */ 435 public static final int 436 AccessFlags = PUBLIC | PROTECTED | PRIVATE, 437 LocalClassFlags = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC | IDENTITY_TYPE, 438 StaticLocalClassFlags = LocalClassFlags | STATIC | INTERFACE, 439 MemberClassFlags = LocalClassFlags | INTERFACE | AccessFlags, 440 MemberStaticClassFlags = MemberClassFlags | STATIC, 441 ClassFlags = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION, 442 InterfaceVarFlags = FINAL | STATIC | PUBLIC, 443 VarFlags = AccessFlags | FINAL | STATIC | 444 VOLATILE | TRANSIENT | ENUM, 445 ConstructorFlags = AccessFlags, 446 InterfaceMethodFlags = ABSTRACT | PUBLIC, 447 MethodFlags = AccessFlags | ABSTRACT | STATIC | NATIVE | 448 SYNCHRONIZED | FINAL | STRICTFP, 449 RecordMethodFlags = AccessFlags | ABSTRACT | STATIC | 450 SYNCHRONIZED | FINAL | STRICTFP; 451 public static final long 452 ExtendedStandardFlags = (long)StandardFlags | DEFAULT | SEALED | NON_SEALED | VALUE_CLASS, 453 ExtendedMemberClassFlags = (long)MemberClassFlags | SEALED | NON_SEALED | VALUE_CLASS, 454 ExtendedMemberStaticClassFlags = (long) MemberStaticClassFlags | SEALED | NON_SEALED | VALUE_CLASS, 455 ExtendedClassFlags = (long)ClassFlags | SEALED | NON_SEALED | VALUE_CLASS, 456 ExtendedLocalClassFlags = (long) LocalClassFlags | VALUE_CLASS, 457 ExtendedStaticLocalClassFlags = (long) StaticLocalClassFlags | VALUE_CLASS, 458 ExtendedVarFlags = (long) VarFlags | STRICT, 459 ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT | SEALED | NON_SEALED | VALUE_CLASS, 460 InterfaceMethodMask = ABSTRACT | PRIVATE | STATIC | PUBLIC | STRICTFP | DEFAULT, 461 AnnotationTypeElementMask = ABSTRACT | PUBLIC, 462 LocalVarFlags = FINAL | PARAMETER, 463 ReceiverParamFlags = PARAMETER; 464 465 public static Set<Modifier> asModifierSet(long flags) { 466 Set<Modifier> modifiers = modifierSets.get(flags); 467 if (modifiers == null) { 468 modifiers = java.util.EnumSet.noneOf(Modifier.class); 469 if (0 != (flags & PUBLIC)) modifiers.add(Modifier.PUBLIC); 470 if (0 != (flags & PROTECTED)) modifiers.add(Modifier.PROTECTED); 471 if (0 != (flags & PRIVATE)) modifiers.add(Modifier.PRIVATE); 472 if (0 != (flags & ABSTRACT)) modifiers.add(Modifier.ABSTRACT); 473 if (0 != (flags & STATIC)) modifiers.add(Modifier.STATIC); 474 if (0 != (flags & SEALED)) modifiers.add(Modifier.SEALED); 475 if (0 != (flags & NON_SEALED)) 476 modifiers.add(Modifier.NON_SEALED); 477 if (0 != (flags & FINAL)) modifiers.add(Modifier.FINAL); 478 if (0 != (flags & TRANSIENT)) modifiers.add(Modifier.TRANSIENT); 479 if (0 != (flags & VOLATILE)) modifiers.add(Modifier.VOLATILE); 480 if (0 != (flags & SYNCHRONIZED)) 481 modifiers.add(Modifier.SYNCHRONIZED); 482 if (0 != (flags & NATIVE)) modifiers.add(Modifier.NATIVE); 483 if (0 != (flags & STRICTFP)) modifiers.add(Modifier.STRICTFP); 484 if (0 != (flags & DEFAULT)) modifiers.add(Modifier.DEFAULT); 485 if (0 != (flags & VALUE_CLASS)) modifiers.add(Modifier.VALUE); 486 modifiers = Collections.unmodifiableSet(modifiers); 487 modifierSets.put(flags, modifiers); 488 } 489 return modifiers; 490 } 491 492 // Cache of modifier sets. 493 private static final Map<Long, Set<Modifier>> modifierSets = new ConcurrentHashMap<>(64); 494 495 public static boolean isStatic(Symbol symbol) { 496 return (symbol.flags() & STATIC) != 0; 497 } 498 499 public static boolean isEnum(Symbol symbol) { 500 return (symbol.flags() & ENUM) != 0; 501 } 502 503 public static boolean isConstant(Symbol.VarSymbol symbol) { 504 return symbol.getConstValue() != null; 505 } 506 507 public enum Flag { 508 PUBLIC(Flags.PUBLIC), 509 PRIVATE(Flags.PRIVATE), 510 PROTECTED(Flags.PROTECTED), 511 STATIC(Flags.STATIC), 512 FINAL(Flags.FINAL), 513 SYNCHRONIZED(Flags.SYNCHRONIZED), 514 VOLATILE(Flags.VOLATILE), 515 TRANSIENT(Flags.TRANSIENT), 516 NATIVE(Flags.NATIVE), 517 INTERFACE(Flags.INTERFACE), 518 ABSTRACT(Flags.ABSTRACT), 519 DEFAULT(Flags.DEFAULT), 520 STRICTFP(Flags.STRICTFP), 521 BRIDGE(Flags.BRIDGE), 522 SYNTHETIC(Flags.SYNTHETIC), 523 ANNOTATION(Flags.ANNOTATION), 524 DEPRECATED(Flags.DEPRECATED), 525 HASINIT(Flags.HASINIT), 526 IDENTITY_TYPE(Flags.IDENTITY_TYPE) { 527 @Override 528 public String toString() { 529 return "identity"; 530 } 531 }, 532 VALUE(Flags.VALUE_CLASS), 533 IMPLICIT_CLASS(Flags.IMPLICIT_CLASS), 534 BLOCK(Flags.BLOCK), 535 FROM_SOURCE(Flags.FROM_SOURCE), 536 ENUM(Flags.ENUM), 537 MANDATED(Flags.MANDATED), 538 NOOUTERTHIS(Flags.NOOUTERTHIS), 539 EXISTS(Flags.EXISTS), 540 COMPOUND(Flags.COMPOUND), 541 CLASS_SEEN(Flags.CLASS_SEEN), 542 SOURCE_SEEN(Flags.SOURCE_SEEN), 543 LOCKED(Flags.LOCKED), 544 UNATTRIBUTED(Flags.UNATTRIBUTED), 545 ANONCONSTR(Flags.ANONCONSTR), 546 ACYCLIC(Flags.ACYCLIC), 547 PARAMETER(Flags.PARAMETER), 548 VARARGS(Flags.VARARGS), 549 ACYCLIC_ANN(Flags.ACYCLIC_ANN), 550 GENERATEDCONSTR(Flags.GENERATEDCONSTR), 551 HYPOTHETICAL(Flags.HYPOTHETICAL), 552 PROPRIETARY(Flags.PROPRIETARY), 553 UNION(Flags.UNION), 554 EFFECTIVELY_FINAL(Flags.EFFECTIVELY_FINAL), 555 CLASH(Flags.CLASH), 556 AUXILIARY(Flags.AUXILIARY), 557 NOT_IN_PROFILE(Flags.NOT_IN_PROFILE), 558 BAD_OVERRIDE(Flags.BAD_OVERRIDE), 559 SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC), 560 THROWS(Flags.THROWS), 561 LAMBDA_METHOD(Flags.LAMBDA_METHOD), 562 TYPE_TRANSLATED(Flags.TYPE_TRANSLATED), 563 MODULE(Flags.MODULE), 564 AUTOMATIC_MODULE(Flags.AUTOMATIC_MODULE), 565 SYSTEM_MODULE(Flags.SYSTEM_MODULE), 566 DEPRECATED_ANNOTATION(Flags.DEPRECATED_ANNOTATION), 567 DEPRECATED_REMOVAL(Flags.DEPRECATED_REMOVAL), 568 HAS_RESOURCE(Flags.HAS_RESOURCE), 569 // Bit 48 is currently available 570 ANONCONSTR_BASED(Flags.ANONCONSTR_BASED), 571 NAME_FILLED(Flags.NAME_FILLED), 572 PREVIEW_API(Flags.PREVIEW_API), 573 PREVIEW_REFLECTIVE(Flags.PREVIEW_REFLECTIVE), 574 MATCH_BINDING(Flags.MATCH_BINDING), 575 MATCH_BINDING_TO_OUTER(Flags.MATCH_BINDING_TO_OUTER), 576 RECORD(Flags.RECORD), 577 RECOVERABLE(Flags.RECOVERABLE), 578 SEALED(Flags.SEALED), 579 NON_SEALED(Flags.NON_SEALED) { 580 @Override 581 public String toString() { 582 return "non-sealed"; 583 } 584 }, 585 STRICT(Flags.STRICT); 586 587 Flag(long flag) { 588 this.value = flag; 589 this.lowercaseName = StringUtils.toLowerCase(name()); 590 } 591 592 @Override 593 public String toString() { 594 return lowercaseName; 595 } 596 597 final long value; 598 final String lowercaseName; 599 } 600 601 }