Skip to content

Commit 1c60ede

Browse files
authored
Merge pull request #12 from gostaticanalysis/fix-decl-stmt
Fix bug for valuespec
2 parents 9f68c64 + ada958d commit 1c60ede

File tree

2 files changed

+67
-21
lines changed

2 files changed

+67
-21
lines changed

forcetypeassert.go

Lines changed: 61 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,38 +24,78 @@ func run(pass *analysis.Pass) (interface{}, error) {
2424

2525
nodeFilter := []ast.Node{
2626
(*ast.AssignStmt)(nil),
27+
(*ast.ValueSpec)(nil),
2728
}
2829

2930
inspect.Preorder(nodeFilter, func(n ast.Node) {
3031
switch n := n.(type) {
3132
case *ast.AssignStmt:
32-
if !hasTypeAssertion(n.Rhs) {
33-
return
34-
}
35-
// if right hand has 2 or more values, assign statement can't assert boolean value which describes type assertion is succeeded
36-
if len(n.Rhs) > 1 {
37-
pass.Reportf(n.Pos(), "right hand must be only type assertion")
38-
return
39-
}
40-
if len(n.Lhs) == 2 {
41-
return
42-
}
43-
44-
tae, ok := n.Rhs[0].(*ast.TypeAssertExpr)
45-
if !ok {
46-
pass.Reportf(n.Pos(), "right hand is not TypeAssertion")
47-
return
48-
}
49-
if tae.Type == nil {
50-
return
51-
}
52-
pass.Reportf(n.Pos(), "type assertion must be checked")
33+
checkAssignStmt(pass, n)
34+
case *ast.ValueSpec:
35+
checkValueSpec(pass, n)
5336
}
5437
})
5538

5639
return nil, nil
5740
}
5841

42+
func checkAssignStmt(pass *analysis.Pass, n *ast.AssignStmt) {
43+
if !hasTypeAssertion(n.Rhs) {
44+
return
45+
}
46+
47+
// 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 {
49+
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
65+
}
66+
67+
pass.Reportf(n.Pos(), "type assertion must be checked")
68+
}
69+
70+
func checkValueSpec(pass *analysis.Pass, n *ast.ValueSpec) {
71+
if !hasTypeAssertion(n.Values) {
72+
return
73+
}
74+
75+
// 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 {
77+
pass.Reportf(n.Pos(), "right hand must be only type assertion")
78+
return
79+
}
80+
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+
97+
}
98+
5999
func hasTypeAssertion(exprs []ast.Expr) bool {
60100
for _, node := range exprs {
61101
_, ok := node.(*ast.TypeAssertExpr)

testdata/src/a/a.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ package a
22

33
import "fmt"
44

5+
var _, _ = ((interface{})(nil)).(string) // OK
6+
var _ = ((interface{})(nil)).(string) // want `type assertion must be checked`
7+
var _, _ = ((interface{})(nil)).(string), true // want `right hand must be only type assertion`
8+
59
func f() {
610
var i interface{} = "hello"
711

@@ -24,4 +28,6 @@ func f() {
2428
switch i.(type) { // ok
2529
case string:
2630
}
31+
32+
var _ = i.(string) // want `type assertion must be checked`
2733
}

0 commit comments

Comments
 (0)