4 ms·
> I've found that line comments (which must end in a newline, regardless of where they appear) are one of the major sources of complexity in writing a good form
by justinpombrio 3y ago
> I've found that line comments (which must end in a newline, regardless of where they appear) are one of the major sources of complexity in writing a good formatter.
Indeed they are!
Most line comments appear in places that already have forced line breaks (and no choices), and thus aren't a problem. E.g. comments in function bodies or at the top level.
But then there's nasty cases like:
[ 1, // one
2]
and
let x = 5; // long comment that doesn't fit on the line
An important thing to remember is that you're writing code to construct a Notation, and you can do whatever you like in that code. E.g. for the first example, disable the single-line layout if there's a `//` comment inside, and for the second example, move the comment to the line above if it's too long.
There's also a small modification to the printing algorithm which can help, that I didn't describe in this post. The "softer rule" can be enforced by the printer. When picking between `x | y`, it can pick `x` if it fits on the line and does not contain a newline inside of a flat. (EDIT: switched to better modification.)
EDIT: munificent, how does dart-fmt handle that second example with the long end-of-line comment?
- munificent 3y agoWe're in the middle of a rewrite of the formatter, so my answer will be sort of hand-wavey to try to cover how both of them work. Basically, we take the incoming tree and convert it to an internal representation that has some nesting structuring and understands places where line splitting choices can be made. When a mandatory newline (like from a line comment or multi-line string) occurs, we walk outwards to the surrounding IR nodes ("chunks" in the old formatter, "pieces" in the new one) and tell them that a newline has occurred. In the old formatter, that tells the surrounding rules to "harden", which turns them into the maximally split form. In the new formatter, each piece can choose whether or not it allows newlines in different contexts. If it gets word that a newline occurs where not allowed, that solution is invalidated and the solver goes looking for a better one.