Skip to content

Instantly share code, notes, and snippets.

@detailyang
Created September 11, 2018 13:19
Show Gist options
  • Save detailyang/f0ade324fd0da66abcfda9065e5892c0 to your computer and use it in GitHub Desktop.
Save detailyang/f0ade324fd0da66abcfda9065e5892c0 to your computer and use it in GitHub Desktop.
check type assertion
package main
import (
"flag"
"fmt"
"go/ast"
"go/parser"
"go/token"
"os"
"path/filepath"
"strings"
)
func checktype(filename string) {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, filename, nil, 0)
if err != nil {
return
}
ast.Inspect(f, func(n ast.Node) bool {
switch as := n.(type) {
case *ast.AssignStmt:
for _, rh := range as.Rhs {
te, ok := rh.(*ast.TypeAssertExpr)
if !ok {
continue
}
// Skip x.(Type)
if te.Type == nil {
continue
}
// check lhs
if len(as.Lhs) != 2 {
fmt.Println(fset.Position(as.Pos()))
break
}
e, ok := as.Lhs[1].(*ast.Ident)
if !ok {
fmt.Println(fset.Position(as.Pos()))
break
}
if e.Name == "ok" || e.Name == "_" {
break
}
fmt.Println(fset.Position(e.Pos()))
break
}
case *ast.ExprStmt:
ce, ok := as.X.(*ast.CallExpr)
if !ok {
break
}
for _, arg := range ce.Args {
ts, ok := arg.(*ast.TypeAssertExpr)
if !ok {
continue
}
fmt.Println(fset.Position(ts.Pos()))
break
}
}
return true
})
}
func visit(path string, f os.FileInfo, err error) error {
if err != nil {
fmt.Printf("prevent panic by handling failure accessing a path %q: %v\n", path, err)
return err
}
if !strings.HasSuffix(path, "go") || strings.Contains(path, "vendor") {
return nil
}
if f.IsDir() {
return nil
}
checktype(path)
return nil
}
func main() {
flag.Parse()
root := flag.Arg(0)
filepath.Walk(root, visit)
}
package main
import (
"flag"
"fmt"
"go/ast"
"go/parser"
"go/token"
"os"
"path/filepath"
"strings"
)
func checktype(filename string) {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, filename, nil, 0)
if err != nil {
return
}
ast.Inspect(f, func(n ast.Node) bool {
switch as := n.(type) {
case *ast.AssignStmt:
for _, rh := range as.Rhs {
te, ok := rh.(*ast.TypeAssertExpr)
if !ok {
continue
}
// Skip x.(Type)
if te.Type == nil {
continue
}
// check lhs
if len(as.Lhs) != 2 {
fmt.Println(fset.Position(as.Pos()))
break
}
e, ok := as.Lhs[1].(*ast.Ident)
if !ok {
fmt.Println(fset.Position(as.Pos()))
break
}
if e.Name == "ok" || e.Name == "_" {
break
}
fmt.Println(fset.Position(e.Pos()))
break
}
case *ast.ExprStmt:
ce, ok := as.X.(*ast.CallExpr)
if !ok {
break
}
for _, arg := range ce.Args {
ts, ok := arg.(*ast.TypeAssertExpr)
if !ok {
continue
}
fmt.Println(fset.Position(ts.Pos()))
break
}
}
return true
})
}
func visit(path string, f os.FileInfo, err error) error {
if err != nil {
fmt.Printf("prevent panic by handling failure accessing a path %q: %v\n", path, err)
return err
}
if !strings.HasSuffix(path, "go") || strings.Contains(path, "vendor") {
return nil
}
if f.IsDir() {
return nil
}
checktype(path)
return nil
}
func main() {
flag.Parse()
root := flag.Arg(0)
filepath.Walk(root, visit)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment