]> Cypherpunks repositories - gostls13.git/commitdiff
Simplified parser interface.
authorRobert Griesemer <gri@golang.org>
Tue, 5 Jan 2010 01:26:01 +0000 (17:26 -0800)
committerRobert Griesemer <gri@golang.org>
Tue, 5 Jan 2010 01:26:01 +0000 (17:26 -0800)
R=rsc, r
CC=golang-dev, rog
https://golang.org/cl/183116

src/cmd/cgo/ast.go
src/cmd/godoc/godoc.go
src/pkg/go/parser/interface.go
src/pkg/go/parser/parser_test.go

index c78d8bb8e66deb44e841d68c73b39428dfb881fd..7d6221369e17658c47b29953ca0d093ae51328b8 100644 (file)
@@ -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
index 8b6bc5e4602ab19cbc372bf147a1ca2b8dc093f9..9331d2caef48e85913d8e5ea7db872186cc81988 100644 (file)
@@ -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
index 1c0514a78aa2768a4239eaecf966db2fc6c629fe..b261a4a7ee535208a24f1c5db71a3be8efeade85 100644 (file)
@@ -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
 }
index 208a7c51389680c3cba06f9d497171cca1450a45..2f7bace6ffb9bd36e934cb642383629dab616ed1 100644 (file)
@@ -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) {