Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions rule/package_comments.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,16 @@ func (l *lintPackageComments) Visit(_ ast.Node) ast.Visitor {
lastCG = cg
}
if lastCG != nil && strings.HasPrefix(lastCG.Text(), prefix) {
endPos := l.file.ToPosition(lastCG.End())
endLine := commentGroupEndLine(l.file, lastCG)
pkgPos := l.file.ToPosition(l.fileAst.Package)
if endPos.Line+1 < pkgPos.Line {
if endLine+1 < pkgPos.Line {
// There isn't a great place to anchor this error;
// the start of the blank lines between the doc and the package statement
// is at least pointing at the location of the problem.
pos := token.Position{
Filename: endPos.Filename,
Filename: pkgPos.Filename,
// Offset not set; it is non-trivial, and doesn't appear to be needed.
Line: endPos.Line + 1,
Line: endLine + 1,
Column: 1,
}
l.onFailure(lint.Failure{
Expand Down Expand Up @@ -163,6 +163,16 @@ func (l *lintPackageComments) Visit(_ ast.Node) ast.Visitor {
return nil
}

// commentGroupEndLine returns the line of the last character of the given comment group.
//
// It does not rely on [ast.CommentGroup.End] because that position is derived from the
// comment text, from which the scanner strips carriage returns. On CRLF sources End()
// therefore points before the actual end of a block comment (see https://go.dev/issue/41197).
func commentGroupEndLine(file *lint.File, cg *ast.CommentGroup) int {
lastComment := cg.List[len(cg.List)-1]
return file.ToPosition(lastComment.Slash).Line + strings.Count(lastComment.Text, "\n")
}

func isEmptyDoc(commentGroup *ast.CommentGroup) bool {
return commentGroup == nil || commentGroup.Text() == ""
}
13 changes: 13 additions & 0 deletions test/package_comments_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package test_test

import (
"testing"

"github.com/mgechev/revive/rule"
)

func TestPackageComments(t *testing.T) {
testRule(t, "package_comments/issue607_not_match", &rule.PackageCommentsRule{})
testRule(t, "package_comments/issue607_match", &rule.PackageCommentsRule{})
testRule(t, "package_comments/issue607_drift_not_match", &rule.PackageCommentsRule{})
}
2 changes: 2 additions & 0 deletions testdata/package_comments/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Fixtures in this directory must keep Windows line endings.
*.go text eol=crlf
9 changes: 9 additions & 0 deletions testdata/package_comments/issue607_drift_not_match.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
Package fixtures has a multi-line comment.





*/
package fixtures
8 changes: 8 additions & 0 deletions testdata/package_comments/issue607_match.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Package fixtures has a multi-line comment.
Its line endings have a carriage return.
*/

package fixtures

// MATCH:5 /package comment is detached; there should be no blank lines between it and the package statement/
5 changes: 5 additions & 0 deletions testdata/package_comments/issue607_not_match.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/*
Package fixtures has a multi-line comment.
Its line endings have a carriage return.
*/
package fixtures