Commit 1afc37fa authored by Robert Griesemer's avatar Robert Griesemer

go/printer/gofmt: remove special case for multi-line raw strings

As a special case, multi-line raw strings (i.e., strings in `` quotes)
were not indented if they were the only token on a line. This heuristic
was meant to improve formatting for multi-line raw strings where sub-
sequent lines are not indented at the level of the surrounding code.
Multiple people have complained about this. Removing the heuristic
again because it makes the formatting more regular, easier to under-
stand, and simplifies the implementation.

- manual changes to ebnf/ebnf_test.go for readability
- gofmt -w src misc

Fixes #1643.

R=r, rsc
CC=golang-dev
https://golang.org/cl/4307045
parent d54c4ecc
...@@ -12,7 +12,7 @@ import ( ...@@ -12,7 +12,7 @@ import (
var httpserverFix = fix{ var httpserverFix = fix{
"httpserver", "httpserver",
httpserver, httpserver,
`Adapt http server methods and functions to changes `Adapt http server methods and functions to changes
made to the http ResponseWriter interface. made to the http ResponseWriter interface.
http://codereview.appspot.com/4245064 Hijacker http://codereview.appspot.com/4245064 Hijacker
......
...@@ -11,7 +11,7 @@ import ( ...@@ -11,7 +11,7 @@ import (
var netdialFix = fix{ var netdialFix = fix{
"netdial", "netdial",
netdial, netdial,
`Adapt 3-argument calls of net.Dial to use 2-argument form. `Adapt 3-argument calls of net.Dial to use 2-argument form.
http://codereview.appspot.com/4244055 http://codereview.appspot.com/4244055
`, `,
...@@ -20,7 +20,7 @@ http://codereview.appspot.com/4244055 ...@@ -20,7 +20,7 @@ http://codereview.appspot.com/4244055
var tlsdialFix = fix{ var tlsdialFix = fix{
"tlsdial", "tlsdial",
tlsdial, tlsdial,
`Adapt 4-argument calls of tls.Dial to use 3-argument form. `Adapt 4-argument calls of tls.Dial to use 3-argument form.
http://codereview.appspot.com/4244055 http://codereview.appspot.com/4244055
`, `,
...@@ -29,7 +29,7 @@ http://codereview.appspot.com/4244055 ...@@ -29,7 +29,7 @@ http://codereview.appspot.com/4244055
var netlookupFix = fix{ var netlookupFix = fix{
"netlookup", "netlookup",
netlookup, netlookup,
`Adapt 3-result calls to net.LookupHost to use 2-result form. `Adapt 3-result calls to net.LookupHost to use 2-result form.
http://codereview.appspot.com/4244055 http://codereview.appspot.com/4244055
`, `,
......
...@@ -12,7 +12,7 @@ import ( ...@@ -12,7 +12,7 @@ import (
var procattrFix = fix{ var procattrFix = fix{
"procattr", "procattr",
procattr, procattr,
`Adapt calls to os.StartProcess to use new ProcAttr type. `Adapt calls to os.StartProcess to use new ProcAttr type.
http://codereview.appspot.com/4253052 http://codereview.appspot.com/4253052
`, `,
......
...@@ -15,20 +15,16 @@ var fset = token.NewFileSet() ...@@ -15,20 +15,16 @@ var fset = token.NewFileSet()
var grammars = []string{ var grammars = []string{
`Program = . `Program = .`,
`,
`Program = foo . `Program = foo .
foo = "foo" . foo = "foo" .`,
`,
`Program = "a" | "b" "c" . `Program = "a" | "b" "c" .`,
`,
`Program = "a" ... "z" . `Program = "a" ... "z" .`,
`,
`Program = Song . `Program = Song .
Song = { Note } . Song = { Note } .
Note = Do | (Re | Mi | Fa | So | La) | Ti . Note = Do | (Re | Mi | Fa | So | La) | Ti .
Do = "c" . Do = "c" .
...@@ -38,8 +34,7 @@ foo = "foo" . ...@@ -38,8 +34,7 @@ foo = "foo" .
So = "g" . So = "g" .
La = "a" . La = "a" .
Ti = ti . Ti = ti .
ti = "b" . ti = "b" .`,
`,
} }
......
...@@ -14,7 +14,6 @@ import ( ...@@ -14,7 +14,6 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings"
"tabwriter" "tabwriter"
) )
...@@ -35,13 +34,6 @@ const ( ...@@ -35,13 +34,6 @@ const (
) )
const (
esc2 = '\xfe' // an escape byte that cannot occur in regular UTF-8
_ = 1 / (esc2 - tabwriter.Escape) // cause compiler error if esc2 == tabwriter.Escape
esc2str = "\xfe"
)
var ( var (
esc = []byte{tabwriter.Escape} esc = []byte{tabwriter.Escape}
htab = []byte{'\t'} htab = []byte{'\t'}
...@@ -775,21 +767,7 @@ func (p *printer) print(args ...interface{}) { ...@@ -775,21 +767,7 @@ func (p *printer) print(args ...interface{}) {
data = x.Name data = x.Name
tok = token.IDENT tok = token.IDENT
case *ast.BasicLit: case *ast.BasicLit:
// If we have a raw string that spans multiple lines and
// the opening quote (`) is on a line preceded only by
// indentation, we don't want to write that indentation
// because the following lines of the raw string are not
// indented. It's easiest to correct the output at the end
// via the trimmer (because of the complex handling of
// white space).
// Mark multi-line raw strings by replacing the opening
// quote with esc2 and have the trimmer take care of fixing
// it up.
if x.Value[0] == '`' && strings.Index(x.Value, "\n") > 0 {
data = p.escape(esc2str + x.Value[1:])
} else {
data = p.escape(x.Value) data = p.escape(x.Value)
}
tok = x.Kind tok = x.Kind
case token.Token: case token.Token:
s := x.String() s := x.String()
...@@ -874,7 +852,6 @@ type trimmer struct { ...@@ -874,7 +852,6 @@ type trimmer struct {
output io.Writer output io.Writer
state int state int
space bytes.Buffer space bytes.Buffer
hasText bool
} }
...@@ -882,15 +859,11 @@ type trimmer struct { ...@@ -882,15 +859,11 @@ type trimmer struct {
// It can be in one of the following states: // It can be in one of the following states:
const ( const (
inSpace = iota // inside space inSpace = iota // inside space
atEscape // inside space and the last char was an opening tabwriter.Escape
inEscape // inside text bracketed by tabwriter.Escapes inEscape // inside text bracketed by tabwriter.Escapes
inText // inside text inText // inside text
) )
var backquote = []byte{'`'}
// Design note: It is tempting to eliminate extra blanks occurring in // Design note: It is tempting to eliminate extra blanks occurring in
// whitespace in this function as it could simplify some // whitespace in this function as it could simplify some
// of the blanks logic in the node printing functions. // of the blanks logic in the node printing functions.
...@@ -899,9 +872,8 @@ var backquote = []byte{'`'} ...@@ -899,9 +872,8 @@ var backquote = []byte{'`'}
func (p *trimmer) Write(data []byte) (n int, err os.Error) { func (p *trimmer) Write(data []byte) (n int, err os.Error) {
// invariants: // invariants:
// p.state == inSpace, atEscape: // p.state == inSpace:
// p.space is unwritten // p.space is unwritten
// p.hasText indicates if there is any text on this line
// p.state == inEscape, inText: // p.state == inEscape, inText:
// data[m:n] is unwritten // data[m:n] is unwritten
m := 0 m := 0
...@@ -918,32 +890,20 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) { ...@@ -918,32 +890,20 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) {
case '\n', '\f': case '\n', '\f':
p.space.Reset() // discard trailing space p.space.Reset() // discard trailing space
_, err = p.output.Write(newlines[0:1]) // write newline _, err = p.output.Write(newlines[0:1]) // write newline
p.hasText = false
case tabwriter.Escape: case tabwriter.Escape:
p.state = atEscape _, err = p.output.Write(p.space.Bytes())
p.state = inEscape
m = n + 1 // +1: skip tabwriter.Escape
default: default:
_, err = p.output.Write(p.space.Bytes()) _, err = p.output.Write(p.space.Bytes())
p.state = inText p.state = inText
m = n m = n
} }
case atEscape:
// discard indentation if we have a multi-line raw string
// (see printer.print for details)
if b != esc2 || p.hasText {
_, err = p.output.Write(p.space.Bytes())
}
p.state = inEscape
m = n
if b == esc2 {
_, err = p.output.Write(backquote) // convert back
m++
}
case inEscape: case inEscape:
if b == tabwriter.Escape { if b == tabwriter.Escape {
_, err = p.output.Write(data[m:n]) _, err = p.output.Write(data[m:n])
p.state = inSpace p.state = inSpace
p.space.Reset() p.space.Reset()
p.hasText = true
} }
case inText: case inText:
switch b { switch b {
...@@ -952,19 +912,18 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) { ...@@ -952,19 +912,18 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) {
p.state = inSpace p.state = inSpace
p.space.Reset() p.space.Reset()
p.space.WriteByte(b) // WriteByte returns no errors p.space.WriteByte(b) // WriteByte returns no errors
p.hasText = true
case '\n', '\f': case '\n', '\f':
_, err = p.output.Write(data[m:n]) _, err = p.output.Write(data[m:n])
p.state = inSpace p.state = inSpace
p.space.Reset() p.space.Reset()
_, err = p.output.Write(newlines[0:1]) // write newline _, err = p.output.Write(newlines[0:1]) // write newline
p.hasText = false
case tabwriter.Escape: case tabwriter.Escape:
_, err = p.output.Write(data[m:n]) _, err = p.output.Write(data[m:n])
p.state = atEscape p.state = inEscape
p.space.Reset() m = n + 1 // +1: skip tabwriter.Escape
p.hasText = true
} }
default:
panic("unreachable")
} }
if err != nil { if err != nil {
return return
...@@ -977,7 +936,6 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) { ...@@ -977,7 +936,6 @@ func (p *trimmer) Write(data []byte) (n int, err os.Error) {
_, err = p.output.Write(data[m:n]) _, err = p.output.Write(data[m:n])
p.state = inSpace p.state = inSpace
p.space.Reset() p.space.Reset()
p.hasText = true
} }
return return
......
...@@ -253,8 +253,8 @@ bar` ...@@ -253,8 +253,8 @@ bar`
var _ = `` var _ = ``
var _ = `foo` var _ = `foo`
var _ = var _ =
// the next line should not be indented // the next line should remain indented
`foo `foo
bar` bar`
var _ = // comment var _ = // comment
...@@ -262,8 +262,8 @@ bar` ...@@ -262,8 +262,8 @@ bar`
var _ = // comment var _ = // comment
`foo` `foo`
var _ = // comment var _ = // comment
// the next line should not be indented // the next line should remain indented
`foo `foo
bar` bar`
var _ = /* comment */ `` var _ = /* comment */ ``
...@@ -276,12 +276,12 @@ bar` ...@@ -276,12 +276,12 @@ bar`
var _ = /* comment */ var _ = /* comment */
`foo` `foo`
var _ = /* comment */ var _ = /* comment */
// the next line should not be indented // the next line should remain indented
`foo `foo
bar` bar`
var board = []int( var board = []int(
`........... `...........
........... ...........
....●●●.... ....●●●....
....●●●.... ....●●●....
...@@ -296,8 +296,8 @@ bar` ...@@ -296,8 +296,8 @@ bar`
var state = S{ var state = S{
"foo", "foo",
// the next line should not be indented // the next line should remain indented
`........... `...........
........... ...........
....●●●.... ....●●●....
....●●●.... ....●●●....
......
...@@ -256,7 +256,7 @@ var _ = ...@@ -256,7 +256,7 @@ var _ =
var _ = var _ =
`foo` `foo`
var _ = var _ =
// the next line should not be indented // the next line should remain indented
`foo `foo
bar` bar`
...@@ -266,7 +266,7 @@ bar` ...@@ -266,7 +266,7 @@ bar`
var _ = // comment var _ = // comment
`foo` `foo`
var _ = // comment var _ = // comment
// the next line should not be indented // the next line should remain indented
`foo `foo
bar` bar`
...@@ -282,7 +282,7 @@ bar` ...@@ -282,7 +282,7 @@ bar`
var _ = /* comment */ var _ = /* comment */
`foo` `foo`
var _ = /* comment */ var _ = /* comment */
// the next line should not be indented // the next line should remain indented
`foo `foo
bar` bar`
...@@ -304,7 +304,7 @@ var board = []int( ...@@ -304,7 +304,7 @@ var board = []int(
var state = S{ var state = S{
"foo", "foo",
// the next line should not be indented // the next line should remain indented
`........... `...........
........... ...........
....●●●.... ....●●●....
......
...@@ -239,7 +239,8 @@ func _() { ...@@ -239,7 +239,8 @@ func _() {
_ = `foo _ = `foo
bar` bar`
_ = `three spaces before the end of the line starting here: _ = `three spaces before the end of the line starting here:
they must not be removed` } they must not be removed`
}
func _() { func _() {
...@@ -252,8 +253,8 @@ bar` ...@@ -252,8 +253,8 @@ bar`
var _ = `` var _ = ``
var _ = `foo` var _ = `foo`
var _ = var _ =
// the next line should not be indented // the next line should remain indented
`foo `foo
bar` bar`
var _ = // comment var _ = // comment
...@@ -261,8 +262,8 @@ bar` ...@@ -261,8 +262,8 @@ bar`
var _ = // comment var _ = // comment
`foo` `foo`
var _ = // comment var _ = // comment
// the next line should not be indented // the next line should remain indented
`foo `foo
bar` bar`
var _ = /* comment */ `` var _ = /* comment */ ``
...@@ -275,12 +276,12 @@ bar` ...@@ -275,12 +276,12 @@ bar`
var _ = /* comment */ var _ = /* comment */
`foo` `foo`
var _ = /* comment */ var _ = /* comment */
// the next line should not be indented // the next line should remain indented
`foo `foo
bar` bar`
var board = []int( var board = []int(
`........... `...........
........... ...........
....●●●.... ....●●●....
....●●●.... ....●●●....
...@@ -295,8 +296,8 @@ bar` ...@@ -295,8 +296,8 @@ bar`
var state = S{ var state = S{
"foo", "foo",
// the next line should not be indented // the next line should remain indented
`........... `...........
........... ...........
....●●●.... ....●●●....
....●●●.... ....●●●....
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment