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 / lint / lintutil / format / format.go
1 // Package format provides formatters for linter problems.
2 package format
3
4 import (
5         "encoding/json"
6         "fmt"
7         "go/token"
8         "io"
9         "os"
10         "path/filepath"
11         "text/tabwriter"
12
13         "honnef.co/go/tools/lint"
14 )
15
16 func shortPath(path string) string {
17         cwd, err := os.Getwd()
18         if err != nil {
19                 return path
20         }
21         if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
22                 return rel
23         }
24         return path
25 }
26
27 func relativePositionString(pos token.Position) string {
28         s := shortPath(pos.Filename)
29         if pos.IsValid() {
30                 if s != "" {
31                         s += ":"
32                 }
33                 s += fmt.Sprintf("%d:%d", pos.Line, pos.Column)
34         }
35         if s == "" {
36                 s = "-"
37         }
38         return s
39 }
40
41 type Statter interface {
42         Stats(total, errors, warnings, ignored int)
43 }
44
45 type Formatter interface {
46         Format(p lint.Problem)
47 }
48
49 type Text struct {
50         W io.Writer
51 }
52
53 func (o Text) Format(p lint.Problem) {
54         fmt.Fprintf(o.W, "%s: %s\n", relativePositionString(p.Pos), p.String())
55         for _, r := range p.Related {
56                 fmt.Fprintf(o.W, "\t%s: %s\n", relativePositionString(r.Pos), r.Message)
57         }
58 }
59
60 type JSON struct {
61         W io.Writer
62 }
63
64 func severity(s lint.Severity) string {
65         switch s {
66         case lint.Error:
67                 return "error"
68         case lint.Warning:
69                 return "warning"
70         case lint.Ignored:
71                 return "ignored"
72         }
73         return ""
74 }
75
76 func (o JSON) Format(p lint.Problem) {
77         type location struct {
78                 File   string `json:"file"`
79                 Line   int    `json:"line"`
80                 Column int    `json:"column"`
81         }
82         type related struct {
83                 Location location `json:"location"`
84                 End      location `json:"end"`
85                 Message  string   `json:"message"`
86         }
87         jp := struct {
88                 Code     string    `json:"code"`
89                 Severity string    `json:"severity,omitempty"`
90                 Location location  `json:"location"`
91                 End      location  `json:"end"`
92                 Message  string    `json:"message"`
93                 Related  []related `json:"related,omitempty"`
94         }{
95                 Code:     p.Check,
96                 Severity: severity(p.Severity),
97                 Location: location{
98                         File:   p.Pos.Filename,
99                         Line:   p.Pos.Line,
100                         Column: p.Pos.Column,
101                 },
102                 End: location{
103                         File:   p.End.Filename,
104                         Line:   p.End.Line,
105                         Column: p.End.Column,
106                 },
107                 Message: p.Message,
108         }
109         for _, r := range p.Related {
110                 jp.Related = append(jp.Related, related{
111                         Location: location{
112                                 File:   r.Pos.Filename,
113                                 Line:   r.Pos.Line,
114                                 Column: r.Pos.Column,
115                         },
116                         End: location{
117                                 File:   r.End.Filename,
118                                 Line:   r.End.Line,
119                                 Column: r.End.Column,
120                         },
121                         Message: r.Message,
122                 })
123         }
124         _ = json.NewEncoder(o.W).Encode(jp)
125 }
126
127 type Stylish struct {
128         W io.Writer
129
130         prevFile string
131         tw       *tabwriter.Writer
132 }
133
134 func (o *Stylish) Format(p lint.Problem) {
135         pos := p.Pos
136         if pos.Filename == "" {
137                 pos.Filename = "-"
138         }
139
140         if pos.Filename != o.prevFile {
141                 if o.prevFile != "" {
142                         o.tw.Flush()
143                         fmt.Fprintln(o.W)
144                 }
145                 fmt.Fprintln(o.W, pos.Filename)
146                 o.prevFile = pos.Filename
147                 o.tw = tabwriter.NewWriter(o.W, 0, 4, 2, ' ', 0)
148         }
149         fmt.Fprintf(o.tw, "  (%d, %d)\t%s\t%s\n", pos.Line, pos.Column, p.Check, p.Message)
150         for _, r := range p.Related {
151                 fmt.Fprintf(o.tw, "    (%d, %d)\t\t  %s\n", r.Pos.Line, r.Pos.Column, r.Message)
152         }
153 }
154
155 func (o *Stylish) Stats(total, errors, warnings, ignored int) {
156         if o.tw != nil {
157                 o.tw.Flush()
158                 fmt.Fprintln(o.W)
159         }
160         fmt.Fprintf(o.W, " ✖ %d problems (%d errors, %d warnings, %d ignored)\n",
161                 total, errors, warnings, ignored)
162 }