@@ -25,83 +25,89 @@ func run(pass *analysis.Pass) (interface{}, error) {
25
25
nodeFilter := []ast.Node {
26
26
(* ast .AssignStmt )(nil ),
27
27
(* ast .ValueSpec )(nil ),
28
+ (* ast .TypeAssertExpr )(nil ),
28
29
}
29
30
30
- inspect .Preorder (nodeFilter , func (n ast.Node ) {
31
+ inspect .Nodes (nodeFilter , func (n ast.Node , push bool ) bool {
32
+ if ! push {
33
+ return false
34
+ }
31
35
switch n := n .(type ) {
32
36
case * ast.AssignStmt :
33
- checkAssignStmt (pass , n )
37
+ return checkAssignStmt (pass , n )
34
38
case * ast.ValueSpec :
35
- checkValueSpec (pass , n )
39
+ return checkValueSpec (pass , n )
40
+ case * ast.TypeAssertExpr :
41
+ if n .Type != nil {
42
+ pass .Reportf (n .Pos (), "type assertion must be checked" )
43
+ }
44
+ return false
36
45
}
46
+
47
+ return true
37
48
})
38
49
39
50
return nil , nil
40
51
}
41
52
42
- func checkAssignStmt (pass * analysis.Pass , n * ast.AssignStmt ) {
43
- if ! hasTypeAssertion (n .Rhs ) {
44
- return
53
+ func checkAssignStmt (pass * analysis.Pass , n * ast.AssignStmt ) bool {
54
+ tae := findTypeAssertion (n .Rhs )
55
+ if tae == nil {
56
+ return true
45
57
}
46
58
59
+ switch {
47
60
// if right hand has 2 or more values, assign statement can't assert boolean value which describes type assertion is succeeded
48
- if len (n .Rhs ) > 1 {
61
+ case len (n .Rhs ) > 1 :
49
62
pass .Reportf (n .Pos (), "right hand must be only type assertion" )
50
- return
51
- }
52
-
53
- if len (n .Lhs ) == 2 {
54
- return
55
- }
56
-
57
- tae , ok := n .Rhs [0 ].(* ast.TypeAssertExpr )
58
- if ! ok {
59
- pass .Reportf (n .Pos (), "right hand is not TypeAssertion" )
60
- return
61
- }
62
-
63
- if tae .Type == nil {
64
- return
63
+ return false
64
+ case len (n .Lhs ) != 2 && tae .Type != nil :
65
+ pass .Reportf (n .Pos (), "type assertion must be checked" )
66
+ return false
67
+ case len (n .Lhs ) == 2 :
68
+ return false
65
69
}
66
70
67
- pass . Reportf ( n . Pos (), "type assertion must be checked" )
71
+ return true
68
72
}
69
73
70
- func checkValueSpec (pass * analysis.Pass , n * ast.ValueSpec ) {
71
- if ! hasTypeAssertion (n .Values ) {
72
- return
74
+ func checkValueSpec (pass * analysis.Pass , n * ast.ValueSpec ) bool {
75
+ tae := findTypeAssertion (n .Values )
76
+ if tae == nil {
77
+ return true
73
78
}
74
79
80
+ switch {
75
81
// if right hand has 2 or more values, assign statement can't assert boolean value which describes type assertion is succeeded
76
- if len (n .Values ) > 1 {
82
+ case len (n .Values ) > 1 :
77
83
pass .Reportf (n .Pos (), "right hand must be only type assertion" )
78
- return
84
+ return false
85
+ case len (n .Names ) != 2 && tae .Type != nil :
86
+ pass .Reportf (n .Pos (), "type assertion must be checked" )
87
+ return false
88
+ case len (n .Names ) == 2 :
89
+ return false
79
90
}
80
91
81
- if len (n .Names ) == 2 {
82
- return
83
- }
84
-
85
- tae , ok := n .Values [0 ].(* ast.TypeAssertExpr )
86
- if ! ok {
87
- pass .Reportf (n .Pos (), "right hand is not TypeAssertion" )
88
- return
89
- }
90
-
91
- if tae .Type == nil {
92
- return
93
- }
94
-
95
- pass .Reportf (n .Pos (), "type assertion must be checked" )
96
-
92
+ return true
97
93
}
98
94
99
- func hasTypeAssertion (exprs []ast.Expr ) bool {
100
- for _ , node := range exprs {
101
- _ , ok := node .(* ast.TypeAssertExpr )
102
- if ok {
95
+ func findTypeAssertion (exprs []ast.Expr ) * ast.TypeAssertExpr {
96
+ for _ , expr := range exprs {
97
+ var typeAssertExpr * ast.TypeAssertExpr
98
+ ast .Inspect (expr , func (n ast.Node ) bool {
99
+ switch n := n .(type ) {
100
+ case * ast.FuncLit :
101
+ return false
102
+ case * ast.TypeAssertExpr :
103
+ typeAssertExpr = n
104
+ return false
105
+ }
103
106
return true
107
+ })
108
+ if typeAssertExpr != nil {
109
+ return typeAssertExpr
104
110
}
105
111
}
106
- return false
112
+ return nil
107
113
}
0 commit comments