Merge pull request #12 from adfin/master
Use static parsing instead of requiring a binary.
This commit is contained in:
commit
ff3de3c0dd
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user