aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2010-01-04 17:26:01 -0800
committerRobert Griesemer <gri@golang.org>2010-01-04 17:26:01 -0800
commit50442290bb862c51e1a93a9fd712481423688206 (patch)
treea720086b51666293ac259ff23c7cb3a035bd7300
parenta0ee18bdd5bcb91dce0e909bcebad3c0010ef83f (diff)
downloadgo-50442290bb862c51e1a93a9fd712481423688206.tar.gz
go-50442290bb862c51e1a93a9fd712481423688206.zip
Simplified parser interface.
R=rsc, r CC=golang-dev, rog https://golang.org/cl/183116
-rw-r--r--src/cmd/cgo/ast.go2
-rw-r--r--src/cmd/godoc/godoc.go14
-rw-r--r--src/pkg/go/parser/interface.go64
-rw-r--r--src/pkg/go/parser/parser_test.go13
4 files changed, 39 insertions, 54 deletions
diff --git a/src/cmd/cgo/ast.go b/src/cmd/cgo/ast.go
index c78d8bb8e6..7d6221369e 100644
--- a/src/cmd/cgo/ast.go
+++ b/src/cmd/cgo/ast.go
@@ -59,7 +59,7 @@ type FuncType struct {
func openProg(name string, p *Prog) {
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 list, ok := err.(scanner.ErrorList); ok {
// If err is a scanner.ErrorList, its String will print just
diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go
index 8b6bc5e460..9331d2caef 100644
--- a/src/cmd/godoc/godoc.go
+++ b/src/cmd/godoc/godoc.go
@@ -1021,10 +1021,18 @@ func (h *httpHandler) getPageInfo(path string) PageInfo {
}
// get package AST
- pkg, err := parser.ParsePackage(dirname, filter, parser.ParseComments)
+ pkgs, err := parser.ParseDir(dirname, filter, parser.ParseComments)
if err != nil {
- // TODO: parse errors should be shown instead of an empty directory
- log.Stderrf("parser.parsePackage: %s", err)
+ // TODO: errors should be shown instead of an empty directory
+ 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
diff --git a/src/pkg/go/parser/interface.go b/src/pkg/go/parser/interface.go
index 1c0514a78a..b261a4a7ee 100644
--- a/src/pkg/go/parser/interface.go
+++ b/src/pkg/go/parser/interface.go
@@ -8,7 +8,6 @@ package parser
import (
"bytes"
- "fmt"
"go/ast"
"go/scanner"
"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
-// corresponding AST. If the file cannot be read, has syntax errors, or
-// does not belong to the package (i.e., pkgname != "" and the package
-// name in the file doesn't match pkkname), an error is returned.
+// ParseDir calls ParseFile for the files 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 os.Dir entries passing through the filter
+// are considered. The mode bits are passed to ParseFile unchanged.
//
-func ParsePkgFile(pkgname, filename string, mode uint) (*ast.File, os.Error) {
- src, err := ioutil.ReadFile(filename)
- if err != nil {
- 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.
+// If the directory couldn't be read, a nil map and the respective error are
+// returned. If a parse error occured, a non-nil but incomplete map and the
+// error are returned.
//
-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)
if err != nil {
return nil, err
@@ -178,25 +152,23 @@ func ParsePackage(path string, filter func(*os.Dir) bool, mode uint) (*ast.Packa
return nil, err
}
- name := ""
- files := make(map[string]*ast.File)
+ pkgs := make(map[string]*ast.Package)
for i := 0; i < len(list); i++ {
entry := &list[i]
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 {
- return nil, err
+ return pkgs, err
}
- files[entry.Name] = src
- if name == "" {
- name = src.Name.Value
+ name := src.Name.Value
+ pkg, found := pkgs[name]
+ 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 nil, os.NewError(path + ": no package found")
- }
-
- return &ast.Package{name, path, files}, nil
+ return pkgs, nil
}
diff --git a/src/pkg/go/parser/parser_test.go b/src/pkg/go/parser/parser_test.go
index 208a7c5138..2f7bace6ff 100644
--- a/src/pkg/go/parser/parser_test.go
+++ b/src/pkg/go/parser/parser_test.go
@@ -78,12 +78,17 @@ func dirFilter(d *os.Dir) bool { return nameFilter(d.Name) }
func TestParse4(t *testing.T) {
path := "."
- pkg, err := ParsePackage(path, dirFilter, 0)
+ pkgs, err := ParseDir(path, dirFilter, 0)
if err != nil {
- t.Fatalf("ParsePackage(%s): %v", path, err)
+ t.Fatalf("ParseDir(%s): %v", path, err)
}
- if pkg.Name != "parser" {
- t.Errorf("incorrect package name: %s", pkg.Name)
+ if len(pkgs) != 1 {
+ 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 {
if !nameFilter(filename) {