some deletions
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / analysis / passes / structtag / structtag.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/analysis/passes/structtag/structtag.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/analysis/passes/structtag/structtag.go
deleted file mode 100644 (file)
index f0b1505..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package structtag defines an Analyzer that checks struct field tags
-// are well formed.
-package structtag
-
-import (
-       "errors"
-       "go/ast"
-       "go/token"
-       "go/types"
-       "path/filepath"
-       "reflect"
-       "strconv"
-       "strings"
-
-       "golang.org/x/tools/go/analysis"
-       "golang.org/x/tools/go/analysis/passes/inspect"
-       "golang.org/x/tools/go/ast/inspector"
-)
-
-const Doc = `check that struct field tags conform to reflect.StructTag.Get
-
-Also report certain struct tags (json, xml) used with unexported fields.`
-
-var Analyzer = &analysis.Analyzer{
-       Name:             "structtag",
-       Doc:              Doc,
-       Requires:         []*analysis.Analyzer{inspect.Analyzer},
-       RunDespiteErrors: true,
-       Run:              run,
-}
-
-func run(pass *analysis.Pass) (interface{}, error) {
-       inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
-
-       nodeFilter := []ast.Node{
-               (*ast.StructType)(nil),
-       }
-       inspect.Preorder(nodeFilter, func(n ast.Node) {
-               styp, ok := pass.TypesInfo.Types[n.(*ast.StructType)].Type.(*types.Struct)
-               // Type information may be incomplete.
-               if !ok {
-                       return
-               }
-               var seen namesSeen
-               for i := 0; i < styp.NumFields(); i++ {
-                       field := styp.Field(i)
-                       tag := styp.Tag(i)
-                       checkCanonicalFieldTag(pass, field, tag, &seen)
-               }
-       })
-       return nil, nil
-}
-
-// namesSeen keeps track of encoding tags by their key, name, and nested level
-// from the initial struct. The level is taken into account because equal
-// encoding key names only conflict when at the same level; otherwise, the lower
-// level shadows the higher level.
-type namesSeen map[uniqueName]token.Pos
-
-type uniqueName struct {
-       key   string // "xml" or "json"
-       name  string // the encoding name
-       level int    // anonymous struct nesting level
-}
-
-func (s *namesSeen) Get(key, name string, level int) (token.Pos, bool) {
-       if *s == nil {
-               *s = make(map[uniqueName]token.Pos)
-       }
-       pos, ok := (*s)[uniqueName{key, name, level}]
-       return pos, ok
-}
-
-func (s *namesSeen) Set(key, name string, level int, pos token.Pos) {
-       if *s == nil {
-               *s = make(map[uniqueName]token.Pos)
-       }
-       (*s)[uniqueName{key, name, level}] = pos
-}
-
-var checkTagDups = []string{"json", "xml"}
-var checkTagSpaces = map[string]bool{"json": true, "xml": true, "asn1": true}
-
-// checkCanonicalFieldTag checks a single struct field tag.
-func checkCanonicalFieldTag(pass *analysis.Pass, field *types.Var, tag string, seen *namesSeen) {
-       switch pass.Pkg.Path() {
-       case "encoding/json", "encoding/xml":
-               // These packages know how to use their own APIs.
-               // Sometimes they are testing what happens to incorrect programs.
-               return
-       }
-
-       for _, key := range checkTagDups {
-               checkTagDuplicates(pass, tag, key, field, field, seen, 1)
-       }
-
-       if err := validateStructTag(tag); err != nil {
-               pass.Reportf(field.Pos(), "struct field tag %#q not compatible with reflect.StructTag.Get: %s", tag, err)
-       }
-
-       // Check for use of json or xml tags with unexported fields.
-
-       // Embedded struct. Nothing to do for now, but that
-       // may change, depending on what happens with issue 7363.
-       // TODO(adonovan): investigate, now that that issue is fixed.
-       if field.Anonymous() {
-               return
-       }
-
-       if field.Exported() {
-               return
-       }
-
-       for _, enc := range [...]string{"json", "xml"} {
-               switch reflect.StructTag(tag).Get(enc) {
-               // Ignore warning if the field not exported and the tag is marked as
-               // ignored.
-               case "", "-":
-               default:
-                       pass.Reportf(field.Pos(), "struct field %s has %s tag but is not exported", field.Name(), enc)
-                       return
-               }
-       }
-}
-
-// checkTagDuplicates checks a single struct field tag to see if any tags are
-// duplicated. nearest is the field that's closest to the field being checked,
-// while still being part of the top-level struct type.
-func checkTagDuplicates(pass *analysis.Pass, tag, key string, nearest, field *types.Var, seen *namesSeen, level int) {
-       val := reflect.StructTag(tag).Get(key)
-       if val == "-" {
-               // Ignored, even if the field is anonymous.
-               return
-       }
-       if val == "" || val[0] == ',' {
-               if !field.Anonymous() {
-                       // Ignored if the field isn't anonymous.
-                       return
-               }
-               typ, ok := field.Type().Underlying().(*types.Struct)
-               if !ok {
-                       return
-               }
-               for i := 0; i < typ.NumFields(); i++ {
-                       field := typ.Field(i)
-                       if !field.Exported() {
-                               continue
-                       }
-                       tag := typ.Tag(i)
-                       checkTagDuplicates(pass, tag, key, nearest, field, seen, level+1)
-               }
-               return
-       }
-       if key == "xml" && field.Name() == "XMLName" {
-               // XMLName defines the XML element name of the struct being
-               // checked. That name cannot collide with element or attribute
-               // names defined on other fields of the struct. Vet does not have a
-               // check for untagged fields of type struct defining their own name
-               // by containing a field named XMLName; see issue 18256.
-               return
-       }
-       if i := strings.Index(val, ","); i >= 0 {
-               if key == "xml" {
-                       // Use a separate namespace for XML attributes.
-                       for _, opt := range strings.Split(val[i:], ",") {
-                               if opt == "attr" {
-                                       key += " attribute" // Key is part of the error message.
-                                       break
-                               }
-                       }
-               }
-               val = val[:i]
-       }
-       if pos, ok := seen.Get(key, val, level); ok {
-               alsoPos := pass.Fset.Position(pos)
-               alsoPos.Column = 0
-
-               // Make the "also at" position relative to the current position,
-               // to ensure that all warnings are unambiguous and correct. For
-               // example, via anonymous struct fields, it's possible for the
-               // two fields to be in different packages and directories.
-               thisPos := pass.Fset.Position(field.Pos())
-               rel, err := filepath.Rel(filepath.Dir(thisPos.Filename), alsoPos.Filename)
-               if err != nil {
-                       // Possibly because the paths are relative; leave the
-                       // filename alone.
-               } else {
-                       alsoPos.Filename = rel
-               }
-
-               pass.Reportf(nearest.Pos(), "struct field %s repeats %s tag %q also at %s", field.Name(), key, val, alsoPos)
-       } else {
-               seen.Set(key, val, level, field.Pos())
-       }
-}
-
-var (
-       errTagSyntax      = errors.New("bad syntax for struct tag pair")
-       errTagKeySyntax   = errors.New("bad syntax for struct tag key")
-       errTagValueSyntax = errors.New("bad syntax for struct tag value")
-       errTagValueSpace  = errors.New("suspicious space in struct tag value")
-       errTagSpace       = errors.New("key:\"value\" pairs not separated by spaces")
-)
-
-// validateStructTag parses the struct tag and returns an error if it is not
-// in the canonical format, which is a space-separated list of key:"value"
-// settings. The value may contain spaces.
-func validateStructTag(tag string) error {
-       // This code is based on the StructTag.Get code in package reflect.
-
-       n := 0
-       for ; tag != ""; n++ {
-               if n > 0 && tag != "" && tag[0] != ' ' {
-                       // More restrictive than reflect, but catches likely mistakes
-                       // like `x:"foo",y:"bar"`, which parses as `x:"foo" ,y:"bar"` with second key ",y".
-                       return errTagSpace
-               }
-               // Skip leading space.
-               i := 0
-               for i < len(tag) && tag[i] == ' ' {
-                       i++
-               }
-               tag = tag[i:]
-               if tag == "" {
-                       break
-               }
-
-               // Scan to colon. A space, a quote or a control character is a syntax error.
-               // Strictly speaking, control chars include the range [0x7f, 0x9f], not just
-               // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
-               // as it is simpler to inspect the tag's bytes than the tag's runes.
-               i = 0
-               for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
-                       i++
-               }
-               if i == 0 {
-                       return errTagKeySyntax
-               }
-               if i+1 >= len(tag) || tag[i] != ':' {
-                       return errTagSyntax
-               }
-               if tag[i+1] != '"' {
-                       return errTagValueSyntax
-               }
-               key := tag[:i]
-               tag = tag[i+1:]
-
-               // Scan quoted string to find value.
-               i = 1
-               for i < len(tag) && tag[i] != '"' {
-                       if tag[i] == '\\' {
-                               i++
-                       }
-                       i++
-               }
-               if i >= len(tag) {
-                       return errTagValueSyntax
-               }
-               qvalue := tag[:i+1]
-               tag = tag[i+1:]
-
-               value, err := strconv.Unquote(qvalue)
-               if err != nil {
-                       return errTagValueSyntax
-               }
-
-               if !checkTagSpaces[key] {
-                       continue
-               }
-
-               switch key {
-               case "xml":
-                       // If the first or last character in the XML tag is a space, it is
-                       // suspicious.
-                       if strings.Trim(value, " ") != value {
-                               return errTagValueSpace
-                       }
-
-                       // If there are multiple spaces, they are suspicious.
-                       if strings.Count(value, " ") > 1 {
-                               return errTagValueSpace
-                       }
-
-                       // If there is no comma, skip the rest of the checks.
-                       comma := strings.IndexRune(value, ',')
-                       if comma < 0 {
-                               continue
-                       }
-
-                       // If the character before a comma is a space, this is suspicious.
-                       if comma > 0 && value[comma-1] == ' ' {
-                               return errTagValueSpace
-                       }
-                       value = value[comma+1:]
-               case "json":
-                       // JSON allows using spaces in the name, so skip it.
-                       comma := strings.IndexRune(value, ',')
-                       if comma < 0 {
-                               continue
-                       }
-                       value = value[comma+1:]
-               }
-
-               if strings.IndexByte(value, ' ') >= 0 {
-                       return errTagValueSpace
-               }
-       }
-       return nil
-}