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