@@ -24,7 +24,8 @@ const (
24
24
25
25
// Settings contains settings for edge-cases
26
26
type Settings struct {
27
- MultiIf bool
27
+ MultiIf bool
28
+ MultiFunc bool
28
29
}
29
30
30
31
// Run runs this linter on the provided code
@@ -47,42 +48,40 @@ func Run(file *ast.File, fset *token.FileSet, settings Settings) []Message {
47
48
}
48
49
49
50
type visitor struct {
50
- comments []* ast.CommentGroup
51
- fset * token.FileSet
52
- messages []Message
53
- multiIf map [* ast.BlockStmt ]bool
54
- settings Settings
51
+ comments []* ast.CommentGroup
52
+ fset * token.FileSet
53
+ messages []Message
54
+ wantNewline map [* ast.BlockStmt ]bool
55
+ settings Settings
55
56
}
56
57
57
58
func (v * visitor ) Visit (node ast.Node ) ast.Visitor {
58
59
if node == nil {
59
60
return v
60
61
}
61
62
62
- if v .settings .MultiIf {
63
- if stmt , ok := node .( * ast. IfStmt ); ok {
64
- start , end := posLine ( v . fset , stmt . Cond . Pos ()), posLine ( v . fset , stmt . Cond . End ())
63
+ if stmt , ok := node .( * ast. IfStmt ); ok && v .settings .MultiIf {
64
+ checkMultiLine ( v , stmt . Body , stmt . Cond )
65
+ }
65
66
66
- if end > start { // Check only multi line conditions
67
- v .multiIf [stmt .Body ] = true
68
- }
69
- }
67
+ if stmt , ok := node .(* ast.FuncDecl ); ok && v .settings .MultiFunc {
68
+ checkMultiLine (v , stmt .Body , stmt .Type )
70
69
}
71
70
72
71
if stmt , ok := node .(* ast.BlockStmt ); ok {
73
- multiIf := v .multiIf [stmt ]
72
+ wantNewline := v .wantNewline [stmt ]
74
73
75
74
comments := v .comments
76
- if multiIf {
77
- comments = nil
75
+ if wantNewline {
76
+ comments = nil // Comments also count as a newline if we want a newline
78
77
}
79
78
first , last := firstAndLast (comments , v .fset , stmt .Pos (), stmt .End (), stmt .List )
80
79
81
80
startMsg := checkStart (v .fset , stmt .Lbrace , first )
82
81
83
- if multiIf && startMsg == nil {
84
- v .messages = append (v .messages , Message {v .fset .Position (stmt .Pos ()), MessageTypeAddAfter , `multi-line if should be followed by a newline` })
85
- } else if ! multiIf && startMsg != nil {
82
+ if wantNewline && startMsg == nil {
83
+ v .messages = append (v .messages , Message {v .fset .Position (stmt .Pos ()), MessageTypeAddAfter , `multi-line statement should be followed by a newline` })
84
+ } else if ! wantNewline && startMsg != nil {
86
85
v .messages = append (v .messages , * startMsg )
87
86
}
88
87
@@ -94,6 +93,14 @@ func (v *visitor) Visit(node ast.Node) ast.Visitor {
94
93
return v
95
94
}
96
95
96
+ func checkMultiLine (v * visitor , body * ast.BlockStmt , stmtStart ast.Node ) {
97
+ start , end := posLine (v .fset , stmtStart .Pos ()), posLine (v .fset , stmtStart .End ())
98
+
99
+ if end > start { // Check only multi line conditions
100
+ v .wantNewline [body ] = true
101
+ }
102
+ }
103
+
97
104
func posLine (fset * token.FileSet , pos token.Pos ) int {
98
105
return fset .Position (pos ).Line
99
106
}
0 commit comments