Commit 85498cbc authored by Robert Griesemer's avatar Robert Griesemer

remove assumption that all files belonging to a package are in the same directory:

- adjust ast.Package node and doc.PackageDoc correspondingly
- introduce parser.ParseFiles

R=rsc
CC=golang-dev
https://golang.org/cl/207087
parent 2f816d5b
...@@ -183,11 +183,12 @@ func ParsePackage(path string, filter func(*os.Dir) bool, mode uint) (*ast.Packa ...@@ -183,11 +183,12 @@ func ParsePackage(path string, filter func(*os.Dir) bool, mode uint) (*ast.Packa
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) filename := pathutil.Join(path, entry.Name)
src, err := ParsePkgFile(name, filename, mode)
if err != nil { if err != nil {
return nil, err return nil, err
} }
files[entry.Name] = src files[filename] = src
if name == "" { if name == "" {
name = src.Name.Name() name = src.Name.Name()
} }
...@@ -198,5 +199,5 @@ func ParsePackage(path string, filter func(*os.Dir) bool, mode uint) (*ast.Packa ...@@ -198,5 +199,5 @@ func ParsePackage(path string, filter func(*os.Dir) bool, mode uint) (*ast.Packa
return nil, os.NewError(path + ": no package found") return nil, os.NewError(path + ": no package found")
} }
return &ast.Package{name, path, nil, files}, nil return &ast.Package{name, nil, files}, nil
} }
...@@ -722,7 +722,6 @@ type File struct { ...@@ -722,7 +722,6 @@ type File struct {
// //
type Package struct { type Package struct {
Name string // package name Name string // package name
Path string // package path
Scope *Scope // package scope Scope *Scope // package scope
Files map[string]*File // path-relative filenames Files map[string]*File // Go source files by filename
} }
...@@ -293,7 +293,7 @@ func NewFileDoc(file *ast.File) *PackageDoc { ...@@ -293,7 +293,7 @@ func NewFileDoc(file *ast.File) *PackageDoc {
var r docReader var r docReader
r.init(file.Name.Name()) r.init(file.Name.Name())
r.addFile(file) r.addFile(file)
return r.newDoc("", "", nil) return r.newDoc("", nil)
} }
...@@ -307,7 +307,7 @@ func NewPackageDoc(pkg *ast.Package, importpath string) *PackageDoc { ...@@ -307,7 +307,7 @@ func NewPackageDoc(pkg *ast.Package, importpath string) *PackageDoc {
filenames[i] = filename filenames[i] = filename
i++ i++
} }
return r.newDoc(importpath, pkg.Path, filenames) return r.newDoc(importpath, filenames)
} }
...@@ -511,7 +511,6 @@ func makeBugDocs(v *vector.Vector) []string { ...@@ -511,7 +511,6 @@ func makeBugDocs(v *vector.Vector) []string {
type PackageDoc struct { type PackageDoc struct {
PackageName string PackageName string
ImportPath string ImportPath string
FilePath string
Filenames []string Filenames []string
Doc string Doc string
Consts []*ValueDoc Consts []*ValueDoc
...@@ -524,11 +523,10 @@ type PackageDoc struct { ...@@ -524,11 +523,10 @@ type PackageDoc struct {
// newDoc returns the accumulated documentation for the package. // newDoc returns the accumulated documentation for the package.
// //
func (doc *docReader) newDoc(importpath, filepath string, filenames []string) *PackageDoc { func (doc *docReader) newDoc(importpath string, filenames []string) *PackageDoc {
p := new(PackageDoc) p := new(PackageDoc)
p.PackageName = doc.pkgName p.PackageName = doc.pkgName
p.ImportPath = importpath p.ImportPath = importpath
p.FilePath = filepath
sort.SortStrings(filenames) sort.SortStrings(filenames)
p.Filenames = filenames p.Filenames = filenames
p.Doc = CommentText(doc.doc) p.Doc = CommentText(doc.doc)
......
...@@ -143,6 +143,35 @@ func ParseFile(filename string, src interface{}, scope *ast.Scope, mode uint) (* ...@@ -143,6 +143,35 @@ func ParseFile(filename string, src interface{}, scope *ast.Scope, mode uint) (*
} }
// ParseFiles calls ParseFile for each file in the filenames list and returns
// a map of package name -> package AST with all the packages found. The mode
// bits are passed to ParseFile unchanged.
//
// Files with parse errors are ignored. In this case the map of packages may
// be incomplete (missing packages and/or incomplete packages) and the last
// error encountered is returned.
//
func ParseFiles(filenames []string, scope *ast.Scope, mode uint) (map[string]*ast.Package, os.Error) {
pkgs := make(map[string]*ast.Package)
var err os.Error
for _, filename := range filenames {
var src *ast.File
src, err = ParseFile(filename, nil, scope, mode)
if err == nil {
name := src.Name.Name()
pkg, found := pkgs[name]
if !found {
pkg = &ast.Package{name, scope, make(map[string]*ast.File)}
pkgs[name] = pkg
}
pkg.Files[filename] = src
}
}
return pkgs, err
}
// ParseDir calls ParseFile for the files in the directory specified by path and // 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 // 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 // filter != nil, only the files with os.Dir entries passing through the filter
...@@ -164,24 +193,17 @@ func ParseDir(path string, filter func(*os.Dir) bool, mode uint) (map[string]*as ...@@ -164,24 +193,17 @@ func ParseDir(path string, filter func(*os.Dir) bool, mode uint) (map[string]*as
return nil, err return nil, err
} }
var scope *ast.Scope = nil // for now tracking of declarations is disabled filenames := make([]string, len(list))
pkgs := make(map[string]*ast.Package) n := 0
for i := 0; i < len(list); i++ { for i := 0; i < len(list); i++ {
entry := &list[i] d := &list[i]
if filter == nil || filter(entry) { if filter == nil || filter(d) {
src, err := ParseFile(pathutil.Join(path, entry.Name), nil, scope, mode) filenames[n] = pathutil.Join(path, d.Name)
if err != nil { n++
return pkgs, err
}
name := src.Name.Name()
pkg, found := pkgs[name]
if !found {
pkg = &ast.Package{name, path, scope, make(map[string]*ast.File)}
pkgs[name] = pkg
}
pkg.Files[entry.Name] = src
} }
} }
filenames = filenames[0:n]
return pkgs, nil var scope *ast.Scope = nil // for now tracking of declarations is disabled
return ParseFiles(filenames, scope, mode)
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment