func Field(t types.Type, name string) (int, *types.Var) {
	switch t := t.(type) {
	case *types.Pointer:
		return Field(t.Elem(), name)
	case *types.Named:
		return Field(t.Underlying(), name)
	case *types.Struct:
		for i := 0; i < t.NumFields(); i++ {
			f := t.Field(i)
			if f.Name() == name {
				return i, f
			}
		}
	}
	return -1, nil
}
Field returns field of the struct type.
If the type is not struct or has not the field,
Field returns -1, nil.
If the type is a named type or a pointer type,
Field calls itself recursively with
an underlying type or an element type of pointer.
package analysisutil
import (
	"go/ast"
	"go/types"
	"golang.org/x/tools/go/analysis"
)
var errType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface)
func ImplementsError(t types.Type) bool {
	return types.Implements(t, errType)
}
func ObjectOf(pass *analysis.Pass, pkg, name string) types.Object {
	obj := LookupFromImports(pass.Pkg.Imports(), pkg, name)
	if obj != nil {
		return obj
	}
	if RemoveVendor(pass.Pkg.Name()) != RemoveVendor(pkg) {
		return nil
	}
	return pass.Pkg.Scope().Lookup(name)
}
func TypeOf(pass *analysis.Pass, pkg, name string) types.Type {
	if name == "" {
		return nil
	}
	if name[0] == '*' {
		obj := TypeOf(pass, pkg, name[1:])
		if obj == nil {
			return nil
		}
		return types.NewPointer(obj)
	}
	obj := ObjectOf(pass, pkg, name)
	if obj == nil {
		return nil
	}
	return obj.Type()
}
func MethodOf(typ types.Type, name string) *types.Func {
	switch typ := typ.(type) {
	case *types.Named:
		for i := 0; i < typ.NumMethods(); i++ {
			if f := typ.Method(i); f.Name() == name {
				return f
			}
		}
	case *types.Pointer:
		return MethodOf(typ.Elem(), name)
	}
	return nil
}
func identical(x, y types.Type) (ret bool) {
	defer func() {
		r := recover()
		switch r := r.(type) {
		case string:
			if r == "unreachable" {
				ret = false
				return
			}
		case nil:
			return
		}
		panic(r)
	}()
	return types.Identical(x, y)
}
func Interfaces(pkg *types.Package) map[string]*types.Interface {
	ifs := map[string]*types.Interface{}
	for _, n := range pkg.Scope().Names() {
		o := pkg.Scope().Lookup(n)
		if o != nil {
			i, ok := o.Type().Underlying().(*types.Interface)
			if ok {
				ifs[n] = i
			}
		}
	}
	return ifs
}
func Structs(pkg *types.Package) map[string]*types.Struct {
	structs := map[string]*types.Struct{}
	for _, n := range pkg.Scope().Names() {
		o := pkg.Scope().Lookup(n)
		if o != nil {
			s, ok := o.Type().Underlying().(*types.Struct)
			if ok {
				structs[n] = s
			}
		}
	}
	return structs
}
func HasField(s *types.Struct, f *types.Var) bool {
	if s == nil || f == nil {
		return false
	}
	for i := 0; i < s.NumFields(); i++ {
		if s.Field(i) == f {
			return true
		}
	}
	return false
}