92 lines
1.9 KiB
Go
92 lines
1.9 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"go/ast"
|
||
|
"go/build"
|
||
|
"go/parser"
|
||
|
"go/token"
|
||
|
"path/filepath"
|
||
|
|
||
|
"github.com/pkg/errors"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
_defaultFileFilter = FilterOnlyCodeFile
|
||
|
|
||
|
_errors = make([]string, 0)
|
||
|
_warns = make([]string, 0)
|
||
|
)
|
||
|
|
||
|
// AstInspect .
|
||
|
func AstInspect(dir string) (err error) {
|
||
|
var (
|
||
|
files []*ast.File
|
||
|
fset *token.FileSet
|
||
|
)
|
||
|
if dir, err = filepath.Abs(dir); err != nil {
|
||
|
err = errors.WithStack(err)
|
||
|
return
|
||
|
}
|
||
|
if files, fset, err = parsePackageFiles(dir); err != nil {
|
||
|
return
|
||
|
}
|
||
|
for _, f := range files {
|
||
|
handler := defaultNodeHandler(f, dir, fset)
|
||
|
ast.Inspect(f, handler)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func defaultNodeHandler(f *ast.File, dir string, fileset *token.FileSet) func(ast.Node) bool {
|
||
|
return func(node ast.Node) bool {
|
||
|
if node == nil {
|
||
|
return false
|
||
|
}
|
||
|
for _, l := range _lints {
|
||
|
if !l.fn(dir, f, node) {
|
||
|
switch l.s.l {
|
||
|
case "e":
|
||
|
_errors = append(_errors, fmt.Sprintf("%s --> %s", fileset.PositionFor(node.Pos(), true), l.s.d))
|
||
|
case "w":
|
||
|
_warns = append(_warns, fmt.Sprintf("%s --> %s", fileset.PositionFor(node.Pos(), true), l.s.d))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func parsePackageFilesByPath(dir string, importPath string) (files []*ast.File, fset *token.FileSet, err error) {
|
||
|
var pkg *build.Package
|
||
|
if pkg, err = build.Import(importPath, dir, build.FindOnly); err != nil {
|
||
|
return
|
||
|
}
|
||
|
return parsePackageFiles(pkg.Dir)
|
||
|
}
|
||
|
|
||
|
func parsePackageFiles(absDir string) (files []*ast.File, fset *token.FileSet, err error) {
|
||
|
var ok bool
|
||
|
if files, fset, ok = packageCache(absDir); ok {
|
||
|
return
|
||
|
}
|
||
|
defer func() {
|
||
|
setPackageCache(absDir, fset, files)
|
||
|
}()
|
||
|
|
||
|
fset = token.NewFileSet()
|
||
|
var (
|
||
|
pkgMap map[string]*ast.Package
|
||
|
)
|
||
|
if pkgMap, err = parser.ParseDir(fset, absDir, _defaultFileFilter, parser.ParseComments); err != nil {
|
||
|
err = errors.WithStack(err)
|
||
|
return
|
||
|
}
|
||
|
for _, v := range pkgMap {
|
||
|
for _, f := range v.Files {
|
||
|
files = append(files, f)
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|