• Dmitri Shuralyov's avatar
    go/format, cmd/gofmt: fix issues with partial Go code with indent · 912ec199
    Dmitri Shuralyov authored
    Fixes #5551.
    Fixes #4449.
    
    Adds tests for both issues.
    
    Note that the two issues occur only when formatting partial Go code
    with indent.
    
    The best way to understand the change is as follows: I took the code
    of cmd/gofmt and go/format, combined it into one unified code that
    does not suffer from either 4449 nor 5551, and then applied that code
    to both cmd/gofmt and go/format.
    
    As a result, there is now much more identical code between the two
    packages, making future code deduplication easier (it was not possible
    to do that now without adding public APIs, which I was advised not to
    do at this time).
    
    More specifically, I took the parse() of cmd/gofmt which correctly
    preserves comments (issue 5551) and modified it to fix issue where
    it would sometimes modify literal values (issue 4449).
    
    I ended up removing the matchSpace() function because it no longer
    needed to do some of its work (insert indent), and a part of its work
    had to be done in advance (determining the indentation of first code
    line), because that calculation is required for cfg.Fprint() to run.
    
    adjustIndent is used to adjust the indent of cfg.Fprint() to compensate
    for the body of wrapper func being indented by one level. This allows
    to get rid of the bytes.Replace text manipulation of inner content,
    which was problematic and sometimes altered raw string literals (issue
    4449). This means that sometimes the value of cfg.Indent is negative,
    but that works as expected.
    
    So now the algorithm for formatting partial Go code is:
    
    1. Determine and prepend leading space of original source.
    2. Determine and prepend indentation of first code line.
    3. Format and write partial Go code (with all of its leading &
       trailing space trimmed).
    4. Determine and append trailing space of original source.
    
    LGTM=gri
    R=golang-codereviews, bradfitz, gri
    CC=golang-codereviews
    https://golang.org/cl/142360043
    912ec199
stdin6.input 217 Bytes