github.com/alecthomas/golangci-lint@v1.4.2-0.20180609094924-581a3564ff68/pkg/lint/astcache/astcache.go (about) 1 package astcache 2 3 import ( 4 "fmt" 5 "go/ast" 6 "go/parser" 7 "go/token" 8 "os" 9 "path/filepath" 10 11 "github.com/sirupsen/logrus" 12 "golang.org/x/tools/go/loader" 13 ) 14 15 type File struct { 16 F *ast.File 17 Fset *token.FileSet 18 Name string 19 err error 20 } 21 22 type Cache struct { 23 m map[string]*File 24 s []*File 25 } 26 27 func (c Cache) GetAllValidFiles() []*File { 28 return c.s 29 } 30 31 func (c *Cache) prepareValidFiles() { 32 files := make([]*File, 0, len(c.m)) 33 for _, f := range c.m { 34 if f.err != nil || f.F == nil { 35 continue 36 } 37 files = append(files, f) 38 } 39 c.s = files 40 } 41 42 func LoadFromProgram(prog *loader.Program) (*Cache, error) { 43 c := &Cache{ 44 m: map[string]*File{}, 45 } 46 47 root, err := os.Getwd() 48 if err != nil { 49 return nil, fmt.Errorf("can't get working dir: %s", err) 50 } 51 52 for _, pkg := range prog.InitialPackages() { 53 for _, f := range pkg.Files { 54 pos := prog.Fset.Position(f.Pos()) 55 if pos.Filename == "" { 56 continue 57 } 58 59 relPath, err := filepath.Rel(root, pos.Filename) 60 if err != nil { 61 logrus.Warnf("Can't get relative path for %s and %s: %s", 62 root, pos.Filename, err) 63 continue 64 } 65 66 c.m[relPath] = &File{ 67 F: f, 68 Fset: prog.Fset, 69 Name: relPath, 70 } 71 } 72 } 73 74 c.prepareValidFiles() 75 return c, nil 76 } 77 78 func LoadFromFiles(files []string) *Cache { 79 c := &Cache{ 80 m: map[string]*File{}, 81 } 82 fset := token.NewFileSet() 83 for _, filePath := range files { 84 f, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments) // comments needed by e.g. golint 85 c.m[filePath] = &File{ 86 F: f, 87 Fset: fset, 88 err: err, 89 Name: filePath, 90 } 91 } 92 93 c.prepareValidFiles() 94 return c 95 }