8344841: ClassPrinter prints confusing value for null

Reviewed-by: liach
This commit is contained in:
Adam Sotona 2024-11-25 13:45:34 +00:00
parent ddc8a9d5da
commit c6b14c62f6
2 changed files with 29 additions and 12 deletions

View File

@ -53,6 +53,7 @@ import static java.lang.classfile.constantpool.PoolEntry.TAG_FLOAT;
import static java.lang.classfile.constantpool.PoolEntry.TAG_LONG;
import static java.lang.classfile.constantpool.PoolEntry.TAG_STRING;
import static java.lang.classfile.constantpool.PoolEntry.*;
import static java.lang.constant.ConstantDescs.BSM_NULL_CONSTANT;
import static java.util.Objects.requireNonNull;
import static jdk.internal.classfile.impl.ClassPrinterImpl.Style.BLOCK;
import static jdk.internal.classfile.impl.ClassPrinterImpl.Style.FLOW;
@ -274,7 +275,12 @@ public final class ClassPrinterImpl {
private static void toYaml(int indent, boolean skipFirstIndent, Node node, Consumer<String> out) {
switch (node) {
case LeafNode leaf -> {
out.accept(quoteAndEscapeYaml(leaf.value()));
var v = leaf.value();
if (BSM_NULL_CONSTANT.equals(v)) {
out.accept("null");
} else {
out.accept(quoteAndEscapeYaml(v));
}
}
case ListNodeImpl list -> {
switch (list.style()) {
@ -329,6 +335,7 @@ public final class ClassPrinterImpl {
String s = String.valueOf(value);
if (value instanceof Number) return s;
if (s.length() == 0) return "''";
if (s.equalsIgnoreCase("null")) return "'" + s + "'";
var sb = new StringBuilder(s.length() << 1);
s.chars().forEach(c -> {
switch (c) {
@ -358,7 +365,12 @@ public final class ClassPrinterImpl {
private static void toJson(int indent, boolean skipFirstIndent, Node node, Consumer<String> out) {
switch (node) {
case LeafNode leaf -> {
out.accept(quoteAndEscapeJson(leaf.value()));
var v = leaf.value();
if (BSM_NULL_CONSTANT.equals(v)) {
out.accept("null");
} else {
out.accept(quoteAndEscapeJson(v));
}
}
case ListNodeImpl list -> {
out.accept("[");
@ -434,7 +446,12 @@ public final class ClassPrinterImpl {
switch (node) {
case LeafNode leaf -> {
out.accept("<" + name + ">");
out.accept(xmlEscape(leaf.value()));
var v = leaf.value();
if (BSM_NULL_CONSTANT.equals(v)) {
out.accept("<null/>");
} else {
out.accept(xmlEscape(v));
}
}
case ListNodeImpl list -> {
switch (list.style()) {
@ -542,7 +559,7 @@ public final class ClassPrinterImpl {
ret.accept("long");
ret.accept("long2");
}
case NULL -> ret.accept("null");
case NULL -> ret.accept(BSM_NULL_CONSTANT);
case TOP -> ret.accept("?");
case UNINITIALIZED_THIS -> ret.accept("THIS");
}
@ -929,9 +946,9 @@ public final class ClassPrinterImpl {
nodes.add(map("enclosing method",
"class", ema.enclosingClass().name().stringValue(),
"method name", ema.enclosingMethodName()
.map(Utf8Entry::stringValue).orElse("null"),
.<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT),
"method type", ema.enclosingMethodType()
.map(Utf8Entry::stringValue).orElse("null")));
.<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT)));
case ExceptionsAttribute exa ->
nodes.add(list("exceptions", "exc", exa.exceptions().stream()
.map(e -> e.name().stringValue())));
@ -940,15 +957,15 @@ public final class ClassPrinterImpl {
.map(ic -> new MapNodeImpl(FLOW, "cls").with(
leaf("inner class", ic.innerClass().name().stringValue()),
leaf("outer class", ic.outerClass()
.map(cle -> cle.name().stringValue()).orElse("null")),
leaf("inner name", ic.innerName().map(Utf8Entry::stringValue).orElse("null")),
.map(cle -> (ConstantDesc)cle.name().stringValue()).orElse(BSM_NULL_CONSTANT)),
leaf("inner name", ic.innerName().<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT)),
list("flags", "flag", ic.flags().stream().map(AccessFlag::name))))));
case MethodParametersAttribute mpa -> {
var n = new MapNodeImpl(BLOCK, "method parameters");
for (int i = 0; i < mpa.parameters().size(); i++) {
var p = mpa.parameters().get(i);
n.with(new MapNodeImpl(FLOW, i + 1).with(
leaf("name", p.name().map(Utf8Entry::stringValue).orElse("null")),
leaf("name", p.name().<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT)),
list("flags", "flag", p.flags().stream().map(AccessFlag::name))));
}
}
@ -956,7 +973,7 @@ public final class ClassPrinterImpl {
nodes.add(new MapNodeImpl(BLOCK, "module")
.with(leaf("name", ma.moduleName().name().stringValue()),
list("flags","flag", ma.moduleFlags().stream().map(AccessFlag::name)),
leaf("version", ma.moduleVersion().map(Utf8Entry::stringValue).orElse("null")),
leaf("version", ma.moduleVersion().<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT)),
list("uses", "class", ma.uses().stream().map(ce -> ce.name().stringValue())),
new ListNodeImpl(BLOCK, "requires", ma.requires().stream().map(req ->
new MapNodeImpl(FLOW, "req").with(

View File

@ -472,7 +472,7 @@ class ClassPrinterTest {
"source file": "Foo.java",
"inner classes": [
{"inner class": "Phee", "outer class": "Phoo", "inner name": "InnerName", "flags": ["PROTECTED"]},
{"inner class": "Phoo", "outer class": "null", "inner name": "null", "flags": ["PRIVATE"]}],
{"inner class": "Phoo", "outer class": null, "inner name": null, "flags": ["PRIVATE"]}],
"enclosing method": {"class": "Phee", "method name": "enclosingMethod", "method type": "(Ljava/util/Collection;)Ljava/lang/Double;"},
"signature": "LBoo;LPhee;LPhoo;",
"nest host": "Phee",
@ -725,7 +725,7 @@ class ClassPrinterTest {
<source_file>Foo.java</source_file>
<inner_classes>
<cls><inner_class>Phee</inner_class><outer_class>Phoo</outer_class><inner_name>InnerName</inner_name><flags><flag>PROTECTED</flag></flags></cls>
<cls><inner_class>Phoo</inner_class><outer_class>null</outer_class><inner_name>null</inner_name><flags><flag>PRIVATE</flag></flags></cls></inner_classes>
<cls><inner_class>Phoo</inner_class><outer_class><null/></outer_class><inner_name><null/></inner_name><flags><flag>PRIVATE</flag></flags></cls></inner_classes>
<enclosing_method><class>Phee</class><method_name>enclosingMethod</method_name><method_type>(Ljava/util/Collection;)Ljava/lang/Double;</method_type></enclosing_method>
<signature>LBoo;LPhee;LPhoo;</signature>
<nest_host>Phee</nest_host>