3

I stumbled across this answer to a question on how to get all the types in a package:

https://stackoverflow.com/a/32142080/470339

Which works great. However, the next step I'd like to take is then iterate over each of these types to get, for example, NumMethod(). I don't see an immediately obvious way to do so - can anyone shed some light, or will I have to resort to messing with the AST?

Alastair
  • 5,894
  • 7
  • 34
  • 61

1 Answers1

6

You can use the Scope and the names to Lookup the Objects you're interested in.

An Object describes a named language entity such as a package, constant, type, variable, function (incl. methods), or label. All objects implement the Object interface.

There is a Named type that implements the Object interface and that has a method called NumMethods.

package main

import (
    "fmt"
    "go/importer"
    "go/types"
)

func main() {
    pkg, err := importer.Default().Import("time")
    if err != nil {
        fmt.Printf("error: %s\n", err.Error())
        return
    }

    scope := pkg.Scope()
    for _, name := range scope.Names() {
        if name == "Time" {
            obj := scope.Lookup(name)
            if tn, ok := obj.Type().(*types.Named); ok {
                fmt.Printf("%#v\n", tn.NumMethods())
            }
        }
    }
}

Then, if you want to go further, *types.Named implements the Type interface, so you can look at its underlying type which is also a types.Type implemented by Struct, Slice, etc.

mkopriva
  • 35,176
  • 4
  • 57
  • 71