mirror of https://github.com/golang/go.git
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/105040 Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
2b7cfc515b
commit
70f5afa210
|
|
@ -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
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue