本文整理汇总了Golang中go/types.NewMethodSet函数的典型用法代码示例。如果您正苦于以下问题:Golang NewMethodSet函数的具体用法?Golang NewMethodSet怎么用?Golang NewMethodSet使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了NewMethodSet函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: MethodSet
// MethodSet returns the method set of type T. It is thread-safe.
//
// If cache is nil, this function is equivalent to types.NewMethodSet(T).
// Utility functions can thus expose an optional *MethodSetCache
// parameter to clients that care about performance.
//
func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet {
if cache == nil {
return types.NewMethodSet(T)
}
cache.mu.Lock()
defer cache.mu.Unlock()
switch T := T.(type) {
case *types.Named:
return cache.lookupNamed(T).value
case *types.Pointer:
if N, ok := T.Elem().(*types.Named); ok {
return cache.lookupNamed(N).pointer
}
}
// all other types
// (The map uses pointer equivalence, not type identity.)
mset := cache.others[T]
if mset == nil {
mset = types.NewMethodSet(T)
if cache.others == nil {
cache.others = make(map[types.Type]*types.MethodSet)
}
cache.others[T] = mset
}
return mset
}
示例2: lockPath
// lockPath returns a typePath describing the location of a lock value
// contained in typ. If there is no contained lock, it returns nil.
func lockPath(tpkg *types.Package, typ types.Type) typePath {
if typ == nil {
return nil
}
// We're only interested in the case in which the underlying
// type is a struct. (Interfaces and pointers are safe to copy.)
styp, ok := typ.Underlying().(*types.Struct)
if !ok {
return nil
}
// We're looking for cases in which a reference to this type
// can be locked, but a value cannot. This differentiates
// embedded interfaces from embedded values.
if plock := types.NewMethodSet(types.NewPointer(typ)).Lookup(tpkg, "Lock"); plock != nil {
if lock := types.NewMethodSet(typ).Lookup(tpkg, "Lock"); lock == nil {
return []types.Type{typ}
}
}
nfields := styp.NumFields()
for i := 0; i < nfields; i++ {
ftyp := styp.Field(i).Type()
subpath := lockPath(tpkg, ftyp)
if subpath != nil {
return append(subpath, typ)
}
}
return nil
}
示例3: lookupNamed
func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } {
if cache.named == nil {
cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet })
}
// Avoid recomputing mset(*T) for each distinct Pointer
// instance whose underlying type is a named type.
msets, ok := cache.named[named]
if !ok {
msets.value = types.NewMethodSet(named)
msets.pointer = types.NewMethodSet(types.NewPointer(named))
cache.named[named] = msets
}
return msets
}
示例4: PrintSkeleton
//!+
func PrintSkeleton(pkg *types.Package, ifacename, concname string) error {
obj := pkg.Scope().Lookup(ifacename)
if obj == nil {
return fmt.Errorf("%s.%s not found", pkg.Path(), ifacename)
}
if _, ok := obj.(*types.TypeName); !ok {
return fmt.Errorf("%v is not a named type", obj)
}
iface, ok := obj.Type().Underlying().(*types.Interface)
if !ok {
return fmt.Errorf("type %v is a %T, not an interface",
obj, obj.Type().Underlying())
}
// Use first letter of type name as receiver parameter.
if !isValidIdentifier(concname) {
return fmt.Errorf("invalid concrete type name: %q", concname)
}
r, _ := utf8.DecodeRuneInString(concname)
fmt.Printf("// *%s implements %s.%s.\n", concname, pkg.Path(), ifacename)
fmt.Printf("type %s struct{}\n", concname)
mset := types.NewMethodSet(iface)
for i := 0; i < mset.Len(); i++ {
meth := mset.At(i).Obj()
sig := types.TypeString(meth.Type(), (*types.Package).Name)
fmt.Printf("func (%c *%s) %s%s {\n\tpanic(\"unimplemented\")\n}\n",
r, concname, meth.Name(),
strings.TrimPrefix(sig, "func"))
}
return nil
}
示例5: makeIfaceSummary
func makeIfaceSummary(iface *types.Interface) ifaceSummary {
summary := ifaceSummary{
iface: iface,
implementable: true,
}
methodset := types.NewMethodSet(iface)
for i := 0; i < methodset.Len(); i++ {
obj := methodset.At(i).Obj()
if !obj.Exported() {
summary.implementable = false
continue
}
m, ok := obj.(*types.Func)
if !ok {
log.Panicf("unexpected methodset obj: %s (%T)", obj, obj)
}
if !isImplementable(m.Type().(*types.Signature)) {
summary.implementable = false
}
if isCallable(m) {
summary.callable = append(summary.callable, m)
}
}
return summary
}
示例6: getMethods
func getMethods(pkg *types.Package, typename string) map[string]*types.Func {
r := make(map[string]*types.Func)
mset := types.NewMethodSet(types.NewPointer(pkg.Scope().Lookup(typename).Type()))
for i := 0; i < mset.Len(); i++ {
fn := mset.At(i).Obj().(*types.Func)
r[fn.Name()] = fn
}
return r
}
示例7: combinedMethodSet
// combinedMethodSet returns the method set for a named type T
// merged with all the methods of *T that have different names than
// the methods of T.
//
// combinedMethodSet is analogous to types/typeutil.IntuitiveMethodSet
// but doesn't require a MethodSetCache.
// TODO(gri) If this functionality doesn't change over time, consider
// just calling IntuitiveMethodSet eventually.
func combinedMethodSet(T *types.Named) []*types.Selection {
// method set for T
mset := types.NewMethodSet(T)
var res []*types.Selection
for i, n := 0, mset.Len(); i < n; i++ {
res = append(res, mset.At(i))
}
// add all *T methods with names different from T methods
pmset := types.NewMethodSet(types.NewPointer(T))
for i, n := 0, pmset.Len(); i < n; i++ {
pm := pmset.At(i)
if obj := pm.Obj(); mset.Lookup(obj.Pkg(), obj.Name()) == nil {
res = append(res, pm)
}
}
return res
}
示例8: emitType
func (w *Walker) emitType(obj *types.TypeName) {
name := obj.Name()
typ := obj.Type()
switch typ := typ.Underlying().(type) {
case *types.Struct:
w.emitStructType(name, typ)
case *types.Interface:
w.emitIfaceType(name, typ)
return // methods are handled by emitIfaceType
default:
w.emitf("type %s %s", name, w.typeString(typ.Underlying()))
}
// emit methods with value receiver
var methodNames map[string]bool
vset := types.NewMethodSet(typ)
for i, n := 0, vset.Len(); i < n; i++ {
m := vset.At(i)
if m.Obj().Exported() {
w.emitMethod(m)
if methodNames == nil {
methodNames = make(map[string]bool)
}
methodNames[m.Obj().Name()] = true
}
}
// emit methods with pointer receiver; exclude
// methods that we have emitted already
// (the method set of *T includes the methods of T)
pset := types.NewMethodSet(types.NewPointer(typ))
for i, n := 0, pset.Len(); i < n; i++ {
m := pset.At(i)
if m.Obj().Exported() && !methodNames[m.Obj().Name()] {
w.emitMethod(m)
}
}
}
示例9: exportedMethodSet
func exportedMethodSet(T types.Type) []*types.Func {
var methods []*types.Func
methodset := types.NewMethodSet(T)
for i := 0; i < methodset.Len(); i++ {
obj := methodset.At(i).Obj()
if !obj.Exported() {
continue
}
switch obj := obj.(type) {
case *types.Func:
methods = append(methods, obj)
default:
log.Panicf("unexpected methodset obj: %s", obj)
}
}
return methods
}
示例10: ExampleMethodSet
// ExampleMethodSet prints the method sets of various types.
func ExampleMethodSet() {
// Parse a single source file.
const input = `
package temperature
import "fmt"
type Celsius float64
func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) }
func (c *Celsius) SetF(f float64) { *c = Celsius(f - 32 / 9 * 5) }
`
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "celsius.go", input, 0)
if err != nil {
log.Fatal(err)
}
// Type-check a package consisting of this file.
// Type information for the imported packages
// comes from $GOROOT/pkg/$GOOS_$GOOARCH/fmt.a.
conf := types.Config{Importer: importer.Default()}
pkg, err := conf.Check("temperature", fset, []*ast.File{f}, nil)
if err != nil {
log.Fatal(err)
}
// Print the method sets of Celsius and *Celsius.
celsius := pkg.Scope().Lookup("Celsius").Type()
for _, t := range []types.Type{celsius, types.NewPointer(celsius)} {
fmt.Printf("Method set of %s:\n", t)
mset := types.NewMethodSet(t)
for i := 0; i < mset.Len(); i++ {
fmt.Println(mset.At(i))
}
fmt.Println()
}
// Output:
// Method set of temperature.Celsius:
// method (temperature.Celsius) String() string
//
// Method set of *temperature.Celsius:
// method (*temperature.Celsius) SetF(f float64)
// method (*temperature.Celsius) String() string
}
示例11: methodDocComment
func methodDocComment(prog *loader.Program, tname *types.TypeName, methodName string) (string, error) {
t := tname.Type()
if !types.IsInterface(t) {
// Use the pointer type to get as many methods as possible.
t = types.NewPointer(t)
}
mset := types.NewMethodSet(t)
sel := mset.Lookup(nil, methodName)
if sel == nil {
return "", errgo.Newf("cannot find method %v on %v", methodName, t)
}
obj := sel.Obj()
decl, err := findDecl(prog, obj.Pos())
if err != nil {
return "", errgo.Mask(err)
}
switch decl := decl.(type) {
case *ast.GenDecl:
if decl.Tok != token.TYPE {
return "", errgo.Newf("found non-type decl %#v", decl)
}
for _, spec := range decl.Specs {
tspec := spec.(*ast.TypeSpec)
it := tspec.Type.(*ast.InterfaceType)
for _, m := range it.Methods.List {
for _, id := range m.Names {
if id.Pos() == obj.Pos() {
return m.Doc.Text(), nil
}
}
}
}
return "", errgo.Newf("method definition not found in type")
case *ast.FuncDecl:
if decl.Name.Pos() != obj.Pos() {
return "", errgo.Newf("method definition not found (at %#v)", prog.Fset.Position(obj.Pos()))
}
return decl.Doc.Text(), nil
default:
return "", errgo.Newf("unexpected declaration %T found", decl)
}
}
示例12: emitIfaceType
func (w *Walker) emitIfaceType(name string, typ *types.Interface) {
pop := w.pushScope("type " + name + " interface")
var methodNames []string
complete := true
mset := types.NewMethodSet(typ)
for i, n := 0, mset.Len(); i < n; i++ {
m := mset.At(i).Obj().(*types.Func)
if !m.Exported() {
complete = false
continue
}
methodNames = append(methodNames, m.Name())
w.emitf("%s%s", m.Name(), w.signatureString(m.Type().(*types.Signature)))
}
if !complete {
// The method set has unexported methods, so all the
// implementations are provided by the same package,
// so the method set can be extended. Instead of recording
// the full set of names (below), record only that there were
// unexported methods. (If the interface shrinks, we will notice
// because a method signature emitted during the last loop
// will disappear.)
w.emitf("unexported methods")
}
pop()
if !complete {
return
}
if len(methodNames) == 0 {
w.emitf("type %s interface {}", name)
return
}
sort.Strings(methodNames)
w.emitf("type %s interface { %s }", name, strings.Join(methodNames, ", "))
}
示例13: exportedMethodSet
func exportedMethodSet(T types.Type) []*types.Func {
var methods []*types.Func
methodset := types.NewMethodSet(T)
for i := 0; i < methodset.Len(); i++ {
obj := methodset.At(i).Obj()
if !obj.Exported() {
continue
}
// Skip methods from the embedded classes, so that
// only methods that are implemented in Go are included.
if pref := pkgFirstElem(obj.Pkg()); pref == "Java" || pref == "ObjC" {
continue
}
switch obj := obj.(type) {
case *types.Func:
methods = append(methods, obj)
default:
log.Panicf("unexpected methodset obj: %s", obj)
}
}
return methods
}
示例14: TestCorrectMethodPackage
// Smoke test to ensure that imported methods get the correct package.
func TestCorrectMethodPackage(t *testing.T) {
skipSpecialPlatforms(t)
// This package only handles gc export data.
if runtime.Compiler != "gc" {
t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
return
}
imports := make(map[string]*types.Package)
_, err := Import(imports, "net/http")
if err != nil {
t.Fatal(err)
}
mutex := imports["sync"].Scope().Lookup("Mutex").(*types.TypeName).Type()
mset := types.NewMethodSet(types.NewPointer(mutex)) // methods of *sync.Mutex
sel := mset.Lookup(nil, "Lock")
lock := sel.Obj().(*types.Func)
if got, want := lock.Pkg().Path(), "sync"; got != want {
t.Errorf("got package path %q; want %q", got, want)
}
}
示例15: process
// process collects informations about a go package.
func (p *Package) process() error {
var err error
funcs := make(map[string]Func)
structs := make(map[string]Struct)
scope := p.pkg.Scope()
for _, name := range scope.Names() {
obj := scope.Lookup(name)
if !obj.Exported() {
continue
}
p.n++
p.syms.addSymbol(obj)
}
for _, name := range scope.Names() {
obj := scope.Lookup(name)
if !obj.Exported() {
continue
}
switch obj := obj.(type) {
case *types.Const:
p.addConst(obj)
case *types.Var:
p.addVar(obj)
case *types.Func:
funcs[name], err = newFuncFrom(p, "", obj, obj.Type().(*types.Signature))
if err != nil {
return err
}
case *types.TypeName:
named := obj.Type().(*types.Named)
switch typ := named.Underlying().(type) {
case *types.Struct:
structs[name], err = newStruct(p, obj)
if err != nil {
return err
}
case *types.Basic:
// ok. handled by p.syms-types
case *types.Array:
// ok. handled by p.syms-types
case *types.Interface:
// ok. handled by p.syms-types
case *types.Signature:
// ok. handled by p.syms-types
case *types.Slice:
// ok. handled by p.syms-types
default:
//TODO(sbinet)
panic(fmt.Errorf("not yet supported: %v (%T)", typ, obj))
}
default:
//TODO(sbinet)
panic(fmt.Errorf("not yet supported: %v (%T)", obj, obj))
}
}
// remove ctors from funcs.
// add methods.
for sname, s := range structs {
for name, fct := range funcs {
if fct.Return() == nil {
continue
}
if fct.Return() == s.GoType() {
delete(funcs, name)
fct.doc = p.getDoc(sname, scope.Lookup(name))
fct.ctor = true
s.ctors = append(s.ctors, fct)
structs[sname] = s
}
}
ptyp := types.NewPointer(s.GoType())
p.syms.addType(nil, ptyp)
mset := types.NewMethodSet(ptyp)
for i := 0; i < mset.Len(); i++ {
meth := mset.At(i)
if !meth.Obj().Exported() {
continue
}
m, err := newFuncFrom(p, sname, meth.Obj(), meth.Type().(*types.Signature))
if err != nil {
return err
//.........这里部分代码省略.........