mirror of
https://github.com/golang/go
synced 2024-11-22 03:54:39 -07:00
Simplified parser interface.
R=rsc, r CC=golang-dev, rog https://golang.org/cl/183116
This commit is contained in:
parent
a0ee18bdd5
commit
50442290bb
@ -59,7 +59,7 @@ type FuncType struct {
|
|||||||
|
|
||||||
func openProg(name string, p *Prog) {
|
func openProg(name string, p *Prog) {
|
||||||
var err os.Error
|
var err os.Error
|
||||||
p.AST, err = parser.ParsePkgFile("", name, parser.ParseComments)
|
p.AST, err = parser.ParseFile(name, nil, parser.ParseComments)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if list, ok := err.(scanner.ErrorList); ok {
|
if list, ok := err.(scanner.ErrorList); ok {
|
||||||
// If err is a scanner.ErrorList, its String will print just
|
// If err is a scanner.ErrorList, its String will print just
|
||||||
|
@ -1021,10 +1021,18 @@ func (h *httpHandler) getPageInfo(path string) PageInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get package AST
|
// get package AST
|
||||||
pkg, err := parser.ParsePackage(dirname, filter, parser.ParseComments)
|
pkgs, err := parser.ParseDir(dirname, filter, parser.ParseComments)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: parse errors should be shown instead of an empty directory
|
// TODO: errors should be shown instead of an empty directory
|
||||||
log.Stderrf("parser.parsePackage: %s", err)
|
log.Stderrf("parser.parseDir: %s", err)
|
||||||
|
}
|
||||||
|
if len(pkgs) != 1 {
|
||||||
|
// TODO: should handle multiple packages
|
||||||
|
log.Stderrf("parser.parseDir: found %d packages", len(pkgs))
|
||||||
|
}
|
||||||
|
var pkg *ast.Package
|
||||||
|
for _, pkg = range pkgs {
|
||||||
|
break // take the first package found
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute package documentation
|
// compute package documentation
|
||||||
|
@ -8,7 +8,6 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/scanner"
|
"go/scanner"
|
||||||
"io"
|
"io"
|
||||||
@ -132,41 +131,16 @@ func ParseFile(filename string, src interface{}, mode uint) (*ast.File, os.Error
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ParsePkgFile parses the file specified by filename and returns the
|
// ParseDir calls ParseFile for the files in the directory specified by path and
|
||||||
// corresponding AST. If the file cannot be read, has syntax errors, or
|
// returns a map of package name -> package AST with all the packages found. If
|
||||||
// does not belong to the package (i.e., pkgname != "" and the package
|
// filter != nil, only the files with os.Dir entries passing through the filter
|
||||||
// name in the file doesn't match pkkname), an error is returned.
|
// are considered. The mode bits are passed to ParseFile unchanged.
|
||||||
//
|
//
|
||||||
func ParsePkgFile(pkgname, filename string, mode uint) (*ast.File, os.Error) {
|
// If the directory couldn't be read, a nil map and the respective error are
|
||||||
src, err := ioutil.ReadFile(filename)
|
// returned. If a parse error occured, a non-nil but incomplete map and the
|
||||||
if err != nil {
|
// error are returned.
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if pkgname != "" {
|
|
||||||
prog, err := ParseFile(filename, src, PackageClauseOnly)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if prog.Name.Value != pkgname {
|
|
||||||
return nil, os.NewError(fmt.Sprintf("multiple packages found: %s, %s", prog.Name.Value, pkgname))
|
|
||||||
}
|
|
||||||
if mode == PackageClauseOnly {
|
|
||||||
return prog, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ParseFile(filename, src, mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ParsePackage parses all files in the directory specified by path and
|
|
||||||
// returns an AST representing the package found. The set of files may be
|
|
||||||
// restricted by providing a non-nil filter function; only the files with
|
|
||||||
// os.Dir entries passing through the filter are considered.
|
|
||||||
// If ParsePackage does not find exactly one package, it returns an error.
|
|
||||||
//
|
//
|
||||||
func ParsePackage(path string, filter func(*os.Dir) bool, mode uint) (*ast.Package, os.Error) {
|
func ParseDir(path string, filter func(*os.Dir) bool, mode uint) (map[string]*ast.Package, os.Error) {
|
||||||
fd, err := os.Open(path, os.O_RDONLY, 0)
|
fd, err := os.Open(path, os.O_RDONLY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -178,25 +152,23 @@ func ParsePackage(path string, filter func(*os.Dir) bool, mode uint) (*ast.Packa
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
name := ""
|
pkgs := make(map[string]*ast.Package)
|
||||||
files := make(map[string]*ast.File)
|
|
||||||
for i := 0; i < len(list); i++ {
|
for i := 0; i < len(list); i++ {
|
||||||
entry := &list[i]
|
entry := &list[i]
|
||||||
if filter == nil || filter(entry) {
|
if filter == nil || filter(entry) {
|
||||||
src, err := ParsePkgFile(name, pathutil.Join(path, entry.Name), mode)
|
src, err := ParseFile(pathutil.Join(path, entry.Name), nil, mode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return pkgs, err
|
||||||
}
|
}
|
||||||
files[entry.Name] = src
|
name := src.Name.Value
|
||||||
if name == "" {
|
pkg, found := pkgs[name]
|
||||||
name = src.Name.Value
|
if !found {
|
||||||
|
pkg = &ast.Package{name, path, make(map[string]*ast.File)}
|
||||||
|
pkgs[name] = pkg
|
||||||
}
|
}
|
||||||
|
pkg.Files[entry.Name] = src
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(files) == 0 {
|
return pkgs, nil
|
||||||
return nil, os.NewError(path + ": no package found")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ast.Package{name, path, files}, nil
|
|
||||||
}
|
}
|
||||||
|
@ -78,12 +78,17 @@ func dirFilter(d *os.Dir) bool { return nameFilter(d.Name) }
|
|||||||
|
|
||||||
func TestParse4(t *testing.T) {
|
func TestParse4(t *testing.T) {
|
||||||
path := "."
|
path := "."
|
||||||
pkg, err := ParsePackage(path, dirFilter, 0)
|
pkgs, err := ParseDir(path, dirFilter, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("ParsePackage(%s): %v", path, err)
|
t.Fatalf("ParseDir(%s): %v", path, err)
|
||||||
}
|
}
|
||||||
if pkg.Name != "parser" {
|
if len(pkgs) != 1 {
|
||||||
t.Errorf("incorrect package name: %s", pkg.Name)
|
t.Errorf("incorrect number of packages: %d", len(pkgs))
|
||||||
|
}
|
||||||
|
pkg, found := pkgs["parser"]
|
||||||
|
if pkg == nil || !found {
|
||||||
|
t.Errorf(`package "parser" not found`)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
for filename, _ := range pkg.Files {
|
for filename, _ := range pkg.Files {
|
||||||
if !nameFilter(filename) {
|
if !nameFilter(filename) {
|
||||||
|
Loading…
Reference in New Issue
Block a user