Bump wsl to v1.2.7
This commit is contained in:
parent
1248f098de
commit
14ebae2906
@ -223,10 +223,12 @@ linters-settings:
|
|||||||
allow-assign-and-call: true
|
allow-assign-and-call: true
|
||||||
# Allow multiline assignments to be cuddled. Default is true.
|
# Allow multiline assignments to be cuddled. Default is true.
|
||||||
allow-multiline-assign: true
|
allow-multiline-assign: true
|
||||||
# Allow case blocks to end with a whitespace.
|
|
||||||
allow-case-traling-whitespace: true
|
|
||||||
# Allow declarations (var) to be cuddled.
|
# Allow declarations (var) to be cuddled.
|
||||||
allow-cuddle-declarations: false
|
allow-cuddle-declarations: false
|
||||||
|
# Allow trailing comments in ending of blocks
|
||||||
|
allow-trailing-comment: false
|
||||||
|
# Force newlines in end of case at this limit (0 = never).
|
||||||
|
force-case-trailing-whitespace: 0
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
enable:
|
enable:
|
||||||
|
@ -824,10 +824,12 @@ linters-settings:
|
|||||||
allow-assign-and-call: true
|
allow-assign-and-call: true
|
||||||
# Allow multiline assignments to be cuddled. Default is true.
|
# Allow multiline assignments to be cuddled. Default is true.
|
||||||
allow-multiline-assign: true
|
allow-multiline-assign: true
|
||||||
# Allow case blocks to end with a whitespace.
|
|
||||||
allow-case-traling-whitespace: true
|
|
||||||
# Allow declarations (var) to be cuddled.
|
# Allow declarations (var) to be cuddled.
|
||||||
allow-cuddle-declarations: false
|
allow-cuddle-declarations: false
|
||||||
|
# Allow trailing comments in ending of blocks
|
||||||
|
allow-trailing-comment: false
|
||||||
|
# Force newlines in end of case at this limit (0 = never).
|
||||||
|
force-case-trailing-whitespace: 0
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
enable:
|
enable:
|
||||||
|
2
go.mod
2
go.mod
@ -4,7 +4,7 @@ go 1.12
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/OpenPeeDeeP/depguard v1.0.1
|
github.com/OpenPeeDeeP/depguard v1.0.1
|
||||||
github.com/bombsimon/wsl v1.2.5
|
github.com/bombsimon/wsl v1.2.7
|
||||||
github.com/fatih/color v1.7.0
|
github.com/fatih/color v1.7.0
|
||||||
github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db
|
github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db
|
||||||
github.com/go-lintpack/lintpack v0.5.2
|
github.com/go-lintpack/lintpack v0.5.2
|
||||||
|
4
go.sum
4
go.sum
@ -11,8 +11,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
|
|||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/bombsimon/wsl v1.2.5 h1:9gTOkIwVtoDZywvX802SDHokeX4kW1cKnV8ZTVAPkRs=
|
github.com/bombsimon/wsl v1.2.7 h1:hckBZYt27e6Ff6yqV/SurMUe48BmXzJk/KVjxDyWtUE=
|
||||||
github.com/bombsimon/wsl v1.2.5/go.mod h1:43lEF/i0kpXbLCeDXL9LMT8c92HyBywXb0AsgMHYngM=
|
github.com/bombsimon/wsl v1.2.7/go.mod h1:43lEF/i0kpXbLCeDXL9LMT8c92HyBywXb0AsgMHYngM=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
|
@ -255,11 +255,12 @@ type GocognitSettings struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type WSLSettings struct {
|
type WSLSettings struct {
|
||||||
StrictAppend bool `mapstructure:"strict-append"`
|
StrictAppend bool `mapstructure:"strict-append"`
|
||||||
AllowAssignAndCallCuddle bool `mapstructure:"allow-assign-and-call"`
|
AllowAssignAndCallCuddle bool `mapstructure:"allow-assign-and-call"`
|
||||||
AllowMultiLineAssignCuddle bool `mapstructure:"allow-multiline-assign"`
|
AllowMultiLineAssignCuddle bool `mapstructure:"allow-multiline-assign"`
|
||||||
AllowCaseTrailingWhitespace bool `mapstructure:"allow-case-trailing-whitespace"`
|
AllowCuddleDeclaration bool `mapstructure:"allow-cuddle-declarations"`
|
||||||
AllowCuddleDeclaration bool `mapstructure:"allow-cuddle-declarations"`
|
AllowTrailingComment bool `mapstructure:"allow-trailing-comment"`
|
||||||
|
CaseForceTrailingWhitespaceLimit int `mapstructure:"force-case-trailing-whitespace:"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultLintersSettings = LintersSettings{
|
var defaultLintersSettings = LintersSettings{
|
||||||
@ -291,11 +292,12 @@ var defaultLintersSettings = LintersSettings{
|
|||||||
MinComplexity: 30,
|
MinComplexity: 30,
|
||||||
},
|
},
|
||||||
WSL: WSLSettings{
|
WSL: WSLSettings{
|
||||||
StrictAppend: true,
|
StrictAppend: true,
|
||||||
AllowAssignAndCallCuddle: true,
|
AllowAssignAndCallCuddle: true,
|
||||||
AllowMultiLineAssignCuddle: true,
|
AllowMultiLineAssignCuddle: true,
|
||||||
AllowCaseTrailingWhitespace: true,
|
AllowCuddleDeclaration: false,
|
||||||
AllowCuddleDeclaration: false,
|
AllowTrailingComment: false,
|
||||||
|
CaseForceTrailingWhitespaceLimit: 0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,13 +37,14 @@ func NewWSL() *goanalysis.Linter {
|
|||||||
files = []string{}
|
files = []string{}
|
||||||
linterCfg = lintCtx.Cfg.LintersSettings.WSL
|
linterCfg = lintCtx.Cfg.LintersSettings.WSL
|
||||||
processorCfg = wsl.Configuration{
|
processorCfg = wsl.Configuration{
|
||||||
StrictAppend: linterCfg.StrictAppend,
|
StrictAppend: linterCfg.StrictAppend,
|
||||||
AllowAssignAndCallCuddle: linterCfg.AllowAssignAndCallCuddle,
|
AllowAssignAndCallCuddle: linterCfg.AllowAssignAndCallCuddle,
|
||||||
AllowMultiLineAssignCuddle: linterCfg.AllowMultiLineAssignCuddle,
|
AllowMultiLineAssignCuddle: linterCfg.AllowMultiLineAssignCuddle,
|
||||||
AllowCaseTrailingWhitespace: linterCfg.AllowCaseTrailingWhitespace,
|
AllowCuddleDeclaration: linterCfg.AllowCuddleDeclaration,
|
||||||
AllowCuddleDeclaration: linterCfg.AllowCuddleDeclaration,
|
AllowTrailingComment: linterCfg.AllowTrailingComment,
|
||||||
AllowCuddleWithCalls: []string{"Lock", "RLock"},
|
CaseForceTrailingWhitespaceLimit: linterCfg.CaseForceTrailingWhitespaceLimit,
|
||||||
AllowCuddleWithRHS: []string{"Unlock", "RUnlock"},
|
AllowCuddleWithCalls: []string{"Lock", "RLock"},
|
||||||
|
AllowCuddleWithRHS: []string{"Unlock", "RUnlock"},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
40
test/testdata/wsl.go
vendored
40
test/testdata/wsl.go
vendored
@ -159,7 +159,7 @@ func allowTrailing(i int) {
|
|||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
fmt.Println("two")
|
fmt.Println("two")
|
||||||
|
// Comments OK too!
|
||||||
case 3:
|
case 3:
|
||||||
fmt.Println("three")
|
fmt.Println("three")
|
||||||
}
|
}
|
||||||
@ -172,3 +172,41 @@ func ExampleSomeOutput() {
|
|||||||
// Output:
|
// Output:
|
||||||
// Hello, world
|
// Hello, world
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IncDecStmt() {
|
||||||
|
counter := 0
|
||||||
|
for range make([]int, 5) {
|
||||||
|
counter++
|
||||||
|
}
|
||||||
|
|
||||||
|
type t struct {
|
||||||
|
counter int
|
||||||
|
}
|
||||||
|
|
||||||
|
x := t{5}
|
||||||
|
|
||||||
|
x.counter--
|
||||||
|
if x.counter > 0 {
|
||||||
|
fmt.Println("not yet 0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AnonymousBlock() {
|
||||||
|
func(a, b int) { // ERROR "block should not start with a whitespace"
|
||||||
|
|
||||||
|
fmt.Println(a + b)
|
||||||
|
}(1, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MultilineComment() {
|
||||||
|
if true {
|
||||||
|
/*
|
||||||
|
Ok to start block with
|
||||||
|
a
|
||||||
|
long
|
||||||
|
multiline
|
||||||
|
cmoment
|
||||||
|
*/
|
||||||
|
fmt.Println("true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
6
vendor/github.com/bombsimon/wsl/.travis.yml
generated
vendored
6
vendor/github.com/bombsimon/wsl/.travis.yml
generated
vendored
@ -2,9 +2,9 @@
|
|||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- "1.13"
|
- 1.13.x
|
||||||
- "1.12"
|
- 1.12.x
|
||||||
- "1.11"
|
- 1.11.x
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
|
670
vendor/github.com/bombsimon/wsl/README.md
generated
vendored
670
vendor/github.com/bombsimon/wsl/README.md
generated
vendored
@ -21,595 +21,105 @@ might be bugs or unintentional false positives so I would love an
|
|||||||
[issue](https://github.com/bombsimon/wsl/issues/new) to fix, discuss, change or
|
[issue](https://github.com/bombsimon/wsl/issues/new) to fix, discuss, change or
|
||||||
make something configurable!
|
make something configurable!
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### By `go get` (local installation)
|
||||||
|
|
||||||
|
You can do that by using:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go get -u github.com/bombsimon/wsl/cmd/...
|
||||||
|
```
|
||||||
|
|
||||||
|
### By golangci-lint (CI automation)
|
||||||
|
|
||||||
|
`wsl` is already integrated with
|
||||||
|
[golangci-lint](https://github.com/golangci/golangci-lint). Please refer to the
|
||||||
|
instructions there.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Install by using `go get -u github.com/bombsimon/wsl/cmd/...`.
|
How to use depends on how you install `wsl`.
|
||||||
|
|
||||||
Run with `wsl [--no-test] <file1> [files...]` or `wsl ./package/...`. The "..."
|
### With local binary
|
||||||
wildcard is not used like other `go` commands but instead can only be to a
|
|
||||||
relative or absolute path.
|
The general command format for `wsl` is:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ wsl [flags] <file1> [files...]
|
||||||
|
$ wsl [flags] </path/to/package/...>
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
$ wsl ./main.go
|
||||||
|
$ wsl --no-test ./main.go
|
||||||
|
$ wsl -allow-declaration ./main.go
|
||||||
|
$ wsl --no-test --allow-cuddle-declaration ./main.go
|
||||||
|
$ wsl --no-test --allow-trailing-comment ./myProject/...
|
||||||
|
```
|
||||||
|
|
||||||
|
The "..." wildcard is not used like other `go` commands but instead can only
|
||||||
|
be to a relative or absolute path.
|
||||||
|
|
||||||
By default, the linter will run on `./...` which means all go files in the
|
By default, the linter will run on `./...` which means all go files in the
|
||||||
current path and all subsequent paths, including test files. To disable linting
|
current path and all subsequent paths, including test files. To disable linting
|
||||||
test files, use `-n` or `--no-test`.
|
test files, use `-n` or `--no-test`.
|
||||||
|
|
||||||
This linter can also be used as a part of
|
### By `golangci-lint` (CI automation)
|
||||||
[golangci-lint](https://github.com/golangci/golangci-lint)
|
|
||||||
|
|
||||||
## Rules
|
The recommended command is:
|
||||||
|
|
||||||
Note that this linter doesn't take in consideration the issues that will be
|
```sh
|
||||||
fixed with `gofmt` so ensure that the code is properly formatted.
|
golangci-lint --disable-all --enable wsl
|
||||||
|
|
||||||
### Never use empty lines
|
|
||||||
|
|
||||||
Even though this linter was built to **promote** the usage of empty lines, there
|
|
||||||
are a few places where they should never be used.
|
|
||||||
|
|
||||||
Never use empty lines in the start or end of a block!
|
|
||||||
|
|
||||||
**Don't**
|
|
||||||
|
|
||||||
```go
|
|
||||||
if someBooleanValue {
|
|
||||||
|
|
||||||
fmt.Println("i like starting newlines")
|
|
||||||
}
|
|
||||||
|
|
||||||
if someOtherBooleanValue {
|
|
||||||
fmt.Println("also trailing")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
fmt.Println("switch is also a block")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case 1:
|
|
||||||
|
|
||||||
fmt.Println("not in a case")
|
|
||||||
case 2:
|
|
||||||
fmt.Println("or at the end")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func neverNewlineAfterReturn() {
|
|
||||||
return true
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func notEvenWithComments() {
|
|
||||||
return false
|
|
||||||
// I just forgot to say this...
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Do**
|
For more information, please refer to
|
||||||
|
[golangci-lint](https://github.com/golangci/golangci-lint)'s documentation.
|
||||||
```go
|
|
||||||
if someBooleanValue {
|
## Issues and configuration
|
||||||
fmt.Println("this is tight and nice")
|
|
||||||
}
|
The linter suppers a few ways to configure it to satisfy more than one kind of
|
||||||
|
code style. These settings could be set either with flags or with YAML
|
||||||
switch {
|
configuration if used via `golangci-lint`.
|
||||||
case 1:
|
|
||||||
fmt.Println("no blank lines here")
|
The supported configuration can be found [in the documentation](doc/configuration.md).
|
||||||
case 2:
|
|
||||||
// Comments are fine here!
|
Below are the available checklist for any hit from `wsl`. If you do not see any,
|
||||||
fmt.Println("or here")
|
feel free to raise an [issue](https://github.com/bombsimon/wsl/issues/new).
|
||||||
}
|
|
||||||
|
> **Note**: this linter doesn't take in consideration the issues that will be
|
||||||
func returnCuddleded() {
|
> fixed with `go fmt -s` so ensure that the code is properly formatted before
|
||||||
// My comment goes above the last statement!
|
> use.
|
||||||
return true
|
|
||||||
}
|
* [Anonymous switch statements should never be cuddled](doc/rules.md#anonymous-switch-statements-should-never-be-cuddled)
|
||||||
```
|
* [Append only allowed to cuddle with appended value](doc/rules.md#append-only-allowed-to-cuddle-with-appended-value)
|
||||||
|
* [Assignments should only be cuddled with other assignments](doc/rules.md#assignments-should-only-be-cuddled-with-other-assignments)
|
||||||
### Use empty lines
|
* [Block should not end with a whitespace (or comment)](doc/rules.md#block-should-not-end-with-a-whitespace-or-comment)
|
||||||
|
* [Block should not start with a whitespace](doc/rules.md#block-should-not-start-with-a-whitespace)
|
||||||
There's an easy way to improve logic and readability by enforcing whitespaces at
|
* [Case block should end with newline at this size](doc/rules.md#case-block-should-end-with-newline-at-this-size)
|
||||||
the right places. Usually this is around blocks and after declarations.
|
* [Branch statements should not be cuddled if block has more than two lines](doc/rules.md#branch-statements-should-not-be-cuddled-if-block-has-more-than-two-lines)
|
||||||
|
* [Declarations should never be cuddled](doc/rules.md#declarations-should-never-be-cuddled)
|
||||||
#### If
|
* [Defer statements should only be cuddled with expressions on same variable](doc/rules.md#defer-statements-should-only-be-cuddled-with-expressions-on-same-variable)
|
||||||
|
* [Expressions should not be cuddled with blocks](doc/rules.md#expressions-should-not-be-cuddled-with-blocks)
|
||||||
If statements should only be cuddled with assignments/declarations of variables
|
* [Expressions should not be cuddled with declarations or returns](doc/rules.md#expressions-should-not-be-cuddled-with-declarations-or-returns)
|
||||||
used in the condition and only one assignment should be cuddled. Never cuddle if
|
* [For statement without condition should never be cuddled](doc/rules.md#for-statement-without-condition-should-never-be-cuddled)
|
||||||
with anything but assignments.
|
* [For statements should only be cuddled with assignments used in the iteration](doc/rules.md#for-statements-should-only-be-cuddled-with-assignments-used-in-the-iteration)
|
||||||
|
* [Go statements can only invoke functions assigned on line above](doc/rules.md#go-statements-can-only-invoke-functions-assigned-on-line-above)
|
||||||
**Don't**
|
* [If statements should only be cuddled with assignments](doc/rules.md#if-statements-should-only-be-cuddled-with-assignments)
|
||||||
|
* [If statements should only be cuddled with assignments used in the if
|
||||||
```go
|
statement
|
||||||
notConditional := "x"
|
itself](doc/rules.md#if-statements-should-only-be-cuddled-with-assignments-used-in-the-if-statement-itself)
|
||||||
if somethingElse == "y" {
|
* [Only cuddled expressions if assigning variable or using from line
|
||||||
fmt.Println("what am i checking?")
|
above](doc/rules.md#only-cuddled-expressions-if-assigning-variable-or-using-from-line-above)
|
||||||
}
|
* [Only one cuddle assignment allowed before defer statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-defer-statement)
|
||||||
|
* [Only one cuddle assginment allowed before for statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-for-statement)
|
||||||
first := 1
|
* [Only one cuddle assignment allowed before go statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-go-statement)
|
||||||
second := 2
|
* [Only one cuddle assignment allowed before if statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-if-statement)
|
||||||
third := 3
|
* [Only one cuddle assignment allowed before range statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-range-statement)
|
||||||
forever := 4
|
* [Only one cuddle assignment allowed before switch statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-switch-statement)
|
||||||
if forever {
|
* [Only one cuddle assignment allowed before type switch statement](doc/rules.md#only-one-cuddle-assignment-allowed-before-type-switch-statement)
|
||||||
return true
|
* [Ranges should only be cuddled with assignments used in the iteration](doc/rules.md#ranges-should-only-be-cuddled-with-assignments-used-in-the-iteration)
|
||||||
}
|
* [Return statements should not be cuddled if block has more than two lines](doc/rules.md#return-statements-should-not-be-cuddled-if-block-has-more-than-two-lines)
|
||||||
|
* [Stmt type not implemented](doc/rules.md#stmt-type-not-implemented)
|
||||||
if false {
|
* [Switch statements should only be cuddled with variables switched](doc/rules.md#switch-statements-should-only-be-cuddled-with-variables-switched)
|
||||||
fmt.Println("first if")
|
* [Type switch statements should only be cuddled with variables switched](doc/rules.md#type-switch-statements-should-only-be-cuddled-with-variables-switched)
|
||||||
}
|
|
||||||
if true {
|
|
||||||
fmt.Println("second if is cuddled")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Do**
|
|
||||||
|
|
||||||
```go
|
|
||||||
val, err := SomeThing()
|
|
||||||
if err != nil {
|
|
||||||
// err is assigned on line above
|
|
||||||
}
|
|
||||||
|
|
||||||
first := 1
|
|
||||||
second := 2
|
|
||||||
third := 3
|
|
||||||
forever := 4
|
|
||||||
|
|
||||||
if forever > 3 {
|
|
||||||
return fmt.Sprintf("group multiple assignments away from if")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Or separate from your condition.
|
|
||||||
first := 1
|
|
||||||
second := 2
|
|
||||||
third := 3
|
|
||||||
|
|
||||||
forever := 4
|
|
||||||
if forever > 3 {
|
|
||||||
return fmt.Sprintf("group multiple assignments away from if")
|
|
||||||
}
|
|
||||||
|
|
||||||
if false {
|
|
||||||
// This is one statement
|
|
||||||
}
|
|
||||||
|
|
||||||
if true {
|
|
||||||
// This is another one, don't cuddled them!
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Return
|
|
||||||
|
|
||||||
Return should be placed on a separate line from other statement unless the block
|
|
||||||
consists of only two lines (including the return).
|
|
||||||
|
|
||||||
**Don't**
|
|
||||||
|
|
||||||
```go
|
|
||||||
doSomething()
|
|
||||||
add := 1+2
|
|
||||||
fmt.Sprintf(add)
|
|
||||||
return false
|
|
||||||
|
|
||||||
if true {
|
|
||||||
stmt.X = true
|
|
||||||
stmt.Y = false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Do**
|
|
||||||
|
|
||||||
```go
|
|
||||||
doSomething()
|
|
||||||
|
|
||||||
add := 1+2
|
|
||||||
fmt.Sprintf(add))
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
if true {
|
|
||||||
stmt.X = "only one line without return, may cuddled"
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if thisWorksToo {
|
|
||||||
whitespace := true
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Branch statement
|
|
||||||
|
|
||||||
The same rule as for return
|
|
||||||
|
|
||||||
**Don't**
|
|
||||||
|
|
||||||
```go
|
|
||||||
for i := range make([]int, 5) {
|
|
||||||
if i > 2 {
|
|
||||||
sendToOne(i)
|
|
||||||
sendToSecond(i)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Do**
|
|
||||||
|
|
||||||
```go
|
|
||||||
for i := range make([]int, 5) {
|
|
||||||
if i > 2 {
|
|
||||||
sendToOne(i)
|
|
||||||
sendToSecond(i)
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if statement == "is short" {
|
|
||||||
sendToOne(i)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Assignment
|
|
||||||
|
|
||||||
Assignments may only be cuddled with other assignments.
|
|
||||||
|
|
||||||
**Don't**
|
|
||||||
|
|
||||||
```go
|
|
||||||
assignOne := "one"
|
|
||||||
callFunc(assignOne)
|
|
||||||
assignTwo := "two")
|
|
||||||
callFunc(assignTwo)
|
|
||||||
|
|
||||||
if true {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
assigningClose := "bad"
|
|
||||||
|
|
||||||
var x = 2
|
|
||||||
y := 3
|
|
||||||
```
|
|
||||||
|
|
||||||
**Do**
|
|
||||||
|
|
||||||
```go
|
|
||||||
assignOne := "one"
|
|
||||||
assignTwo := "two")
|
|
||||||
|
|
||||||
callFunc(assignOne)
|
|
||||||
callFunc(assignTwo)
|
|
||||||
|
|
||||||
// Or group assignment and call by usage.
|
|
||||||
assignOne := "one"
|
|
||||||
callFunc(assignOne)
|
|
||||||
|
|
||||||
assignTwo := "two")
|
|
||||||
callFunc(assignTwo)
|
|
||||||
|
|
||||||
if true {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
notAssigningClose := "not bad"
|
|
||||||
|
|
||||||
var x = 2
|
|
||||||
|
|
||||||
y := 3
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Declarations
|
|
||||||
|
|
||||||
Declarations should never be cuddled with anything, not even other declarations.
|
|
||||||
|
|
||||||
**Don't**
|
|
||||||
|
|
||||||
```go
|
|
||||||
var x int
|
|
||||||
var y int
|
|
||||||
|
|
||||||
z := 2
|
|
||||||
var a
|
|
||||||
```
|
|
||||||
|
|
||||||
**Do**
|
|
||||||
|
|
||||||
```go
|
|
||||||
// Group declarations, they'll align nice and tidy!
|
|
||||||
var (
|
|
||||||
x int
|
|
||||||
y int
|
|
||||||
)
|
|
||||||
|
|
||||||
z := 2
|
|
||||||
|
|
||||||
var a
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Expressions
|
|
||||||
|
|
||||||
Expressions (function calls) may never be cuddled with declarations or return
|
|
||||||
statements. Expressions may also not be cuddled with assignments if not passed
|
|
||||||
to the expression func.
|
|
||||||
|
|
||||||
**Don't**
|
|
||||||
|
|
||||||
```go
|
|
||||||
var a bool
|
|
||||||
fmt.Println(a)
|
|
||||||
|
|
||||||
foo := true
|
|
||||||
someFunc(false)
|
|
||||||
|
|
||||||
if someBool() {
|
|
||||||
fmt.Println("doing things")
|
|
||||||
}
|
|
||||||
x.Calling()
|
|
||||||
```
|
|
||||||
|
|
||||||
**Do**
|
|
||||||
|
|
||||||
```go
|
|
||||||
var b bool
|
|
||||||
|
|
||||||
fmt.Println(b)
|
|
||||||
|
|
||||||
foo := true
|
|
||||||
someFunc(foo)
|
|
||||||
|
|
||||||
bar := false
|
|
||||||
|
|
||||||
someFunc(true)
|
|
||||||
|
|
||||||
if someBool() {
|
|
||||||
fmt.Println("doing things")
|
|
||||||
}
|
|
||||||
|
|
||||||
x.Calling()
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Ranges
|
|
||||||
|
|
||||||
Range statements may only be cuddled with assignments that are used in the
|
|
||||||
range. Just like if statements this only applies if it's a single assignment
|
|
||||||
cuddled and not multiple.
|
|
||||||
|
|
||||||
Ranges may also be cuddled with assignments that are used directly in the block
|
|
||||||
as first statement.
|
|
||||||
|
|
||||||
**Don't**
|
|
||||||
|
|
||||||
```go
|
|
||||||
noRangeList := []string{"a", "b", "c"}
|
|
||||||
for _, x := range anotherList {
|
|
||||||
fmt.Println(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
oneList := []int{1, 2, 3}
|
|
||||||
twoList := []int{4, 5, 6}
|
|
||||||
for i := range twoList {
|
|
||||||
fmt.Println("too much assignments!")
|
|
||||||
}
|
|
||||||
|
|
||||||
myCount := 0
|
|
||||||
for _, v := range aList {
|
|
||||||
fmt.Sprintf("first statement doesn't use assignment")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Do**
|
|
||||||
|
|
||||||
```go
|
|
||||||
rangeList := []string{"a", "b", "c"}
|
|
||||||
for _, x := range rangeList {
|
|
||||||
fmt.Println(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
oneList := []int{1, 2, 3}
|
|
||||||
|
|
||||||
twoList := []int{4, 5, 6}
|
|
||||||
for i := range twoList {
|
|
||||||
fmt.Println("too much assignments!")
|
|
||||||
}
|
|
||||||
|
|
||||||
myCount := 0
|
|
||||||
for _, v := range aList {
|
|
||||||
myCount += v
|
|
||||||
|
|
||||||
fmt.Sprintf("first statement uses cuddled assignment")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Defer
|
|
||||||
|
|
||||||
Defer is almost handled like return statements but there are cases where
|
|
||||||
grouping defer statements with each other or expression calls may improve
|
|
||||||
readability.
|
|
||||||
|
|
||||||
Defer statements may be cuddled with other defer statements as many times as you
|
|
||||||
like. It may also be cuddled with assignments above or expression variables on
|
|
||||||
the line above.
|
|
||||||
|
|
||||||
**Don't**
|
|
||||||
|
|
||||||
```go
|
|
||||||
first := getFirst()
|
|
||||||
defer first.Close()
|
|
||||||
second := getSecond() // This will fail
|
|
||||||
defer second.Close()
|
|
||||||
|
|
||||||
first := getFirst()
|
|
||||||
second := getSecond()
|
|
||||||
defer first.Close() // Too many assignments above
|
|
||||||
defer second.Close()
|
|
||||||
|
|
||||||
m1.Lock()
|
|
||||||
defer m2.RUnlock() // Not the expression above
|
|
||||||
```
|
|
||||||
|
|
||||||
**Do**
|
|
||||||
|
|
||||||
```go
|
|
||||||
first := getFirst()
|
|
||||||
second := getSecond()
|
|
||||||
|
|
||||||
defer first.Close()
|
|
||||||
defer second.Close()
|
|
||||||
|
|
||||||
// Or group by usage.
|
|
||||||
first := getFirst()
|
|
||||||
defer first.Close()
|
|
||||||
|
|
||||||
second := getSecond()
|
|
||||||
defer second.Close()
|
|
||||||
|
|
||||||
m.Lock()
|
|
||||||
defer m.Unlock()
|
|
||||||
```
|
|
||||||
|
|
||||||
#### For loops
|
|
||||||
|
|
||||||
For statements works similar like ranges except that anonymous (infinite) loops
|
|
||||||
may never be cuddled. Just like the range statement, variables used in the for
|
|
||||||
or in first statement in the body may be cuddled.
|
|
||||||
|
|
||||||
**Don't**
|
|
||||||
|
|
||||||
```go
|
|
||||||
t := true
|
|
||||||
for notT {
|
|
||||||
fmt.Println("where's t used?")
|
|
||||||
}
|
|
||||||
|
|
||||||
n := 0
|
|
||||||
m := 1
|
|
||||||
for x < 100 {
|
|
||||||
n += x // m not used in for or body
|
|
||||||
}
|
|
||||||
|
|
||||||
n := 1
|
|
||||||
for {
|
|
||||||
fmt.Println("never cuddled for without condition")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Do**
|
|
||||||
|
|
||||||
```go
|
|
||||||
t := true
|
|
||||||
for t {
|
|
||||||
fmt.Println("t used in for")
|
|
||||||
}
|
|
||||||
|
|
||||||
n := 0
|
|
||||||
for x < 100 {
|
|
||||||
n += x // n used in first block statement.
|
|
||||||
}
|
|
||||||
|
|
||||||
n := 1
|
|
||||||
|
|
||||||
for {
|
|
||||||
fmt.Println("never cuddled for without condition")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Go
|
|
||||||
|
|
||||||
Go routines may only be executed if there's a maximum of one assignments above
|
|
||||||
and that assignment is used in the expression.
|
|
||||||
|
|
||||||
**Don't**
|
|
||||||
|
|
||||||
```go
|
|
||||||
first := func() {}
|
|
||||||
second := func() {}
|
|
||||||
go second()
|
|
||||||
|
|
||||||
notUsed := func() {}
|
|
||||||
go first()
|
|
||||||
|
|
||||||
x := "1"
|
|
||||||
go func() {
|
|
||||||
fmt.Println("where's x used!=")
|
|
||||||
}()
|
|
||||||
```
|
|
||||||
|
|
||||||
**Do**
|
|
||||||
|
|
||||||
```go
|
|
||||||
first := func() {}
|
|
||||||
go first()
|
|
||||||
|
|
||||||
notUsed := func() {}
|
|
||||||
|
|
||||||
first := func() {}
|
|
||||||
go first()
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Switch and Type switch
|
|
||||||
|
|
||||||
The same rules applies for switch and type switch statements with the exception
|
|
||||||
of anonymous type switches. That means type switches where a new variable is not
|
|
||||||
assigned. It's also allowed to cuddled type switches with variables used if it's
|
|
||||||
used as the first argument in the first case.
|
|
||||||
|
|
||||||
Type switches may only be cuddled with one assignment above and if that
|
|
||||||
assignment is used in the switch.
|
|
||||||
|
|
||||||
**Don't**
|
|
||||||
|
|
||||||
```go
|
|
||||||
notSome := SomeInt()
|
|
||||||
switch some {
|
|
||||||
case 1:
|
|
||||||
fmt.Println("1")
|
|
||||||
default:
|
|
||||||
fmt.Println("not 1")
|
|
||||||
}
|
|
||||||
|
|
||||||
notSwitched := SomeInt()
|
|
||||||
switch {
|
|
||||||
case 1 > 2:
|
|
||||||
fmt.Println("whitespace between assignments")
|
|
||||||
}
|
|
||||||
|
|
||||||
n := 0
|
|
||||||
switch v := some.(type):
|
|
||||||
case typeOne:
|
|
||||||
x := v.X // n not used in switch or body
|
|
||||||
case typeTwo:
|
|
||||||
x := v.X
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Do**
|
|
||||||
|
|
||||||
```go
|
|
||||||
some := SomeInt()
|
|
||||||
switch some {
|
|
||||||
case 1:
|
|
||||||
fmt.Println("1")
|
|
||||||
default:
|
|
||||||
fmt.Println("not 1")
|
|
||||||
}
|
|
||||||
|
|
||||||
notSwitched := SomeInt()
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case 1 > 2:
|
|
||||||
fmt.Println("whitespace between assignments")
|
|
||||||
}
|
|
||||||
|
|
||||||
n := 0
|
|
||||||
switch v := some.(type):
|
|
||||||
case typeOne:
|
|
||||||
n = v.X // n is used first in block, OK to cuddle
|
|
||||||
case typeTwo:
|
|
||||||
n = v.Y
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
209
vendor/github.com/bombsimon/wsl/wsl.go
generated
vendored
209
vendor/github.com/bombsimon/wsl/wsl.go
generated
vendored
@ -50,21 +50,12 @@ type Configuration struct {
|
|||||||
// }
|
// }
|
||||||
AllowMultiLineAssignCuddle bool
|
AllowMultiLineAssignCuddle bool
|
||||||
|
|
||||||
// AllowCaseTrailingWhitespace will allow case blocks to end with a
|
// If the number of lines in a case block is equal to or lager than this
|
||||||
// whitespace. Sometimes this might actually improve readability. This
|
// number, the case *must* end white a newline.
|
||||||
// defaults to false but setting it to true will enable the following
|
CaseForceTrailingWhitespaceLimit int
|
||||||
// example:
|
|
||||||
// switch {
|
// AllowTrailingComment will allow blocks to end with comments.
|
||||||
// case 1:
|
AllowTrailingComment bool
|
||||||
// fmt.Println(1)
|
|
||||||
//
|
|
||||||
// case 2:
|
|
||||||
// fmt.Println(2)
|
|
||||||
//
|
|
||||||
// case 3:
|
|
||||||
// fmt:println(3)
|
|
||||||
// }
|
|
||||||
AllowCaseTrailingWhitespace bool
|
|
||||||
|
|
||||||
// AllowCuddleDeclaration will allow multiple var/declaration statements to
|
// AllowCuddleDeclaration will allow multiple var/declaration statements to
|
||||||
// be cuddled. This defaults to false but setting it to true will enable the
|
// be cuddled. This defaults to false but setting it to true will enable the
|
||||||
@ -93,12 +84,13 @@ type Configuration struct {
|
|||||||
// DefaultConfig returns default configuration
|
// DefaultConfig returns default configuration
|
||||||
func DefaultConfig() Configuration {
|
func DefaultConfig() Configuration {
|
||||||
return Configuration{
|
return Configuration{
|
||||||
StrictAppend: true,
|
StrictAppend: true,
|
||||||
AllowAssignAndCallCuddle: true,
|
AllowAssignAndCallCuddle: true,
|
||||||
AllowMultiLineAssignCuddle: true,
|
AllowMultiLineAssignCuddle: true,
|
||||||
AllowCaseTrailingWhitespace: false,
|
AllowTrailingComment: false,
|
||||||
AllowCuddleWithCalls: []string{"Lock", "RLock"},
|
CaseForceTrailingWhitespaceLimit: 0,
|
||||||
AllowCuddleWithRHS: []string{"Unlock", "RUnlock"},
|
AllowCuddleWithCalls: []string{"Lock", "RLock"},
|
||||||
|
AllowCuddleWithRHS: []string{"Unlock", "RUnlock"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,14 +195,12 @@ func (p *Processor) parseBlockBody(ident *ast.Ident, block *ast.BlockStmt) {
|
|||||||
// nolint: gocognit
|
// nolint: gocognit
|
||||||
func (p *Processor) parseBlockStatements(statements []ast.Stmt) {
|
func (p *Processor) parseBlockStatements(statements []ast.Stmt) {
|
||||||
for i, stmt := range statements {
|
for i, stmt := range statements {
|
||||||
// TODO: How to tell when and where func literals may exist to enforce
|
// Start by checking if this statement is another block (other than if,
|
||||||
// linting.
|
// for and range). This could be assignment to a function, defer or go
|
||||||
if as, isAssignStmt := stmt.(*ast.AssignStmt); isAssignStmt {
|
// call with an inline function or similar. If this is found we start by
|
||||||
for _, rhs := range as.Rhs {
|
// parsing this body block before moving on.
|
||||||
if fl, isFuncLit := rhs.(*ast.FuncLit); isFuncLit {
|
for _, stmtBlocks := range p.findBlockStmt(stmt) {
|
||||||
p.parseBlockBody(nil, fl.Body)
|
p.parseBlockBody(nil, stmtBlocks)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
firstBodyStatement := p.firstBodyStatement(i, statements)
|
firstBodyStatement := p.firstBodyStatement(i, statements)
|
||||||
@ -322,11 +312,15 @@ func (p *Processor) parseBlockStatements(statements []ast.Stmt) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) {
|
if atLeastOneInListsMatch(rightAndLeftHandSide, assignedOnLineAbove) {
|
||||||
if !atLeastOneInListsMatch(assignedOnLineAbove, assignedFirstInBlock) {
|
continue
|
||||||
p.addError(t.Pos(), "if statements should only be cuddled with assignments used in the if statement itself")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if atLeastOneInListsMatch(assignedOnLineAbove, assignedFirstInBlock) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
p.addError(t.Pos(), "if statements should only be cuddled with assignments used in the if statement itself")
|
||||||
case *ast.ReturnStmt:
|
case *ast.ReturnStmt:
|
||||||
if isLastStatementInBlockOfOnlyTwoLines() {
|
if isLastStatementInBlockOfOnlyTwoLines() {
|
||||||
continue
|
continue
|
||||||
@ -473,6 +467,10 @@ func (p *Processor) parseBlockStatements(statements []ast.Stmt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *ast.GoStmt:
|
case *ast.GoStmt:
|
||||||
|
if _, ok := previousStatement.(*ast.GoStmt); ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if moreThanOneStatementAbove() {
|
if moreThanOneStatementAbove() {
|
||||||
p.addError(t.Pos(), "only one cuddle assignment allowed before go statement")
|
p.addError(t.Pos(), "only one cuddle assignment allowed before go statement")
|
||||||
|
|
||||||
@ -595,9 +593,10 @@ func (p *Processor) findLHS(node ast.Node) []string {
|
|||||||
*ast.ReturnStmt, *ast.GoStmt, *ast.CaseClause,
|
*ast.ReturnStmt, *ast.GoStmt, *ast.CaseClause,
|
||||||
*ast.CommClause, *ast.CallExpr, *ast.UnaryExpr,
|
*ast.CommClause, *ast.CallExpr, *ast.UnaryExpr,
|
||||||
*ast.BranchStmt, *ast.TypeSpec, *ast.ChanType,
|
*ast.BranchStmt, *ast.TypeSpec, *ast.ChanType,
|
||||||
*ast.DeferStmt, *ast.TypeAssertExpr, *ast.IncDecStmt,
|
*ast.DeferStmt, *ast.TypeAssertExpr, *ast.RangeStmt:
|
||||||
*ast.RangeStmt:
|
// Nothing to add to LHS
|
||||||
// Nothing to add to LHS
|
case *ast.IncDecStmt:
|
||||||
|
return p.findLHS(t.X)
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
return []string{t.Name}
|
return []string{t.Name}
|
||||||
case *ast.AssignStmt:
|
case *ast.AssignStmt:
|
||||||
@ -722,6 +721,33 @@ func (p *Processor) findRHS(node ast.Node) []string {
|
|||||||
return rhs
|
return rhs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Processor) findBlockStmt(node ast.Node) []*ast.BlockStmt {
|
||||||
|
var blocks []*ast.BlockStmt
|
||||||
|
|
||||||
|
switch t := node.(type) {
|
||||||
|
case *ast.AssignStmt:
|
||||||
|
for _, x := range t.Rhs {
|
||||||
|
blocks = append(blocks, p.findBlockStmt(x)...)
|
||||||
|
}
|
||||||
|
case *ast.CallExpr:
|
||||||
|
blocks = append(blocks, p.findBlockStmt(t.Fun)...)
|
||||||
|
case *ast.FuncLit:
|
||||||
|
blocks = append(blocks, t.Body)
|
||||||
|
case *ast.ExprStmt:
|
||||||
|
blocks = append(blocks, p.findBlockStmt(t.X)...)
|
||||||
|
case *ast.ReturnStmt:
|
||||||
|
for _, x := range t.Results {
|
||||||
|
blocks = append(blocks, p.findBlockStmt(x)...)
|
||||||
|
}
|
||||||
|
case *ast.DeferStmt:
|
||||||
|
blocks = append(blocks, p.findBlockStmt(t.Call)...)
|
||||||
|
case *ast.GoStmt:
|
||||||
|
blocks = append(blocks, p.findBlockStmt(t.Call)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return blocks
|
||||||
|
}
|
||||||
|
|
||||||
// maybeX extracts the X field from an AST node and returns it with a true value
|
// maybeX extracts the X field from an AST node and returns it with a true value
|
||||||
// if it exists. If the node doesn't have an X field nil and false is returned.
|
// if it exists. If the node doesn't have an X field nil and false is returned.
|
||||||
// Known fields with X that are handled:
|
// Known fields with X that are handled:
|
||||||
@ -839,7 +865,10 @@ func (p *Processor) findLeadingAndTrailingWhitespaces(ident *ast.Ident, stmt, ne
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
allowedLinesBeforeFirstStatement += len(commentGroup.List)
|
// Support both /* multiline */ and //single line comments
|
||||||
|
for _, c := range commentGroup.List {
|
||||||
|
allowedLinesBeforeFirstStatement += len(strings.Split(c.Text, "\n"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -850,38 +879,92 @@ func (p *Processor) findLeadingAndTrailingWhitespaces(ident *ast.Ident, stmt, ne
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the blockEndLine is 0 we're a case clause. If we don't have any
|
// If the blockEndLine is not 0 we're a regular block (not case).
|
||||||
// nextStatement the trailing whitespace will be handled when parsing the
|
if blockEndLine != 0 {
|
||||||
// switch. If we do have a next statement we can see where it starts by
|
if p.config.AllowTrailingComment {
|
||||||
// getting it's colon position.
|
if lastComment, ok := commentMap[lastStatement]; ok {
|
||||||
if blockEndLine == 0 {
|
var (
|
||||||
if nextStatement == nil {
|
lastCommentGroup = lastComment[len(lastComment)-1]
|
||||||
return
|
lastCommentLine = lastCommentGroup.List[len(lastCommentGroup.List)-1]
|
||||||
|
countNewlines = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
countNewlines += len(strings.Split(lastCommentLine.Text, "\n"))
|
||||||
|
|
||||||
|
// No newlines between trailing comments and end of block.
|
||||||
|
if p.nodeStart(lastCommentLine)+countNewlines != blockEndLine-1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we allow case to end white whitespace just return.
|
if p.nodeEnd(lastStatement) != blockEndLine-1 && !isExampleFunc(ident) {
|
||||||
if p.config.AllowCaseTrailingWhitespace {
|
p.addError(blockEndPos, "block should not end with a whitespace (or comment)")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n := nextStatement.(type) {
|
return
|
||||||
case *ast.CaseClause:
|
|
||||||
blockEndPos = n.Case
|
|
||||||
case *ast.CommClause:
|
|
||||||
blockEndPos = n.Case
|
|
||||||
default:
|
|
||||||
// We're not at the end of the case?
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
blockEndLine = p.fileSet.Position(blockEndPos).Line
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.nodeEnd(lastStatement) != blockEndLine-1 && !isExampleFunc(ident) {
|
// If we don't have any nextStatement the trailing whitespace will be
|
||||||
p.addError(
|
// handled when parsing the switch. If we do have a next statement we can
|
||||||
blockEndPos,
|
// see where it starts by getting it's colon position. We set the end of the
|
||||||
"block should not end with a whitespace (or comment)",
|
// current case to the position of the next case.
|
||||||
)
|
switch n := nextStatement.(type) {
|
||||||
|
case *ast.CaseClause:
|
||||||
|
blockEndPos = n.Case
|
||||||
|
case *ast.CommClause:
|
||||||
|
blockEndPos = n.Case
|
||||||
|
default:
|
||||||
|
// No more cases
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
blockEndLine = p.fileSet.Position(blockEndPos).Line - 1
|
||||||
|
|
||||||
|
var (
|
||||||
|
blockSize = blockEndLine - blockStartLine
|
||||||
|
caseTrailingCommentLines int
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: I don't know what comments are bound to in cases. For regular
|
||||||
|
// blocks the last comment is bound to the last statement but for cases
|
||||||
|
// they are bound to the case clause expression. This will however get us all
|
||||||
|
// comments and depending on the case expression this gets tricky.
|
||||||
|
//
|
||||||
|
// To handle this I get the comment map from the current statement (the case
|
||||||
|
// itself) and iterate through all groups and all comment within all groups.
|
||||||
|
// I then get the comments after the last statement but before the next case
|
||||||
|
// clause and just map each line of comment that way.
|
||||||
|
for _, commentGroups := range commentMap {
|
||||||
|
for _, commentGroup := range commentGroups {
|
||||||
|
for _, comment := range commentGroup.List {
|
||||||
|
commentLine := p.fileSet.Position(comment.Pos()).Line
|
||||||
|
|
||||||
|
// Ignore comments before the last statement.
|
||||||
|
if commentLine <= p.nodeStart(lastStatement) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore comments after the end of this case.
|
||||||
|
if commentLine > blockEndLine {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// This allows /* multiline */ comments with newlines as well
|
||||||
|
// as regular (//) ones
|
||||||
|
caseTrailingCommentLines += len(strings.Split(comment.Text, "\n"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hasTrailingWhitespace := p.nodeEnd(lastStatement)+caseTrailingCommentLines != blockEndLine
|
||||||
|
|
||||||
|
// If the force trailing limit is configured and we don't end with a newline.
|
||||||
|
if p.config.CaseForceTrailingWhitespaceLimit > 0 && !hasTrailingWhitespace {
|
||||||
|
// Check if the block size is too big to miss the newline.
|
||||||
|
if blockSize >= p.config.CaseForceTrailingWhitespaceLimit {
|
||||||
|
p.addError(lastStatement.Pos(), "case block should end with newline at this size")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -4,7 +4,7 @@ github.com/BurntSushi/toml
|
|||||||
github.com/OpenPeeDeeP/depguard
|
github.com/OpenPeeDeeP/depguard
|
||||||
# github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6
|
# github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6
|
||||||
github.com/StackExchange/wmi
|
github.com/StackExchange/wmi
|
||||||
# github.com/bombsimon/wsl v1.2.5
|
# github.com/bombsimon/wsl v1.2.7
|
||||||
github.com/bombsimon/wsl
|
github.com/bombsimon/wsl
|
||||||
# github.com/davecgh/go-spew v1.1.1
|
# github.com/davecgh/go-spew v1.1.1
|
||||||
github.com/davecgh/go-spew/spew
|
github.com/davecgh/go-spew/spew
|
||||||
|
Loading…
x
Reference in New Issue
Block a user