github.com/yukk001/go1.10.8@v0.0.0-20190813125351-6df2d3982e20/src/cmd/go/internal/vet/vetflag.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package vet 6 7 import ( 8 "flag" 9 "fmt" 10 "os" 11 "strings" 12 13 "cmd/go/internal/base" 14 "cmd/go/internal/cmdflag" 15 "cmd/go/internal/work" 16 ) 17 18 const cmd = "vet" 19 20 // vetFlagDefn is the set of flags we process. 21 var vetFlagDefn = []*cmdflag.Defn{ 22 // Note: Some flags, in particular -tags and -v, are known to 23 // vet but also defined as build flags. This works fine, so we 24 // don't define them here but use AddBuildFlags to init them. 25 // However some, like -x, are known to the build but not 26 // to vet. We handle them in vetFlags. 27 28 // local. 29 {Name: "all", BoolVar: new(bool)}, 30 {Name: "asmdecl", BoolVar: new(bool)}, 31 {Name: "assign", BoolVar: new(bool)}, 32 {Name: "atomic", BoolVar: new(bool)}, 33 {Name: "bool", BoolVar: new(bool)}, 34 {Name: "buildtags", BoolVar: new(bool)}, 35 {Name: "cgocall", BoolVar: new(bool)}, 36 {Name: "composites", BoolVar: new(bool)}, 37 {Name: "copylocks", BoolVar: new(bool)}, 38 {Name: "httpresponse", BoolVar: new(bool)}, 39 {Name: "lostcancel", BoolVar: new(bool)}, 40 {Name: "methods", BoolVar: new(bool)}, 41 {Name: "nilfunc", BoolVar: new(bool)}, 42 {Name: "printf", BoolVar: new(bool)}, 43 {Name: "printfuncs"}, 44 {Name: "rangeloops", BoolVar: new(bool)}, 45 {Name: "shadow", BoolVar: new(bool)}, 46 {Name: "shadowstrict", BoolVar: new(bool)}, 47 {Name: "shift", BoolVar: new(bool)}, 48 {Name: "source", BoolVar: new(bool)}, 49 {Name: "structtags", BoolVar: new(bool)}, 50 {Name: "tests", BoolVar: new(bool)}, 51 {Name: "unreachable", BoolVar: new(bool)}, 52 {Name: "unsafeptr", BoolVar: new(bool)}, 53 {Name: "unusedfuncs"}, 54 {Name: "unusedresult", BoolVar: new(bool)}, 55 {Name: "unusedstringmethods"}, 56 } 57 58 var vetTool string 59 60 // add build flags to vetFlagDefn. 61 func init() { 62 var cmd base.Command 63 work.AddBuildFlags(&cmd) 64 cmd.Flag.StringVar(&vetTool, "vettool", "", "path to vet tool binary") // for cmd/vet tests; undocumented for now 65 cmd.Flag.VisitAll(func(f *flag.Flag) { 66 vetFlagDefn = append(vetFlagDefn, &cmdflag.Defn{ 67 Name: f.Name, 68 Value: f.Value, 69 }) 70 }) 71 } 72 73 // vetFlags processes the command line, splitting it at the first non-flag 74 // into the list of flags and list of packages. 75 func vetFlags(args []string) (passToVet, packageNames []string) { 76 for i := 0; i < len(args); i++ { 77 if !strings.HasPrefix(args[i], "-") { 78 return args[:i], args[i:] 79 } 80 81 f, value, extraWord := cmdflag.Parse(cmd, vetFlagDefn, args, i) 82 if f == nil { 83 fmt.Fprintf(os.Stderr, "vet: flag %q not defined\n", args[i]) 84 fmt.Fprintf(os.Stderr, "Run \"go help vet\" for more information\n") 85 os.Exit(2) 86 } 87 if f.Value != nil { 88 if err := f.Value.Set(value); err != nil { 89 base.Fatalf("invalid flag argument for -%s: %v", f.Name, err) 90 } 91 switch f.Name { 92 // Flags known to the build but not to vet, so must be dropped. 93 case "x", "n", "vettool": 94 if extraWord { 95 args = append(args[:i], args[i+2:]...) 96 extraWord = false 97 } else { 98 args = append(args[:i], args[i+1:]...) 99 } 100 i-- 101 } 102 } 103 if extraWord { 104 i++ 105 } 106 } 107 return args, nil 108 }