diff --git a/.golangci.example.yml b/.golangci.example.yml index fc2c9b63..24b95b96 100644 --- a/.golangci.example.yml +++ b/.golangci.example.yml @@ -209,7 +209,8 @@ linters-settings: max-blank-identifiers: 2 whitespace: - multi-if: false + multi-if: false # Enforces newlines (or comments) after every multi-line if statement + multi-func: false # Enforces newlines (or comments) after every multi-line function signature linters: enable: diff --git a/README.md b/README.md index a86618e0..6ed42704 100644 --- a/README.md +++ b/README.md @@ -799,7 +799,8 @@ linters-settings: max-blank-identifiers: 2 whitespace: - multi-if: false + multi-if: false # Enforces newlines (or comments) after every multi-line if statement + multi-func: false # Enforces newlines (or comments) after every multi-line function signature linters: enable: diff --git a/go.mod b/go.mod index 4e947924..79472285 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/stretchr/testify v1.4.0 github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e github.com/ultraware/funlen v0.0.2 - github.com/ultraware/whitespace v0.0.3 + github.com/ultraware/whitespace v0.0.4 github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517 github.com/valyala/quicktemplate v1.2.0 golang.org/x/tools v0.0.0-20190912215617-3720d1ec3678 diff --git a/go.sum b/go.sum index b51dbe75..2fb86c66 100644 --- a/go.sum +++ b/go.sum @@ -232,8 +232,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.3 h1:S5BCRRB5sttNy0bSOhbpw+0mb+cHiCmWfrvxpEzuUk0= -github.com/ultraware/whitespace v0.0.3/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= +github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg= +github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517 h1:ChMKTho2hWKpks/nD/FL2KqM1wuVt62oJeiE8+eFpGs= github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= diff --git a/pkg/config/config.go b/pkg/config/config.go index eb0f6ef4..d1420a74 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -175,7 +175,8 @@ type LintersSettings struct { Statements int } Whitespace struct { - MultiIf bool `mapstructure:"multi-if"` + MultiIf bool `mapstructure:"multi-if"` + MultiFunc bool `mapstructure:"multi-func"` } Lll LllSettings diff --git a/pkg/golinters/whitespace.go b/pkg/golinters/whitespace.go index c27fca25..5064cef2 100644 --- a/pkg/golinters/whitespace.go +++ b/pkg/golinters/whitespace.go @@ -28,7 +28,8 @@ func NewWhitespace() *goanalysis.Linter { []*analysis.Analyzer{analyzer}, nil, ).WithContextSetter(func(lintCtx *linter.Context) { - settings := whitespace.Settings{MultiIf: lintCtx.Cfg.LintersSettings.Whitespace.MultiIf} + cfg := lintCtx.Cfg.LintersSettings.Whitespace + settings := whitespace.Settings{MultiIf: cfg.MultiIf, MultiFunc: cfg.MultiFunc} analyzer.Run = func(pass *analysis.Pass) (interface{}, error) { var issues []whitespace.Message diff --git a/test/testdata/fix/in/whitespace.go b/test/testdata/fix/in/whitespace.go index f5c3bc0d..787ffbbb 100644 --- a/test/testdata/fix/in/whitespace.go +++ b/test/testdata/fix/in/whitespace.go @@ -1,5 +1,6 @@ //args: -Ewhitespace //config: linters-settings.whitespace.multi-if=true +//config: linters-settings.whitespace.multi-func=true package p import "fmt" @@ -47,9 +48,14 @@ func twoLeadingNewlines() { fmt.Println("Hello world") } +func multiFuncFunc(a int, + b int) { + fmt.Println("Hello world") +} + func multiIfFunc() { if 1 == 1 && 2 == 2 { - fmt.Println(`Hello multi-line world`) + fmt.Println("Hello multi-line world") } } diff --git a/test/testdata/fix/out/whitespace.go b/test/testdata/fix/out/whitespace.go index 55e87ab5..a6856f25 100644 --- a/test/testdata/fix/out/whitespace.go +++ b/test/testdata/fix/out/whitespace.go @@ -1,5 +1,6 @@ //args: -Ewhitespace //config: linters-settings.whitespace.multi-if=true +//config: linters-settings.whitespace.multi-func=true package p import "fmt" @@ -43,10 +44,16 @@ func twoLeadingNewlines() { fmt.Println("Hello world") } +func multiFuncFunc(a int, + b int) { + + fmt.Println("Hello world") +} + func multiIfFunc() { if 1 == 1 && 2 == 2 { - fmt.Println(`Hello multi-line world`) + fmt.Println("Hello multi-line world") } } diff --git a/vendor/github.com/ultraware/whitespace/README.md b/vendor/github.com/ultraware/whitespace/README.md index 5dbf9a38..aed9a485 100644 --- a/vendor/github.com/ultraware/whitespace/README.md +++ b/vendor/github.com/ultraware/whitespace/README.md @@ -2,52 +2,6 @@ Whitespace is a linter that checks for unnecessary newlines at the start and end of functions, if, for, etc. -Example code: - -```go -package main - -import "fmt" - -func main() { - - fmt.Println("Hello world") -} -``` - -Reults in: - -``` -$ whitespace . -main.go:6:unnecessary newline -``` - ## Installation guide -```bash -go get git.ultraware.nl/NiseVoid/whitespace -``` - -### Gometalinter - -You can add whitespace to gometalinter and enable it. - -`.gometalinter.json`: - -```json -{ - "Linters": { - "whitespace": "whitespace:PATH:LINE:MESSAGE" - }, - - "Enable": [ - "whitespace" - ] -} -``` - -commandline: - -```bash -gometalinter --linter "whitespace:whitespace:PATH:LINE:MESSAGE" --enable "whitespace" -``` +Whitespace is included in [https://github.com/golangci/golangci-lint/](golangci-lint). Install it and enable whitespace. diff --git a/vendor/github.com/ultraware/whitespace/main.go b/vendor/github.com/ultraware/whitespace/main.go index 1286afdf..c36086c0 100644 --- a/vendor/github.com/ultraware/whitespace/main.go +++ b/vendor/github.com/ultraware/whitespace/main.go @@ -24,7 +24,8 @@ const ( // Settings contains settings for edge-cases type Settings struct { - MultiIf bool + MultiIf bool + MultiFunc bool } // Run runs this linter on the provided code @@ -47,11 +48,11 @@ func Run(file *ast.File, fset *token.FileSet, settings Settings) []Message { } type visitor struct { - comments []*ast.CommentGroup - fset *token.FileSet - messages []Message - multiIf map[*ast.BlockStmt]bool - settings Settings + comments []*ast.CommentGroup + fset *token.FileSet + messages []Message + wantNewline map[*ast.BlockStmt]bool + settings Settings } func (v *visitor) Visit(node ast.Node) ast.Visitor { @@ -59,30 +60,28 @@ func (v *visitor) Visit(node ast.Node) ast.Visitor { return v } - 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 stmt, ok := node.(*ast.IfStmt); ok && v.settings.MultiIf { + checkMultiLine(v, stmt.Body, stmt.Cond) + } - if end > start { // Check only multi line conditions - v.multiIf[stmt.Body] = true - } - } + if stmt, ok := node.(*ast.FuncDecl); ok && v.settings.MultiFunc { + checkMultiLine(v, stmt.Body, stmt.Type) } if stmt, ok := node.(*ast.BlockStmt); ok { - multiIf := v.multiIf[stmt] + wantNewline := v.wantNewline[stmt] comments := v.comments - if multiIf { - comments = nil + if wantNewline { + comments = nil // Comments also count as a newline if we want a newline } 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 { + if wantNewline && startMsg == nil { + v.messages = append(v.messages, Message{v.fset.Position(stmt.Pos()), MessageTypeAddAfter, `multi-line statement should be followed by a newline`}) + } else if !wantNewline && startMsg != nil { v.messages = append(v.messages, *startMsg) } @@ -94,6 +93,14 @@ func (v *visitor) Visit(node ast.Node) ast.Visitor { return v } +func checkMultiLine(v *visitor, body *ast.BlockStmt, stmtStart ast.Node) { + start, end := posLine(v.fset, stmtStart.Pos()), posLine(v.fset, stmtStart.End()) + + if end > start { // Check only multi line conditions + v.wantNewline[body] = true + } +} + func posLine(fset *token.FileSet, pos token.Pos) int { return fset.Position(pos).Line } diff --git a/vendor/modules.txt b/vendor/modules.txt index 0d480b85..8e44d6c1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -168,7 +168,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.3 +# github.com/ultraware/whitespace v0.0.4 github.com/ultraware/whitespace # github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517 github.com/uudashr/gocognit