Skip to content

Commit

Permalink
Merge pull request #23 from gostaticanalysis/support-any
Browse files Browse the repository at this point in the history
Support any
  • Loading branch information
tenntenn authored Feb 13, 2025
2 parents 7fe9237 + 244cc10 commit 7ec5400
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 12 deletions.
15 changes: 11 additions & 4 deletions forcetypeassert.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package forcetypeassert

import (
"go/ast"
"go/types"
"reflect"

"golang.org/x/tools/go/analysis"
Expand Down Expand Up @@ -42,7 +43,9 @@ func (p *Panicable) At(i int) ast.Node {

const Doc = "forcetypeassert is finds type assertions which did forcely"

func run(pass *analysis.Pass) (interface{}, error) {
var anyTyp = types.Universe.Lookup("any").Type()

func run(pass *analysis.Pass) (any, error) {
inspect, _ := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
result := &Panicable{m: make(map[ast.Node]bool)}

Expand All @@ -62,7 +65,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
case *ast.ValueSpec:
return checkValueSpec(pass, result, n)
case *ast.TypeAssertExpr:
if n.Type != nil {
if n.Type != nil && !isAny(pass, n.Type) {
result.m[n] = true
result.nodes = append(result.nodes, n)
pass.Reportf(n.Pos(), "type assertion must be checked")
Expand All @@ -76,6 +79,10 @@ func run(pass *analysis.Pass) (interface{}, error) {
return result, nil
}

func isAny(pass *analysis.Pass, expr ast.Expr) bool {
return types.Identical(pass.TypesInfo.TypeOf(expr), anyTyp)
}

func checkAssignStmt(pass *analysis.Pass, result *Panicable, n *ast.AssignStmt) bool {
tae := findTypeAssertion(n.Rhs)
if tae == nil {
Expand All @@ -87,7 +94,7 @@ func checkAssignStmt(pass *analysis.Pass, result *Panicable, n *ast.AssignStmt)
case len(n.Rhs) > 1:
pass.Reportf(n.Pos(), "right hand must be only type assertion")
return false
case len(n.Lhs) != 2 && tae.Type != nil:
case len(n.Lhs) != 2 && tae.Type != nil && !isAny(pass, tae.Type):
result.m[n] = true
result.nodes = append(result.nodes, n)
pass.Reportf(n.Pos(), "type assertion must be checked")
Expand All @@ -110,7 +117,7 @@ func checkValueSpec(pass *analysis.Pass, result *Panicable, n *ast.ValueSpec) bo
case len(n.Values) > 1:
pass.Reportf(n.Pos(), "right hand must be only type assertion")
return false
case len(n.Names) != 2 && tae.Type != nil:
case len(n.Names) != 2 && tae.Type != nil && !isAny(pass, tae.Type):
result.m[n] = true
result.nodes = append(result.nodes, n)
pass.Reportf(n.Pos(), "type assertion must be checked")
Expand Down
9 changes: 5 additions & 4 deletions testdata/src/a/a.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package a

import "fmt"

var _, _ = ((interface{})(nil)).(string) // OK
var _ = ((interface{})(nil)).(string) // want `type assertion must be checked`
var _, _ = ((interface{})(nil)).(string), true // want `right hand must be only type assertion`
var _, _ = any(nil).(string) // OK
var _ = any(nil).(any) // OK for issue#17
var _ = any(nil).(string) // want `type assertion must be checked`
var _, _ = any(nil).(string), true // want `right hand must be only type assertion`

func f() {
var i interface{} = "hello"
var i any = "hello"

_ = i.(string) // want `type assertion must be checked`

Expand Down
8 changes: 4 additions & 4 deletions testdata/src/b/b.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package b

import "fmt"

var _, _ = ((interface{})(nil)).(string) // OK
var _ = ((interface{})(nil)).(string) // want `panicable`
var _, _ = ((interface{})(nil)).(string), true // OK
var _, _ = any(nil).(string) // OK
var _ = any(nil).(string) // want `panicable`
var _, _ = any(nil).(string), true // OK

func f() {
var i interface{} = "hello"
var i any = "hello"

_ = i.(string) // want `panicable`

Expand Down

0 comments on commit 7ec5400

Please sign in to comment.