Merge pull request #12 from adfin/master

Use static parsing instead of requiring a binary.
This commit is contained in:
Francesc Campoy 2016-05-27 18:16:08 -05:00
commit ff3de3c0dd
3 changed files with 23 additions and 39 deletions

View File

@ -98,8 +98,13 @@ func main() {
} else if len(args) > 1 { } else if len(args) > 1 {
log.Fatalf("only one directory at a time") log.Fatalf("only one directory at a time")
} }
dir, err := filepath.Abs(dir)
if err != nil {
log.Fatalf("unable to determine absolute filepath for requested path %s: %v",
dir, err)
}
pkg, err := parser.ParsePackage(dir, *outputPrefix, *outputSuffix+".go") pkg, err := parser.ParsePackage(dir)
if err != nil { if err != nil {
log.Fatalf("parsing package: %v", err) log.Fatalf("parsing package: %v", err)
} }

View File

@ -10,15 +10,14 @@ import (
"fmt" "fmt"
"go/ast" "go/ast"
"go/build" "go/build"
"go/parser" "go/constant"
"go/token" "go/token"
"go/types"
"log" "log"
"path/filepath" "path/filepath"
"strings" "strings"
"go/constant" "golang.org/x/tools/go/loader"
"go/importer"
"go/types"
) )
// A Package contains all the information related to a parsed package. // A Package contains all the information related to a parsed package.
@ -30,45 +29,25 @@ type Package struct {
} }
// ParsePackage parses the package in the given directory and returns it. // ParsePackage parses the package in the given directory and returns it.
func ParsePackage(directory, skipPrefix, skipSuffix string) (*Package, error) { func ParsePackage(directory string) (*Package, error) {
pkgDir, err := build.Default.ImportDir(directory, 0) relDir, err := filepath.Rel(filepath.Join(build.Default.GOPATH, "src"), directory)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot process directory %s: %s", directory, err) return nil, fmt.Errorf("provided directory not under GOPATH (%s): %v",
build.Default.GOPATH, err)
} }
var files []*ast.File conf := loader.Config{TypeChecker: types.Config{FakeImportC: true}}
fs := token.NewFileSet() conf.Import(relDir)
for _, name := range pkgDir.GoFiles { program, err := conf.Load()
if !strings.HasSuffix(name, ".go") || if err != nil {
(skipSuffix != "" && strings.HasPrefix(name, skipPrefix) && return nil, fmt.Errorf("couldn't load package: %v", err)
strings.HasSuffix(name, skipSuffix)) {
continue
}
if directory != "." {
name = filepath.Join(directory, name)
}
f, err := parser.ParseFile(fs, name, nil, 0)
if err != nil {
return nil, fmt.Errorf("parsing file %v: %v", name, err)
}
files = append(files, f)
}
if len(files) == 0 {
return nil, fmt.Errorf("%s: no buildable Go files", directory)
}
// type-check the package
defs := make(map[*ast.Ident]types.Object)
config := types.Config{FakeImportC: true, Importer: importer.Default()}
info := &types.Info{Defs: defs}
if _, err := config.Check(directory, fs, files, info); err != nil {
return nil, fmt.Errorf("type-checking package: %v", err)
} }
pkgInfo := program.Package(relDir)
return &Package{ return &Package{
Name: files[0].Name.Name, Name: pkgInfo.Pkg.Name(),
files: files, files: pkgInfo.Files,
defs: defs, defs: pkgInfo.Defs,
}, nil }, nil
} }

View File

@ -47,7 +47,7 @@ func generateHandler(w http.ResponseWriter, r *http.Request) error {
} }
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
pkg, err := parser.ParsePackage(dir, "", "") pkg, err := parser.ParsePackage(dir)
if err != nil { if err != nil {
return fmt.Errorf("parse package: %v", err) return fmt.Errorf("parse package: %v", err)
} }