Skip to content

Instantly share code, notes, and snippets.

@mpppk
Created February 8, 2019 06:13
Show Gist options
  • Save mpppk/026e8a67d1cd4b16bf588cb21312e8e7 to your computer and use it in GitHub Desktop.
Save mpppk/026e8a67d1cd4b16bf588cb21312e8e7 to your computer and use it in GitHub Desktop.
getFuncDeclResultTypes
package main
import (
"fmt"
"go/ast"
"go/parser"
)
import "golang.org/x/tools/go/loader"
func main() {
source := `
package main
import "fmt"
type s struct{}
func (s s)Println(x string) {}
func increment(v int) int {
return v + 1
}
func main(){
fmt.Println("xxx")
{
fmt := s{}
fmt.Println("yyy")
}
fmt.Println("xxx")
}
`
lo := loader.Config{ParserMode: parser.ParseComments}
astf, err := lo.ParseFile("main.go", source)
if err != nil {
panic(err)
}
lo.CreateFromFiles("main", astf)
prog, err := lo.Load()
if err != nil {
panic(err)
}
targetPkgName := "fmt"
targetFuncName := "Println"
targetPkg := prog.Package(targetPkgName)
if types, ok := getFuncDeclResultTypes(targetPkg, targetFuncName); ok {
fmt.Println(types)
}
}
func getFuncDeclResultTypes(packageInfo *loader.PackageInfo, funcName string) (types []string, ok bool) {
funcDecl, ok := getFuncDecl(packageInfo, funcName)
if !ok {
return nil, false
}
results := funcDecl.Type.Results.List
for _, result := range results {
if typeIdent, ok := result.Type.(*ast.Ident); ok {
types = append(types, typeIdent.Name)
}
}
return types, true
}
func getFuncDecl(packageInfo *loader.PackageInfo, funcName string) (*ast.FuncDecl, bool) {
for _, file := range packageInfo.Files {
ast.FileExports(file)
for _, decl := range file.Decls {
if funcDecl, ok := decl.(*ast.FuncDecl); ok {
if funcDecl.Name.Name == funcName {
return funcDecl, true
}
}
}
}
return nil, false
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment