Skip to content

Commit f5cca90

Browse files
authored
goheader: fix invalid position (#5238)
1 parent c3e693d commit f5cca90

File tree

4 files changed

+56
-16
lines changed

4 files changed

+56
-16
lines changed

pkg/golinters/goheader/goheader.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,31 +65,56 @@ func runGoHeader(pass *analysis.Pass, conf *goheader.Configuration) error {
6565
for _, file := range pass.Files {
6666
position := goanalysis.GetFilePosition(pass, file)
6767

68+
if !strings.HasSuffix(position.Filename, ".go") {
69+
continue
70+
}
71+
6872
issue := a.Analyze(&goheader.Target{File: file, Path: position.Filename})
6973
if issue == nil {
7074
continue
7175
}
7276

7377
f := pass.Fset.File(file.Pos())
7478

75-
start := f.LineStart(issue.Location().Line + 1)
79+
commentLine := 1
80+
var offset int
81+
82+
// Inspired by https://github.com/denis-tingaikin/go-header/blob/4c75a6a2332f025705325d6c71fff4616aedf48f/analyzer.go#L85-L92
83+
if len(file.Comments) > 0 && file.Comments[0].Pos() < file.Package {
84+
if !strings.HasPrefix(file.Comments[0].List[0].Text, "/*") {
85+
// When the comment are "//" there is a one character offset.
86+
offset = 1
87+
}
88+
commentLine = goanalysis.GetFilePositionFor(pass.Fset, file.Comments[0].Pos()).Line
89+
}
7690

7791
diag := analysis.Diagnostic{
78-
Pos: start,
92+
Pos: f.LineStart(issue.Location().Line+1) + token.Pos(issue.Location().Position-offset), // The position of the first divergence.
7993
Message: issue.Message(),
8094
}
8195

8296
if fix := issue.Fix(); fix != nil {
83-
end := len(fix.Actual)
97+
current := len(fix.Actual)
8498
for _, s := range fix.Actual {
85-
end += len(s)
99+
current += len(s)
100+
}
101+
102+
start := f.LineStart(commentLine)
103+
104+
end := start + token.Pos(current)
105+
106+
header := strings.Join(fix.Expected, "\n") + "\n"
107+
108+
// Adds an extra line between the package and the header.
109+
if end == file.Package {
110+
header += "\n"
86111
}
87112

88113
diag.SuggestedFixes = []analysis.SuggestedFix{{
89114
TextEdits: []analysis.TextEdit{{
90115
Pos: start,
91-
End: start + token.Pos(end),
92-
NewText: []byte(strings.Join(fix.Expected, "\n") + "\n"),
116+
End: end,
117+
NewText: []byte(header),
93118
}},
94119
}}
95120
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
Copyright 2024 The Awesome Project Authors
3+
4+
Use of this source code is governed by LICENSE.md
5+
*/
6+
7+
//golangcitest:args -Egoheader
8+
//golangcitest:expected_exitcode 0
9+
//golangcitest:config_path testdata/goheader-fix.yml
10+
package p
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
Copyright 2024 The Awesome Project Authors
3+
4+
Use of this source code is governed by LICENSE
5+
*/
6+
7+
//golangcitest:args -Egoheader
8+
//golangcitest:expected_exitcode 0
9+
//golangcitest:config_path testdata/goheader-fix.yml
10+
package p

pkg/result/processors/fixer.go

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"errors"
1111
"fmt"
1212
"go/format"
13-
"go/token"
1413
"os"
1514
"slices"
1615

@@ -77,7 +76,7 @@ func (p Fixer) process(issues []result.Issue) ([]result.Issue, error) {
7776
for i := range issues {
7877
issue := issues[i]
7978

80-
if issue.SuggestedFixes == nil || skipTextEditWithoutPosition(&issue) {
79+
if issue.SuggestedFixes == nil || skipNoTextEdit(&issue) {
8180
notFixableIssues = append(notFixableIssues, issue)
8281
continue
8382
}
@@ -197,19 +196,15 @@ func (p Fixer) printStat() {
197196
p.sw.PrintStages()
198197
}
199198

200-
func skipTextEditWithoutPosition(issue *result.Issue) bool {
199+
func skipNoTextEdit(issue *result.Issue) bool {
201200
var onlyMessage int
202-
var count int
203201
for _, sf := range issue.SuggestedFixes {
204-
for _, edit := range sf.TextEdits {
205-
count++
206-
if edit.Pos == token.NoPos && edit.End == token.NoPos {
207-
onlyMessage++
208-
}
202+
if len(sf.TextEdits) == 0 {
203+
onlyMessage++
209204
}
210205
}
211206

212-
return count == onlyMessage
207+
return len(issue.SuggestedFixes) == onlyMessage
213208
}
214209

215210
// validateEdits returns a list of edits that is sorted and

0 commit comments

Comments
 (0)