Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.0.1-2020.1.5 / facts / generated.go
1 package facts
2
3 import (
4         "bufio"
5         "bytes"
6         "io"
7         "os"
8         "reflect"
9         "strings"
10
11         "golang.org/x/tools/go/analysis"
12 )
13
14 type Generator int
15
16 // A list of known generators we can detect
17 const (
18         Unknown Generator = iota
19         Goyacc
20         Cgo
21         Stringer
22         ProtocGenGo
23 )
24
25 var (
26         // used by cgo before Go 1.11
27         oldCgo = []byte("// Created by cgo - DO NOT EDIT")
28         prefix = []byte("// Code generated ")
29         suffix = []byte(" DO NOT EDIT.")
30         nl     = []byte("\n")
31         crnl   = []byte("\r\n")
32 )
33
34 func isGenerated(path string) (Generator, bool) {
35         f, err := os.Open(path)
36         if err != nil {
37                 return 0, false
38         }
39         defer f.Close()
40         br := bufio.NewReader(f)
41         for {
42                 s, err := br.ReadBytes('\n')
43                 if err != nil && err != io.EOF {
44                         return 0, false
45                 }
46                 s = bytes.TrimSuffix(s, crnl)
47                 s = bytes.TrimSuffix(s, nl)
48                 if bytes.HasPrefix(s, prefix) && bytes.HasSuffix(s, suffix) {
49                         text := string(s[len(prefix) : len(s)-len(suffix)])
50                         switch text {
51                         case "by goyacc.":
52                                 return Goyacc, true
53                         case "by cmd/cgo;":
54                                 return Cgo, true
55                         case "by protoc-gen-go.":
56                                 return ProtocGenGo, true
57                         }
58                         if strings.HasPrefix(text, `by "stringer `) {
59                                 return Stringer, true
60                         }
61                         if strings.HasPrefix(text, `by goyacc `) {
62                                 return Goyacc, true
63                         }
64
65                         return Unknown, true
66                 }
67                 if bytes.Equal(s, oldCgo) {
68                         return Cgo, true
69                 }
70                 if err == io.EOF {
71                         break
72                 }
73         }
74         return 0, false
75 }
76
77 var Generated = &analysis.Analyzer{
78         Name: "isgenerated",
79         Doc:  "annotate file names that have been code generated",
80         Run: func(pass *analysis.Pass) (interface{}, error) {
81                 m := map[string]Generator{}
82                 for _, f := range pass.Files {
83                         path := pass.Fset.PositionFor(f.Pos(), false).Filename
84                         g, ok := isGenerated(path)
85                         if ok {
86                                 m[path] = g
87                         }
88                 }
89                 return m, nil
90         },
91         RunDespiteErrors: true,
92         ResultType:       reflect.TypeOf(map[string]Generator{}),
93 }