-
-
Save roscopecoltran/e7842a928b94e7ae55a0475486270d01 to your computer and use it in GitHub Desktop.
具象のerrorを返してるかチェックする
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"go/ast" | |
"go/importer" | |
"go/parser" | |
"go/token" | |
"go/types" | |
"os" | |
) | |
func run(files []string) error { | |
fset := token.NewFileSet() | |
fs := make([]*ast.File, 0, len(files)) | |
for _, fname := range files { | |
f, err := parser.ParseFile(fset, fname, nil, 0) | |
if err != nil { | |
return err | |
} | |
fs = append(fs, f) | |
} | |
config := types.Config{ | |
Importer: importer.Default(), | |
} | |
info := &types.Info{ | |
Uses: map[*ast.Ident]types.Object{}, | |
} | |
if _, err := config.Check("main", fset, fs, info); err != nil { | |
return err | |
} | |
errTyp := types.Universe.Lookup("error").Type().Underlying().(*types.Interface) | |
for _, f := range fs { | |
ast.Inspect(f, func(n ast.Node) bool { | |
switch n := n.(type) { | |
case *ast.FuncType: | |
if n.Results == nil { | |
return false | |
} | |
for _, r := range n.Results.List { | |
ident, ok := r.Type.(*ast.Ident) | |
if !ok { | |
continue | |
} | |
o := info.Uses[ident] | |
if o == nil { | |
continue | |
} | |
if t := o.Type(); !types.Identical(t.Underlying(), errTyp) && | |
types.Implements(t, errTyp) { | |
fmt.Println(fset.Position(ident.Pos())) | |
} | |
} | |
} | |
return true | |
}) | |
} | |
return nil | |
} | |
func main() { | |
if err := run(os.Args[1:]); err != nil { | |
fmt.Fprintln(os.Stderr, "Error:", err) | |
os.Exit(1) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment