Skip to content

Commit 5eae4e3

Browse files
Add support to cuddle assignments for a whole block (#163)
* Support to cuddle assignments for a whole block * Implement PR suggestions * Update doc/configuration.md Co-authored-by: Simon Sawert <[email protected]> --------- Co-authored-by: Simon Sawert <[email protected]>
1 parent 66344d2 commit 5eae4e3

File tree

9 files changed

+768
-12
lines changed

9 files changed

+768
-12
lines changed

analyzer.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func defaultConfig() *Configuration {
3737
AllowCuddleWithRHS: []string{"Unlock", "RUnlock"},
3838
ErrorVariableNames: []string{"err"},
3939
ForceCaseTrailingWhitespaceLimit: 0,
40+
AllowCuddleUsedInBlock: false,
4041
}
4142
}
4243

@@ -68,6 +69,7 @@ func (wa *wslAnalyzer) flags() flag.FlagSet {
6869
flags.BoolVar(&wa.config.ForceExclusiveShortDeclarations, "force-short-decl-cuddling", false, "Force short declarations to cuddle by themselves")
6970
flags.BoolVar(&wa.config.StrictAppend, "strict-append", true, "Strict rules for append")
7071
flags.BoolVar(&wa.config.IncludeGenerated, "include-generated", false, "Include generated files")
72+
flags.BoolVar(&wa.config.AllowCuddleUsedInBlock, "allow-cuddle-used-in-block", false, "Allow cuddling of variables used in block statements")
7173
flags.IntVar(&wa.config.ForceCaseTrailingWhitespaceLimit, "force-case-trailing-whitespace", 0, "Force newlines for case blocks > this number.")
7274

7375
flags.Var(&multiStringValue{slicePtr: &wa.config.AllowCuddleWithCalls}, "allow-cuddle-with-calls", "Comma separated list of idents that can have cuddles after")

doc/configuration.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,109 @@ var (
233233
)
234234
```
235235

236+
### allow-cuddle-used-in-block
237+
238+
Controls if you may cuddle variables used anywhere in the following block.
239+
240+
> Default value: false
241+
242+
Supported when true:
243+
244+
```go
245+
counter := 0
246+
if somethingTrue {
247+
checker := getAChecker()
248+
if !checker {
249+
return
250+
}
251+
252+
counter++
253+
}
254+
255+
var numbers []int
256+
for i := 0; i < 10; i++ {
257+
if 1 == 1 {
258+
numbers = append(numbers, i)
259+
}
260+
}
261+
262+
var numbers2 []int
263+
for {
264+
if 1 == 1 {
265+
numbers2 = append(numbers2, 1)
266+
}
267+
}
268+
269+
var id string
270+
switch {
271+
case int:
272+
if true {
273+
id = strconv.Itoa(i)
274+
}
275+
case uint32:
276+
if true {
277+
id = strconv.Itoa(int(i))
278+
}
279+
case string:
280+
if true {
281+
id = i
282+
}
283+
}
284+
```
285+
286+
Required when false:
287+
288+
```go
289+
counter := 0
290+
291+
if somethingTrue {
292+
checker := getAChecker()
293+
if !checker {
294+
return
295+
}
296+
297+
counter++
298+
}
299+
300+
var numbers []int
301+
302+
for i := 0; i < 10; i++ {
303+
if 1 == 1 {
304+
numbers = append(numbers, i)
305+
}
306+
}
307+
308+
var numbers2 []int
309+
310+
for {
311+
if 1 == 1 {
312+
numbers2 = append(numbers2, 1)
313+
}
314+
}
315+
316+
var id string
317+
318+
switch {
319+
case int:
320+
if true {
321+
id = strconv.Itoa(i)
322+
}
323+
case uint32:
324+
if true {
325+
id = strconv.Itoa(int(i))
326+
}
327+
case string:
328+
if true {
329+
id = i
330+
}
331+
}
332+
```
333+
334+
**Note**: this means the option _overrides_ the following rules:
335+
- [Anonymous switch statements should never be cuddled](rules.md#anonymous-switch-statements-should-never-be-cuddled)
336+
- [For statement without condition should never be cuddled](rules.md#for-statement-without-condition-should-never-be-cuddled)
337+
338+
236339
### [allow-trailing-comment](rules.md#block-should-not-end-with-a-whitespace-or-comment)
237340

238341
Controls if blocks can end with comments. This is not encouraged sine it's

doc/rules.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ linter and how they should be resolved or configured to handle.
66
## Checklist
77

88
### Anonymous switch statements should never be cuddled
9+
> Can be configured, see [configuration
10+
documentation](configuration.md#allow-cuddle-used-in-block)
911

1012
Anonymous `switch` statements (mindless `switch`) should deserve its needed
1113
attention that it does not need any assigned variables. Hence, it should not
@@ -398,6 +400,8 @@ run()
398400
---
399401

400402
### For statement without condition should never be cuddled
403+
> Can be configured, see [configuration
404+
documentation](configuration.md#allow-cuddle-used-in-block)
401405

402406
`for` loop without conditions (infinity loop) should deserves its own
403407
attention. Hence, it should not be cuddled with anyone.
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package testpkg
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
)
7+
8+
func ForCuddleAssignmentWholeBlock() {
9+
x := 1
10+
y := 2
11+
12+
var numbers []int
13+
for i := 0; i < 10; i++ { // want "for statements should only be cuddled with assignments used in the iteration"
14+
if x == y {
15+
numbers = append(numbers, i)
16+
}
17+
}
18+
19+
var numbers2 []int
20+
for i := range 10 { // want "ranges should only be cuddled with assignments used in the iteration"
21+
if x == y {
22+
numbers2 = append(numbers2, i)
23+
}
24+
}
25+
26+
var numbers3 []int
27+
for { // want "for statement without condition should never be cuddled"
28+
if x == y {
29+
numbers3 = append(numbers3, i)
30+
}
31+
}
32+
33+
environment = make(map[string]string)
34+
for _, env := range req.GetConfig().GetEnvs() { // want "ranges should only be cuddled with assignments used in the iteration"
35+
switch env.GetKey() {
36+
case "user-data":
37+
cloudInitUserData = env.GetValue()
38+
default:
39+
environment[env.GetKey()] = env.GetValue()
40+
}
41+
}
42+
}
43+
44+
func IfCuddleAssignmentWholeBlock() {
45+
x := 1
46+
y := 2
47+
48+
counter := 0
49+
if somethingTrue { // want "if statements should only be cuddled with assignments used in the if statement itself"
50+
checker := getAChecker()
51+
if !checker {
52+
return
53+
}
54+
55+
counter++ // Cuddled variable used in block, but not as first statement
56+
}
57+
58+
var number2 []int
59+
if x == y { // want "if statements should only be cuddled with assignments used in the if statement itself"
60+
fmt.Println("a")
61+
} else {
62+
if x > y {
63+
number2 = append(number2, i)
64+
}
65+
}
66+
67+
var number3 []int
68+
if x == y { // want "if statements should only be cuddled with assignments used in the if statement itself"
69+
fmt.Println("a")
70+
} else if x > y {
71+
if x == y {
72+
number3 = append(number3, i)
73+
}
74+
}
75+
76+
var number4 []int
77+
if x == y { // want "if statements should only be cuddled with assignments used in the if statement itself"
78+
if x == y {
79+
number4 = append(number4, i)
80+
}
81+
} else if x > y {
82+
if x == y {
83+
number4 = append(number4, i)
84+
}
85+
} else {
86+
if x > y {
87+
number4 = append(number4, i)
88+
}
89+
}
90+
}
91+
92+
func SwitchCuddleAssignmentWholeBlock() {
93+
var id string
94+
var b bool // want "declarations should never be cuddled"
95+
switch b { // want "only one cuddle assignment allowed before switch statement"
96+
case true:
97+
id = "a"
98+
case false:
99+
id = "b"
100+
}
101+
102+
var b bool
103+
var id string // want "declarations should never be cuddled"
104+
switch b { // want "only one cuddle assignment allowed before switch statement"
105+
case true:
106+
id = "a"
107+
case false:
108+
id = "b"
109+
}
110+
111+
var id2 string
112+
switch i := objectID.(type) { // want "type switch statements should only be cuddled with variables switched"
113+
case int:
114+
if true {
115+
id2 = strconv.Itoa(i)
116+
}
117+
case uint32:
118+
if true {
119+
id2 = strconv.Itoa(int(i))
120+
}
121+
case string:
122+
if true {
123+
id2 = i
124+
}
125+
}
126+
127+
var id3 string
128+
switch { // want "anonymous switch statements should never be cuddled"
129+
case int:
130+
if true {
131+
id3 = strconv.Itoa(i)
132+
}
133+
case uint32:
134+
if true {
135+
id3 = strconv.Itoa(int(i))
136+
}
137+
case string:
138+
if true {
139+
id3 = i
140+
}
141+
}
142+
}

0 commit comments

Comments
 (0)