Skip to content

Commit

Permalink
Rename 'issue' to 'position'.
Browse files Browse the repository at this point in the history
  • Loading branch information
Denis Krivak committed May 16, 2020
1 parent 93d86a1 commit d220581
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 60 deletions.
41 changes: 20 additions & 21 deletions godot.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,24 @@ import (

const noPeriodMessage = "Top level comment should end in a period"

// Settings contains linter settings.
type Settings struct {
// Check all top-level comments, not only declarations
CheckAll bool
}

// Issue contains a description of linting error and a possible replacement.
type Issue struct {
Pos token.Position
Message string
}

// issue is an intermediate representation of linting error. It is local
// for one comment line/multiline comment group.
type issue struct {
// position is an position inside a comment (might be multiline comment).
type position struct {
line int
column int
}

// Settings contains linter settings.
type Settings struct {
// Check all top-level comments, not only declarations
CheckAll bool
}

var (
// List of valid last characters.
lastChars = []string{".", "?", "!"}
Expand Down Expand Up @@ -89,33 +88,33 @@ func check(fset *token.FileSet, group *ast.CommentGroup) (iss Issue, ok bool) {
// for "/*"-comment
last := group.List[len(group.List)-1]

i, ok := checkComment(last.Text)
p, ok := checkComment(last.Text)
if ok {
return Issue{}, true
}
pos := fset.Position(last.Slash)
pos.Line += i.line
pos.Column = i.column
pos.Line += p.line
pos.Column = p.column
iss.Pos = pos
iss.Message = noPeriodMessage
return iss, false
}

func checkComment(comment string) (iss issue, ok bool) {
func checkComment(comment string) (pos position, ok bool) {
// Check last line of "//"-comment
if strings.HasPrefix(comment, "//") {
iss.column = len(comment)
pos.column = len(comment)
comment = strings.TrimPrefix(comment, "//")
if checkLastChar(comment) {
return issue{}, true
return position{}, true
}
return iss, false
return pos, false
}

// Skip cgo code blocks
// TODO: Find a better way to detect cgo code
if strings.Contains(comment, "#include") || strings.Contains(comment, "#define") {
return issue{}, true
return position{}, true
}

// Check last non-empty line in multiline "/*"-comment block
Expand All @@ -127,17 +126,17 @@ func checkComment(comment string) (iss issue, ok bool) {
}
break
}
iss.line = i
pos.line = i
comment = lines[i]
comment = strings.TrimSuffix(comment, "*/")
comment = strings.TrimRight(comment, " ")
iss.column = len(comment) // last non-space char in comment line
pos.column = len(comment) // last non-space char in comment line
comment = strings.TrimPrefix(comment, "/*")

if checkLastChar(comment) {
return issue{}, true
return position{}, true
}
return iss, false
return pos, false
}

func checkLastChar(s string) bool {
Expand Down
78 changes: 39 additions & 39 deletions godot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,222 +13,222 @@ func TestCheckComment(t *testing.T) {
name string
comment string
ok bool
issue issue
pos position
}{
// Single line comments
{
name: "singleline comment: ok",
comment: "// Hello, world.",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: no period",
comment: "// Hello, world",
ok: false,
issue: issue{line: 0, column: 15},
pos: position{line: 0, column: 15},
},
{
name: "singleline comment: question mark",
comment: "// Hello, world?",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: exclamation mark",
comment: "// Hello, world!",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: code example without period",
comment: "// x == y",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: code example without period and long indentation",
comment: "// x == y",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: code example without period and tab indentation",
comment: "//\tx == y",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: code example without period and mixed indentation",
comment: "// \tx == y",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: empty line",
comment: "//",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: empty line with spaces",
comment: "// ",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: without indentation and with period",
comment: "//hello, world.",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: without indentation and without period",
comment: "//hello, world",
ok: false,
issue: issue{line: 0, column: 14},
pos: position{line: 0, column: 14},
},
{
name: "singleline comment: nolint mark without period",
comment: "// nolint: test",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: nolint mark without indentation without period",
comment: "//nolint: test",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: build tags",
comment: "// +build !linux",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: cgo exported function",
comment: "//export FuncName",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "singleline comment: url at the end of line",
comment: "// Read more: http://example.com/",
ok: true,
issue: issue{},
pos: position{},
},
// Multiline comments
{
name: "multiline comment: ok",
comment: "/*\n" + "Hello, world.\n" + "*/",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "multiline comment: no period",
comment: "/*\n" + "Hello, world\n" + "*/",
ok: false,
issue: issue{line: 1, column: 12},
pos: position{line: 1, column: 12},
},
{
name: "multiline comment: question mark",
comment: "/*\n" + "Hello, world?\n" + "*/",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "multiline comment: exclamation mark",
comment: "/*\n" + "Hello, world!\n" + "*/",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "multiline comment: code example without period",
comment: "/*\n" + " x == y\n" + "*/",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "multiline comment: code example without period and long indentation",
comment: "/*\n" + " x == y\n" + "*/",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "multiline comment: code example without period and tab indentation",
comment: "/*\n" + "\tx == y\n" + "*/",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "multiline comment: empty line",
comment: "/**/",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "multiline comment: empty line inside",
comment: "/*\n" + "\n" + "*/",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "multiline comment: empty line with spaces",
comment: "/*\n" + " \n" + "*/",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "multiline comment: closing with whitespaces",
comment: "/*\n" + " \n" + " */",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "multiline comment: one-liner with period",
comment: "/* Hello, world. */",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "multiline comment: one-liner with period and without indentation",
comment: "/*Hello, world.*/",
ok: true,
issue: issue{},
pos: position{},
},
{
name: "multiline comment: one-liner without period and without indentation",
comment: "/*Hello, world*/",
ok: false,
issue: issue{line: 0, column: 14},
pos: position{line: 0, column: 14},
},
{
name: "multiline comment: long comment",
comment: "/*\n" + "\n" + " \n" + "Hello, world\n" + "\n" + " \n" + "*/",
ok: false,
issue: issue{line: 3, column: 12},
pos: position{line: 3, column: 12},
},
{
name: "multiline comment: url at the end of line",
comment: "/*\n" + "Read more: http://example.com/" + "*/",
ok: true,
issue: issue{},
pos: position{},
},
}

for _, tt := range testCases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
iss, ok := checkComment(tt.comment)
pos, ok := checkComment(tt.comment)
if ok != tt.ok {
t.Fatalf("Wrong result, expected %v, got %v", tt.ok, ok)
}
if iss.line != tt.issue.line {
t.Fatalf("Wrong line, expected %d, got %d", tt.issue.line, iss.line)
if pos.line != tt.pos.line {
t.Fatalf("Wrong line, expected %d, got %d", tt.pos.line, pos.line)
}
if iss.column != tt.issue.column {
t.Fatalf("Wrong column, expected %d, got %d", tt.issue.column, iss.column)
if pos.column != tt.pos.column {
t.Fatalf("Wrong column, expected %d, got %d", tt.pos.column, pos.column)
}
})
}
Expand Down

0 comments on commit d220581

Please sign in to comment.