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; 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 restricted method declaration. 394 */ 395 public static final long RESTRICTED = 1L<<62; // MethodSymbols 396 397 /** 398 * Flag to indicate that the class/interface was declared with the non-sealed modifier. 399 */ 400 public static final long NON_SEALED = 1L<<63; // ClassSymbols 401 402 /** 403 * Describe modifier flags as they might appear in source code, i.e., 404 * separated by spaces and in the order suggested by JLS 8.1.1. 405 */ 406 public static String toSource(long flags) { 407 return asModifierSet(flags).stream() 408 .map(Modifier::toString) 409 .collect(Collectors.joining(" ")); 410 } 411 412 /** Modifier masks. 413 */ 414 public static final int 415 AccessFlags = PUBLIC | PROTECTED | PRIVATE, 416 LocalClassFlags = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC, 417 StaticLocalFlags = LocalClassFlags | STATIC | INTERFACE, 418 MemberClassFlags = LocalClassFlags | INTERFACE | AccessFlags, 419 MemberStaticClassFlags = MemberClassFlags | STATIC, 420 ClassFlags = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION, 421 InterfaceVarFlags = FINAL | STATIC | PUBLIC, 422 VarFlags = AccessFlags | FINAL | STATIC | 423 VOLATILE | TRANSIENT | ENUM, 424 ConstructorFlags = AccessFlags, 425 InterfaceMethodFlags = ABSTRACT | PUBLIC, 426 MethodFlags = AccessFlags | ABSTRACT | STATIC | NATIVE | 427 SYNCHRONIZED | FINAL | STRICTFP, 428 RecordMethodFlags = AccessFlags | ABSTRACT | STATIC | 429 SYNCHRONIZED | FINAL | STRICTFP; 430 public static final long 431 ExtendedStandardFlags = (long)StandardFlags | DEFAULT | SEALED | NON_SEALED, 432 ExtendedMemberClassFlags = (long)MemberClassFlags | SEALED | NON_SEALED, 433 ExtendedMemberStaticClassFlags = (long) MemberStaticClassFlags | SEALED | NON_SEALED, 434 ExtendedClassFlags = (long)ClassFlags | SEALED | NON_SEALED, 435 ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT | SEALED | NON_SEALED, 436 InterfaceMethodMask = ABSTRACT | PRIVATE | STATIC | PUBLIC | STRICTFP | DEFAULT, 437 AnnotationTypeElementMask = ABSTRACT | PUBLIC, 438 LocalVarFlags = FINAL | PARAMETER, 439 ReceiverParamFlags = PARAMETER; 440 441 public static Set<Modifier> asModifierSet(long flags) { 442 Set<Modifier> modifiers = modifierSets.get(flags); 443 if (modifiers == null) { 444 modifiers = java.util.EnumSet.noneOf(Modifier.class); 445 if (0 != (flags & PUBLIC)) modifiers.add(Modifier.PUBLIC); 446 if (0 != (flags & PROTECTED)) modifiers.add(Modifier.PROTECTED); 447 if (0 != (flags & PRIVATE)) modifiers.add(Modifier.PRIVATE); 448 if (0 != (flags & ABSTRACT)) modifiers.add(Modifier.ABSTRACT); 449 if (0 != (flags & STATIC)) modifiers.add(Modifier.STATIC); 450 if (0 != (flags & SEALED)) modifiers.add(Modifier.SEALED); 451 if (0 != (flags & NON_SEALED)) 452 modifiers.add(Modifier.NON_SEALED); 453 if (0 != (flags & FINAL)) modifiers.add(Modifier.FINAL); 454 if (0 != (flags & TRANSIENT)) modifiers.add(Modifier.TRANSIENT); 455 if (0 != (flags & VOLATILE)) modifiers.add(Modifier.VOLATILE); 456 if (0 != (flags & SYNCHRONIZED)) 457 modifiers.add(Modifier.SYNCHRONIZED); 458 if (0 != (flags & NATIVE)) modifiers.add(Modifier.NATIVE); 459 if (0 != (flags & STRICTFP)) modifiers.add(Modifier.STRICTFP); 460 if (0 != (flags & DEFAULT)) modifiers.add(Modifier.DEFAULT); 461 modifiers = Collections.unmodifiableSet(modifiers); 462 modifierSets.put(flags, modifiers); 463 } 464 return modifiers; 465 } 466 467 // Cache of modifier sets. 468 private static final Map<Long, Set<Modifier>> modifierSets = new ConcurrentHashMap<>(64); 469 470 public static boolean isStatic(Symbol symbol) { 471 return (symbol.flags() & STATIC) != 0; 472 } 473 474 public static boolean isEnum(Symbol symbol) { 475 return (symbol.flags() & ENUM) != 0; 476 } 477 478 public static boolean isConstant(Symbol.VarSymbol symbol) { 479 return symbol.getConstValue() != null; 480 } 481 482 483 public enum Flag { 484 PUBLIC(Flags.PUBLIC), 485 PRIVATE(Flags.PRIVATE), 486 PROTECTED(Flags.PROTECTED), 487 STATIC(Flags.STATIC), 488 FINAL(Flags.FINAL), 489 SYNCHRONIZED(Flags.SYNCHRONIZED), 490 VOLATILE(Flags.VOLATILE), 491 TRANSIENT(Flags.TRANSIENT), 492 NATIVE(Flags.NATIVE), 493 INTERFACE(Flags.INTERFACE), 494 ABSTRACT(Flags.ABSTRACT), 495 DEFAULT(Flags.DEFAULT), 496 STRICTFP(Flags.STRICTFP), 497 BRIDGE(Flags.BRIDGE), 498 SYNTHETIC(Flags.SYNTHETIC), 499 ANNOTATION(Flags.ANNOTATION), 500 DEPRECATED(Flags.DEPRECATED), 501 HASINIT(Flags.HASINIT), 502 IMPLICIT_CLASS(Flags.IMPLICIT_CLASS), 503 BLOCK(Flags.BLOCK), 504 FROM_SOURCE(Flags.FROM_SOURCE), 505 ENUM(Flags.ENUM), 506 MANDATED(Flags.MANDATED), 507 NOOUTERTHIS(Flags.NOOUTERTHIS), 508 EXISTS(Flags.EXISTS), 509 COMPOUND(Flags.COMPOUND), 510 CLASS_SEEN(Flags.CLASS_SEEN), 511 SOURCE_SEEN(Flags.SOURCE_SEEN), 512 LOCKED(Flags.LOCKED), 513 UNATTRIBUTED(Flags.UNATTRIBUTED), 514 ANONCONSTR(Flags.ANONCONSTR), 515 ACYCLIC(Flags.ACYCLIC), 516 PARAMETER(Flags.PARAMETER), 517 VARARGS(Flags.VARARGS), 518 ACYCLIC_ANN(Flags.ACYCLIC_ANN), 519 GENERATEDCONSTR(Flags.GENERATEDCONSTR), 520 HYPOTHETICAL(Flags.HYPOTHETICAL), 521 PROPRIETARY(Flags.PROPRIETARY), 522 UNION(Flags.UNION), 523 EFFECTIVELY_FINAL(Flags.EFFECTIVELY_FINAL), 524 CLASH(Flags.CLASH), 525 AUXILIARY(Flags.AUXILIARY), 526 NOT_IN_PROFILE(Flags.NOT_IN_PROFILE), 527 BAD_OVERRIDE(Flags.BAD_OVERRIDE), 528 SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC), 529 THROWS(Flags.THROWS), 530 LAMBDA_METHOD(Flags.LAMBDA_METHOD), 531 TYPE_TRANSLATED(Flags.TYPE_TRANSLATED), 532 MODULE(Flags.MODULE), 533 AUTOMATIC_MODULE(Flags.AUTOMATIC_MODULE), 534 SYSTEM_MODULE(Flags.SYSTEM_MODULE), 535 DEPRECATED_ANNOTATION(Flags.DEPRECATED_ANNOTATION), 536 DEPRECATED_REMOVAL(Flags.DEPRECATED_REMOVAL), 537 HAS_RESOURCE(Flags.HAS_RESOURCE), 538 // Bit 48 is currently available 539 ANONCONSTR_BASED(Flags.ANONCONSTR_BASED), 540 NAME_FILLED(Flags.NAME_FILLED), 541 PREVIEW_API(Flags.PREVIEW_API), 542 PREVIEW_REFLECTIVE(Flags.PREVIEW_REFLECTIVE), 543 MATCH_BINDING(Flags.MATCH_BINDING), 544 MATCH_BINDING_TO_OUTER(Flags.MATCH_BINDING_TO_OUTER), 545 RECORD(Flags.RECORD), 546 RECOVERABLE(Flags.RECOVERABLE), 547 SEALED(Flags.SEALED), 548 NON_SEALED(Flags.NON_SEALED) { 549 @Override 550 public String toString() { 551 return "non-sealed"; 552 } 553 }; 554 555 Flag(long flag) { 556 this.value = flag; 557 this.lowercaseName = StringUtils.toLowerCase(name()); 558 } 559 560 @Override 561 public String toString() { 562 return lowercaseName; 563 } 564 565 final long value; 566 final String lowercaseName; 567 } 568 569 }