- format
- importer
- parser
- printer
- scanner
format
format包实现Go源码的标准格式。
func Node
func Node(dst io.Writer, fset *token.FileSet, node interface{}) error
节点以标准gofmt格式格式化节点,并将结果写入dst。
节点类型必须为* ast.File,* printer.CommentedNode,[] ast.Decl,[] ast.Stmt,或与ast.Expr,ast.Decl,ast.Spec或ast.Stmt兼容的分配。 节点不修改节点。 不会对表示部分源文件的节点的导入进行排序(即,如果该节点不是* ast.File或* printer.CommentedNode不包装* ast.File的节点)。
该函数可能会提早返回(在写入整个结果之前)并返回格式错误,例如由于AST错误。
The node type must be *ast.File, *printer.CommentedNode, []ast.Decl, []ast.Stmt, or assignment-compatible to ast.Expr, ast.Decl, ast.Spec, or ast.Stmt. Node does not modify node. Imports are not sorted for nodes representing partial source files (i.e., if the node is not an *ast.File or a *printer.CommentedNode not wrapping an *ast.File).
The function may return early (before the entire result is written) and return a formatting error, for instance due to an incorrect AST.
func Source
func Source(src []byte) ([]byte, error)
源格式为标准gofmt格式的src,并返回结果或(I / O或语法)错误。 src应该是语法上正确的Go源文件,或者是Go声明或语句的列表。
如果src是部分源文件,则将src的前导和尾随空格应用于结果(以使其与src具有相同的前导和尾随空格),并且将结果缩进与src的第一行相同的数量 包含代码。 导入未针对部分源文件进行排序。
importer
importer包提供对导出数据导入器的访问。
func Default
func Default() types.Importer
Default为构建正在运行的二进制文件的编译器返回一个Importer。 如果可用,结果将实现types.ImporterFrom。
func For
func For(compiler string, lookup Lookup) types.Importer
对于给定的编译器和查找接口,For返回一个Importer,或者为nil。 支持的编译器为“ gc”和“ gccgo”。 如果lookup为nil,则使用给定编译器的默认程序包查找机制。 BUG(issue13847):对于不支持非nil查找功能。
type Lookup
type Lookup func(path string) (io.ReadCloser, error)
查找功能返回读取器以访问给定导入路径的包数据,如果找不到匹配的包,则返回错误。
Bugs
☞ 对于不支持非nil的查找功能。
parser
parser包为Go源文件实现了一个解析器。 输入可以以多种形式提供(请参阅各种Parse *函数); 输出是代表Go源代码的抽象语法树(AST)。 通过Parse *函数之一调用解析器。
func ParseDir
func ParseDir(fset *token.FileSet, path string, filter func(os.FileInfo) bool, mode Mode) (pkgs map[string]*ast.Package, first error)
ParseDir在路径指定的目录中对名称以“ .go”结尾的所有文件调用ParseFile,并返回包名称->包AST的映射,其中找到了所有包。
如果filter!= nil,则仅考虑通过os.FileInfo条目(通过“ .go”结尾)的文件。 模式位保持不变地传递给ParseFile。 位置信息记录在fset中。
如果无法读取目录,则返回nil映射和相应的错误。 如果发生解析错误,则返回非零但不完整的映射和遇到的第一个错误。
func ParseExpr
func ParseExpr(x string) (ast.Expr, error)
ParseExpr是用于获取表达式x的AST的便捷函数。 AST中记录的位置信息是不确定的。 错误消息中使用的文件名是空字符串。
func ParseFile
func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) (f *ast.File, err error)
ParseFile解析单个Go源文件的源代码,并返回相应的ast.File节点。 可以通过源文件的文件名或src参数提供源代码。
如果src!= nil,则ParseFile从src解析源,并且仅在记录位置信息时使用文件名。 src参数的参数类型必须为字符串,[] byte或io.Reader。 如果src == nil,则ParseFile解析文件名指定的文件。
mode参数控制已解析的源文本的数量以及其他可选的解析器功能。 位置信息记录在文件集fset中。
如果无法读取源,则返回的AST为nil,并且错误指示特定的失败。 如果读取了源但发现语法错误,则结果是部分AST(带有ast.Bad *节点表示错误源代码的片段)。 通过scanner.ErrorList返回多个错误,该错误按文件位置排序。
Code:
fset := token.NewFileSet() // positions are relative to fset
// Parse the file containing this very example
// but stop after processing the imports.
f, err := parser.ParseFile(fset, "example_test.go", nil, parser.ImportsOnly)
if err != nil {
fmt.Println(err)
return
}
// Print the imports from the file's AST.
for _, s := range f.Imports {
fmt.Println(s.Path.Value)
}
Output:
"fmt"
"go/parser"
"go/token"
type Mode
type Mode uint
Mode值是一组标志(或0)。 它们控制已解析的源代码的数量以及其他可选的解析器功能。
const (
PackageClauseOnly Mode = 1 << iota // stop parsing after package clause
ImportsOnly // stop parsing after import declarations
ParseComments // parse comments and add them to AST
Trace // print a trace of parsed productions
DeclarationErrors // report declaration errors
SpuriousErrors // same as AllErrors, for backward-compatibility
AllErrors = SpuriousErrors // report all errors (not just the first 10 on different lines)
)
printer
打包打印机实现AST节点的打印。
func Fprint
func Fprint(output io.Writer, fset *token.FileSet, node interface{}) error
Fprint“漂亮地打印”要输出的AST节点。 它使用默认设置调用Config.Fprint。
// Parse source file and extract the AST without comments for
// this function, with position information referring to the
// file set fset.
funcAST, fset := parseFunc("example_test.go", "ExampleFprint")
// Print the function body into buffer buf.
// The file set is provided to the printer so that it knows
// about the original source formatting and can add additional
// line breaks where they were present in the source.
var buf bytes.Buffer
printer.Fprint(&buf, fset, funcAST.Body)
// Remove braces {} enclosing the function body, unindent,
// and trim leading and trailing white space.
s := buf.String()
s = s[1 : len(s)-1]
s = strings.TrimSpace(strings.Replace(s, "\n\t", "\n", -1))
// Print the cleaned-up body text to stdout.
fmt.Println(s)
Output:
funcAST, fset := parseFunc("example_test.go", "ExampleFprint")
var buf bytes.Buffer
printer.Fprint(&buf, fset, funcAST.Body)
s := buf.String()
s = s[1 : len(s)-1]
s = strings.TrimSpace(strings.Replace(s, "\n\t", "\n", -1))
fmt.Println(s)
type CommentedNode
type CommentedNode struct {
Node interface{} // *ast.File, or ast.Expr, ast.Decl, ast.Spec, or ast.Stmt
Comments []*ast.CommentGroup
}
CommentedNode捆绑了AST节点和相应的注释。 它可以作为任何Fprint函数的参数提供。
type Config
type Config struct {
Mode Mode // default: 0
Tabwidth int // default: 8
Indent int // default: 0 (all code is indented at least by this much)
}
Config节点控制Fprint的输出。
func (*Config) Fprint
func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node interface{}) error
Fprint“漂亮地打印” AST节点以输出给定配置cfg。 相对于文件集fset解释位置信息。 节点类型必须为* ast.File,* CommentedNode,[] ast.Decl,[] ast.Stmt,或与ast.Expr,ast.Decl,ast.Spec或ast.Stmt分配兼容。
type Mode
type Mode uint
Mode 值是一组标志(或0)。 他们控制打印。
const (
RawFormat Mode = 1 << iota // do not use a tabwriter; if set, UseSpaces is ignored
TabIndent // use tabs for indentation independent of UseSpaces
UseSpaces // use spaces instead of tabs for alignment
SourcePos // emit //line comments to preserve original source positions
)
scanner
scanner包程序实现了Go源文本的扫描程序。 它以[] byte作为源,然后可以通过重复调用Scan方法来对其进行标记。
func PrintError
func PrintError(w io.Writer, err error)
PrintError是一个实用程序函数,如果err参数是ErrorList,则将错误列表打印到w,每行一个错误。 否则,它将输出err字符串。
type Error
type Error struct {
Pos token.Position
Msg string
}
在ErrorList中,错误由* Error表示。 位置Pos(如果有效)指向有问题的令牌的开头,并且错误条件由Msg描述。
func (Error) Error
func (e Error) Error() string
Error实现错误接口。
type ErrorHandler
type ErrorHandler func(pos token.Position, msg string)
可以将ErrorHandler提供给Scanner.Init。 如果遇到语法错误并安装了处理程序,则会使用一个位置和一条错误消息来调用该处理程序。 该位置指向有问题的令牌的开头。
type ErrorList
type ErrorList []*Error
ErrorList是* Error的列表。 ErrorList的零值是可以使用的空ErrorList。
func (*ErrorList) Add
func (p *ErrorList) Add(pos token.Position, msg string)
Add将具有给定位置的错误和错误消息添加到ErrorList。
func (ErrorList) Err
func (p ErrorList) Err() error
错误返回与该错误列表等效的错误。 如果列表为空,则Err返回nil。
func (ErrorList) Error
func (p ErrorList) Error() string
ErrorList实现错误接口。
func (ErrorList) Len
func (p ErrorList) Len() int
ErrorList实现排序接口。
func (ErrorList) Less
func (p ErrorList) Less(i, j int) bool
func (*ErrorList) RemoveMultiples
func (p *ErrorList) RemoveMultiples()
RemoveMultiples对ErrorList进行排序,并删除每行中除第一个错误以外的所有错误。
func (*ErrorList) Reset
func (p *ErrorList) Reset()
重置会将ErrorList重置为没有错误。
func (ErrorList) Sort
func (p ErrorList) Sort()
排序对ErrorList进行排序。 *Error条目按位置排序,其他错误则按错误消息排序,且在任何*Error条目之前。
func (ErrorList) Swap
func (p ErrorList) Swap(i, j int)
type Mode
type Mode uint
Mode值是一组标志(或0)。 它们控制扫描仪的行为。
const (
ScanComments Mode = 1 << iota // return comments as COMMENT tokens
)
type Scanner
type Scanner struct {
// public state - ok to modify
ErrorCount int // number of errors encountered
// contains filtered or unexported fields
}
扫描仪在处理给定文本时会保留扫描仪的内部状态。 可以将其分配为另一个数据结构的一部分,但必须在使用前通过Init进行初始化。
func (*Scanner) Init
func (s *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode Mode)
Init通过将扫描器设置在src的开头来准备扫描器以标记文本src。 扫描仪使用文件集文件获取位置信息,并为每行添加行信息。 重新扫描同一文件时,可以使用相同的文件,因为已经存在的行信息将被忽略。 如果文件大小与src大小不匹配,则Init会引起恐慌。
如果Scan调用遇到语法错误并且err不为nil,则会调用错误处理程序err。 同样,对于遇到的每个错误,“扫描器”字段ErrorCount都加1。 模式参数确定如何处理注释。
请注意,如果文件的第一个字符有错误,则Init可能会调用err。
func (*Scanner) Scan
func (s *Scanner) Scan() (pos token.Pos, tok token.Token, lit string)
Scan将扫描下一个令牌,并返回令牌位置,令牌及其文字字符串(如果适用)。源端由token.EOF指示。
如果返回的令牌是文字(token.IDENT,Token.INT,Token.FLOAT,Token.IMAG,Token.CHAR,Token.STRING)或token.COMMENT,则文字字符串具有相应的值。
如果返回的令牌是关键字,则文字字符串是关键字。
如果返回的令牌是token.SEMICOLON,则相应的文字字符串是“;”如果源中存在分号,则为\ n,如果由于换行或EOF而插入了分号,则为“ \ n”。
如果返回的令牌是token.ILLEGAL,则文字字符串是有问题的字符。
在所有其他情况下,Scan返回一个空的文字字符串。
为了更宽容的解析,即使遇到语法错误,Scan也会尽可能返回有效的令牌。因此,即使最终的令牌序列不包含非法令牌,客户端也不会假定没有错误发生。相反,它必须检查扫描程序的ErrorCount或错误处理程序的调用次数(如果已安装)。
扫描会将行信息添加到添加到使用Init设置的文件集的文件中。令牌位置相对于该文件,因此相对于文件集。
有疑问加站长微信联系(非本文作者)