Skip to content

Commit c68f2f8

Browse files
dspeziagriesemer
authored andcommitted
go/format: fix //line corner case when formatting statements
The code formatting mechanism can be applied to partial Go code, such as a list of statements. The statements are wrapped into a function definition (to be parsed fine), and unwrapped after formatting. When the statements contain //line annotations, it may fail, because not all comments are flushed by the printer before the final '}'. Formatting "\ta()\n//line :1" results in "\ta() }\n\n//line", which is wrong. Tweaked the wrapping/unwrapping code to make sure comments are flushed before the '}'. Fixes #11276 Change-Id: Id15c80279b0382ee9ed939cca1647f525c4929f5 Reviewed-on: https://go-review.googlesource.com/11282 Run-TryBot: Robert Griesemer <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent 7708248 commit c68f2f8

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

src/go/format/format_test.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,11 @@ var tests = []string{
9191
"\n\t\t\n\n\t\t\tx := 0\n\t\t\tconst s = `\n\t\tfoo\n`\n\n\n", // no indentation removed inside raw strings
9292

9393
// comments
94-
"i := 5 /* Comment */", // Issue 5551.
94+
"i := 5 /* Comment */", // Issue 5551.
95+
"\ta()\n//line :1", // Issue 11276.
96+
"\t//xxx\n\ta()\n//line :2", // Issue 11276.
97+
"\ta() //line :1\n\tb()\n", // Issue 11276.
98+
"x := 0\n//line :1\n//line :2", // Issue 11276.
9599

96100
// erroneous programs
97101
"ERROR1 + 2 +",

src/internal/format/format.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ func Parse(fset *token.FileSet, filename string, src []byte, fragmentOk bool) (
5858
// by inserting a package clause and turning the list
5959
// into a function body. This handles expressions too.
6060
// Insert using a ;, not a newline, so that the line numbers
61-
// in fsrc match the ones in src.
62-
fsrc := append(append([]byte("package p; func _() {"), src...), '\n', '}')
61+
// in fsrc match the ones in src. Add an extra '\n' before the '}'
62+
// to make sure comments are flushed before the '}'.
63+
fsrc := append(append([]byte("package p; func _() {"), src...), '\n', '\n', '}')
6364
file, err = parser.ParseFile(fset, filename, fsrc, parserMode)
6465
if err == nil {
6566
sourceAdj = func(src []byte, indent int) []byte {
@@ -71,7 +72,8 @@ func Parse(fset *token.FileSet, filename string, src []byte, fragmentOk bool) (
7172
// Gofmt has turned the ; into a \n\n.
7273
// There will be two non-blank lines with indent, hence 2*indent.
7374
src = src[2*indent+len("package p\n\nfunc _() {"):]
74-
src = src[:len(src)-(indent+len("\n}\n"))]
75+
// Remove only the "}\n" suffix: remaining whitespaces will be trimmed anyway
76+
src = src[:len(src)-len("}\n")]
7577
return bytes.TrimSpace(src)
7678
}
7779
// Gofmt has also indented the function body one level.

0 commit comments

Comments
 (0)