go/format:在源代码中包含//go:build指令时,格式化节点可能存在内部错误,

mrphzbgm  于 5个月前  发布在  Go
关注(0)|答案(2)|浏览(70)

复现者:

  1. func TestBuildDirectiveFormat(t *testing.T) {
  2. const src = "package A\nimport()\nfunc A(){0//go:build\n0}"
  3. fs := token.NewFileSet()
  4. f, err := parser.ParseFile(fs, "test.go", src, parser.ParseComments|parser.SkipObjectResolution)
  5. if err != nil {
  6. t.Fatal(err)
  7. }
  8. if err := printer.Fprint(io.Discard, fs, f); err != nil {
  9. t.Fatal(err) // no error
  10. }
  11. if err := format.Node(io.Discard, fs, f); err != nil {
  12. t.Fatal(err) // format.Node internal error (8:5: expected ';', found 0 (and 1 more errors))
  13. }
  14. }

printer.Fprint 对于相同的源文件没有返回错误,只返回了 format.Node 的错误。这种情况发生在:
go/src/go/format/format.go
第76行到第80行
| | file, err=parser.ParseFile(fset, "", buf.Bytes(), parserMode) |
| | iferr!=nil { |
| | // 我们不应该在这里。如果我们在这里,请提供良好的诊断信息。 |
| | returnfmt.Errorf("format.Node内部错误 (%s)", err) |
| | } |
CC @griesemer

nc1teljy

nc1teljy1#

这种情况发生是因为,在以下文件中:
go/src/go/format/format.go
第71行到第81行
| | varbuf bytes.Buffer |
| | err:=config.Fprint(&buf, fset, file) |
| | iferr!=nil { |
| | returnerr |
| | } |
| | file, err=parser.ParseFile(fset, "", buf.Bytes(), parserMode) |
| | iferr!=nil { |
| | // We should never get here. If we do, provide good diagnostic. |
| | returnfmt.Errorf("format.Node internal error (%s)", err) |
| | } |
| | ast.SortImports(fset, file) |
格式化后的源代码为:

  1. "//go:build\n\npackage A\n\nimport ()\n\nfunc A() {\n\t0 0\n}\n"

这里的错误格式化发生在以下文件中:
go/src/go/printer/printer.go
第1371行到第1373行
| | // output is buffered in p.output now. |
| | // fix //go:build and // +build comments if needed. |
| | p.fixGoBuildLines() |

展开查看全部
sbtkgmzw

sbtkgmzw2#

https://go.dev/cl/609055提到了这个问题:go/printer: correctly print trailing //go:build and //+build

相关问题