diff options
author | Michael Muré <batolettre@gmail.com> | 2018-12-23 17:11:37 +0100 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2018-12-23 17:11:37 +0100 |
commit | 1410a1af75b1ab9ea3f980a7e372728f9a123abf (patch) | |
tree | e24db8f84c48b20158b1f1fd6d281d700421279c /vendor/github.com/99designs/gqlgen/internal | |
parent | 8fc15a032f021c855abf66ed303c003d57c340ea (diff) | |
download | git-bug-1410a1af75b1ab9ea3f980a7e372728f9a123abf.tar.gz |
upgrade gqlgen to v0.7.1
Diffstat (limited to 'vendor/github.com/99designs/gqlgen/internal')
-rw-r--r-- | vendor/github.com/99designs/gqlgen/internal/imports/prune.go | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/vendor/github.com/99designs/gqlgen/internal/imports/prune.go b/vendor/github.com/99designs/gqlgen/internal/imports/prune.go new file mode 100644 index 00000000..d2469e83 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/internal/imports/prune.go @@ -0,0 +1,119 @@ +// Wrapper around x/tools/imports that only removes imports, never adds new ones. + +package imports + +import ( + "bytes" + "go/ast" + "go/build" + "go/parser" + "go/printer" + "go/token" + "path/filepath" + "strings" + + "golang.org/x/tools/imports" + + "golang.org/x/tools/go/ast/astutil" +) + +type visitFn func(node ast.Node) + +func (fn visitFn) Visit(node ast.Node) ast.Visitor { + fn(node) + return fn +} + +// Prune removes any unused imports +func Prune(filename string, src []byte) ([]byte, error) { + fset := token.NewFileSet() + + file, err := parser.ParseFile(fset, filename, src, parser.ParseComments|parser.AllErrors) + if err != nil { + return nil, err + } + + unused, err := getUnusedImports(file, filename) + if err != nil { + return nil, err + } + for ipath, name := range unused { + astutil.DeleteNamedImport(fset, file, name, ipath) + } + printConfig := &printer.Config{Mode: printer.TabIndent, Tabwidth: 8} + + var buf bytes.Buffer + if err := printConfig.Fprint(&buf, fset, file); err != nil { + return nil, err + } + + return imports.Process(filename, buf.Bytes(), &imports.Options{FormatOnly: true, Comments: true, TabIndent: true, TabWidth: 8}) +} + +func getUnusedImports(file ast.Node, filename string) (map[string]string, error) { + imported := map[string]*ast.ImportSpec{} + used := map[string]bool{} + + abs, err := filepath.Abs(filename) + if err != nil { + return nil, err + } + srcDir := filepath.Dir(abs) + + ast.Walk(visitFn(func(node ast.Node) { + if node == nil { + return + } + switch v := node.(type) { + case *ast.ImportSpec: + if v.Name != nil { + imported[v.Name.Name] = v + break + } + ipath := strings.Trim(v.Path.Value, `"`) + if ipath == "C" { + break + } + + local := importPathToName(ipath, srcDir) + + imported[local] = v + 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 + } + used[xident.Name] = true + } + }), file) + + for pkg := range used { + delete(imported, pkg) + } + + unusedImport := map[string]string{} + for pkg, is := range imported { + if !used[pkg] && pkg != "_" && pkg != "." { + name := "" + if is.Name != nil { + name = is.Name.Name + } + unusedImport[strings.Trim(is.Path.Value, `"`)] = name + } + } + + return unusedImport, nil +} + +func importPathToName(importPath, srcDir string) (packageName string) { + pkg, err := build.Default.Import(importPath, srcDir, 0) + if err != nil { + return "" + } + + return pkg.Name +} |