Commit 70f5afa2 authored by Robert Griesemer's avatar Robert Griesemer

go/printer, gofmt: handle raw string literals containing newlines better

A raw string containing newlines breaks whatever columns structure
has been established so far. Recognize the situation and force a
new section of alignment with the first line break seen after the
the raw string.

Applied gofmt to src and misc.

Fixes #9064.

Change-Id: I961e94b529b1fd421908311f366b113e2ec9b7f0
Reviewed-on: https://go-review.googlesource.com/105040Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
parent 2b7cfc51
...@@ -135,7 +135,7 @@ func init() { ...@@ -135,7 +135,7 @@ func init() {
fp01 = regInfo{inputs: nil, outputs: fponly} fp01 = regInfo{inputs: nil, outputs: fponly}
fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: fponly} fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
fp21load = regInfo{inputs: []regMask{fp, gpspsb, 0}, outputs: fponly} fp21load = regInfo{inputs: []regMask{fp, gpspsb, 0}, outputs: fponly}
fpgp = regInfo{inputs: fponly, outputs: gponly} fpgp = regInfo{inputs: fponly, outputs: gponly}
gpfp = regInfo{inputs: gponly, outputs: fponly} gpfp = regInfo{inputs: gponly, outputs: fponly}
fp11 = regInfo{inputs: fponly, outputs: fponly} fp11 = regInfo{inputs: fponly, outputs: fponly}
...@@ -531,4 +531,4 @@ func init() { ...@@ -531,4 +531,4 @@ func init() {
framepointerreg: int8(num["BP"]), framepointerreg: int8(num["BP"]),
linkreg: -1, // not used linkreg: -1, // not used
}) })
} }
\ No newline at end of file
...@@ -55,14 +55,15 @@ type printer struct { ...@@ -55,14 +55,15 @@ type printer struct {
fset *token.FileSet fset *token.FileSet
// Current state // Current state
output []byte // raw printer result output []byte // raw printer result
indent int // current indentation indent int // current indentation
level int // level == 0: outside composite literal; level > 0: inside composite literal level int // level == 0: outside composite literal; level > 0: inside composite literal
mode pmode // current printer mode mode pmode // current printer mode
impliedSemi bool // if set, a linebreak implies a semicolon endAlignment bool // if set, terminate alignment immediately
lastTok token.Token // last token printed (token.ILLEGAL if it's whitespace) impliedSemi bool // if set, a linebreak implies a semicolon
prevOpen token.Token // previous non-brace "open" token (, [, or token.ILLEGAL lastTok token.Token // last token printed (token.ILLEGAL if it's whitespace)
wsbuf []whiteSpace // delayed white space prevOpen token.Token // previous non-brace "open" token (, [, or token.ILLEGAL
wsbuf []whiteSpace // delayed white space
// Positions // Positions
// The out position differs from the pos position when the result // The out position differs from the pos position when the result
...@@ -232,6 +233,20 @@ func (p *printer) writeIndent() { ...@@ -232,6 +233,20 @@ func (p *printer) writeIndent() {
// writeByte writes ch n times to p.output and updates p.pos. // writeByte writes ch n times to p.output and updates p.pos.
// Only used to write formatting (white space) characters. // Only used to write formatting (white space) characters.
func (p *printer) writeByte(ch byte, n int) { func (p *printer) writeByte(ch byte, n int) {
if p.endAlignment {
// Ignore any alignment control character;
// and at the end of the line, break with
// a formfeed to indicate termination of
// existing columns.
switch ch {
case '\t', '\v':
ch = ' '
case '\n', '\f':
ch = '\f'
p.endAlignment = false
}
}
if p.out.Column == 1 { if p.out.Column == 1 {
// no need to write line directives before white space // no need to write line directives before white space
p.writeIndent() p.writeIndent()
...@@ -298,10 +313,15 @@ func (p *printer) writeString(pos token.Position, s string, isLit bool) { ...@@ -298,10 +313,15 @@ func (p *printer) writeString(pos token.Position, s string, isLit bool) {
nlines := 0 nlines := 0
var li int // index of last newline; valid if nlines > 0 var li int // index of last newline; valid if nlines > 0
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
// Go tokens cannot contain '\f' - no need to look for it // Raw string literals may contain any character except back quote (`).
if s[i] == '\n' { if ch := s[i]; ch == '\n' || ch == '\f' {
// account for line break
nlines++ nlines++
li = i li = i
// A line break inside a literal will break whatever column
// formatting is in place; ignore any further alignment through
// the end of the line.
p.endAlignment = true
} }
} }
p.pos.Offset += len(s) p.pos.Offset += len(s)
......
...@@ -256,7 +256,7 @@ func _( ...@@ -256,7 +256,7 @@ func _(
) { ) {
} }
// Example from issue 2597. // Example from issue #2597.
func ManageStatus0( func ManageStatus0(
in <-chan *Status, in <-chan *Status,
req <-chan Request, req <-chan Request,
...@@ -272,4 +272,24 @@ func ManageStatus1( ...@@ -272,4 +272,24 @@ func ManageStatus1(
) { ) {
} }
// Example from issue #9064.
func (y *y) xerrors() error {
_ = "xerror.test" //TODO-
_ = []byte(`
foo bar foo bar foo bar
`) //TODO-
}
func _() {
_ = "abc" // foo
_ = `abc_0123456789_` // foo
}
func _() {
_ = "abc" // foo
_ = `abc
0123456789
` // foo
}
// There should be exactly one linebreak after this comment. // There should be exactly one linebreak after this comment.
...@@ -252,7 +252,7 @@ func _( ...@@ -252,7 +252,7 @@ func _(
y T, y T,
) {} ) {}
// Example from issue 2597. // Example from issue #2597.
func ManageStatus0( func ManageStatus0(
in <-chan *Status, in <-chan *Status,
req <-chan Request, req <-chan Request,
...@@ -267,5 +267,25 @@ func ManageStatus1( ...@@ -267,5 +267,25 @@ func ManageStatus1(
TargetHistorySize int, TargetHistorySize int,
) { ) {
} }
// Example from issue #9064.
func (y *y) xerrors() error {
_ = "xerror.test" //TODO-
_ = []byte(`
foo bar foo bar foo bar
`) //TODO-
}
func _() {
_ = "abc" // foo
_ = `abc_0123456789_` // foo
}
func _() {
_ = "abc" // foo
_ = `abc
0123456789
` // foo
}
// There should be exactly one linebreak after this comment. // There should be exactly one linebreak after this comment.
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