mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-15 13:49:42 +02:00
8362885: A more formal way to mark javac's Flags that belong to a specific Symbol type only
Reviewed-by: ihse, liach, vromero, mcimadamore, erikj
This commit is contained in:
parent
25480f0011
commit
72e22b4de5
8 changed files with 422 additions and 140 deletions
|
@ -36,7 +36,7 @@ $(eval $(call SetupJavaCompilation, BUILD_TOOLS_LANGTOOLS, \
|
|||
COMPILER := bootjdk, \
|
||||
TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \
|
||||
SRC := $(TOPDIR)/make/langtools/tools, \
|
||||
INCLUDES := compileproperties propertiesparser, \
|
||||
INCLUDES := compileproperties flagsgenerator propertiesparser, \
|
||||
COPY := .properties, \
|
||||
BIN := $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes, \
|
||||
))
|
||||
|
|
161
make/langtools/tools/flagsgenerator/FlagsGenerator.java
Normal file
161
make/langtools/tools/flagsgenerator/FlagsGenerator.java
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package flagsgenerator;
|
||||
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
import com.sun.source.util.JavacTask;
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.source.util.Trees;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
public class FlagsGenerator {
|
||||
public static void main(String... args) throws IOException {
|
||||
var compiler = ToolProvider.getSystemJavaCompiler();
|
||||
|
||||
try (var fm = compiler.getStandardFileManager(null, null, null)) {
|
||||
JavacTask task = (JavacTask) compiler.getTask(null, null, d -> {}, null, null, fm.getJavaFileObjects(args[0]));
|
||||
Trees trees = Trees.instance(task);
|
||||
CompilationUnitTree cut = task.parse().iterator().next();
|
||||
|
||||
task.analyze();
|
||||
|
||||
TypeElement clazz = (TypeElement) trees.getElement(new TreePath(new TreePath(cut), cut.getTypeDecls().get(0)));
|
||||
Map<Integer, List<String>> flag2Names = new TreeMap<>();
|
||||
Map<FlagTarget, Map<Integer, List<String>>> target2FlagBit2Fields = new EnumMap<>(FlagTarget.class);
|
||||
Map<String, String> customToString = new HashMap<>();
|
||||
Set<String> noToString = new HashSet<>();
|
||||
|
||||
for (VariableElement field : ElementFilter.fieldsIn(clazz.getEnclosedElements())) {
|
||||
String flagName = field.getSimpleName().toString();
|
||||
for (AnnotationMirror am : field.getAnnotationMirrors()) {
|
||||
switch (am.getAnnotationType().toString()) {
|
||||
case "com.sun.tools.javac.code.Flags.Use" -> {
|
||||
long flagValue = ((Number) field.getConstantValue()).longValue();
|
||||
int flagBit = 63 - Long.numberOfLeadingZeros(flagValue);
|
||||
|
||||
flag2Names.computeIfAbsent(flagBit, _ -> new ArrayList<>())
|
||||
.add(flagName);
|
||||
|
||||
List<?> originalTargets = (List<?>) valueOfValueAttribute(am);
|
||||
originalTargets.stream()
|
||||
.map(value -> FlagTarget.valueOf(value.toString()))
|
||||
.forEach(target -> target2FlagBit2Fields.computeIfAbsent(target, _ -> new HashMap<>())
|
||||
.computeIfAbsent(flagBit, _ -> new ArrayList<>())
|
||||
.add(flagName));
|
||||
}
|
||||
case "com.sun.tools.javac.code.Flags.CustomToStringValue" -> {
|
||||
customToString.put(flagName, (String) valueOfValueAttribute(am));
|
||||
}
|
||||
case "com.sun.tools.javac.code.Flags.NoToStringValue" -> {
|
||||
noToString.add(flagName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//verify there are no flag overlaps:
|
||||
for (Entry<FlagTarget, Map<Integer, List<String>>> targetAndFlag : target2FlagBit2Fields.entrySet()) {
|
||||
for (Entry<Integer, List<String>> flagAndFields : targetAndFlag.getValue().entrySet()) {
|
||||
if (flagAndFields.getValue().size() > 1) {
|
||||
throw new AssertionError("duplicate flag for target: " + targetAndFlag.getKey() +
|
||||
", flag: " + flagAndFields.getKey() +
|
||||
", flags fields: " + flagAndFields.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(Paths.get(args[1])))) {
|
||||
out.println("""
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
public enum FlagsEnum {
|
||||
""");
|
||||
for (Entry<Integer, List<String>> e : flag2Names.entrySet()) {
|
||||
String constantName = e.getValue().stream().collect(Collectors.joining("_OR_"));
|
||||
String toString = e.getValue()
|
||||
.stream()
|
||||
.filter(n -> !noToString.contains(n))
|
||||
.map(n -> customToString.getOrDefault(n, n.toLowerCase(Locale.US)))
|
||||
.collect(Collectors.joining(" or "));
|
||||
out.println(" " + constantName + "(1L<<" + e.getKey() + ", \"" + toString + "\"),");
|
||||
}
|
||||
out.println("""
|
||||
;
|
||||
|
||||
private final long value;
|
||||
private final String toString;
|
||||
private FlagsEnum(long value, String toString) {
|
||||
this.value = value;
|
||||
this.toString = toString;
|
||||
}
|
||||
public long value() {
|
||||
return value;
|
||||
}
|
||||
public String toString() {
|
||||
return toString;
|
||||
}
|
||||
}
|
||||
""");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Object valueOfValueAttribute(AnnotationMirror am) {
|
||||
return am.getElementValues()
|
||||
.values()
|
||||
.iterator()
|
||||
.next()
|
||||
.getValue();
|
||||
}
|
||||
|
||||
private enum FlagTarget {
|
||||
BLOCK,
|
||||
CLASS,
|
||||
METHOD,
|
||||
MODULE,
|
||||
PACKAGE,
|
||||
TYPE_VAR,
|
||||
VARIABLE;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -76,7 +76,7 @@ public interface MessageType {
|
|||
ANNOTATION("annotation", "Compound", "com.sun.tools.javac.code.Attribute"),
|
||||
BOOLEAN("boolean", "boolean", null),
|
||||
COLLECTION("collection", "Collection", "java.util"),
|
||||
FLAG("flag", "Flag", "com.sun.tools.javac.code.Flags"),
|
||||
FLAG("flag", "FlagsEnum", "com.sun.tools.javac.code"),
|
||||
FRAGMENT("fragment", "Fragment", null),
|
||||
DIAGNOSTIC("diagnostic", "JCDiagnostic", "com.sun.tools.javac.util"),
|
||||
MODIFIER("modifier", "Modifier", "javax.lang.model.element"),
|
||||
|
|
|
@ -41,17 +41,17 @@ $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
|
|||
|
||||
TARGETS += $(COMPILE_PROPERTIES)
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Compile properties files into enum-like classes using the propertiesparser tool
|
||||
#
|
||||
|
||||
# To avoid reevaluating the compilation setup for the tools each time this file
|
||||
# is included, the following trick is used to be able to declare a dependency on
|
||||
# the built tools.
|
||||
BUILD_TOOLS_LANGTOOLS := $(call SetupJavaCompilationCompileTarget, \
|
||||
BUILD_TOOLS_LANGTOOLS, $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes)
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Compile properties files into enum-like classes using the propertiesparser tool
|
||||
#
|
||||
|
||||
TOOL_PARSEPROPERTIES_CMD := $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes \
|
||||
propertiesparser.PropertiesParser
|
||||
|
||||
|
@ -76,3 +76,26 @@ $(eval $(call SetupExecute, PARSEPROPERTIES, \
|
|||
TARGETS += $(PARSEPROPERTIES)
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Generate FlagsEnum from Flags constants
|
||||
#
|
||||
|
||||
TOOL_FLAGSGENERATOR_CMD := $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes \
|
||||
flagsgenerator.FlagsGenerator
|
||||
|
||||
FLAGS_SRC := \
|
||||
$(MODULE_SRC)/share/classes/com/sun/tools/javac/code/Flags.java
|
||||
|
||||
FLAGS_OUT := \
|
||||
$(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/com/sun/tools/javac/code/FlagsEnum.java
|
||||
|
||||
$(eval $(call SetupExecute, FLAGSGENERATOR, \
|
||||
WARN := Generating FlagsEnum, \
|
||||
DEPS := $(FLAGS_SRC) $(BUILD_TOOLS_LANGTOOLS), \
|
||||
OUTPUT_FILE := $(FLAGS_OUT), \
|
||||
COMMAND := $(TOOL_FLAGSGENERATOR_CMD) $(FLAGS_SRC) $(FLAGS_OUT), \
|
||||
))
|
||||
|
||||
TARGETS += $(FLAGSGENERATOR)
|
||||
|
||||
################################################################################
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
|
@ -35,7 +37,6 @@ import java.util.stream.Collectors;
|
|||
import javax.lang.model.element.Modifier;
|
||||
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
import com.sun.tools.javac.util.StringUtils;
|
||||
|
||||
/** Access flags and other modifiers for Java classes and members.
|
||||
*
|
||||
|
@ -51,7 +52,7 @@ public class Flags {
|
|||
public static String toString(long flags) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
String sep = "";
|
||||
for (Flag flag : asFlagSet(flags)) {
|
||||
for (FlagsEnum flag : asFlagSet(flags)) {
|
||||
buf.append(sep);
|
||||
buf.append(flag);
|
||||
sep = " ";
|
||||
|
@ -59,12 +60,12 @@ public class Flags {
|
|||
return buf.toString();
|
||||
}
|
||||
|
||||
public static EnumSet<Flag> asFlagSet(long flags) {
|
||||
EnumSet<Flag> flagSet = EnumSet.noneOf(Flag.class);
|
||||
for (Flag flag : Flag.values()) {
|
||||
if ((flags & flag.value) != 0) {
|
||||
public static EnumSet<FlagsEnum> asFlagSet(long flags) {
|
||||
EnumSet<FlagsEnum> flagSet = EnumSet.noneOf(FlagsEnum.class);
|
||||
for (FlagsEnum flag : FlagsEnum.values()) {
|
||||
if ((flags & flag.value()) != 0) {
|
||||
flagSet.add(flag);
|
||||
flags &= ~flag.value;
|
||||
flags &= ~flag.value();
|
||||
}
|
||||
}
|
||||
Assert.check(flags == 0);
|
||||
|
@ -73,42 +74,67 @@ public class Flags {
|
|||
|
||||
/* Standard Java flags.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||
public static final int PUBLIC = 1;
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||
public static final int PRIVATE = 1<<1;
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||
public static final int PROTECTED = 1<<2;
|
||||
@Use({FlagTarget.BLOCK, FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||
public static final int STATIC = 1<<3;
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||
public static final int FINAL = 1<<4;
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final int SYNCHRONIZED = 1<<5;
|
||||
@Use({FlagTarget.VARIABLE})
|
||||
public static final int VOLATILE = 1<<6;
|
||||
@Use({FlagTarget.VARIABLE})
|
||||
public static final int TRANSIENT = 1<<7;
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final int NATIVE = 1<<8;
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final int INTERFACE = 1<<9;
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD})
|
||||
public static final int ABSTRACT = 1<<10;
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD})
|
||||
public static final int STRICTFP = 1<<11;
|
||||
|
||||
/* Flag that marks a symbol synthetic, added in classfile v49.0. */
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||
public static final int SYNTHETIC = 1<<12;
|
||||
|
||||
/** Flag that marks attribute interfaces, added in classfile v49.0. */
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final int ANNOTATION = 1<<13;
|
||||
|
||||
/** An enumeration type or an enumeration constant, added in
|
||||
* classfile v49.0. */
|
||||
@Use({FlagTarget.CLASS, FlagTarget.VARIABLE})
|
||||
public static final int ENUM = 1<<14;
|
||||
|
||||
/** Added in SE8, represents constructs implicitly declared in source. */
|
||||
@Use({FlagTarget.MODULE, FlagTarget.VARIABLE})
|
||||
public static final int MANDATED = 1<<15;
|
||||
|
||||
@NotFlag
|
||||
public static final int StandardFlags = 0x0fff;
|
||||
|
||||
// Because the following access flags are overloaded with other
|
||||
// bit positions, we translate them when reading and writing class
|
||||
// files into unique bits positions: ACC_SYNTHETIC <-> SYNTHETIC,
|
||||
// for example.
|
||||
public static final int ACC_SUPER = 0x0020;
|
||||
public static final int ACC_BRIDGE = 0x0040;
|
||||
public static final int ACC_VARARGS = 0x0080;
|
||||
public static final int ACC_MODULE = 0x8000;
|
||||
@Use({FlagTarget.CLASS})
|
||||
@NoToStringValue
|
||||
public static final int ACC_SUPER = 1<<5;
|
||||
@Use({FlagTarget.METHOD})
|
||||
@NoToStringValue
|
||||
public static final int ACC_BRIDGE = 1<<6;
|
||||
@Use({FlagTarget.METHOD})
|
||||
@NoToStringValue
|
||||
public static final int ACC_VARARGS = 1<<7;
|
||||
@Use({FlagTarget.CLASS})
|
||||
@NoToStringValue
|
||||
public static final int ACC_MODULE = 1<<15;
|
||||
|
||||
/* ***************************************
|
||||
* Internal compiler flags (no bits in the lower 16).
|
||||
|
@ -116,25 +142,30 @@ public class Flags {
|
|||
|
||||
/** Flag is set if symbol is deprecated. See also DEPRECATED_REMOVAL.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.MODULE, FlagTarget.PACKAGE, FlagTarget.TYPE_VAR, FlagTarget.VARIABLE})
|
||||
public static final int DEPRECATED = 1<<17;
|
||||
|
||||
/** Flag is set for a variable symbol if the variable's definition
|
||||
* has an initializer part.
|
||||
*/
|
||||
@Use({FlagTarget.VARIABLE})
|
||||
public static final int HASINIT = 1<<18;
|
||||
|
||||
/** Class is an implicitly declared top level class.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final int IMPLICIT_CLASS = 1<<19;
|
||||
|
||||
/** Flag is set for compiler-generated anonymous method symbols
|
||||
* that `own' an initializer block.
|
||||
*/
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final int BLOCK = 1<<20;
|
||||
|
||||
/** Flag is set for ClassSymbols that are being compiled from source.
|
||||
*/
|
||||
public static final int FROM_SOURCE = 1<<21; //ClassSymbols
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final int FROM_SOURCE = 1<<21;
|
||||
|
||||
/** Flag is set for nested classes that do not access instance members
|
||||
* or `this' of an outer class and therefore don't need to be passed
|
||||
|
@ -143,25 +174,30 @@ public class Flags {
|
|||
* todo: use this value for optimizing away this$n parameters in
|
||||
* other cases.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS, FlagTarget.VARIABLE})
|
||||
public static final int NOOUTERTHIS = 1<<22;
|
||||
|
||||
/** Flag is set for package symbols if a package has a member or
|
||||
* directory and therefore exists.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS, FlagTarget.PACKAGE})
|
||||
public static final int EXISTS = 1<<23;
|
||||
|
||||
/** Flag is set for compiler-generated compound classes
|
||||
* representing multiple variable bounds
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final int COMPOUND = 1<<24;
|
||||
|
||||
/** Flag is set for class symbols if a class file was found for this class.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final int CLASS_SEEN = 1<<25;
|
||||
|
||||
/** Flag is set for class symbols if a source file was found for this
|
||||
* class.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final int SOURCE_SEEN = 1<<26;
|
||||
|
||||
/* State flags (are reset during compilation).
|
||||
|
@ -172,242 +208,291 @@ public class Flags {
|
|||
* relations. Similarly for constructor call cycle detection in
|
||||
* Attr.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD})
|
||||
public static final int LOCKED = 1<<27;
|
||||
|
||||
/** Flag for class symbols is set and later re-set to indicate that a class
|
||||
* has been entered but has not yet been attributed.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final int UNATTRIBUTED = 1<<28;
|
||||
|
||||
/** Flag for synthesized default constructors of anonymous classes.
|
||||
*/
|
||||
public static final int ANONCONSTR = 1<<29; //non-class members
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final int ANONCONSTR = 1<<29;
|
||||
|
||||
/**
|
||||
* Flag to indicate the superclasses of this ClassSymbol has been attributed.
|
||||
*/
|
||||
public static final int SUPER_OWNER_ATTRIBUTED = 1<<29; //ClassSymbols
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final int SUPER_OWNER_ATTRIBUTED = 1<<29;
|
||||
|
||||
/** Flag for class symbols to indicate it has been checked and found
|
||||
* acyclic.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.TYPE_VAR})
|
||||
public static final int ACYCLIC = 1<<30;
|
||||
|
||||
/** Flag that marks bridge methods.
|
||||
*/
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final long BRIDGE = 1L<<31;
|
||||
|
||||
/** Flag that marks formal parameters.
|
||||
*/
|
||||
@Use({FlagTarget.VARIABLE})
|
||||
public static final long PARAMETER = 1L<<33;
|
||||
|
||||
/** Flag that marks varargs methods.
|
||||
*/
|
||||
@Use({FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||
public static final long VARARGS = 1L<<34;
|
||||
|
||||
/** Flag for annotation type symbols to indicate it has been
|
||||
* checked and found acyclic.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final long ACYCLIC_ANN = 1L<<35;
|
||||
|
||||
/** Flag that marks a generated default constructor.
|
||||
*/
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final long GENERATEDCONSTR = 1L<<36;
|
||||
|
||||
/** Flag that marks a hypothetical method that need not really be
|
||||
* generated in the binary, but is present in the symbol table to
|
||||
* simplify checking for erasure clashes - also used for 292 poly sig methods.
|
||||
*/
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final long HYPOTHETICAL = 1L<<37;
|
||||
|
||||
/**
|
||||
* Flag that marks an internal proprietary class.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final long PROPRIETARY = 1L<<38;
|
||||
|
||||
/**
|
||||
* Flag that marks a multi-catch parameter.
|
||||
*/
|
||||
@Use({FlagTarget.VARIABLE})
|
||||
public static final long UNION = 1L<<39;
|
||||
|
||||
/**
|
||||
* Flags an erroneous TypeSymbol as viable for recovery.
|
||||
* TypeSymbols only.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS, FlagTarget.TYPE_VAR})
|
||||
public static final long RECOVERABLE = 1L<<40;
|
||||
|
||||
/**
|
||||
* Flag that marks an 'effectively final' local variable.
|
||||
*/
|
||||
@Use({FlagTarget.VARIABLE})
|
||||
public static final long EFFECTIVELY_FINAL = 1L<<41;
|
||||
|
||||
/**
|
||||
* Flag that marks non-override equivalent methods with the same signature,
|
||||
* or a conflicting match binding (BindingSymbol).
|
||||
*/
|
||||
@Use({FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||
public static final long CLASH = 1L<<42;
|
||||
|
||||
/**
|
||||
* Flag that marks either a default method or an interface containing default methods.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD})
|
||||
public static final long DEFAULT = 1L<<43; // part of ExtendedStandardFlags, cannot be reused
|
||||
|
||||
/**
|
||||
* Flag that marks class as auxiliary, ie a non-public class following
|
||||
* the public class in a source file, that could block implicit compilation.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final long AUXILIARY = 1L<<44;
|
||||
|
||||
/**
|
||||
* Flag that marks that a symbol is not available in the current profile
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final long NOT_IN_PROFILE = 1L<<45;
|
||||
|
||||
/**
|
||||
* Flag that indicates that an override error has been detected by Check.
|
||||
*/
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final long BAD_OVERRIDE = 1L<<45;
|
||||
|
||||
/**
|
||||
* Flag that indicates a signature polymorphic method (292).
|
||||
*/
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final long SIGNATURE_POLYMORPHIC = 1L<<46;
|
||||
|
||||
/**
|
||||
* Flag that indicates that an inference variable is used in a 'throws' clause.
|
||||
*/
|
||||
@Use({FlagTarget.TYPE_VAR})
|
||||
public static final long THROWS = 1L<<47;
|
||||
|
||||
/**
|
||||
* Flag to indicate sealed class/interface declaration.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final long SEALED = 1L<<48; // part of ExtendedStandardFlags, cannot be reused
|
||||
|
||||
/**
|
||||
* Flag that marks a synthetic method body for a lambda expression
|
||||
*/
|
||||
public static final long LAMBDA_METHOD = 1L<<49; //MethodSymbols only
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final long LAMBDA_METHOD = 1L<<49;
|
||||
|
||||
/**
|
||||
* Flag that marks a synthetic local capture field in a local/anon class
|
||||
*/
|
||||
public static final long LOCAL_CAPTURE_FIELD = 1L<<49; //VarSymbols only
|
||||
@Use({FlagTarget.VARIABLE})
|
||||
public static final long LOCAL_CAPTURE_FIELD = 1L<<49;
|
||||
|
||||
/**
|
||||
* Flag to control recursion in TransTypes
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final long TYPE_TRANSLATED = 1L<<50;
|
||||
|
||||
/**
|
||||
* Flag to indicate class symbol is for module-info
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final long MODULE = 1L<<51;
|
||||
|
||||
/**
|
||||
* Flag to indicate the given ModuleSymbol is an automatic module.
|
||||
*/
|
||||
public static final long AUTOMATIC_MODULE = 1L<<52; //ModuleSymbols only
|
||||
@Use({FlagTarget.MODULE})
|
||||
public static final long AUTOMATIC_MODULE = 1L<<52;
|
||||
|
||||
/**
|
||||
* Flag to indicate the given PackageSymbol contains any non-.java and non-.class resources.
|
||||
*/
|
||||
public static final long HAS_RESOURCE = 1L<<52; //PackageSymbols only
|
||||
@Use({FlagTarget.PACKAGE})
|
||||
public static final long HAS_RESOURCE = 1L<<52;
|
||||
|
||||
/**
|
||||
* Flag to indicate the given ParamSymbol has a user-friendly name filled.
|
||||
*/
|
||||
public static final long NAME_FILLED = 1L<<52; //ParamSymbols only
|
||||
@Use({FlagTarget.VARIABLE}) //ParamSymbols only
|
||||
public static final long NAME_FILLED = 1L<<52;
|
||||
|
||||
/**
|
||||
* Flag to indicate the given ModuleSymbol is a system module.
|
||||
*/
|
||||
public static final long SYSTEM_MODULE = 1L<<53; //ModuleSymbols only
|
||||
@Use({FlagTarget.MODULE})
|
||||
public static final long SYSTEM_MODULE = 1L<<53;
|
||||
|
||||
/**
|
||||
* Flag to indicate the given ClassSymbol is a value based.
|
||||
*/
|
||||
public static final long VALUE_BASED = 1L<<53; //ClassSymbols only
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final long VALUE_BASED = 1L<<53;
|
||||
|
||||
/**
|
||||
* Flag to indicate the given symbol has a @Deprecated annotation.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.MODULE, FlagTarget.PACKAGE, FlagTarget.TYPE_VAR, FlagTarget.VARIABLE})
|
||||
public static final long DEPRECATED_ANNOTATION = 1L<<54;
|
||||
|
||||
/**
|
||||
* Flag to indicate the given symbol has been deprecated and marked for removal.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.MODULE, FlagTarget.PACKAGE, FlagTarget.TYPE_VAR, FlagTarget.VARIABLE})
|
||||
public static final long DEPRECATED_REMOVAL = 1L<<55;
|
||||
|
||||
/**
|
||||
* Flag to indicate the API element in question is for a preview API.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.MODULE, FlagTarget.PACKAGE, FlagTarget.TYPE_VAR, FlagTarget.VARIABLE})
|
||||
public static final long PREVIEW_API = 1L<<56; //any Symbol kind
|
||||
|
||||
/**
|
||||
* Flag for synthesized default constructors of anonymous classes that have an enclosing expression.
|
||||
*/
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final long ANONCONSTR_BASED = 1L<<57;
|
||||
|
||||
/**
|
||||
* Flag that marks finalize block as body-only, should not be copied into catch clauses.
|
||||
* Used to implement try-with-resources.
|
||||
*/
|
||||
public static final long BODY_ONLY_FINALIZE = 1L<<17; //blocks only
|
||||
@Use({FlagTarget.BLOCK})
|
||||
public static final long BODY_ONLY_FINALIZE = 1L<<17;
|
||||
|
||||
/**
|
||||
* Flag to indicate the API element in question is for a preview API.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.MODULE, FlagTarget.PACKAGE, FlagTarget.TYPE_VAR, FlagTarget.VARIABLE})
|
||||
public static final long PREVIEW_REFLECTIVE = 1L<<58; //any Symbol kind
|
||||
|
||||
/**
|
||||
* Flag to indicate the given variable is a match binding variable.
|
||||
*/
|
||||
@Use({FlagTarget.VARIABLE})
|
||||
public static final long MATCH_BINDING = 1L<<59;
|
||||
|
||||
/**
|
||||
* A flag to indicate a match binding variable whose scope extends after the current statement.
|
||||
*/
|
||||
@Use({FlagTarget.VARIABLE})
|
||||
public static final long MATCH_BINDING_TO_OUTER = 1L<<60;
|
||||
|
||||
/**
|
||||
* Flag to indicate that a class is a record. The flag is also used to mark fields that are
|
||||
* part of the state vector of a record and to mark the canonical constructor
|
||||
*/
|
||||
public static final long RECORD = 1L<<61; // ClassSymbols, MethodSymbols and VarSymbols
|
||||
@Use({FlagTarget.CLASS, FlagTarget.VARIABLE, FlagTarget.METHOD})
|
||||
public static final long RECORD = 1L<<61;
|
||||
|
||||
/**
|
||||
* Flag to mark a record constructor as a compact one
|
||||
*/
|
||||
public static final long COMPACT_RECORD_CONSTRUCTOR = 1L<<51; // MethodSymbols only
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final long COMPACT_RECORD_CONSTRUCTOR = 1L<<51;
|
||||
|
||||
/**
|
||||
* Flag to mark a record field that was not initialized in the compact constructor
|
||||
*/
|
||||
public static final long UNINITIALIZED_FIELD= 1L<<51; // VarSymbols only
|
||||
@Use({FlagTarget.VARIABLE})
|
||||
public static final long UNINITIALIZED_FIELD= 1L<<51;
|
||||
|
||||
/** Flag is set for compiler-generated record members, it could be applied to
|
||||
* accessors and fields
|
||||
*/
|
||||
public static final int GENERATED_MEMBER = 1<<24; // MethodSymbols and VarSymbols
|
||||
@Use({FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||
public static final int GENERATED_MEMBER = 1<<24;
|
||||
|
||||
/**
|
||||
* Flag to indicate restricted method declaration.
|
||||
*/
|
||||
public static final long RESTRICTED = 1L<<62; // MethodSymbols
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final long RESTRICTED = 1L<<62;
|
||||
|
||||
/**
|
||||
* Flag to indicate parameters that require identity.
|
||||
*/
|
||||
public static final long REQUIRES_IDENTITY = 1L<<62; // VarSymbols (parameters)
|
||||
@Use({FlagTarget.VARIABLE}) //ParamSymbols only
|
||||
public static final long REQUIRES_IDENTITY = 1L<<62;
|
||||
|
||||
/**
|
||||
* Flag to indicate type annotations have been queued for field initializers.
|
||||
*/
|
||||
public static final long FIELD_INIT_TYPE_ANNOTATIONS_QUEUED = 1L<<53; // VarSymbols
|
||||
@Use({FlagTarget.VARIABLE})
|
||||
public static final long FIELD_INIT_TYPE_ANNOTATIONS_QUEUED = 1L<<53;
|
||||
|
||||
/**
|
||||
* Flag to indicate that the class/interface was declared with the non-sealed modifier.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
@CustomToStringValue("non-sealed")
|
||||
public static final long NON_SEALED = 1L<<63; // part of ExtendedStandardFlags, cannot be reused
|
||||
|
||||
/**
|
||||
|
@ -422,6 +507,7 @@ public class Flags {
|
|||
|
||||
/** Modifier masks.
|
||||
*/
|
||||
@NotFlag
|
||||
public static final int
|
||||
AccessFlags = PUBLIC | PROTECTED | PRIVATE,
|
||||
LocalClassFlags = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC,
|
||||
|
@ -438,6 +524,7 @@ public class Flags {
|
|||
SYNCHRONIZED | FINAL | STRICTFP,
|
||||
RecordMethodFlags = AccessFlags | ABSTRACT | STATIC |
|
||||
SYNCHRONIZED | FINAL | STRICTFP;
|
||||
@NotFlag
|
||||
public static final long
|
||||
//NOTE: flags in ExtendedStandardFlags cannot be overlayed across Symbol kinds:
|
||||
ExtendedStandardFlags = (long)StandardFlags | DEFAULT | SEALED | NON_SEALED,
|
||||
|
@ -491,91 +578,45 @@ public class Flags {
|
|||
return symbol.getConstValue() != null;
|
||||
}
|
||||
|
||||
|
||||
public enum Flag {
|
||||
PUBLIC(Flags.PUBLIC),
|
||||
PRIVATE(Flags.PRIVATE),
|
||||
PROTECTED(Flags.PROTECTED),
|
||||
STATIC(Flags.STATIC),
|
||||
FINAL(Flags.FINAL),
|
||||
SYNCHRONIZED(Flags.SYNCHRONIZED),
|
||||
VOLATILE(Flags.VOLATILE),
|
||||
TRANSIENT(Flags.TRANSIENT),
|
||||
NATIVE(Flags.NATIVE),
|
||||
INTERFACE(Flags.INTERFACE),
|
||||
ABSTRACT(Flags.ABSTRACT),
|
||||
DEFAULT(Flags.DEFAULT),
|
||||
STRICTFP(Flags.STRICTFP),
|
||||
BRIDGE(Flags.BRIDGE),
|
||||
SYNTHETIC(Flags.SYNTHETIC),
|
||||
ANNOTATION(Flags.ANNOTATION),
|
||||
DEPRECATED(Flags.DEPRECATED),
|
||||
HASINIT(Flags.HASINIT),
|
||||
IMPLICIT_CLASS(Flags.IMPLICIT_CLASS),
|
||||
BLOCK(Flags.BLOCK),
|
||||
FROM_SOURCE(Flags.FROM_SOURCE),
|
||||
ENUM(Flags.ENUM),
|
||||
MANDATED(Flags.MANDATED),
|
||||
NOOUTERTHIS(Flags.NOOUTERTHIS),
|
||||
EXISTS(Flags.EXISTS),
|
||||
COMPOUND(Flags.COMPOUND),
|
||||
CLASS_SEEN(Flags.CLASS_SEEN),
|
||||
SOURCE_SEEN(Flags.SOURCE_SEEN),
|
||||
LOCKED(Flags.LOCKED),
|
||||
UNATTRIBUTED(Flags.UNATTRIBUTED),
|
||||
ANONCONSTR(Flags.ANONCONSTR),
|
||||
ACYCLIC(Flags.ACYCLIC),
|
||||
PARAMETER(Flags.PARAMETER),
|
||||
VARARGS(Flags.VARARGS),
|
||||
ACYCLIC_ANN(Flags.ACYCLIC_ANN),
|
||||
GENERATEDCONSTR(Flags.GENERATEDCONSTR),
|
||||
HYPOTHETICAL(Flags.HYPOTHETICAL),
|
||||
PROPRIETARY(Flags.PROPRIETARY),
|
||||
UNION(Flags.UNION),
|
||||
EFFECTIVELY_FINAL(Flags.EFFECTIVELY_FINAL),
|
||||
CLASH(Flags.CLASH),
|
||||
AUXILIARY(Flags.AUXILIARY),
|
||||
NOT_IN_PROFILE(Flags.NOT_IN_PROFILE),
|
||||
BAD_OVERRIDE(Flags.BAD_OVERRIDE),
|
||||
SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC),
|
||||
THROWS(Flags.THROWS),
|
||||
LAMBDA_METHOD(Flags.LAMBDA_METHOD),
|
||||
TYPE_TRANSLATED(Flags.TYPE_TRANSLATED),
|
||||
MODULE(Flags.MODULE),
|
||||
AUTOMATIC_MODULE(Flags.AUTOMATIC_MODULE),
|
||||
SYSTEM_MODULE(Flags.SYSTEM_MODULE),
|
||||
DEPRECATED_ANNOTATION(Flags.DEPRECATED_ANNOTATION),
|
||||
DEPRECATED_REMOVAL(Flags.DEPRECATED_REMOVAL),
|
||||
HAS_RESOURCE(Flags.HAS_RESOURCE),
|
||||
SEALED(Flags.SEALED),
|
||||
ANONCONSTR_BASED(Flags.ANONCONSTR_BASED),
|
||||
NAME_FILLED(Flags.NAME_FILLED),
|
||||
PREVIEW_API(Flags.PREVIEW_API),
|
||||
PREVIEW_REFLECTIVE(Flags.PREVIEW_REFLECTIVE),
|
||||
MATCH_BINDING(Flags.MATCH_BINDING),
|
||||
MATCH_BINDING_TO_OUTER(Flags.MATCH_BINDING_TO_OUTER),
|
||||
RECORD(Flags.RECORD),
|
||||
RECOVERABLE(Flags.RECOVERABLE),
|
||||
RESTRICTED(Flags.RESTRICTED),
|
||||
NON_SEALED(Flags.NON_SEALED) {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "non-sealed";
|
||||
}
|
||||
};
|
||||
|
||||
Flag(long flag) {
|
||||
this.value = flag;
|
||||
this.lowercaseName = StringUtils.toLowerCase(name());
|
||||
public enum FlagTarget {
|
||||
/** This flag can appear the JCBlock.
|
||||
*/
|
||||
BLOCK,
|
||||
/** This flag can appear on ClassSymbols.
|
||||
*/
|
||||
CLASS,
|
||||
/** This flag can appear on ModuleSymbols.
|
||||
*/
|
||||
MODULE,
|
||||
/** This flag can appear on PackageSymbols.
|
||||
*/
|
||||
PACKAGE,
|
||||
/** This flag can appear on TypeVarSymbols.
|
||||
*/
|
||||
TYPE_VAR,
|
||||
/** This flag can appear on MethodSymbols.
|
||||
*/
|
||||
METHOD,
|
||||
/** This flag can appear on VarSymbols, includes
|
||||
* including ParamSymbol, and BindingSymbol.
|
||||
*/
|
||||
VARIABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return lowercaseName;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Use {
|
||||
public FlagTarget[] value();
|
||||
}
|
||||
|
||||
final long value;
|
||||
final String lowercaseName;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface NotFlag {}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface CustomToStringValue {
|
||||
public String value();
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface NoToStringValue {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ import com.sun.tools.javac.code.Directive.RequiresDirective;
|
|||
import com.sun.tools.javac.code.Directive.RequiresFlag;
|
||||
import com.sun.tools.javac.code.Directive.UsesDirective;
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Flags.Flag;
|
||||
import com.sun.tools.javac.code.FlagsEnum;
|
||||
import com.sun.tools.javac.code.Kinds;
|
||||
import com.sun.tools.javac.code.Lint;
|
||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||
|
@ -825,7 +825,7 @@ public class Modules extends JCTree.Visitor {
|
|||
}
|
||||
if (tree.isStaticPhase) {
|
||||
if (msym == syms.java_base && source.compareTo(Source.JDK10) >= 0) {
|
||||
log.error(tree.pos(), Errors.ModNotAllowedHere(EnumSet.of(Flag.STATIC)));
|
||||
log.error(tree.pos(), Errors.ModNotAllowedHere(EnumSet.of(FlagsEnum.STATIC)));
|
||||
} else {
|
||||
flags.add(RequiresFlag.STATIC_PHASE);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import javax.tools.*;
|
|||
import com.sun.tools.javac.api.*;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
|
||||
import com.sun.tools.javac.api.Formattable.LocalizedString;
|
||||
import com.sun.tools.javac.code.Flags.Flag;
|
||||
import com.sun.tools.javac.code.FlagsEnum;
|
||||
import com.sun.tools.javac.code.Kinds.KindName;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.file.*;
|
||||
|
@ -303,7 +303,7 @@ class ArgTypeCompilerFactory implements Example.Compiler.Factory {
|
|||
return "number";
|
||||
if (o instanceof String)
|
||||
return "string";
|
||||
if (o instanceof Flag)
|
||||
if (o instanceof FlagsEnum)
|
||||
return "modifier";
|
||||
if (o instanceof KindName)
|
||||
return "symbol kind";
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Google LLC. All rights reserved.
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -23,28 +24,84 @@
|
|||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8211138
|
||||
* @bug 8211138 8362885
|
||||
* @summary Missing Flag enum constants
|
||||
* @library /tools/javac/lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.code
|
||||
* @run main FlagsTest
|
||||
* @compile FlagsTest.java
|
||||
* @run main/manual FlagsTest
|
||||
*/
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Flags.FlagTarget;
|
||||
import com.sun.tools.javac.code.Flags.NotFlag;
|
||||
import com.sun.tools.javac.code.Flags.Use;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class FlagsTest {
|
||||
public static void main(String[] args) throws IllegalAccessException {
|
||||
|
||||
private static final int U2_SIZE = 16;
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
findFreeFlags();
|
||||
}
|
||||
|
||||
private static void findFreeFlags() throws Throwable {
|
||||
Map<FlagTarget, Map<Long, List<Field>>> target2Flag2Fields = computeTarget2Flag2Fields();
|
||||
|
||||
for (FlagTarget target : FlagTarget.values()) {
|
||||
long freeFlags = ~collectFlags(target2Flag2Fields, target);
|
||||
|
||||
printFreeFlags(target.name(), freeFlags);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<FlagTarget, Map<Long, List<Field>>> computeTarget2Flag2Fields() throws Throwable {
|
||||
Map<FlagTarget, Map<Long, List<Field>>> target2Flag2Fields = new HashMap<>();
|
||||
for (Field f : Flags.class.getFields()) {
|
||||
if (!Modifier.isStatic(f.getModifiers())) {
|
||||
if (f.isAnnotationPresent(NotFlag.class)) {
|
||||
continue;
|
||||
}
|
||||
long flag = ((Number) f.get(null)).longValue();
|
||||
try {
|
||||
Flags.asFlagSet(flag);
|
||||
} catch (AssertionError e) {
|
||||
throw new AssertionError("missing Flags enum constant for: " + f.getName(), e);
|
||||
|
||||
Use use = f.getAnnotation(Use.class);
|
||||
|
||||
if (use == null) {
|
||||
throw new AssertionError("No @Use and no @NotFlag for: " + f.getName());
|
||||
}
|
||||
|
||||
long flagValue = ((Number) f.get(null)).longValue();
|
||||
|
||||
for (FlagTarget target : use.value()) {
|
||||
target2Flag2Fields.computeIfAbsent(target, _ -> new HashMap<>())
|
||||
.computeIfAbsent(flagValue, _ -> new ArrayList<>())
|
||||
.add(f);
|
||||
}
|
||||
}
|
||||
return target2Flag2Fields;
|
||||
}
|
||||
|
||||
private static void printFreeFlags(String comment, long freeFlags) {
|
||||
System.err.print("free flags for " + comment + ": ");
|
||||
for (int bit = U2_SIZE; bit < Long.SIZE; bit++) { //lowest 16 bits are used in classfiles, never suggest adding anything there
|
||||
if ((freeFlags & (1L << bit)) != 0) {
|
||||
System.err.print("1L<<" + bit + " ");
|
||||
}
|
||||
}
|
||||
System.err.println();
|
||||
}
|
||||
|
||||
private static long collectFlags(Map<FlagTarget, Map<Long, List<Field>>> target2Flag2Fields, FlagTarget... forTargets) {
|
||||
long flags = 0;
|
||||
|
||||
for (FlagTarget target : forTargets) {
|
||||
for (long used : target2Flag2Fields.get(target).keySet()) {
|
||||
flags |= used;
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue