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() {
fp01 = regInfo{inputs: nil, 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}
gpfp = regInfo{inputs: gponly, outputs: fponly}
fp11 = regInfo{inputs: fponly, outputs: fponly}
......@@ -531,4 +531,4 @@ func init() {
framepointerreg: int8(num["BP"]),
linkreg: -1, // not used
})
}
\ No newline at end of file
}
......@@ -55,14 +55,15 @@ type printer struct {
fset *token.FileSet
// Current state
output []byte // raw printer result
indent int // current indentation
level int // level == 0: outside composite literal; level > 0: inside composite literal
mode pmode // current printer mode
impliedSemi bool // if set, a linebreak implies a semicolon
lastTok token.Token // last token printed (token.ILLEGAL if it's whitespace)
prevOpen token.Token // previous non-brace "open" token (, [, or token.ILLEGAL
wsbuf []whiteSpace // delayed white space
output []byte // raw printer result
indent int // current indentation
level int // level == 0: outside composite literal; level > 0: inside composite literal
mode pmode // current printer mode
endAlignment bool // if set, terminate alignment immediately
impliedSemi bool // if set, a linebreak implies a semicolon
lastTok token.Token // last token printed (token.ILLEGAL if it's whitespace)
prevOpen token.Token // previous non-brace "open" token (, [, or token.ILLEGAL
wsbuf []whiteSpace // delayed white space
// Positions
// The out position differs from the pos position when the result
......@@ -232,6 +233,20 @@ func (p *printer) writeIndent() {
// writeByte writes ch n times to p.output and updates p.pos.
// Only used to write formatting (white space) characters.
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 {
// no need to write line directives before white space
p.writeIndent()
......@@ -298,10 +313,15 @@ func (p *printer) writeString(pos token.Position, s string, isLit bool) {
nlines := 0
var li int // index of last newline; valid if nlines > 0
for i := 0; i < len(s); i++ {
// Go tokens cannot contain '\f' - no need to look for it
if s[i] == '\n' {
// Raw string literals may contain any character except back quote (`).
if ch := s[i]; ch == '\n' || ch == '\f' {
// account for line break
nlines++
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)
......
......@@ -256,7 +256,7 @@ func _(
) {
}
// Example from issue 2597.
// Example from issue #2597.
func ManageStatus0(
in <-chan *Status,
req <-chan Request,
......@@ -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.
......@@ -252,7 +252,7 @@ func _(
y T,
) {}
// Example from issue 2597.
// Example from issue #2597.
func ManageStatus0(
in <-chan *Status,
req <-chan Request,
......@@ -267,5 +267,25 @@ func ManageStatus1(
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.
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