1
0
mirror of https://github.com/golang/go synced 2024-10-05 08:21:22 -06:00
go/src/cmd/godoc/parser.go
Russ Cox fae0d35043 godoc: support $GOPATH, simplify file system code
The motivation for this CL is to support $GOPATH well.
Since we already have a FileSystem interface, implement a
Plan 9-style name space.  Bind each of the $GOPATH src
directories onto the $GOROOT src/pkg directory: now
everything is laid out exactly like a normal $GOROOT and
needs very little special case code.

The filter files are no longer used (by us), so I think they
can just be deleted.  Similarly, the Mapping code and the
FileSystem interface were two different ways to accomplish
the same end, so delete the Mapping code.

Within the implementation, since FileSystem is defined to be
slash-separated, use package path consistently, leaving
path/filepath only for manipulating operating system paths.

I kept the -path flag, but I think it can be deleted too.

Fixes #2234.
Fixes #3046.

R=gri, r, r, rsc
CC=golang-dev
https://golang.org/cl/5711058
2012-03-05 10:02:46 -05:00

69 lines
1.7 KiB
Go

// Copyright 2011 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 support functions for parsing .go files.
// Similar functionality is found in package go/parser but the
// functions here operate using godoc's file system fs instead
// of calling the OS's file operations directly.
package main
import (
"go/ast"
"go/parser"
"go/token"
"os"
pathpkg "path"
)
func parseFile(fset *token.FileSet, filename string, mode parser.Mode) (*ast.File, error) {
src, err := ReadFile(fs, filename)
if err != nil {
return nil, err
}
return parser.ParseFile(fset, filename, src, mode)
}
func parseFiles(fset *token.FileSet, filenames []string) (pkgs map[string]*ast.Package, first error) {
pkgs = make(map[string]*ast.Package)
for _, filename := range filenames {
file, err := parseFile(fset, filename, parser.ParseComments)
if err != nil {
if first == nil {
first = err
}
continue
}
name := file.Name.Name
pkg, found := pkgs[name]
if !found {
// TODO(gri) Use NewPackage here; reconsider ParseFiles API.
pkg = &ast.Package{Name: name, Files: make(map[string]*ast.File)}
pkgs[name] = pkg
}
pkg.Files[filename] = file
}
return
}
func parseDir(fset *token.FileSet, path string, filter func(os.FileInfo) bool) (map[string]*ast.Package, error) {
list, err := fs.ReadDir(path)
if err != nil {
return nil, err
}
filenames := make([]string, len(list))
i := 0
for _, d := range list {
if filter == nil || filter(d) {
filenames[i] = pathpkg.Join(path, d.Name())
i++
}
}
filenames = filenames[0:i]
return parseFiles(fset, filenames)
}