Update whitespace

This commit is contained in:
NiseVoid 2019-09-23 12:08:43 +02:00 committed by Trevor Pounds
parent 3aade55e05
commit 9976bdcc5e
10 changed files with 95 additions and 34 deletions

View File

@ -205,6 +205,9 @@ linters-settings:
# checks assignments with too many blank identifiers; default is 2
max-blank-identifiers: 2
whitespace:
multi-if: false
linters:
enable:
- megacheck

View File

@ -790,6 +790,9 @@ linters-settings:
# checks assignments with too many blank identifiers; default is 2
max-blank-identifiers: 2
whitespace:
multi-if: false
linters:
enable:
- megacheck

2
go.mod
View File

@ -37,7 +37,7 @@ require (
github.com/stretchr/testify v1.4.0
github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec
github.com/ultraware/funlen v0.0.2
github.com/ultraware/whitespace v0.0.2
github.com/ultraware/whitespace v0.0.3
github.com/valyala/quicktemplate v1.2.0
golang.org/x/tools v0.0.0-20190912215617-3720d1ec3678
gopkg.in/yaml.v2 v2.2.2

4
go.sum
View File

@ -233,8 +233,8 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ultraware/funlen v0.0.2 h1:Av96YVBwwNSe4MLR7iI/BIa3VyI7/djnto/pK3Uxbdo=
github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
github.com/ultraware/whitespace v0.0.2 h1:iL4Un0C3VaMIBGfDogtcdBeSotjfSHYW8OdI1U9Vqas=
github.com/ultraware/whitespace v0.0.2/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
github.com/ultraware/whitespace v0.0.3 h1:S5BCRRB5sttNy0bSOhbpw+0mb+cHiCmWfrvxpEzuUk0=
github.com/ultraware/whitespace v0.0.3/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=

View File

@ -171,6 +171,9 @@ type LintersSettings struct {
Lines int
Statements int
}
Whitespace struct {
MultiIf bool `mapstructure:"multi-if"`
}
Lll LllSettings
Unparam UnparamSettings

View File

@ -24,9 +24,11 @@ func (Whitespace) Desc() string {
}
func (w Whitespace) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Issue, error) {
settings := whitespace.Settings{MultiIf: lintCtx.Cfg.LintersSettings.Whitespace.MultiIf}
var issues []whitespace.Message
for _, file := range lintCtx.ASTCache.GetAllValidFiles() {
issues = append(issues, whitespace.Run(file.F, file.Fset)...)
issues = append(issues, whitespace.Run(file.F, file.Fset, settings)...)
}
if len(issues) == 0 {
@ -40,34 +42,28 @@ func (w Whitespace) Run(ctx context.Context, lintCtx *linter.Context) ([]result.
Filename: i.Pos.Filename,
Line: i.Pos.Line,
},
LineRange: &result.Range{From: i.Pos.Line, To: i.Pos.Line},
Text: i.Message,
FromLinter: w.Name(),
Replacement: &result.Replacement{},
}
// TODO(jirfag): return more information from Whitespace to get rid of string comparisons
if i.Message == "unnecessary leading newline" {
// cover two lines by the issue: opening bracket "{" (issue.Pos.Line) and following empty line
issue.LineRange = &result.Range{From: issue.Pos.Line, To: issue.Pos.Line + 1}
bracketLine, err := lintCtx.LineCache.GetLine(issue.Pos.Filename, issue.Pos.Line)
if err != nil {
return nil, errors.Wrapf(err, "failed to get line %s:%d", issue.Pos.Filename, issue.Pos.Line)
}
issue.Replacement.NewLines = []string{bracketLine}
} else {
// cover two lines by the issue: closing bracket "}" (issue.Pos.Line) and preceding empty line
issue.LineRange = &result.Range{From: issue.Pos.Line - 1, To: issue.Pos.Line}
bracketLine, err := lintCtx.LineCache.GetLine(issue.Pos.Filename, issue.Pos.Line)
if err != nil {
return nil, errors.Wrapf(err, "failed to get line %s:%d", issue.Pos.Filename, issue.Pos.Line)
}
issue.Replacement.NewLines = []string{bracketLine}
issue.Pos.Line-- // set in sync with LineRange.From to not break fixer and other code features
bracketLine, err := lintCtx.LineCache.GetLine(issue.Pos.Filename, issue.Pos.Line)
if err != nil {
return nil, errors.Wrapf(err, "failed to get line %s:%d", issue.Pos.Filename, issue.Pos.Line)
}
switch i.Type {
case whitespace.MessageTypeLeading:
issue.LineRange.To++ // cover two lines by the issue: opening bracket "{" (issue.Pos.Line) and following empty line
case whitespace.MessageTypeTrailing:
issue.LineRange.From-- // cover two lines by the issue: closing bracket "}" (issue.Pos.Line) and preceding empty line
issue.Pos.Line-- // set in sync with LineRange.From to not break fixer and other code features
case whitespace.MessageTypeAddAfter:
bracketLine += "\n"
}
issue.Replacement.NewLines = []string{bracketLine}
res[k] = issue
}

View File

@ -1,4 +1,5 @@
//args: -Ewhitespace
//config: linters-settings.whitespace.multi-if=true
package p
import "fmt"
@ -45,3 +46,10 @@ func twoLeadingNewlines() {
fmt.Println("Hello world")
}
func multiIfFunc() {
if 1 == 1 &&
2 == 2 {
fmt.Println(`Hello multi-line world`)
}
}

View File

@ -1,4 +1,5 @@
//args: -Ewhitespace
//config: linters-settings.whitespace.multi-if=true
package p
import "fmt"
@ -41,3 +42,11 @@ func twoLeadingNewlines() {
fmt.Println("Hello world")
}
func multiIfFunc() {
if 1 == 1 &&
2 == 2 {
fmt.Println(`Hello multi-line world`)
}
}

View File

@ -8,11 +8,27 @@ import (
// Message contains a message
type Message struct {
Pos token.Position
Type MessageType
Message string
}
// MessageType describes what should happen to fix the warning
type MessageType uint8
// List of MessageTypes
const (
MessageTypeLeading MessageType = iota + 1
MessageTypeTrailing
MessageTypeAddAfter
)
// Settings contains settings for edge-cases
type Settings struct {
MultiIf bool
}
// Run runs this linter on the provided code
func Run(file *ast.File, fset *token.FileSet) []Message {
func Run(file *ast.File, fset *token.FileSet, settings Settings) []Message {
var messages []Message
for _, f := range file.Decls {
@ -21,7 +37,7 @@ func Run(file *ast.File, fset *token.FileSet) []Message {
continue
}
vis := visitor{file.Comments, fset, nil}
vis := visitor{file.Comments, fset, nil, make(map[*ast.BlockStmt]bool), settings}
ast.Walk(&vis, decl)
messages = append(messages, vis.messages...)
@ -34,6 +50,8 @@ type visitor struct {
comments []*ast.CommentGroup
fset *token.FileSet
messages []Message
multiIf map[*ast.BlockStmt]bool
settings Settings
}
func (v *visitor) Visit(node ast.Node) ast.Visitor {
@ -41,12 +59,33 @@ func (v *visitor) Visit(node ast.Node) ast.Visitor {
return v
}
if stmt, ok := node.(*ast.BlockStmt); ok {
first, last := firstAndLast(v.comments, v.fset, stmt.Pos(), stmt.End(), stmt.List)
if v.settings.MultiIf {
if stmt, ok := node.(*ast.IfStmt); ok {
start, end := posLine(v.fset, stmt.Cond.Pos()), posLine(v.fset, stmt.Cond.End())
if msg := checkStart(v.fset, stmt.Lbrace, first); msg != nil {
v.messages = append(v.messages, *msg)
if end > start { // Check only multi line conditions
v.multiIf[stmt.Body] = true
}
}
}
if stmt, ok := node.(*ast.BlockStmt); ok {
multiIf := v.multiIf[stmt]
comments := v.comments
if multiIf {
comments = nil
}
first, last := firstAndLast(comments, v.fset, stmt.Pos(), stmt.End(), stmt.List)
startMsg := checkStart(v.fset, stmt.Lbrace, first)
if multiIf && startMsg == nil {
v.messages = append(v.messages, Message{v.fset.Position(stmt.Pos()), MessageTypeAddAfter, `multi-line if should be followed by a newline`})
} else if !multiIf && startMsg != nil {
v.messages = append(v.messages, *startMsg)
}
if msg := checkEnd(v.fset, stmt.Rbrace, last); msg != nil {
v.messages = append(v.messages, *msg)
}
@ -92,7 +131,7 @@ func checkStart(fset *token.FileSet, start token.Pos, first ast.Node) *Message {
if posLine(fset, start)+1 < posLine(fset, first.Pos()) {
pos := fset.Position(start)
return &Message{pos, `unnecessary leading newline`}
return &Message{pos, MessageTypeLeading, `unnecessary leading newline`}
}
return nil
@ -105,7 +144,7 @@ func checkEnd(fset *token.FileSet, end token.Pos, last ast.Node) *Message {
if posLine(fset, end)-1 > posLine(fset, last.End()) {
pos := fset.Position(end)
return &Message{pos, `unnecessary trailing newline`}
return &Message{pos, MessageTypeTrailing, `unnecessary trailing newline`}
}
return nil

2
vendor/modules.txt vendored
View File

@ -167,7 +167,7 @@ github.com/stretchr/testify/require
github.com/timakin/bodyclose/passes/bodyclose
# github.com/ultraware/funlen v0.0.2
github.com/ultraware/funlen
# github.com/ultraware/whitespace v0.0.2
# github.com/ultraware/whitespace v0.0.3
github.com/ultraware/whitespace
# github.com/valyala/bytebufferpool v1.0.0
github.com/valyala/bytebufferpool