falkreon / Jankson

JSON5 / HJSON parser and preprocessor which preserves ordering and comments
MIT License
51 stars 9 forks source link

Trim Leading Margin in Blockquoted Comments #57

Open halotroop2288 opened 3 years ago

halotroop2288 commented 3 years ago

Kotlin Documentation:

To remove leading whitespace from raw strings, use the trimMargin() function:

val text = """
   |Tell me and I forget.
   |Teach me and I remember.
   |Involve me and I learn.
   |(Benjamin Franklin)
   """.trimMargin()

Input:

@Comment("""
        |Tell me and I forget.
        |Involve me and I remember.
        |Involve me and I learn.
        |(Benjamin Franklin)
        """
) var quoteExample: String

Expected output:

/*
  Tell me and I forget.
  Involve me and I remember.
  Involve me and I learn.
  (Benjamin Franklin)
*/

v1 output:

/* 
            |Tell me and I forget.
            |Involve me and I remember.
            |Involve me and I learn.
            |(Benjamin Franklin)

*/
falkreon commented 3 years ago

As we discussed in chat (but I will explain here for everyone), kotlin blockquotes are "raw strings" and by default preserve leading space. The typical answer to this is trimMargins, but trimMargins won't work from a @Comment annotation because its properties need to be compile-time constants. So we're in a tricky place and kotlin doesn't give us a really clear way to "behave well".

Java handles this pretty reasonably in 14+. After the opening triple-quote, you MUST have a newline, but then all lines have an equal amount of whitespace trimmed from them such that there is at least one line that is empty or starts with non-whitespace, equivalent to the new String::stripIndent method which is largely compatible with kotlin's trimMargin. (https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-3.10.6 , linked here from Java 16 because it was a preview feature in 14 and the documentation on it's kind of janky)

So when Java 17 rolls around to LTS, and Jankson officially supports Java blockquotes in 2.1.x, the natural behavior would seem to be to call String::stripIndent on the contents of a Comment annotation, which will do nothing on a Java blockquote and bring kotlin blockquotes into line with expected behavior.

falkreon commented 3 years ago

Slight note, I'm considering adding a temporary / equivalent method for 2.0.x with a big scare comment reminding me to replace it with stripIndent next version :)