antlr / stringtemplate4

StringTemplate 4
http://www.stringtemplate.org
Other
956 stars 231 forks source link

Auto-indent with special characters, aka line-wrapping JavaDocs #265

Open Clashsoft opened 4 years ago

Clashsoft commented 4 years ago

Description

I am looking for an elegant solution for generating JavaDocs, or in general, multi-line strings where each line begins with some characters that are not necessarily whitespace.

For example, if someone sets the description for something to be a multiline string:

This is a method.
It does cool things.

I want to generate the following doc comment:

/**
 * This is a method.
 * It does cool things.
 */

Workaround

My current solution looks like this:

javadoc(foo) ::= <<
/**
 * <foo.descriptionLines; separator="\n * ">
 */
>>

foo provides two getters, one for the plain description, the other is a helper for splitting that into lines:

class Foo {
    private String description;

    public String getDescription() { return this.description; }

    public List<String> getDescriptionLines() { return Arrays.asList(this.description.split("\n"); }
}

There are two problems with this solution:

  1. The separator in the template duplicates the indent. This is confusing and becomes worse when indenting more:

    /**
    * @param value
    *    <foo.descriptionLines; separator="\n *    ">
    */
  2. The getDescriptionLines method needs to be public, despite technically being a helper method. Users of my library could start using the method and I can never get rid of it. It also needs to be documented.

  3. Line wrapping would either look broken or needs to be implemented manually in getDescriptionLines.

Possible Solutions

The first and third problem could be solved by somehow making AutoIndentWriter and friends aware of the fact that * should be treated as indentation in certain contexts.

The second problem could be solved by a new function, e.g. lines, or an option, e.g. split:

<lines(foo.description); separator="...">
<foo.description; split="\n"; separator="...">
parrt commented 4 years ago

I think improving AutoIndentWriter would be the simplest. I wonder if the idea should be to relax the definition of indentation to include "all from left edge" not "all whitespace from left edge"?

Clashsoft commented 4 years ago

Hm, treating all characters as indentation is problematic in cases like this:

/**
 * @param value <foo.descriptionLines; separator="\n">
 */

Treating * @param value as indentation could create something like this:

/**
 * @param value This is a method.
 * @param value It does cool things.
 */
parrt commented 4 years ago

that's a good point. Maybe we should simply add a feature to the indent writer that indicates what the indent string should be, as an override? Or, maybe that's just on the normal writer?