Source File
interface.go
Belonging Package
go/parser
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file contains the exported entry points for invoking the parser.
package parser
import (
)
// If src != nil, readSource converts src to a []byte if possible;
// otherwise it returns an error. If src == nil, readSource returns
// the result of reading the file specified by filename.
func readSource( string, any) ([]byte, error) {
if != nil {
switch s := .(type) {
case string:
return []byte(), nil
case []byte:
return , nil
case *bytes.Buffer:
// is io.Reader, but src is already available in []byte form
if != nil {
return .Bytes(), nil
}
case io.Reader:
return io.ReadAll()
}
return nil, errors.New("invalid source")
}
return os.ReadFile()
}
// A Mode value is a set of flags (or 0).
// They control the amount of source code parsed and other optional
// parser functionality.
type Mode uint
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
SkipObjectResolution // skip deprecated identifier resolution; see ParseFile
AllErrors = SpuriousErrors // report all errors (not just the first 10 on different lines)
)
// ParseFile parses the source code of a single Go source file and returns
// the corresponding [ast.File] node. The source code may be provided via
// the filename of the source file, or via the src parameter.
//
// If src != nil, ParseFile parses the source from src and the filename is
// only used when recording position information. The type of the argument
// for the src parameter must be string, []byte, or [io.Reader].
// If src == nil, ParseFile parses the file specified by filename.
//
// The mode parameter controls the amount of source text parsed and
// other optional parser functionality. If the [SkipObjectResolution]
// mode bit is set (recommended), the object resolution phase of
// parsing will be skipped, causing File.Scope, File.Unresolved, and
// all Ident.Obj fields to be nil. Those fields are deprecated; see
// [ast.Object] for details.
//
// Position information is recorded in the file set fset, which must not be
// nil.
//
// If the source couldn't be read, the returned AST is nil and the error
// indicates the specific failure. If the source was read but syntax
// errors were found, the result is a partial AST (with [ast.Bad]* nodes
// representing the fragments of erroneous source code). Multiple errors
// are returned via a scanner.ErrorList which is sorted by source position.
func ( *token.FileSet, string, any, Mode) ( *ast.File, error) {
if == nil {
panic("parser.ParseFile: no token.FileSet provided (fset == nil)")
}
// get source
, := readSource(, )
if != nil {
return nil,
}
var parser
defer func() {
if := recover(); != nil {
// resume same panic if it's not a bailout
, := .(bailout)
if ! {
panic()
} else if .msg != "" {
.errors.Add(.file.Position(.pos), .msg)
}
}
// set result values
if == nil {
// source is not a valid Go source file - satisfy
// ParseFile API and return a valid (but) empty
// *ast.File
= &ast.File{
Name: new(ast.Ident),
Scope: ast.NewScope(nil),
}
}
.errors.Sort()
= .errors.Err()
}()
// parse source
.init(, , , )
= .parseFile()
return
}
// ParseDir calls [ParseFile] for all files with names ending in ".go" in the
// directory specified by path and returns a map of package name -> package
// AST with all the packages found.
//
// If filter != nil, only the files with [fs.FileInfo] entries passing through
// the filter (and ending in ".go") are considered. The mode bits are passed
// to [ParseFile] unchanged. Position information is recorded in fset, which
// must not be nil.
//
// If the directory couldn't be read, a nil map and the respective error are
// returned. If a parse error occurred, a non-nil but incomplete map and the
// first error encountered are returned.
func ( *token.FileSet, string, func(fs.FileInfo) bool, Mode) ( map[string]*ast.Package, error) {
, := os.ReadDir()
if != nil {
return nil,
}
= make(map[string]*ast.Package)
for , := range {
if .IsDir() || !strings.HasSuffix(.Name(), ".go") {
continue
}
if != nil {
, := .Info()
if != nil {
return nil,
}
if !() {
continue
}
}
:= filepath.Join(, .Name())
if , := ParseFile(, , nil, ); == nil {
:= .Name.Name
, := []
if ! {
= &ast.Package{
Name: ,
Files: make(map[string]*ast.File),
}
[] =
}
.Files[] =
} else if == nil {
=
}
}
return
}
// ParseExprFrom is a convenience function for parsing an expression.
// The arguments have the same meaning as for [ParseFile], but the source must
// be a valid Go (type or value) expression. Specifically, fset must not
// be nil.
//
// If the source couldn't be read, the returned AST is nil and the error
// indicates the specific failure. If the source was read but syntax
// errors were found, the result is a partial AST (with [ast.Bad]* nodes
// representing the fragments of erroneous source code). Multiple errors
// are returned via a scanner.ErrorList which is sorted by source position.
func ( *token.FileSet, string, any, Mode) ( ast.Expr, error) {
if == nil {
panic("parser.ParseExprFrom: no token.FileSet provided (fset == nil)")
}
// get source
, := readSource(, )
if != nil {
return nil,
}
var parser
defer func() {
if := recover(); != nil {
// resume same panic if it's not a bailout
, := .(bailout)
if ! {
panic()
} else if .msg != "" {
.errors.Add(.file.Position(.pos), .msg)
}
}
.errors.Sort()
= .errors.Err()
}()
// parse expr
.init(, , , )
= .parseRhs()
// If a semicolon was inserted, consume it;
// report an error if there's more tokens.
if .tok == token.SEMICOLON && .lit == "\n" {
.next()
}
.expect(token.EOF)
return
}
// ParseExpr is a convenience function for obtaining the AST of an expression x.
// The position information recorded in the AST is undefined. The filename used
// in error messages is the empty string.
//
// If syntax errors were found, the result is a partial AST (with [ast.Bad]* nodes
// representing the fragments of erroneous source code). Multiple errors are
// returned via a scanner.ErrorList which is sorted by source position.
func ( string) (ast.Expr, error) {
return ParseExprFrom(token.NewFileSet(), "", []byte(), 0)
}
The pages are generated with Golds v0.7.0-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |