github.com/MangoDowner/go-gm@v0.0.0-20180818020936-8baa2bd4408c/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: "source", BoolVar: new(bool)},
    48  	{Name: "structtags", BoolVar: new(bool)},
    49  	{Name: "tests", BoolVar: new(bool)},
    50  	{Name: "unreachable", BoolVar: new(bool)},
    51  	{Name: "unsafeptr", BoolVar: new(bool)},
    52  	{Name: "unusedfuncs"},
    53  	{Name: "unusedresult", BoolVar: new(bool)},
    54  	{Name: "unusedstringmethods"},
    55  }
    56  
    57  // add build flags to vetFlagDefn.
    58  func init() {
    59  	var cmd base.Command
    60  	work.AddBuildFlags(&cmd)
    61  	cmd.Flag.VisitAll(func(f *flag.Flag) {
    62  		vetFlagDefn = append(vetFlagDefn, &cmdflag.Defn{
    63  			Name:  f.Name,
    64  			Value: f.Value,
    65  		})
    66  	})
    67  }
    68  
    69  // vetFlags processes the command line, splitting it at the first non-flag
    70  // into the list of flags and list of packages.
    71  func vetFlags(args []string) (passToVet, packageNames []string) {
    72  	for i := 0; i < len(args); i++ {
    73  		if !strings.HasPrefix(args[i], "-") {
    74  			return args[:i], args[i:]
    75  		}
    76  
    77  		f, value, extraWord := cmdflag.Parse(cmd, vetFlagDefn, args, i)
    78  		if f == nil {
    79  			fmt.Fprintf(os.Stderr, "vet: flag %q not defined\n", args[i])
    80  			fmt.Fprintf(os.Stderr, "Run \"go help vet\" for more information\n")
    81  			os.Exit(2)
    82  		}
    83  		if f.Value != nil {
    84  			if err := f.Value.Set(value); err != nil {
    85  				base.Fatalf("invalid flag argument for -%s: %v", f.Name, err)
    86  			}
    87  			switch f.Name {
    88  			// Flags known to the build but not to vet, so must be dropped.
    89  			case "x", "n":
    90  				args = append(args[:i], args[i+1:]...)
    91  				i--
    92  			}
    93  		}
    94  		if extraWord {
    95  			i++
    96  		}
    97  	}
    98  	return args, nil
    99  }