[External] : Re: Classfile API proposal to integrate basic print functionality directly to ClassModel and MethodModel

Adam Sotona adam.sotona at oracle.com
Wed Jul 27 10:04:33 UTC 2022


Unfortunately, “Prettyprinting” can be reduced to indentation and new lines only for XML and JSON, however YAML offers much more dynamic formatting.

I think when we kick XML out of the equations (and workaround comments), we can simplify the printing API to following:

    enum Style { BLOCK, FLOW }

    public sealed interface Printable {}

    public record PrintableValue(ConstantDesc value) implements Printable {}

    public record PrintableList(Style style, List<? extends Printable> list) implements Printable {}

    public record PrintableMap(Style style, Map<ConstantDesc, Printable> map) implements Printable {}

And get following results:
https://gist.github.com/asotona/01a054ecca5d8f9608516cb738c33ce1
and
https://gist.github.com/asotona/1e9b1c233c606724ad1c4e0eff1df3de




On 27.07.2022 10:10, "Michael van Acken" <michael.van.acken at gmail.com> wrote:

Am Di., 26. Juli 2022 um 21:43 Uhr schrieb Brian Goetz <brian.goetz at oracle.com<mailto:brian.goetz at oracle.com>>:


To be more specific about the actual classes:
Mapping accepts only fragments, because it must render as single line and for example in XML it renders as single element with attributes.

OK, so this unearths a previously unstated requirement: that we be able to turn certain maps into attributes, rather than embedded elements, when converting to XML.  Does this requirement correspond to anything in other formats?  Do we gain anything by dropping this, and formatting always to elements, and/or using other heuristics to determine when we can get away with this format optimization?

In general, I'd like to unearth more of this sort of requirements.  Looking at the current hierarchy, I can't help but feel we've not yet "hit bottom"; it doesn't feel factored into separate concerns yet.  But I'm optimistic we can get there.

Here's a naive decomposition, which looks a lot like the JSON spec if you squint:

    Value = SimpleValue(ConstantDesc) | ListValue(List<Value>) | MapValue(Map<String, Value>)

Converting to this form is useful separate from formatting -- it provides a basis for query/traversal using simple string keys.  But it's not good enough for getting good formatting yet, because you need formatting hints to determine how to lay out / indent, right?  So let's consider how we might add these in as hints, that are more transparent. [...]

If it's a question of prettyprinting where indentation and line breaks
are added automatically, then there is the option to layer all
whitespace manipulation on top of the printed data.  I use this to
prettyprint Clojure data structures, which closely resemble your
`Value` production above.

The key idea goes back to the 1980 paper "Prettyprinting" by Oppen and
boils down to a single decision how to insert line breaks.  Given a
delimited group

  <start><elem><line><elem><line>...<elem><end>

where <start> and <end> are usually literals, <elem> arbitrary data,
and <line> is eventually a single whitespace or a line break.
Determine the width of the group assuming that all <line> (both in the
group itself and as part of elements) are of width one.  If the
group's width fits within the page width remaining, then print each
<line> as a single whitespace, otherwise the group's <line> separators
as line breaks.

The "one line width" flows naturally from the leaves to the root.
Combine this with indentation tracking, and the result is a simple but
capable prettyprinter targeting a given page width as a soft target.
Building on this, I print colorized side-by-side diffs of lists of classfiles.

-- mva

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/classfile-api-dev/attachments/20220727/a242b18f/attachment-0001.htm>


More information about the classfile-api-dev mailing list