diff options
Diffstat (limited to 'vendor/honnef.co/go/tools/facts/generated.go')
-rw-r--r-- | vendor/honnef.co/go/tools/facts/generated.go | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/vendor/honnef.co/go/tools/facts/generated.go b/vendor/honnef.co/go/tools/facts/generated.go new file mode 100644 index 0000000..1ed9563 --- /dev/null +++ b/vendor/honnef.co/go/tools/facts/generated.go | |||
@@ -0,0 +1,86 @@ | |||
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 | ) | ||
23 | |||
24 | var ( | ||
25 | // used by cgo before Go 1.11 | ||
26 | oldCgo = []byte("// Created by cgo - DO NOT EDIT") | ||
27 | prefix = []byte("// Code generated ") | ||
28 | suffix = []byte(" DO NOT EDIT.") | ||
29 | nl = []byte("\n") | ||
30 | crnl = []byte("\r\n") | ||
31 | ) | ||
32 | |||
33 | func isGenerated(path string) (Generator, bool) { | ||
34 | f, err := os.Open(path) | ||
35 | if err != nil { | ||
36 | return 0, false | ||
37 | } | ||
38 | defer f.Close() | ||
39 | br := bufio.NewReader(f) | ||
40 | for { | ||
41 | s, err := br.ReadBytes('\n') | ||
42 | if err != nil && err != io.EOF { | ||
43 | return 0, false | ||
44 | } | ||
45 | s = bytes.TrimSuffix(s, crnl) | ||
46 | s = bytes.TrimSuffix(s, nl) | ||
47 | if bytes.HasPrefix(s, prefix) && bytes.HasSuffix(s, suffix) { | ||
48 | text := string(s[len(prefix) : len(s)-len(suffix)]) | ||
49 | switch text { | ||
50 | case "by goyacc.": | ||
51 | return Goyacc, true | ||
52 | case "by cmd/cgo;": | ||
53 | return Cgo, true | ||
54 | } | ||
55 | if strings.HasPrefix(text, `by "stringer `) { | ||
56 | return Stringer, true | ||
57 | } | ||
58 | return Unknown, true | ||
59 | } | ||
60 | if bytes.Equal(s, oldCgo) { | ||
61 | return Cgo, true | ||
62 | } | ||
63 | if err == io.EOF { | ||
64 | break | ||
65 | } | ||
66 | } | ||
67 | return 0, false | ||
68 | } | ||
69 | |||
70 | var Generated = &analysis.Analyzer{ | ||
71 | Name: "isgenerated", | ||
72 | Doc: "annotate file names that have been code generated", | ||
73 | Run: func(pass *analysis.Pass) (interface{}, error) { | ||
74 | m := map[string]Generator{} | ||
75 | for _, f := range pass.Files { | ||
76 | path := pass.Fset.PositionFor(f.Pos(), false).Filename | ||
77 | g, ok := isGenerated(path) | ||
78 | if ok { | ||
79 | m[path] = g | ||
80 | } | ||
81 | } | ||
82 | return m, nil | ||
83 | }, | ||
84 | RunDespiteErrors: true, | ||
85 | ResultType: reflect.TypeOf(map[string]Generator{}), | ||
86 | } | ||