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, \
|
COMPILER := bootjdk, \
|
||||||
TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \
|
TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \
|
||||||
SRC := $(TOPDIR)/make/langtools/tools, \
|
SRC := $(TOPDIR)/make/langtools/tools, \
|
||||||
INCLUDES := compileproperties propertiesparser, \
|
INCLUDES := compileproperties flagsgenerator propertiesparser, \
|
||||||
COPY := .properties, \
|
COPY := .properties, \
|
||||||
BIN := $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes, \
|
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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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"),
|
ANNOTATION("annotation", "Compound", "com.sun.tools.javac.code.Attribute"),
|
||||||
BOOLEAN("boolean", "boolean", null),
|
BOOLEAN("boolean", "boolean", null),
|
||||||
COLLECTION("collection", "Collection", "java.util"),
|
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),
|
FRAGMENT("fragment", "Fragment", null),
|
||||||
DIAGNOSTIC("diagnostic", "JCDiagnostic", "com.sun.tools.javac.util"),
|
DIAGNOSTIC("diagnostic", "JCDiagnostic", "com.sun.tools.javac.util"),
|
||||||
MODIFIER("modifier", "Modifier", "javax.lang.model.element"),
|
MODIFIER("modifier", "Modifier", "javax.lang.model.element"),
|
||||||
|
|
|
@ -41,17 +41,17 @@ $(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
|
||||||
|
|
||||||
TARGETS += $(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
|
# 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
|
# is included, the following trick is used to be able to declare a dependency on
|
||||||
# the built tools.
|
# the built tools.
|
||||||
BUILD_TOOLS_LANGTOOLS := $(call SetupJavaCompilationCompileTarget, \
|
BUILD_TOOLS_LANGTOOLS := $(call SetupJavaCompilationCompileTarget, \
|
||||||
BUILD_TOOLS_LANGTOOLS, $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes)
|
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 \
|
TOOL_PARSEPROPERTIES_CMD := $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes \
|
||||||
propertiesparser.PropertiesParser
|
propertiesparser.PropertiesParser
|
||||||
|
|
||||||
|
@ -76,3 +76,26 @@ $(eval $(call SetupExecute, PARSEPROPERTIES, \
|
||||||
TARGETS += $(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;
|
package com.sun.tools.javac.code;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -35,7 +37,6 @@ import java.util.stream.Collectors;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
import com.sun.tools.javac.util.Assert;
|
import com.sun.tools.javac.util.Assert;
|
||||||
import com.sun.tools.javac.util.StringUtils;
|
|
||||||
|
|
||||||
/** Access flags and other modifiers for Java classes and members.
|
/** Access flags and other modifiers for Java classes and members.
|
||||||
*
|
*
|
||||||
|
@ -51,7 +52,7 @@ public class Flags {
|
||||||
public static String toString(long flags) {
|
public static String toString(long flags) {
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
String sep = "";
|
String sep = "";
|
||||||
for (Flag flag : asFlagSet(flags)) {
|
for (FlagsEnum flag : asFlagSet(flags)) {
|
||||||
buf.append(sep);
|
buf.append(sep);
|
||||||
buf.append(flag);
|
buf.append(flag);
|
||||||
sep = " ";
|
sep = " ";
|
||||||
|
@ -59,12 +60,12 @@ public class Flags {
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EnumSet<Flag> asFlagSet(long flags) {
|
public static EnumSet<FlagsEnum> asFlagSet(long flags) {
|
||||||
EnumSet<Flag> flagSet = EnumSet.noneOf(Flag.class);
|
EnumSet<FlagsEnum> flagSet = EnumSet.noneOf(FlagsEnum.class);
|
||||||
for (Flag flag : Flag.values()) {
|
for (FlagsEnum flag : FlagsEnum.values()) {
|
||||||
if ((flags & flag.value) != 0) {
|
if ((flags & flag.value()) != 0) {
|
||||||
flagSet.add(flag);
|
flagSet.add(flag);
|
||||||
flags &= ~flag.value;
|
flags &= ~flag.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Assert.check(flags == 0);
|
Assert.check(flags == 0);
|
||||||
|
@ -73,42 +74,67 @@ public class Flags {
|
||||||
|
|
||||||
/* Standard Java flags.
|
/* Standard Java flags.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||||
public static final int PUBLIC = 1;
|
public static final int PUBLIC = 1;
|
||||||
|
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||||
public static final int PRIVATE = 1<<1;
|
public static final int PRIVATE = 1<<1;
|
||||||
|
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||||
public static final int PROTECTED = 1<<2;
|
public static final int PROTECTED = 1<<2;
|
||||||
|
@Use({FlagTarget.BLOCK, FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||||
public static final int STATIC = 1<<3;
|
public static final int STATIC = 1<<3;
|
||||||
|
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||||
public static final int FINAL = 1<<4;
|
public static final int FINAL = 1<<4;
|
||||||
|
@Use({FlagTarget.METHOD})
|
||||||
public static final int SYNCHRONIZED = 1<<5;
|
public static final int SYNCHRONIZED = 1<<5;
|
||||||
|
@Use({FlagTarget.VARIABLE})
|
||||||
public static final int VOLATILE = 1<<6;
|
public static final int VOLATILE = 1<<6;
|
||||||
|
@Use({FlagTarget.VARIABLE})
|
||||||
public static final int TRANSIENT = 1<<7;
|
public static final int TRANSIENT = 1<<7;
|
||||||
|
@Use({FlagTarget.METHOD})
|
||||||
public static final int NATIVE = 1<<8;
|
public static final int NATIVE = 1<<8;
|
||||||
|
@Use({FlagTarget.CLASS})
|
||||||
public static final int INTERFACE = 1<<9;
|
public static final int INTERFACE = 1<<9;
|
||||||
|
@Use({FlagTarget.CLASS, FlagTarget.METHOD})
|
||||||
public static final int ABSTRACT = 1<<10;
|
public static final int ABSTRACT = 1<<10;
|
||||||
|
@Use({FlagTarget.CLASS, FlagTarget.METHOD})
|
||||||
public static final int STRICTFP = 1<<11;
|
public static final int STRICTFP = 1<<11;
|
||||||
|
|
||||||
/* Flag that marks a symbol synthetic, added in classfile v49.0. */
|
/* 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;
|
public static final int SYNTHETIC = 1<<12;
|
||||||
|
|
||||||
/** Flag that marks attribute interfaces, added in classfile v49.0. */
|
/** Flag that marks attribute interfaces, added in classfile v49.0. */
|
||||||
|
@Use({FlagTarget.CLASS})
|
||||||
public static final int ANNOTATION = 1<<13;
|
public static final int ANNOTATION = 1<<13;
|
||||||
|
|
||||||
/** An enumeration type or an enumeration constant, added in
|
/** An enumeration type or an enumeration constant, added in
|
||||||
* classfile v49.0. */
|
* classfile v49.0. */
|
||||||
|
@Use({FlagTarget.CLASS, FlagTarget.VARIABLE})
|
||||||
public static final int ENUM = 1<<14;
|
public static final int ENUM = 1<<14;
|
||||||
|
|
||||||
/** Added in SE8, represents constructs implicitly declared in source. */
|
/** Added in SE8, represents constructs implicitly declared in source. */
|
||||||
|
@Use({FlagTarget.MODULE, FlagTarget.VARIABLE})
|
||||||
public static final int MANDATED = 1<<15;
|
public static final int MANDATED = 1<<15;
|
||||||
|
|
||||||
|
@NotFlag
|
||||||
public static final int StandardFlags = 0x0fff;
|
public static final int StandardFlags = 0x0fff;
|
||||||
|
|
||||||
// Because the following access flags are overloaded with other
|
// Because the following access flags are overloaded with other
|
||||||
// bit positions, we translate them when reading and writing class
|
// bit positions, we translate them when reading and writing class
|
||||||
// files into unique bits positions: ACC_SYNTHETIC <-> SYNTHETIC,
|
// files into unique bits positions: ACC_SYNTHETIC <-> SYNTHETIC,
|
||||||
// for example.
|
// for example.
|
||||||
public static final int ACC_SUPER = 0x0020;
|
@Use({FlagTarget.CLASS})
|
||||||
public static final int ACC_BRIDGE = 0x0040;
|
@NoToStringValue
|
||||||
public static final int ACC_VARARGS = 0x0080;
|
public static final int ACC_SUPER = 1<<5;
|
||||||
public static final int ACC_MODULE = 0x8000;
|
@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).
|
* 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.
|
/** 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;
|
public static final int DEPRECATED = 1<<17;
|
||||||
|
|
||||||
/** Flag is set for a variable symbol if the variable's definition
|
/** Flag is set for a variable symbol if the variable's definition
|
||||||
* has an initializer part.
|
* has an initializer part.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.VARIABLE})
|
||||||
public static final int HASINIT = 1<<18;
|
public static final int HASINIT = 1<<18;
|
||||||
|
|
||||||
/** Class is an implicitly declared top level class.
|
/** Class is an implicitly declared top level class.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS})
|
||||||
public static final int IMPLICIT_CLASS = 1<<19;
|
public static final int IMPLICIT_CLASS = 1<<19;
|
||||||
|
|
||||||
/** Flag is set for compiler-generated anonymous method symbols
|
/** Flag is set for compiler-generated anonymous method symbols
|
||||||
* that `own' an initializer block.
|
* that `own' an initializer block.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.METHOD})
|
||||||
public static final int BLOCK = 1<<20;
|
public static final int BLOCK = 1<<20;
|
||||||
|
|
||||||
/** Flag is set for ClassSymbols that are being compiled from source.
|
/** 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
|
/** 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
|
* 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
|
* todo: use this value for optimizing away this$n parameters in
|
||||||
* other cases.
|
* other cases.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS, FlagTarget.VARIABLE})
|
||||||
public static final int NOOUTERTHIS = 1<<22;
|
public static final int NOOUTERTHIS = 1<<22;
|
||||||
|
|
||||||
/** Flag is set for package symbols if a package has a member or
|
/** Flag is set for package symbols if a package has a member or
|
||||||
* directory and therefore exists.
|
* directory and therefore exists.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS, FlagTarget.PACKAGE})
|
||||||
public static final int EXISTS = 1<<23;
|
public static final int EXISTS = 1<<23;
|
||||||
|
|
||||||
/** Flag is set for compiler-generated compound classes
|
/** Flag is set for compiler-generated compound classes
|
||||||
* representing multiple variable bounds
|
* representing multiple variable bounds
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS})
|
||||||
public static final int COMPOUND = 1<<24;
|
public static final int COMPOUND = 1<<24;
|
||||||
|
|
||||||
/** Flag is set for class symbols if a class file was found for this class.
|
/** 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;
|
public static final int CLASS_SEEN = 1<<25;
|
||||||
|
|
||||||
/** Flag is set for class symbols if a source file was found for this
|
/** Flag is set for class symbols if a source file was found for this
|
||||||
* class.
|
* class.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS})
|
||||||
public static final int SOURCE_SEEN = 1<<26;
|
public static final int SOURCE_SEEN = 1<<26;
|
||||||
|
|
||||||
/* State flags (are reset during compilation).
|
/* State flags (are reset during compilation).
|
||||||
|
@ -172,242 +208,291 @@ public class Flags {
|
||||||
* relations. Similarly for constructor call cycle detection in
|
* relations. Similarly for constructor call cycle detection in
|
||||||
* Attr.
|
* Attr.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS, FlagTarget.METHOD})
|
||||||
public static final int LOCKED = 1<<27;
|
public static final int LOCKED = 1<<27;
|
||||||
|
|
||||||
/** Flag for class symbols is set and later re-set to indicate that a class
|
/** Flag for class symbols is set and later re-set to indicate that a class
|
||||||
* has been entered but has not yet been attributed.
|
* has been entered but has not yet been attributed.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS})
|
||||||
public static final int UNATTRIBUTED = 1<<28;
|
public static final int UNATTRIBUTED = 1<<28;
|
||||||
|
|
||||||
/** Flag for synthesized default constructors of anonymous classes.
|
/** 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.
|
* 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
|
/** Flag for class symbols to indicate it has been checked and found
|
||||||
* acyclic.
|
* acyclic.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS, FlagTarget.METHOD, FlagTarget.TYPE_VAR})
|
||||||
public static final int ACYCLIC = 1<<30;
|
public static final int ACYCLIC = 1<<30;
|
||||||
|
|
||||||
/** Flag that marks bridge methods.
|
/** Flag that marks bridge methods.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.METHOD})
|
||||||
public static final long BRIDGE = 1L<<31;
|
public static final long BRIDGE = 1L<<31;
|
||||||
|
|
||||||
/** Flag that marks formal parameters.
|
/** Flag that marks formal parameters.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.VARIABLE})
|
||||||
public static final long PARAMETER = 1L<<33;
|
public static final long PARAMETER = 1L<<33;
|
||||||
|
|
||||||
/** Flag that marks varargs methods.
|
/** Flag that marks varargs methods.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||||
public static final long VARARGS = 1L<<34;
|
public static final long VARARGS = 1L<<34;
|
||||||
|
|
||||||
/** Flag for annotation type symbols to indicate it has been
|
/** Flag for annotation type symbols to indicate it has been
|
||||||
* checked and found acyclic.
|
* checked and found acyclic.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS})
|
||||||
public static final long ACYCLIC_ANN = 1L<<35;
|
public static final long ACYCLIC_ANN = 1L<<35;
|
||||||
|
|
||||||
/** Flag that marks a generated default constructor.
|
/** Flag that marks a generated default constructor.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.METHOD})
|
||||||
public static final long GENERATEDCONSTR = 1L<<36;
|
public static final long GENERATEDCONSTR = 1L<<36;
|
||||||
|
|
||||||
/** Flag that marks a hypothetical method that need not really be
|
/** Flag that marks a hypothetical method that need not really be
|
||||||
* generated in the binary, but is present in the symbol table to
|
* generated in the binary, but is present in the symbol table to
|
||||||
* simplify checking for erasure clashes - also used for 292 poly sig methods.
|
* simplify checking for erasure clashes - also used for 292 poly sig methods.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.METHOD})
|
||||||
public static final long HYPOTHETICAL = 1L<<37;
|
public static final long HYPOTHETICAL = 1L<<37;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that marks an internal proprietary class.
|
* Flag that marks an internal proprietary class.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS})
|
||||||
public static final long PROPRIETARY = 1L<<38;
|
public static final long PROPRIETARY = 1L<<38;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that marks a multi-catch parameter.
|
* Flag that marks a multi-catch parameter.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.VARIABLE})
|
||||||
public static final long UNION = 1L<<39;
|
public static final long UNION = 1L<<39;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flags an erroneous TypeSymbol as viable for recovery.
|
* Flags an erroneous TypeSymbol as viable for recovery.
|
||||||
* TypeSymbols only.
|
* TypeSymbols only.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS, FlagTarget.TYPE_VAR})
|
||||||
public static final long RECOVERABLE = 1L<<40;
|
public static final long RECOVERABLE = 1L<<40;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that marks an 'effectively final' local variable.
|
* Flag that marks an 'effectively final' local variable.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.VARIABLE})
|
||||||
public static final long EFFECTIVELY_FINAL = 1L<<41;
|
public static final long EFFECTIVELY_FINAL = 1L<<41;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that marks non-override equivalent methods with the same signature,
|
* Flag that marks non-override equivalent methods with the same signature,
|
||||||
* or a conflicting match binding (BindingSymbol).
|
* or a conflicting match binding (BindingSymbol).
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.METHOD, FlagTarget.VARIABLE})
|
||||||
public static final long CLASH = 1L<<42;
|
public static final long CLASH = 1L<<42;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that marks either a default method or an interface containing default methods.
|
* 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
|
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
|
* Flag that marks class as auxiliary, ie a non-public class following
|
||||||
* the public class in a source file, that could block implicit compilation.
|
* the public class in a source file, that could block implicit compilation.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS})
|
||||||
public static final long AUXILIARY = 1L<<44;
|
public static final long AUXILIARY = 1L<<44;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that marks that a symbol is not available in the current profile
|
* 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;
|
public static final long NOT_IN_PROFILE = 1L<<45;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that indicates that an override error has been detected by Check.
|
* Flag that indicates that an override error has been detected by Check.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.METHOD})
|
||||||
public static final long BAD_OVERRIDE = 1L<<45;
|
public static final long BAD_OVERRIDE = 1L<<45;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that indicates a signature polymorphic method (292).
|
* Flag that indicates a signature polymorphic method (292).
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.METHOD})
|
||||||
public static final long SIGNATURE_POLYMORPHIC = 1L<<46;
|
public static final long SIGNATURE_POLYMORPHIC = 1L<<46;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that indicates that an inference variable is used in a 'throws' clause.
|
* Flag that indicates that an inference variable is used in a 'throws' clause.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.TYPE_VAR})
|
||||||
public static final long THROWS = 1L<<47;
|
public static final long THROWS = 1L<<47;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to indicate sealed class/interface declaration.
|
* Flag to indicate sealed class/interface declaration.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS})
|
||||||
public static final long SEALED = 1L<<48; // part of ExtendedStandardFlags, cannot be reused
|
public static final long SEALED = 1L<<48; // part of ExtendedStandardFlags, cannot be reused
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that marks a synthetic method body for a lambda expression
|
* 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
|
* 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
|
* Flag to control recursion in TransTypes
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS})
|
||||||
public static final long TYPE_TRANSLATED = 1L<<50;
|
public static final long TYPE_TRANSLATED = 1L<<50;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to indicate class symbol is for module-info
|
* Flag to indicate class symbol is for module-info
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.CLASS})
|
||||||
public static final long MODULE = 1L<<51;
|
public static final long MODULE = 1L<<51;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to indicate the given ModuleSymbol is an automatic module.
|
* 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.
|
* 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.
|
* 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.
|
* 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.
|
* 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.
|
* 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;
|
public static final long DEPRECATED_ANNOTATION = 1L<<54;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to indicate the given symbol has been deprecated and marked for removal.
|
* 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;
|
public static final long DEPRECATED_REMOVAL = 1L<<55;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to indicate the API element in question is for a preview API.
|
* 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
|
public static final long PREVIEW_API = 1L<<56; //any Symbol kind
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag for synthesized default constructors of anonymous classes that have an enclosing expression.
|
* Flag for synthesized default constructors of anonymous classes that have an enclosing expression.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.METHOD})
|
||||||
public static final long ANONCONSTR_BASED = 1L<<57;
|
public static final long ANONCONSTR_BASED = 1L<<57;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that marks finalize block as body-only, should not be copied into catch clauses.
|
* Flag that marks finalize block as body-only, should not be copied into catch clauses.
|
||||||
* Used to implement try-with-resources.
|
* 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.
|
* 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
|
public static final long PREVIEW_REFLECTIVE = 1L<<58; //any Symbol kind
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to indicate the given variable is a match binding variable.
|
* Flag to indicate the given variable is a match binding variable.
|
||||||
*/
|
*/
|
||||||
|
@Use({FlagTarget.VARIABLE})
|
||||||
public static final long MATCH_BINDING = 1L<<59;
|
public static final long MATCH_BINDING = 1L<<59;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A flag to indicate a match binding variable whose scope extends after the current statement.
|
* 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;
|
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
|
* 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
|
* 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
|
* 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
|
* 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
|
/** Flag is set for compiler-generated record members, it could be applied to
|
||||||
* accessors and fields
|
* 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.
|
* 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.
|
* 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.
|
* 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.
|
* 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
|
public static final long NON_SEALED = 1L<<63; // part of ExtendedStandardFlags, cannot be reused
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -422,6 +507,7 @@ public class Flags {
|
||||||
|
|
||||||
/** Modifier masks.
|
/** Modifier masks.
|
||||||
*/
|
*/
|
||||||
|
@NotFlag
|
||||||
public static final int
|
public static final int
|
||||||
AccessFlags = PUBLIC | PROTECTED | PRIVATE,
|
AccessFlags = PUBLIC | PROTECTED | PRIVATE,
|
||||||
LocalClassFlags = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC,
|
LocalClassFlags = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC,
|
||||||
|
@ -438,6 +524,7 @@ public class Flags {
|
||||||
SYNCHRONIZED | FINAL | STRICTFP,
|
SYNCHRONIZED | FINAL | STRICTFP,
|
||||||
RecordMethodFlags = AccessFlags | ABSTRACT | STATIC |
|
RecordMethodFlags = AccessFlags | ABSTRACT | STATIC |
|
||||||
SYNCHRONIZED | FINAL | STRICTFP;
|
SYNCHRONIZED | FINAL | STRICTFP;
|
||||||
|
@NotFlag
|
||||||
public static final long
|
public static final long
|
||||||
//NOTE: flags in ExtendedStandardFlags cannot be overlayed across Symbol kinds:
|
//NOTE: flags in ExtendedStandardFlags cannot be overlayed across Symbol kinds:
|
||||||
ExtendedStandardFlags = (long)StandardFlags | DEFAULT | SEALED | NON_SEALED,
|
ExtendedStandardFlags = (long)StandardFlags | DEFAULT | SEALED | NON_SEALED,
|
||||||
|
@ -491,91 +578,45 @@ public class Flags {
|
||||||
return symbol.getConstValue() != null;
|
return symbol.getConstValue() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum FlagTarget {
|
||||||
public enum Flag {
|
/** This flag can appear the JCBlock.
|
||||||
PUBLIC(Flags.PUBLIC),
|
*/
|
||||||
PRIVATE(Flags.PRIVATE),
|
BLOCK,
|
||||||
PROTECTED(Flags.PROTECTED),
|
/** This flag can appear on ClassSymbols.
|
||||||
STATIC(Flags.STATIC),
|
*/
|
||||||
FINAL(Flags.FINAL),
|
CLASS,
|
||||||
SYNCHRONIZED(Flags.SYNCHRONIZED),
|
/** This flag can appear on ModuleSymbols.
|
||||||
VOLATILE(Flags.VOLATILE),
|
*/
|
||||||
TRANSIENT(Flags.TRANSIENT),
|
MODULE,
|
||||||
NATIVE(Flags.NATIVE),
|
/** This flag can appear on PackageSymbols.
|
||||||
INTERFACE(Flags.INTERFACE),
|
*/
|
||||||
ABSTRACT(Flags.ABSTRACT),
|
PACKAGE,
|
||||||
DEFAULT(Flags.DEFAULT),
|
/** This flag can appear on TypeVarSymbols.
|
||||||
STRICTFP(Flags.STRICTFP),
|
*/
|
||||||
BRIDGE(Flags.BRIDGE),
|
TYPE_VAR,
|
||||||
SYNTHETIC(Flags.SYNTHETIC),
|
/** This flag can appear on MethodSymbols.
|
||||||
ANNOTATION(Flags.ANNOTATION),
|
*/
|
||||||
DEPRECATED(Flags.DEPRECATED),
|
METHOD,
|
||||||
HASINIT(Flags.HASINIT),
|
/** This flag can appear on VarSymbols, includes
|
||||||
IMPLICIT_CLASS(Flags.IMPLICIT_CLASS),
|
* including ParamSymbol, and BindingSymbol.
|
||||||
BLOCK(Flags.BLOCK),
|
*/
|
||||||
FROM_SOURCE(Flags.FROM_SOURCE),
|
VARIABLE;
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return lowercaseName;
|
|
||||||
}
|
|
||||||
|
|
||||||
final long value;
|
|
||||||
final String lowercaseName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Use {
|
||||||
|
public FlagTarget[] value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@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.RequiresFlag;
|
||||||
import com.sun.tools.javac.code.Directive.UsesDirective;
|
import com.sun.tools.javac.code.Directive.UsesDirective;
|
||||||
import com.sun.tools.javac.code.Flags;
|
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.Kinds;
|
||||||
import com.sun.tools.javac.code.Lint;
|
import com.sun.tools.javac.code.Lint;
|
||||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||||
|
@ -825,7 +825,7 @@ public class Modules extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
if (tree.isStaticPhase) {
|
if (tree.isStaticPhase) {
|
||||||
if (msym == syms.java_base && source.compareTo(Source.JDK10) >= 0) {
|
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 {
|
} else {
|
||||||
flags.add(RequiresFlag.STATIC_PHASE);
|
flags.add(RequiresFlag.STATIC_PHASE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import javax.tools.*;
|
||||||
import com.sun.tools.javac.api.*;
|
import com.sun.tools.javac.api.*;
|
||||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
|
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
|
||||||
import com.sun.tools.javac.api.Formattable.LocalizedString;
|
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.Kinds.KindName;
|
||||||
import com.sun.tools.javac.code.*;
|
import com.sun.tools.javac.code.*;
|
||||||
import com.sun.tools.javac.file.*;
|
import com.sun.tools.javac.file.*;
|
||||||
|
@ -303,7 +303,7 @@ class ArgTypeCompilerFactory implements Example.Compiler.Factory {
|
||||||
return "number";
|
return "number";
|
||||||
if (o instanceof String)
|
if (o instanceof String)
|
||||||
return "string";
|
return "string";
|
||||||
if (o instanceof Flag)
|
if (o instanceof FlagsEnum)
|
||||||
return "modifier";
|
return "modifier";
|
||||||
if (o instanceof KindName)
|
if (o instanceof KindName)
|
||||||
return "symbol kind";
|
return "symbol kind";
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Google LLC. All rights reserved.
|
* 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -23,28 +24,84 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @bug 8211138
|
* @bug 8211138 8362885
|
||||||
* @summary Missing Flag enum constants
|
* @summary Missing Flag enum constants
|
||||||
* @library /tools/javac/lib
|
* @library /tools/javac/lib
|
||||||
* @modules jdk.compiler/com.sun.tools.javac.code
|
* @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;
|
||||||
|
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.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 class FlagsTest {
|
||||||
public static void main(String[] args) throws IllegalAccessException {
|
|
||||||
for (Field f : Flags.class.getFields()) {
|
private static final int U2_SIZE = 16;
|
||||||
if (!Modifier.isStatic(f.getModifiers())) {
|
|
||||||
continue;
|
public static void main(String[] args) throws Throwable {
|
||||||
}
|
findFreeFlags();
|
||||||
long flag = ((Number) f.get(null)).longValue();
|
}
|
||||||
try {
|
|
||||||
Flags.asFlagSet(flag);
|
private static void findFreeFlags() throws Throwable {
|
||||||
} catch (AssertionError e) {
|
Map<FlagTarget, Map<Long, List<Field>>> target2Flag2Fields = computeTarget2Flag2Fields();
|
||||||
throw new AssertionError("missing Flags enum constant for: " + f.getName(), e);
|
|
||||||
}
|
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 (f.isAnnotationPresent(NotFlag.class)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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