+++ /dev/null
-package main
-
-import (
- "flag"
- "fmt"
- "go/ast"
- "go/format"
- "go/parser"
- "go/token"
- "os"
- "path/filepath"
- "reflect"
- "strings"
-
- "honnef.co/go/tools/pattern"
-)
-
-func match(fset *token.FileSet, pat pattern.Pattern, f *ast.File) {
- ast.Inspect(f, func(node ast.Node) bool {
- if node == nil {
- return true
- }
-
- for _, rel := range pat.Relevant {
- if rel == reflect.TypeOf(node) {
- m := &pattern.Matcher{}
- if m.Match(pat.Root, node) {
- fmt.Printf("%s: ", fset.Position(node.Pos()))
- format.Node(os.Stdout, fset, node)
- fmt.Println()
- }
-
- // OPT(dh): we could further speed this up by not
- // chasing down impossible subtrees. For example,
- // we'll never find an ImportSpec beneath a FuncLit.
- return true
- }
- }
- return true
- })
-
-}
-
-func main() {
- flag.Parse()
- // XXX don't use MustParse, handle error
- p := &pattern.Parser{}
- q, err := p.Parse(flag.Args()[0])
- if err != nil {
- fmt.Println(err)
- os.Exit(1)
- }
- dir := flag.Args()[1]
- // XXX should we create a new fileset per file? what if we're
- // checking millions of files, will this use up a lot of memory?
- fset := token.NewFileSet()
- filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
- if err != nil {
- // XXX error handling
- panic(err)
- }
- if !strings.HasSuffix(path, ".go") {
- return nil
- }
- // XXX don't try to parse irregular files or directories
- f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
- if err != nil {
- // XXX log error?
- return nil
- }
-
- match(fset, q, f)
-
- return nil
- })
-}