Skip to content

Commit c6b14c6

Browse files
committed
8344841: ClassPrinter prints confusing value for null
Reviewed-by: liach
1 parent ddc8a9d commit c6b14c6

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

src/java.base/share/classes/jdk/internal/classfile/impl/ClassPrinterImpl.java

+27-10
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import static java.lang.classfile.constantpool.PoolEntry.TAG_LONG;
5454
import static java.lang.classfile.constantpool.PoolEntry.TAG_STRING;
5555
import static java.lang.classfile.constantpool.PoolEntry.*;
56+
import static java.lang.constant.ConstantDescs.BSM_NULL_CONSTANT;
5657
import static java.util.Objects.requireNonNull;
5758
import static jdk.internal.classfile.impl.ClassPrinterImpl.Style.BLOCK;
5859
import static jdk.internal.classfile.impl.ClassPrinterImpl.Style.FLOW;
@@ -274,7 +275,12 @@ public static void toYaml(Node node, Consumer<String> out) {
274275
private static void toYaml(int indent, boolean skipFirstIndent, Node node, Consumer<String> out) {
275276
switch (node) {
276277
case LeafNode leaf -> {
277-
out.accept(quoteAndEscapeYaml(leaf.value()));
278+
var v = leaf.value();
279+
if (BSM_NULL_CONSTANT.equals(v)) {
280+
out.accept("null");
281+
} else {
282+
out.accept(quoteAndEscapeYaml(v));
283+
}
278284
}
279285
case ListNodeImpl list -> {
280286
switch (list.style()) {
@@ -329,6 +335,7 @@ private static String quoteAndEscapeYaml(ConstantDesc value) {
329335
String s = String.valueOf(value);
330336
if (value instanceof Number) return s;
331337
if (s.length() == 0) return "''";
338+
if (s.equalsIgnoreCase("null")) return "'" + s + "'";
332339
var sb = new StringBuilder(s.length() << 1);
333340
s.chars().forEach(c -> {
334341
switch (c) {
@@ -358,7 +365,12 @@ public static void toJson(Node node, Consumer<String> out) {
358365
private static void toJson(int indent, boolean skipFirstIndent, Node node, Consumer<String> out) {
359366
switch (node) {
360367
case LeafNode leaf -> {
361-
out.accept(quoteAndEscapeJson(leaf.value()));
368+
var v = leaf.value();
369+
if (BSM_NULL_CONSTANT.equals(v)) {
370+
out.accept("null");
371+
} else {
372+
out.accept(quoteAndEscapeJson(v));
373+
}
362374
}
363375
case ListNodeImpl list -> {
364376
out.accept("[");
@@ -434,7 +446,12 @@ private static void toXml(int indent, boolean skipFirstIndent, Node node, Consum
434446
switch (node) {
435447
case LeafNode leaf -> {
436448
out.accept("<" + name + ">");
437-
out.accept(xmlEscape(leaf.value()));
449+
var v = leaf.value();
450+
if (BSM_NULL_CONSTANT.equals(v)) {
451+
out.accept("<null/>");
452+
} else {
453+
out.accept(xmlEscape(v));
454+
}
438455
}
439456
case ListNodeImpl list -> {
440457
switch (list.style()) {
@@ -542,7 +559,7 @@ private static Stream<ConstantDesc> convertVTIs(CodeAttribute lr, List<Verificat
542559
ret.accept("long");
543560
ret.accept("long2");
544561
}
545-
case NULL -> ret.accept("null");
562+
case NULL -> ret.accept(BSM_NULL_CONSTANT);
546563
case TOP -> ret.accept("?");
547564
case UNINITIALIZED_THIS -> ret.accept("THIS");
548565
}
@@ -929,9 +946,9 @@ private static Node[] attributesToTree(List<Attribute<?>> attributes, Verbosity
929946
nodes.add(map("enclosing method",
930947
"class", ema.enclosingClass().name().stringValue(),
931948
"method name", ema.enclosingMethodName()
932-
.map(Utf8Entry::stringValue).orElse("null"),
949+
.<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT),
933950
"method type", ema.enclosingMethodType()
934-
.map(Utf8Entry::stringValue).orElse("null")));
951+
.<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT)));
935952
case ExceptionsAttribute exa ->
936953
nodes.add(list("exceptions", "exc", exa.exceptions().stream()
937954
.map(e -> e.name().stringValue())));
@@ -940,23 +957,23 @@ private static Node[] attributesToTree(List<Attribute<?>> attributes, Verbosity
940957
.map(ic -> new MapNodeImpl(FLOW, "cls").with(
941958
leaf("inner class", ic.innerClass().name().stringValue()),
942959
leaf("outer class", ic.outerClass()
943-
.map(cle -> cle.name().stringValue()).orElse("null")),
944-
leaf("inner name", ic.innerName().map(Utf8Entry::stringValue).orElse("null")),
960+
.map(cle -> (ConstantDesc)cle.name().stringValue()).orElse(BSM_NULL_CONSTANT)),
961+
leaf("inner name", ic.innerName().<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT)),
945962
list("flags", "flag", ic.flags().stream().map(AccessFlag::name))))));
946963
case MethodParametersAttribute mpa -> {
947964
var n = new MapNodeImpl(BLOCK, "method parameters");
948965
for (int i = 0; i < mpa.parameters().size(); i++) {
949966
var p = mpa.parameters().get(i);
950967
n.with(new MapNodeImpl(FLOW, i + 1).with(
951-
leaf("name", p.name().map(Utf8Entry::stringValue).orElse("null")),
968+
leaf("name", p.name().<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT)),
952969
list("flags", "flag", p.flags().stream().map(AccessFlag::name))));
953970
}
954971
}
955972
case ModuleAttribute ma ->
956973
nodes.add(new MapNodeImpl(BLOCK, "module")
957974
.with(leaf("name", ma.moduleName().name().stringValue()),
958975
list("flags","flag", ma.moduleFlags().stream().map(AccessFlag::name)),
959-
leaf("version", ma.moduleVersion().map(Utf8Entry::stringValue).orElse("null")),
976+
leaf("version", ma.moduleVersion().<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT)),
960977
list("uses", "class", ma.uses().stream().map(ce -> ce.name().stringValue())),
961978
new ListNodeImpl(BLOCK, "requires", ma.requires().stream().map(req ->
962979
new MapNodeImpl(FLOW, "req").with(

test/jdk/jdk/classfile/ClassPrinterTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ void testPrintJsonTraceAll() throws IOException {
472472
"source file": "Foo.java",
473473
"inner classes": [
474474
{"inner class": "Phee", "outer class": "Phoo", "inner name": "InnerName", "flags": ["PROTECTED"]},
475-
{"inner class": "Phoo", "outer class": "null", "inner name": "null", "flags": ["PRIVATE"]}],
475+
{"inner class": "Phoo", "outer class": null, "inner name": null, "flags": ["PRIVATE"]}],
476476
"enclosing method": {"class": "Phee", "method name": "enclosingMethod", "method type": "(Ljava/util/Collection;)Ljava/lang/Double;"},
477477
"signature": "LBoo;LPhee;LPhoo;",
478478
"nest host": "Phee",
@@ -725,7 +725,7 @@ void testPrintXmlTraceAll() throws IOException {
725725
<source_file>Foo.java</source_file>
726726
<inner_classes>
727727
<cls><inner_class>Phee</inner_class><outer_class>Phoo</outer_class><inner_name>InnerName</inner_name><flags><flag>PROTECTED</flag></flags></cls>
728-
<cls><inner_class>Phoo</inner_class><outer_class>null</outer_class><inner_name>null</inner_name><flags><flag>PRIVATE</flag></flags></cls></inner_classes>
728+
<cls><inner_class>Phoo</inner_class><outer_class><null/></outer_class><inner_name><null/></inner_name><flags><flag>PRIVATE</flag></flags></cls></inner_classes>
729729
<enclosing_method><class>Phee</class><method_name>enclosingMethod</method_name><method_type>(Ljava/util/Collection;)Ljava/lang/Double;</method_type></enclosing_method>
730730
<signature>LBoo;LPhee;LPhoo;</signature>
731731
<nest_host>Phee</nest_host>

0 commit comments

Comments
 (0)