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