Skip to content

Commit 81d85b5

Browse files
authored
fix #824 (#829)
1 parent ed6d9ce commit 81d85b5

File tree

2 files changed

+51
-36
lines changed

2 files changed

+51
-36
lines changed

rule/nested-structs.go

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ func (*NestedStructs) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
1414
var failures []lint.Failure
1515

1616
walker := &lintNestedStructs{
17-
fileAST: file.AST,
1817
onFailure: func(failure lint.Failure) {
1918
failures = append(failures, failure)
2019
},
@@ -31,47 +30,46 @@ func (*NestedStructs) Name() string {
3130
}
3231

3332
type lintNestedStructs struct {
34-
fileAST *ast.File
3533
onFailure func(lint.Failure)
3634
}
3735

3836
func (l *lintNestedStructs) Visit(n ast.Node) ast.Visitor {
39-
switch v := n.(type) {
40-
case *ast.TypeSpec:
41-
_, isInterface := v.Type.(*ast.InterfaceType)
42-
if isInterface {
43-
return nil // do not analyze interface declarations
44-
}
45-
case *ast.FuncDecl:
46-
if v.Body != nil {
47-
ast.Walk(l, v.Body)
48-
}
49-
return nil
50-
case *ast.Field:
51-
_, isChannelField := v.Type.(*ast.ChanType)
52-
if isChannelField {
53-
return nil
54-
}
37+
if v, ok := n.(*ast.StructType); ok {
38+
ls := &lintStruct{l.onFailure}
39+
ast.Walk(ls, v.Fields)
40+
}
5541

56-
filter := func(n ast.Node) bool {
57-
switch n.(type) {
58-
case *ast.StructType:
59-
return true
60-
default:
61-
return false
62-
}
63-
}
64-
structs := pick(v, filter, nil)
65-
for _, s := range structs {
66-
l.onFailure(lint.Failure{
67-
Failure: "no nested structs are allowed",
68-
Category: "style",
69-
Node: s,
70-
Confidence: 1,
71-
})
42+
return l
43+
}
44+
45+
type lintStruct struct {
46+
onFailure func(lint.Failure)
47+
}
48+
49+
func (l *lintStruct) Visit(n ast.Node) ast.Visitor {
50+
switch s := n.(type) {
51+
case *ast.StructType:
52+
l.fail(s)
53+
return nil
54+
case *ast.ArrayType:
55+
if _, ok := s.Elt.(*ast.StructType); ok {
56+
l.fail(s)
7257
}
73-
return nil // no need to visit (again) the field
58+
return nil
59+
case *ast.ChanType:
60+
return nil
61+
case *ast.MapType:
62+
return nil
63+
default:
64+
return l
7465
}
66+
}
7567

76-
return l
68+
func (l *lintStruct) fail(n ast.Node) {
69+
l.onFailure(lint.Failure{
70+
Failure: "no nested structs are allowed",
71+
Category: "style",
72+
Node: n,
73+
Confidence: 1,
74+
})
7775
}

testdata/nested-structs.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@ type Quux struct {
1818
type Quuz struct {
1919
}
2020

21+
type Quiz struct {
22+
s struct{} // MATCH /no nested structs are allowed/
23+
}
24+
25+
type nestedStructInChan struct {
26+
c chan struct {
27+
a int
28+
b struct{ c int } // MATCH /no nested structs are allowed/
29+
}
30+
}
31+
2132
func waldo() (s struct{ b bool }) { return s }
2233

2334
func fred() interface{} {
@@ -45,3 +56,9 @@ type issue744 struct {
4556
type mySetInterface interface {
4657
GetSet() map[string]struct{}
4758
}
59+
60+
// issue 824
61+
type test struct {
62+
foo []chan struct{} // Must not match
63+
bar map[string]struct{} // Must not match
64+
}

0 commit comments

Comments
 (0)