gofmt保留换行符

时间:2017-08-11 09:27:34

标签: go gofmt

使用gofmt格式化源代码时,它会保留换行符,以便您可以将项目组合在一起。我对这是如何实际实施感兴趣。我试着查看github repo golang/go中的源代码,但是无法立即找到它。如果你看https://github.com/golang/go/blob/master/src/go/printer/printer.go#L979

// intersperse extra newlines if present in the source

打印机如何知道源中存在这些额外的换行符? 有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:1)

gofmt适用于AST。当你查看https://golang.org/pkg/go/ast时,你会看到每个节点都有函数Pos()和End(),它们分别返回开头和结尾的token.Pos。这些基本上是源文件中的偏移量,因此对行号/中断一无所知。

但是当与token.Fileset结合使用时,这样的token.Pos可以转换为包含行号的token.Position。 gofmt在print.go:lineFor()函数中执行此操作。

实际插入换行符在nodes.go:linebreak()中完成。 linebreak()的第一个参数是通过在相应的token.Pos上调用前​​面提到的lineFor()获得的行号。该函数计算此行号与打印的最后一个标记的行号之间的差异(在struct printer的pos字段中跟踪)。这告诉它现在要打印的令牌是否与前一个令牌在输入文件中的同一行。如果它不是,那意味着程序员在原始源中包含一个或多个换行符,而linebreak()将输出最多1个空行。虽然它可以保留所有输入换行符,但gofmt的策略是将一系列空行压缩到只有1个空行。

如果您提出此问题的原因是您要自定义gofmt,请查看https://github.com/mbenkmann/goformat