]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/vendor: update to golang.org/x/tools@8e5aba0a
authorAlan Donovan <adonovan@google.com>
Fri, 16 Nov 2018 19:23:15 +0000 (14:23 -0500)
committerAlan Donovan <adonovan@google.com>
Fri, 16 Nov 2018 20:37:19 +0000 (20:37 +0000)
- Adds 'go vet -json' and 'go vet -c=1' flags
- Removes the pkgfact analyzer, included by mistake.

Change-Id: Id3f1879af479efc567ea0508a1de7a37db5bee89
Reviewed-on: https://go-review.googlesource.com/c/149961
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Michael Matloob <matloob@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/vendor/golang.org/x/tools/go/analysis/cmd/vet-lite/main.go
src/cmd/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go
src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go

index d767d56663c52ebb41499c82d633b0a4ad659f8a..259d3976b4e50172d56f00e3c4d71f8847156f43 100644 (file)
@@ -7,8 +7,6 @@
 package main
 
 import (
-       "flag"
-
        "golang.org/x/tools/go/analysis/unitchecker"
 
        "golang.org/x/tools/go/analysis/passes/asmdecl"
@@ -23,7 +21,6 @@ import (
        "golang.org/x/tools/go/analysis/passes/loopclosure"
        "golang.org/x/tools/go/analysis/passes/lostcancel"
        "golang.org/x/tools/go/analysis/passes/nilfunc"
-       "golang.org/x/tools/go/analysis/passes/pkgfact"
        "golang.org/x/tools/go/analysis/passes/printf"
        "golang.org/x/tools/go/analysis/passes/shift"
        "golang.org/x/tools/go/analysis/passes/stdmethods"
@@ -35,11 +32,6 @@ import (
        "golang.org/x/tools/go/analysis/passes/unusedresult"
 )
 
-// Flags for legacy vet compatibility.
-//
-// These flags, plus the shims in analysisflags, enable
-// existing scripts that run vet to continue to work.
-//
 // Legacy vet had the concept of "experimental" checkers. There
 // was exactly one, shadow, and it had to be explicitly enabled
 // by the -shadow flag, which would of course disable all the
@@ -54,12 +46,6 @@ import (
 // Alternatively, one could build a multichecker containing all
 // the desired checks (vet's suite + shadow) and run it in a
 // single "go vet" command.
-func init() {
-       _ = flag.Bool("source", false, "no effect (deprecated)")
-       _ = flag.Bool("v", false, "no effect (deprecated)")
-       _ = flag.Bool("all", false, "no effect (deprecated)")
-       _ = flag.String("tags", "", "no effect (deprecated)")
-}
 
 func main() {
        unitchecker.Main(
@@ -75,7 +61,6 @@ func main() {
                loopclosure.Analyzer,
                lostcancel.Analyzer,
                nilfunc.Analyzer,
-               pkgfact.Analyzer,
                printf.Analyzer,
                shift.Analyzer,
                stdmethods.Analyzer,
index b5ad4f47cb98aa0e8b8fba55dab291c74809bceb..729ac3b41768dab8d13a68b634df46dd1f6543d9 100644 (file)
@@ -11,27 +11,29 @@ import (
        "encoding/json"
        "flag"
        "fmt"
+       "go/token"
        "io"
+       "io/ioutil"
        "log"
        "os"
        "strconv"
+       "strings"
 
        "golang.org/x/tools/go/analysis"
 )
 
+// flags common to all {single,multi,unit}checkers.
+var (
+       JSON    = false // -json
+       Context = -1    // -c=N: if N>0, display offending line plus N lines of context
+)
+
 // Parse creates a flag for each of the analyzer's flags,
 // including (in multi mode) a flag named after the analyzer,
 // parses the flags, then filters and returns the list of
 // analyzers enabled by flags.
 func Parse(analyzers []*analysis.Analyzer, multi bool) []*analysis.Analyzer {
        // Connect each analysis flag to the command line as -analysis.flag.
-       type analysisFlag struct {
-               Name  string
-               Bool  bool
-               Usage string
-       }
-       var analysisFlags []analysisFlag
-
        enabled := make(map[*analysis.Analyzer]*triState)
        for _, a := range analyzers {
                var prefix string
@@ -44,7 +46,6 @@ func Parse(analyzers []*analysis.Analyzer, multi bool) []*analysis.Analyzer {
                        enableUsage := "enable " + a.Name + " analysis"
                        flag.Var(enable, a.Name, enableUsage)
                        enabled[a] = enable
-                       analysisFlags = append(analysisFlags, analysisFlag{a.Name, true, enableUsage})
                }
 
                a.Flags.VisitAll(func(f *flag.Flag) {
@@ -55,9 +56,6 @@ func Parse(analyzers []*analysis.Analyzer, multi bool) []*analysis.Analyzer {
 
                        name := prefix + f.Name
                        flag.Var(f.Value, name, f.Usage)
-
-                       isBool := isBoolFlag(f.Value)
-                       analysisFlags = append(analysisFlags, analysisFlag{name, isBool, f.Usage})
                })
        }
 
@@ -65,23 +63,20 @@ func Parse(analyzers []*analysis.Analyzer, multi bool) []*analysis.Analyzer {
        printflags := flag.Bool("flags", false, "print analyzer flags in JSON")
        addVersionFlag()
 
+       // flags common to all checkers
+       flag.BoolVar(&JSON, "json", JSON, "emit JSON output")
+       flag.IntVar(&Context, "c", Context, `display offending line with this many lines of context`)
+
        // Add shims for legacy vet flags to enable existing
        // scripts that run vet to continue to work.
        _ = flag.Bool("source", false, "no effect (deprecated)")
        _ = flag.Bool("v", false, "no effect (deprecated)")
        _ = flag.Bool("all", false, "no effect (deprecated)")
        _ = flag.String("tags", "", "no effect (deprecated)")
-       for _, name := range []string{"source", "v", "all", "tags"} {
-               f := flag.Lookup(name)
-               isBool := isBoolFlag(f.Value)
-               analysisFlags = append(analysisFlags, analysisFlag{name, isBool, f.Usage})
-       }
        for old, new := range vetLegacyFlags {
                newFlag := flag.Lookup(new)
                if newFlag != nil && flag.Lookup(old) == nil {
                        flag.Var(newFlag.Value, old, "deprecated alias for -"+new)
-                       isBool := isBoolFlag(newFlag.Value)
-                       analysisFlags = append(analysisFlags, analysisFlag{old, isBool, newFlag.Usage})
                }
        }
 
@@ -89,11 +84,7 @@ func Parse(analyzers []*analysis.Analyzer, multi bool) []*analysis.Analyzer {
 
        // -flags: print flags so that go vet knows which ones are legitimate.
        if *printflags {
-               data, err := json.MarshalIndent(analysisFlags, "", "\t")
-               if err != nil {
-                       log.Fatal(err)
-               }
-               os.Stdout.Write(data)
+               printFlags()
                os.Exit(0)
        }
 
@@ -131,6 +122,33 @@ func Parse(analyzers []*analysis.Analyzer, multi bool) []*analysis.Analyzer {
        return analyzers
 }
 
+func printFlags() {
+       type jsonFlag struct {
+               Name  string
+               Bool  bool
+               Usage string
+       }
+       var flags []jsonFlag = nil
+       flag.VisitAll(func(f *flag.Flag) {
+               // Don't report {single,multi}checker debugging
+               // flags as these have no effect on unitchecker
+               // (as invoked by 'go vet').
+               switch f.Name {
+               case "debug", "cpuprofile", "memprofile", "trace":
+                       return
+               }
+
+               b, ok := f.Value.(interface{ IsBoolFlag() bool })
+               isBool := ok && b.IsBoolFlag()
+               flags = append(flags, jsonFlag{f.Name, isBool, f.Usage})
+       })
+       data, err := json.MarshalIndent(flags, "", "\t")
+       if err != nil {
+               log.Fatal(err)
+       }
+       os.Stdout.Write(data)
+}
+
 // addVersionFlag registers a -V flag that, if set,
 // prints the executable version and exits 0.
 //
@@ -238,11 +256,6 @@ func (ts triState) IsBoolFlag() bool {
        return true
 }
 
-func isBoolFlag(v flag.Value) bool {
-       b, ok := v.(interface{ IsBoolFlag() bool })
-       return ok && b.IsBoolFlag()
-}
-
 // Legacy flag support
 
 // vetLegacyFlags maps flags used by legacy vet to their corresponding
@@ -261,3 +274,70 @@ var vetLegacyFlags = map[string]string{
        "unusedfuncs":         "unusedresult.funcs",
        "unusedstringmethods": "unusedresult.stringmethods",
 }
+
+// ---- output helpers common to all drivers ----
+
+// PrintPlain prints a diagnostic in plain text form,
+// with context specified by the -c flag.
+func PrintPlain(fset *token.FileSet, diag analysis.Diagnostic) {
+       posn := fset.Position(diag.Pos)
+       fmt.Fprintf(os.Stderr, "%s: %s\n", posn, diag.Message)
+
+       // -c=N: show offending line plus N lines of context.
+       if Context >= 0 {
+               data, _ := ioutil.ReadFile(posn.Filename)
+               lines := strings.Split(string(data), "\n")
+               for i := posn.Line - Context; i <= posn.Line+Context; i++ {
+                       if 1 <= i && i <= len(lines) {
+                               fmt.Fprintf(os.Stderr, "%d\t%s\n", i, lines[i-1])
+                       }
+               }
+       }
+}
+
+// A JSONTree is a mapping from package ID to analysis name to result.
+// Each result is either a jsonError or a list of jsonDiagnostic.
+type JSONTree map[string]map[string]interface{}
+
+// Add adds the result of analysis 'name' on package 'id'.
+// The result is either a list of diagnostics or an error.
+func (tree JSONTree) Add(fset *token.FileSet, id, name string, diags []analysis.Diagnostic, err error) {
+       var v interface{}
+       if err != nil {
+               type jsonError struct {
+                       Err string `json:"error"`
+               }
+               v = jsonError{err.Error()}
+       } else if len(diags) > 0 {
+               type jsonDiagnostic struct {
+                       Category string `json:"category,omitempty"`
+                       Posn     string `json:"posn"`
+                       Message  string `json:"message"`
+               }
+               var diagnostics []jsonDiagnostic
+               for _, f := range diags {
+                       diagnostics = append(diagnostics, jsonDiagnostic{
+                               Category: f.Category,
+                               Posn:     fset.Position(f.Pos).String(),
+                               Message:  f.Message,
+                       })
+               }
+               v = diagnostics
+       }
+       if v != nil {
+               m, ok := tree[id]
+               if !ok {
+                       m = make(map[string]interface{})
+                       tree[id] = m
+               }
+               m[name] = v
+       }
+}
+
+func (tree JSONTree) Print() {
+       data, err := json.MarshalIndent(tree, "", "\t")
+       if err != nil {
+               log.Panicf("internal error: JSON marshalling failed: %v", err)
+       }
+       fmt.Printf("%s\n", data)
+}
index edfca577bff89758bc96af8972ece68380f0955c..7b8fec9db28d5593d6ee2bfeb6d8d7c737e912c1 100644 (file)
@@ -25,7 +25,6 @@ package unitchecker
 //   so we will not get to analyze it. Yet we must in order
 //   to create base facts for, say, the fmt package for the
 //   printf checker.
-// - support JSON output, factored with multichecker.
 
 import (
        "encoding/gob"
@@ -57,6 +56,7 @@ import (
 // It is provided to the tool in a JSON-encoded file
 // whose name ends with ".cfg".
 type Config struct {
+       ID                        string // e.g. "fmt [fmt.test]"
        Compiler                  string
        Dir                       string
        ImportPath                string
@@ -127,16 +127,37 @@ func Run(configFile string, analyzers []*analysis.Analyzer) {
        }
 
        fset := token.NewFileSet()
-       diags, err := run(fset, cfg, analyzers)
+       results, err := run(fset, cfg, analyzers)
        if err != nil {
                log.Fatal(err)
        }
 
-       if !cfg.VetxOnly && len(diags) > 0 {
-               for _, diag := range diags {
-                       fmt.Fprintf(os.Stderr, "%s: %s\n", fset.Position(diag.Pos), diag.Message)
+       // In VetxOnly mode, the analysis is run only for facts.
+       if !cfg.VetxOnly {
+               if analysisflags.JSON {
+                       // JSON output
+                       tree := make(analysisflags.JSONTree)
+                       for _, res := range results {
+                               tree.Add(fset, cfg.ID, res.a.Name, res.diagnostics, res.err)
+                       }
+                       tree.Print()
+               } else {
+                       // plain text
+                       exit := 0
+                       for _, res := range results {
+                               if res.err != nil {
+                                       log.Println(res.err)
+                                       exit = 1
+                               }
+                       }
+                       for _, res := range results {
+                               for _, diag := range res.diagnostics {
+                                       analysisflags.PrintPlain(fset, diag)
+                                       exit = 1
+                               }
+                       }
+                       os.Exit(exit)
                }
-               os.Exit(1)
        }
 
        os.Exit(0)
@@ -160,7 +181,7 @@ func readConfig(filename string) (*Config, error) {
        return cfg, nil
 }
 
-func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]analysis.Diagnostic, error) {
+func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]result, error) {
        // Load, parse, typecheck.
        var files []*ast.File
        for _, name := range cfg.GoFiles {
@@ -333,14 +354,13 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]an
 
        execAll(analyzers)
 
-       // Return diagnostics from root analyzers.
-       var diags []analysis.Diagnostic
-       for _, a := range analyzers {
+       // Return diagnostics and errors from root analyzers.
+       results := make([]result, len(analyzers))
+       for i, a := range analyzers {
                act := actions[a]
-               if act.err != nil {
-                       return nil, act.err // some analysis failed
-               }
-               diags = append(diags, act.diagnostics...)
+               results[i].a = a
+               results[i].err = act.err
+               results[i].diagnostics = act.diagnostics
        }
 
        data := facts.Encode()
@@ -348,7 +368,13 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]an
                return nil, fmt.Errorf("failed to write analysis facts: %v", err)
        }
 
-       return diags, nil
+       return results, nil
+}
+
+type result struct {
+       a           *analysis.Analyzer
+       diagnostics []analysis.Diagnostic
+       err         error
 }
 
 type importerFunc func(path string) (*types.Package, error)