closes #20
Этот коммит содержится в:
родитель
e9c3d69e2d
коммит
bb0363c4bb
1 изменённых файлов: 65 добавлений и 3 удалений
68
builder.go
68
builder.go
|
@ -3,10 +3,12 @@ package godog
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
|
"go/build"
|
||||||
"go/format"
|
"go/format"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -148,6 +150,37 @@ func (b *builder) registerContexts(f *ast.File) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type visitFn func(node ast.Node) ast.Visitor
|
||||||
|
|
||||||
|
func (fn visitFn) Visit(node ast.Node) ast.Visitor {
|
||||||
|
return fn(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *builder) usedPackages(f *ast.File) []string {
|
||||||
|
var refs []string
|
||||||
|
var visitor visitFn
|
||||||
|
visitor = visitFn(func(node ast.Node) ast.Visitor {
|
||||||
|
if node == nil {
|
||||||
|
return visitor
|
||||||
|
}
|
||||||
|
switch v := node.(type) {
|
||||||
|
case *ast.SelectorExpr:
|
||||||
|
xident, ok := v.X.(*ast.Ident)
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if xident.Obj != nil {
|
||||||
|
// if the parser can resolve it, it's not a package ref
|
||||||
|
break
|
||||||
|
}
|
||||||
|
refs = append(refs, xident.Name)
|
||||||
|
}
|
||||||
|
return visitor
|
||||||
|
})
|
||||||
|
ast.Walk(visitor, f)
|
||||||
|
return refs
|
||||||
|
}
|
||||||
|
|
||||||
func (b *builder) merge() ([]byte, error) {
|
func (b *builder) merge() ([]byte, error) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
if err := b.tpl.Execute(&buf, b); err != nil {
|
if err := b.tpl.Execute(&buf, b); err != nil {
|
||||||
|
@ -158,7 +191,6 @@ func (b *builder) merge() ([]byte, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// b.imports(f)
|
|
||||||
b.deleteImports(f)
|
b.deleteImports(f)
|
||||||
b.files["main.go"] = f
|
b.files["main.go"] = f
|
||||||
|
|
||||||
|
@ -181,13 +213,26 @@ func (b *builder) merge() ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
used := b.usedPackages(ret)
|
||||||
|
isUsed := func(p string) bool {
|
||||||
|
for _, ref := range used {
|
||||||
|
if p == ref {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
for _, spec := range b.imports {
|
for _, spec := range b.imports {
|
||||||
var name string
|
var name string
|
||||||
|
ipath := strings.Trim(spec.Path.Value, `\"`)
|
||||||
|
check := importPathToName(ipath)
|
||||||
if spec.Name != nil {
|
if spec.Name != nil {
|
||||||
name = spec.Name.Name
|
name = spec.Name.Name
|
||||||
|
check = spec.Name.Name
|
||||||
|
}
|
||||||
|
if isUsed(check) {
|
||||||
|
addImport(b.fset, ret, name, ipath)
|
||||||
}
|
}
|
||||||
ipath, _ := strconv.Unquote(spec.Path.Value)
|
|
||||||
addImport(b.fset, ret, name, ipath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
|
@ -358,3 +403,20 @@ func importPath(s *ast.ImportSpec) string {
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var importPathToName = importPathToNameGoPath
|
||||||
|
|
||||||
|
// importPathToNameBasic assumes the package name is the base of import path.
|
||||||
|
func importPathToNameBasic(importPath string) (packageName string) {
|
||||||
|
return path.Base(importPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// importPathToNameGoPath finds out the actual package name, as declared in its .go files.
|
||||||
|
// If there's a problem, it falls back to using importPathToNameBasic.
|
||||||
|
func importPathToNameGoPath(importPath string) (packageName string) {
|
||||||
|
if buildPkg, err := build.Import(importPath, "", 0); err == nil {
|
||||||
|
return buildPkg.Name
|
||||||
|
} else {
|
||||||
|
return importPathToNameBasic(importPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче