Skip to content

Instantly share code, notes, and snippets.

@tenntenn
Last active April 13, 2017 02:41
Show Gist options
  • Save tenntenn/f6bd2bd748b98c5aeff2a0209af615c3 to your computer and use it in GitHub Desktop.
Save tenntenn/f6bd2bd748b98c5aeff2a0209af615c3 to your computer and use it in GitHub Desktop.
package main
import "fmt"
type Err string
func (err Err) Error() string {
return string(err)
}
func f() Err {
return Err("error")
}
func main() {
fmt.Println(f())
fmt.Println(func() Err {
return Err("error2")
})
fmt.Println(func() error {
return nil
})
}
package main
import (
"fmt"
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
)
func main() {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "hoge.go", nil, 0)
if err != nil {
panic(err)
}
config := types.Config{
Importer: importer.Default(),
}
info := &types.Info{
Uses: map[*ast.Ident]types.Object{},
}
_, err = config.Check("main", fset, []*ast.File{f}, info)
if err != nil {
panic(err)
}
errTyp := types.Universe.Lookup("error").Type().Underlying().(*types.Interface)
ast.Inspect(f, func(n ast.Node) bool {
switch n := n.(type) {
case *ast.FuncType:
if n.Results == nil {
return true
}
for _, r := range n.Results.List {
ident, ok := r.Type.(*ast.Ident)
if !ok {
continue
}
o := info.Uses[ident]
if o != nil {
if t := o.Type(); !types.Identical(t.Underlying(), errTyp) &&
types.Implements(t, errTyp) {
fmt.Println(fset.Position(n.Pos()))
}
}
}
}
return true
})
}
% go run main.go
hoge.go:11:1
hoge.go:17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment