From 9976bdcc5e016fa5bb668421908496530fca3178 Mon Sep 17 00:00:00 2001 From: NiseVoid Date: Mon, 23 Sep 2019 12:08:43 +0200 Subject: [PATCH] Update whitespace --- .golangci.example.yml | 3 + README.md | 3 + go.mod | 2 +- go.sum | 4 +- pkg/config/config.go | 3 + pkg/golinters/whitespace.go | 40 ++++++-------- test/testdata/fix/in/whitespace.go | 8 +++ test/testdata/fix/out/whitespace.go | 9 +++ .../github.com/ultraware/whitespace/main.go | 55 ++++++++++++++++--- vendor/modules.txt | 2 +- 10 files changed, 95 insertions(+), 34 deletions(-) diff --git a/.golangci.example.yml b/.golangci.example.yml index 3dba1f05..c2d24c33 100644 --- a/.golangci.example.yml +++ b/.golangci.example.yml @@ -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 diff --git a/README.md b/README.md index 7d2ded62..a7ef7da0 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/go.mod b/go.mod index 3c5f09f2..26b2a759 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index ce56a219..af98c2d1 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/pkg/config/config.go b/pkg/config/config.go index 0eb60244..f07037d9 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -171,6 +171,9 @@ type LintersSettings struct { Lines int Statements int } + Whitespace struct { + MultiIf bool `mapstructure:"multi-if"` + } Lll LllSettings Unparam UnparamSettings diff --git a/pkg/golinters/whitespace.go b/pkg/golinters/whitespace.go index 3143232d..d549c5b4 100644 --- a/pkg/golinters/whitespace.go +++ b/pkg/golinters/whitespace.go @@ -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 } diff --git a/test/testdata/fix/in/whitespace.go b/test/testdata/fix/in/whitespace.go index 915d36e3..f5c3bc0d 100644 --- a/test/testdata/fix/in/whitespace.go +++ b/test/testdata/fix/in/whitespace.go @@ -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`) + } +} diff --git a/test/testdata/fix/out/whitespace.go b/test/testdata/fix/out/whitespace.go index 5c8b997e..55e87ab5 100644 --- a/test/testdata/fix/out/whitespace.go +++ b/test/testdata/fix/out/whitespace.go @@ -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`) + } +} diff --git a/vendor/github.com/ultraware/whitespace/main.go b/vendor/github.com/ultraware/whitespace/main.go index 83c5b40c..1286afdf 100644 --- a/vendor/github.com/ultraware/whitespace/main.go +++ b/vendor/github.com/ultraware/whitespace/main.go @@ -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 diff --git a/vendor/modules.txt b/vendor/modules.txt index 43d802db..6aac0e6f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -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