-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfinding.go
More file actions
78 lines (73 loc) · 2.15 KB
/
Copy pathfinding.go
File metadata and controls
78 lines (73 loc) · 2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package goago
import (
"go/token"
"sort"
)
// A Finding is one reported violation, in the form the report writers consume.
// It is deliberately a flat value rather than an [analysis.Diagnostic] so that
// the JSON schema is stable across x/tools upgrades.
type Finding struct {
// Rule is the canonical kebab-case rule name.
Rule string `json:"rule"`
// Severity is the rule's severity.
Severity Severity `json:"severity"`
// Message states what is wrong and what to write instead.
Message string `json:"message"`
// File is the path as the caller passed it, slash separated.
File string `json:"file"`
// Line and Column are 1-based, matching go vet and gofmt.
Line int `json:"line"`
Column int `json:"column"`
// EndLine and EndColumn bound the offending syntax. They equal Line and
// Column when the rule reports a point rather than a range.
EndLine int `json:"endLine"`
EndColumn int `json:"endColumn"`
// DocURL points at the rule's section in the README.
DocURL string `json:"docURL"`
}
// Position renders the finding in the file:line:col form that editors and
// terminals link on.
func (f Finding) Position() string {
return token.Position{Filename: f.File, Line: f.Line, Column: f.Column}.String()
}
// sortFindings orders findings by file, then line, then column, then rule. This
// order produces the same output bytes across runs and supports CI diffs.
func sortFindings(fs []Finding) {
sort.SliceStable(fs, func(i, j int) bool {
a, b := fs[i], fs[j]
switch {
case a.File != b.File:
return a.File < b.File
case a.Line != b.Line:
return a.Line < b.Line
case a.Column != b.Column:
return a.Column < b.Column
default:
return a.Rule < b.Rule
}
})
}
// dedupe removes findings that are identical in rule and position, which
// happens when the command line names the same package twice.
func dedupe(fs []Finding) []Finding {
if len(fs) < 2 {
return fs
}
type key struct {
rule string
file string
line int
col int
}
seen := make(map[key]bool, len(fs))
out := fs[:0]
for _, f := range fs {
k := key{f.Rule, f.File, f.Line, f.Column}
if seen[k] {
continue
}
seen[k] = true
out = append(out, f)
}
return out
}