本文整理汇总了Golang中code/google/com/p/go/tools/go/types.Func类的典型用法代码示例。如果您正苦于以下问题:Golang Func类的具体用法?Golang Func怎么用?Golang Func使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Func类的18个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: interfaceMethod
// interfaceMethod returns a function pointer for the specified
// interface and method pair.
func (c *compiler) interfaceMethod(iface *LLVMValue, method *types.Func) *LLVMValue {
lliface := iface.LLVMValue()
llitab := c.builder.CreateExtractValue(lliface, 0, "")
llvalue := c.builder.CreateExtractValue(lliface, 1, "")
sig := method.Type().(*types.Signature)
methodset := c.types.MethodSet(sig.Recv().Type())
// TODO(axw) cache ordered method index
var index int
for i := 0; i < methodset.Len(); i++ {
if methodset.At(i).Obj() == method {
index = i
break
}
}
llitab = c.builder.CreateBitCast(llitab, llvm.PointerType(c.runtime.itab.llvm, 0), "")
llifn := c.builder.CreateGEP(llitab, []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), 0, false),
llvm.ConstInt(llvm.Int32Type(), 5, false), // index of itab.fun
}, "")
_ = index
llifn = c.builder.CreateGEP(llifn, []llvm.Value{
llvm.ConstInt(llvm.Int32Type(), uint64(index), false),
}, "")
llifn = c.builder.CreateLoad(llifn, "")
// Strip receiver.
sig = types.NewSignature(nil, nil, sig.Params(), sig.Results(), sig.Variadic())
llfn := llvm.Undef(c.types.ToLLVM(sig))
llifn = c.builder.CreateIntToPtr(llifn, llfn.Type().StructElementTypes()[0], "")
llfn = c.builder.CreateInsertValue(llfn, llifn, 0, "")
llfn = c.builder.CreateInsertValue(llfn, llvalue, 1, "")
return c.NewValue(llfn, sig)
}
开发者ID:minux,项目名称:llgo,代码行数:34,代码来源:interfaces.go
示例2: FuncValue
// FuncValue returns the Function denoted by the source-level named
// function obj.
//
func (prog *Program) FuncValue(obj *types.Func) *Function {
// Package-level function or declared method?
if v := prog.packageLevelValue(obj); v != nil {
return v.(*Function)
}
// Interface method wrapper?
return prog.LookupMethod(recvType(obj), obj.Pkg(), obj.Name())
}
开发者ID:samuelyao314,项目名称:mygo,代码行数:11,代码来源:source.go
示例3: promoteMethod
// promoteMethod promotes a named type's method to another type
// which has embedded the named type.
func (c *compiler) promoteMethod(m *types.Func, recv types.Type, indices []int) types.Object {
var pkg *types.Package
if recv, ok := recv.(*types.Named); ok {
pkg = c.objectdata[recv.Obj()].Package
}
recvvar := types.NewVar(pkg, "", recv)
sig := m.Type().(*types.Signature)
sig = types.NewSignature(recvvar, sig.Params(), sig.Results(), sig.IsVariadic())
f := &synthFunc{pkg: pkg, name: m.Name(), typ: sig}
ident := ast.NewIdent(f.Name())
var isptr bool
if ptr, ok := recv.(*types.Pointer); ok {
isptr = true
recv = ptr.Elem()
}
c.objects[ident] = f
c.objectdata[f] = &ObjectData{Ident: ident, Package: pkg}
if pkg == nil || pkg == c.pkg {
if currblock := c.builder.GetInsertBlock(); !currblock.IsNil() {
defer c.builder.SetInsertPointAtEnd(currblock)
}
llvmfn := c.Resolve(ident).LLVMValue()
llvmfn = c.builder.CreateExtractValue(llvmfn, 0, "")
llvmfn.SetLinkage(llvm.LinkOnceODRLinkage)
entry := llvm.AddBasicBlock(llvmfn, "entry")
c.builder.SetInsertPointAtEnd(entry)
realfn := c.Resolve(c.objectdata[m].Ident).LLVMValue()
realfn = c.builder.CreateExtractValue(realfn, 0, "")
args := llvmfn.Params()
recvarg := args[0]
if !isptr {
ptr := c.builder.CreateAlloca(recvarg.Type(), "")
c.builder.CreateStore(recvarg, ptr)
recvarg = ptr
}
for _, i := range indices {
if i == -1 {
recvarg = c.builder.CreateLoad(recvarg, "")
} else {
recvarg = c.builder.CreateStructGEP(recvarg, i, "")
}
}
args[0] = recvarg
result := c.builder.CreateCall(realfn, args, "")
if sig.Results().Len() == 0 {
c.builder.CreateRetVoid()
} else {
c.builder.CreateRet(result)
}
}
return f
}
开发者ID:hzmangel,项目名称:llgo,代码行数:60,代码来源:functions.go
示例4: printFunc
func (p *printer) printFunc(recvType types.Type, obj *types.Func) {
p.print("func ")
sig := obj.Type().(*types.Signature)
if recvType != nil {
p.print("(")
p.writeType(p.pkg, recvType)
p.print(") ")
}
p.print(obj.Name())
p.writeSignature(p.pkg, sig)
}
开发者ID:samuelyao314,项目名称:mygo,代码行数:11,代码来源:print.go
示例5: methodfunc
func (c *compiler) methodfunc(m *types.Func) *types.Func {
// We're not privy to *Func objects for methods in
// imported packages, so we must synthesise them.
data := c.objectdata[m]
if data == nil {
ident := ast.NewIdent(m.Name())
data = &ObjectData{Ident: ident, Package: m.Pkg()}
c.objects[ident] = m
c.objectdata[m] = data
}
return m
}
开发者ID:hzmangel,项目名称:llgo,代码行数:12,代码来源:functions.go
示例6: printFunc
func (p *printer) printFunc(obj *types.Func) {
p.print("func ")
sig := obj.Type().(*types.Signature)
if recv := sig.Recv(); recv != nil {
p.print("(")
if name := recv.Name(); name != "" {
p.print(name)
p.print(" ")
}
p.writeType(p.pkg, recv.Type())
p.print(") ")
}
p.print(obj.Name())
p.writeSignature(p.pkg, sig)
}
开发者ID:Karthikvb,项目名称:15640_projects,代码行数:15,代码来源:print.go
示例7: lookupMethod
// lookupMethod returns the method set for type typ, which may be one
// of the interpreter's fake types.
func lookupMethod(i *interpreter, typ types.Type, meth *types.Func) *ssa.Function {
switch typ {
case rtypeType:
return i.rtypeMethods[meth.Id()]
case errorType:
return i.errorMethods[meth.Id()]
}
return i.prog.LookupMethod(typ, meth.Pkg(), meth.Name())
}
开发者ID:Karthikvb,项目名称:15640_projects,代码行数:11,代码来源:interp.go
示例8: checkFuncValue
func checkFuncValue(t *testing.T, prog *ssa.Program, obj *types.Func) {
fn := prog.FuncValue(obj)
// fmt.Printf("FuncValue(%s) = %s\n", obj, fn) // debugging
if fn == nil {
t.Errorf("FuncValue(%s) == nil", obj)
return
}
if fnobj := fn.Object(); fnobj != obj {
t.Errorf("FuncValue(%s).Object() == %s; value was %s",
obj, fnobj, fn.Name())
return
}
if !types.Identical(fn.Type(), obj.Type()) {
t.Errorf("FuncValue(%s).Type() == %s", obj, fn.Type())
return
}
}
开发者ID:samuelyao314,项目名称:mygo,代码行数:17,代码来源:source_test.go
示例9: emitFunc
func (w *Walker) emitFunc(f *types.Func) {
sig := f.Type().(*types.Signature)
if sig.Recv() != nil {
panic("method considered a regular function: " + f.String())
}
w.emitf("func %s%s", f.Name(), w.signatureString(sig))
}
开发者ID:bryanxu,项目名称:go-zh,代码行数:7,代码来源:goapi.go
示例10: interfaceMethodWrapper
// interfaceMethodWrapper returns a synthetic wrapper function
// permitting an abstract method obj to be called like a standalone
// function, e.g.:
//
// type I interface { f(x int) R }
// m := I.f // wrapper
// var i I
// m(i, 0)
//
// The wrapper is defined as if by:
//
// func (i I) f(x int, ...) R {
// return i.f(x, ...)
// }
//
// typ is the type of the receiver (I here). It isn't necessarily
// equal to the recvType(obj) because one interface may embed another.
// TODO(adonovan): more tests.
//
// TODO(adonovan): opt: currently the stub is created even when used
// in call position: I.f(i, 0). Clearly this is suboptimal.
//
// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu)
//
func interfaceMethodWrapper(prog *Program, typ types.Type, obj *types.Func) *Function {
// If one interface embeds another they'll share the same
// wrappers for common methods. This is safe, but it might
// confuse some tools because of the implicit interface
// conversion applied to the first argument. If this becomes
// a problem, we should include 'typ' in the memoization key.
fn, ok := prog.ifaceMethodWrappers[obj]
if !ok {
description := "interface method wrapper"
if prog.mode&LogSource != 0 {
defer logStack("(%s).%s, %s", typ, obj.Name(), description)()
}
fn = &Function{
name: obj.Name(),
object: obj,
Signature: obj.Type().(*types.Signature),
Synthetic: description,
pos: obj.Pos(),
Prog: prog,
Pkg: prog.packages[obj.Pkg()],
}
fn.startBody()
fn.addParam("recv", typ, token.NoPos)
createParams(fn)
var c Call
c.Call.Method = obj
c.Call.Value = fn.Params[0]
for _, arg := range fn.Params[1:] {
c.Call.Args = append(c.Call.Args, arg)
}
emitTailCall(fn, &c)
fn.finishBody()
prog.ifaceMethodWrappers[obj] = fn
}
return fn
}
开发者ID:nagyistge,项目名称:hm-workspace,代码行数:62,代码来源:promote.go
示例11: boundMethodWrapper
// boundMethodWrapper returns a synthetic wrapper function that
// delegates to a concrete or interface method.
// The wrapper has one free variable, the method's receiver.
// Use MakeClosure with such a wrapper to construct a bound-method
// closure. e.g.:
//
// type T int or: type T interface { meth() }
// func (t T) meth()
// var t T
// f := t.meth
// f() // calls t.meth()
//
// f is a closure of a synthetic wrapper defined as if by:
//
// f := func() { return t.meth() }
//
// EXCLUSIVE_LOCKS_ACQUIRED(meth.Prog.methodsMu)
//
func boundMethodWrapper(prog *Program, obj *types.Func) *Function {
prog.methodsMu.Lock()
defer prog.methodsMu.Unlock()
fn, ok := prog.boundMethodWrappers[obj]
if !ok {
description := fmt.Sprintf("bound method wrapper for %s", obj)
if prog.mode&LogSource != 0 {
defer logStack("%s", description)()
}
fn = &Function{
name: "bound$" + obj.FullName(),
Signature: changeRecv(obj.Type().(*types.Signature), nil), // drop receiver
Synthetic: description,
Prog: prog,
Pkg: prog.packages[obj.Pkg()],
pos: obj.Pos(),
}
cap := &Capture{name: "recv", typ: recvType(obj), parent: fn}
fn.FreeVars = []*Capture{cap}
fn.startBody()
createParams(fn)
var c Call
if _, ok := recvType(obj).Underlying().(*types.Interface); !ok { // concrete
c.Call.Value = prog.declaredFunc(obj)
c.Call.Args = []Value{cap}
} else {
c.Call.Value = cap
c.Call.Method = obj
}
for _, arg := range fn.Params {
c.Call.Args = append(c.Call.Args, arg)
}
emitTailCall(fn, &c)
fn.finishBody()
prog.boundMethodWrappers[obj] = fn
}
return fn
}
开发者ID:nagyistge,项目名称:hm-workspace,代码行数:59,代码来源:promote.go
示例12: makeBound
// makeBound returns a bound method wrapper (or "bound"), a synthetic
// function that delegates to a concrete or interface method denoted
// by obj. The resulting function has no receiver, but has one free
// variable which will be used as the method's receiver in the
// tail-call.
//
// Use MakeClosure with such a wrapper to construct a bound method
// closure. e.g.:
//
// type T int or: type T interface { meth() }
// func (t T) meth()
// var t T
// f := t.meth
// f() // calls t.meth()
//
// f is a closure of a synthetic wrapper defined as if by:
//
// f := func() { return t.meth() }
//
// Unlike makeWrapper, makeBound need perform no indirection or field
// selections because that can be done before the closure is
// constructed.
//
// EXCLUSIVE_LOCKS_ACQUIRED(meth.Prog.methodsMu)
//
func makeBound(prog *Program, obj *types.Func) *Function {
prog.methodsMu.Lock()
defer prog.methodsMu.Unlock()
fn, ok := prog.bounds[obj]
if !ok {
description := fmt.Sprintf("bound method wrapper for %s", obj)
if prog.mode&LogSource != 0 {
defer logStack("%s", description)()
}
fn = &Function{
name: obj.Name() + "$bound",
object: obj,
Signature: changeRecv(obj.Type().(*types.Signature), nil), // drop receiver
Synthetic: description,
Prog: prog,
pos: obj.Pos(),
}
fv := &FreeVar{name: "recv", typ: recvType(obj), parent: fn}
fn.FreeVars = []*FreeVar{fv}
fn.startBody()
createParams(fn, 0)
var c Call
if !isInterface(recvType(obj)) { // concrete
c.Call.Value = prog.declaredFunc(obj)
c.Call.Args = []Value{fv}
} else {
c.Call.Value = fv
c.Call.Method = obj
}
for _, arg := range fn.Params {
c.Call.Args = append(c.Call.Args, arg)
}
emitTailCall(fn, &c)
fn.finishBody()
prog.bounds[obj] = fn
}
return fn
}
开发者ID:hackrole,项目名称:daily-program,代码行数:66,代码来源:promote.go
示例13: checkMethod
// checkMethod performs safety checks for renaming a method.
// There are three hazards:
// - declaration conflicts
// - selection ambiguity/changes
// - entailed renamings of assignable concrete/interface types (for now, just reject)
func (r *renamer) checkMethod(from *types.Func) {
// e.g. error.Error
if from.Pkg() == nil {
r.errorf(from.Pos(), "you cannot rename built-in method %s", from)
return
}
// As always, having to support concrete methods with pointer
// and non-pointer receivers, and named vs unnamed types with
// methods, makes tooling fun.
// ASSIGNABILITY
//
// For now, if any method renaming breaks a required
// assignability to another type, we reject it.
//
// TODO(adonovan): probably we should compute the entailed
// renamings so that an interface method renaming causes
// concrete methods to change too. But which ones?
//
// There is no correct answer, only heuristics, because Go's
// "duck typing" doesn't distinguish intentional from contingent
// assignability. There are two obvious approaches:
//
// (1) Update the minimum set of types to preserve the
// assignability of types all syntactic assignments
// (incl. implicit ones in calls, returns, sends, etc).
// The satisfy.Finder enumerates these.
// This is likely to be an underapproximation.
//
// (2) Update all types that are assignable to/from the changed
// type. This requires computing the "implements" relation
// for all pairs of types (as godoc and oracle do).
// This is likely to be an overapproximation.
//
// If a concrete type is renamed, we probably do not want to
// rename corresponding interfaces; interface renamings should
// probably be initiated at the interface. (But what if a
// concrete type implements multiple interfaces with the same
// method? Then the user is stuck.)
//
// We need some experience before we decide how to implement this.
// Check for conflict at point of declaration.
// Check to ensure preservation of assignability requirements.
recv := from.Type().(*types.Signature).Recv().Type()
if isInterface(recv) {
// Abstract method
// declaration
prev, _, _ := types.LookupFieldOrMethod(recv, false, from.Pkg(), r.to)
if prev != nil {
r.errorf(from.Pos(), "renaming this interface method %q to %q",
from.Name(), r.to)
r.errorf(prev.Pos(), "\twould conflict with this method")
return
}
// Check all interfaces that embed this one for
// declaration conflicts too.
for _, info := range r.packages {
// Start with named interface types (better errors)
for _, obj := range info.Defs {
if obj, ok := obj.(*types.TypeName); ok && isInterface(obj.Type()) {
f, _, _ := types.LookupFieldOrMethod(
obj.Type(), false, from.Pkg(), from.Name())
if f == nil {
continue
}
t, _, _ := types.LookupFieldOrMethod(
obj.Type(), false, from.Pkg(), r.to)
if t == nil {
continue
}
r.errorf(from.Pos(), "renaming this interface method %q to %q",
from.Name(), r.to)
r.errorf(t.Pos(), "\twould conflict with this method")
r.errorf(obj.Pos(), "\tin named interface type %q", obj.Name())
}
}
// Now look at all literal interface types (includes named ones again).
for e, tv := range info.Types {
if e, ok := e.(*ast.InterfaceType); ok {
_ = e
_ = tv.Type.(*types.Interface)
// TODO(adonovan): implement same check as above.
}
}
}
// assignability
for T := range r.findAssignments(recv) {
if obj, _, _ := types.LookupFieldOrMethod(T, false, from.Pkg(), from.Name()); obj == nil {
continue
//.........这里部分代码省略.........
开发者ID:bryanxu,项目名称:go-zh.tools,代码行数:101,代码来源:check.go
示例14: promoteInterfaceMethod
// promoteInterfaceMethod promotes an interface method to a type
// which has embedded the interface.
//
// TODO consolidate this and promoteMethod.
func (c *compiler) promoteInterfaceMethod(iface *types.Interface, m *types.Func, methodIndex int, recv types.Type, indices []int) types.Object {
var pkg *types.Package
if recv, ok := recv.(*types.Named); ok {
pkg = recv.Obj().Pkg()
}
recvvar := types.NewVar(token.NoPos, pkg, "", recv)
sig := m.Type().(*types.Signature)
sig = types.NewSignature(nil, recvvar, sig.Params(), sig.Results(), sig.IsVariadic())
f := &synthFunc{Func: m, pkg: pkg, typ: sig}
ident := ast.NewIdent(f.Name())
var isptr bool
if ptr, ok := recv.(*types.Pointer); ok {
isptr = true
recv = ptr.Elem()
}
c.typeinfo.Objects[ident] = f
c.objectdata[f] = &ObjectData{Ident: ident}
if pkg == nil || pkg == c.pkg {
if currblock := c.builder.GetInsertBlock(); !currblock.IsNil() {
defer c.builder.SetInsertPointAtEnd(currblock)
}
llvmfn := c.Resolve(ident).LLVMValue()
llvmfn = c.builder.CreateExtractValue(llvmfn, 0, "")
llvmfn.SetLinkage(llvm.LinkOnceODRLinkage)
entry := llvm.AddBasicBlock(llvmfn, "entry")
c.builder.SetInsertPointAtEnd(entry)
args := llvmfn.Params()
ifaceval := args[0]
if !isptr {
ptr := c.builder.CreateAlloca(ifaceval.Type(), "")
c.builder.CreateStore(ifaceval, ptr)
ifaceval = ptr
}
for _, i := range indices {
if i == -1 {
ifaceval = c.builder.CreateLoad(ifaceval, "")
} else {
ifaceval = c.builder.CreateStructGEP(ifaceval, i, "")
}
}
recvarg := c.builder.CreateExtractValue(ifaceval, 0, "")
ifn := c.builder.CreateExtractValue(ifaceval, methodIndex+2, "")
// Add the receiver argument type.
fntyp := ifn.Type().ElementType()
returnType := fntyp.ReturnType()
paramTypes := fntyp.ParamTypes()
paramTypes = append([]llvm.Type{recvarg.Type()}, paramTypes...)
vararg := fntyp.IsFunctionVarArg()
fntyp = llvm.FunctionType(returnType, paramTypes, vararg)
fnptrtyp := llvm.PointerType(fntyp, 0)
ifn = c.builder.CreateBitCast(ifn, fnptrtyp, "")
args[0] = recvarg
result := c.builder.CreateCall(ifn, args, "")
if sig.Results().Len() == 0 {
c.builder.CreateRetVoid()
} else {
c.builder.CreateRet(result)
}
}
return f
}
开发者ID:qioixiy,项目名称:llgo,代码行数:73,代码来源:functions.go
示例15: findObjects
// On success, findObjects returns the list of objects named
// spec.fromName matching the spec. On success, the result has exactly
// one element unless spec.searchFor!="", in which case it has at least one
// element.
//
func findObjects(info *loader.PackageInfo, spec *spec) ([]types.Object, error) {
if spec.pkgMember == "" {
if spec.searchFor == "" {
panic(spec)
}
objects := searchDefs(&info.Info, spec.searchFor)
if objects == nil {
return nil, fmt.Errorf("no object %q declared in package %q",
spec.searchFor, info.Pkg.Path())
}
return objects, nil
}
pkgMember := info.Pkg.Scope().Lookup(spec.pkgMember)
if pkgMember == nil {
return nil, fmt.Errorf("package %q has no member %q",
info.Pkg.Path(), spec.pkgMember)
}
var searchFunc *types.Func
if spec.typeMember == "" {
// package member
if spec.searchFor == "" {
return []types.Object{pkgMember}, nil
}
// Search within pkgMember, which must be a function.
searchFunc, _ = pkgMember.(*types.Func)
if searchFunc == nil {
return nil, fmt.Errorf("cannot search for %q within %s %q",
spec.searchFor, objectKind(pkgMember), pkgMember)
}
} else {
// field/method of type
// e.g. (encoding/json.Decoder).Decode
// or ::x within it.
tName, _ := pkgMember.(*types.TypeName)
if tName == nil {
return nil, fmt.Errorf("%s.%s is a %s, not a type",
info.Pkg.Path(), pkgMember.Name(), objectKind(pkgMember))
}
// search within named type.
obj, _, _ := types.LookupFieldOrMethod(tName.Type(), true, info.Pkg, spec.typeMember)
if obj == nil {
return nil, fmt.Errorf("cannot find field or method %q of %s %s.%s",
spec.typeMember, typeKind(tName.Type()), info.Pkg.Path(), tName.Name())
}
if spec.searchFor == "" {
return []types.Object{obj}, nil
}
searchFunc, _ = obj.(*types.Func)
if searchFunc == nil {
return nil, fmt.Errorf("cannot search for local name %q within %s (%s.%s).%s; need a function",
spec.searchFor, objectKind(obj), info.Pkg.Path(), tName.Name(),
obj.Name())
}
if isInterface(tName.Type()) {
return nil, fmt.Errorf("cannot search for local name %q within abstract method (%s.%s).%s",
spec.searchFor, info.Pkg.Path(), tName.Name(), searchFunc.Name())
}
}
// -- search within function or method --
decl := funcDecl(info, searchFunc)
if decl == nil {
return nil, fmt.Errorf("cannot find syntax for %s", searchFunc) // can't happen?
}
var objects []types.Object
for _, obj := range searchDefs(&info.Info, spec.searchFor) {
// We use positions, not scopes, to determine whether
// the obj is within searchFunc. This is clumsy, but the
// alternative, using the types.Scope tree, doesn't
// account for non-lexical objects like fields and
// interface methods.
if decl.Pos() <= obj.Pos() && obj.Pos() < decl.End() && obj != searchFunc {
objects = append(objects, obj)
}
}
if objects == nil {
return nil, fmt.Errorf("no local definition of %q within %s",
spec.searchFor, searchFunc)
}
return objects, nil
}
开发者ID:bryanxu,项目名称:go-zh.tools,代码行数:95,代码来源:spec.go
示例16: declaredFunc
// declaredFunc returns the concrete function/method denoted by obj.
// Panic ensues if there is none.
//
func (prog *Program) declaredFunc(obj *types.Func) *Function {
if v := prog.packageLevelValue(obj); v != nil {
return v.(*Function)
}
panic("no concrete method: " + obj.String())
}
开发者ID:Karthikvb,项目名称:15640_projects,代码行数:9,代码来源:promote.go
示例17: recvType
// recvType returns the receiver type of method obj.
func recvType(obj *types.Func) types.Type {
return obj.Type().(*types.Signature).Recv().Type()
}
开发者ID:Karthikvb,项目名称:15640_projects,代码行数:4,代码来源:promote.go
示例18: VisitSelectorExpr
func (c *compiler) VisitSelectorExpr(expr *ast.SelectorExpr) Value {
// Imported package funcs/vars.
if ident, ok := expr.X.(*ast.Ident); ok {
if _, ok := c.objects[ident].(*types.Package); ok {
return c.Resolve(expr.Sel)
}
}
// Method expression. Returns an unbound function pointer.
if c.isType(expr.X) {
ftyp := c.types.expr[expr].Type.(*types.Signature)
recvtyp := ftyp.Params().At(0).Type()
var name *types.Named
var isptr bool
if ptrtyp, ok := recvtyp.(*types.Pointer); ok {
isptr = true
name = ptrtyp.Elem().(*types.Named)
} else {
name = recvtyp.(*types.Named)
}
obj := c.methods(name).lookup(expr.Sel.Name, isptr)
method := c.Resolve(c.objectdata[obj].Ident).(*LLVMValue)
return c.NewValue(method.value, ftyp)
}
// Interface: search for method by name.
lhs := c.VisitExpr(expr.X)
name := expr.Sel.Name
if iface, ok := lhs.Type().Underlying().(*types.Interface); ok {
// FIXME
//i := sort.Search(len(iface.Methods), func(i int) bool {
// return iface.Methods[i].Name >= name
//})
var i int
var m *types.Func
for ; i < iface.NumMethods(); i++ {
m = iface.Method(i)
if m.Name() == name {
break
}
}
structValue := lhs.LLVMValue()
receiver := c.builder.CreateExtractValue(structValue, 1, "")
f := c.builder.CreateExtractValue(structValue, i+2, "")
ftype := m.Type()
types := []llvm.Type{f.Type(), receiver.Type()}
llvmStructType := llvm.StructType(types, false)
structValue = llvm.Undef(llvmStructType)
structValue = c.builder.CreateInsertValue(structValue, f, 0, "")
structValue = c.builder.CreateInsertValue(structValue, receiver, 1, "")
return c.NewValue(structValue, ftype)
}
// Method.
if typ, ok := c.types.expr[expr].Type.(*types.Signature); ok && typ.Recv() != nil {
var isptr bool
typ := lhs.Type()
if ptr, ok := typ.(*types.Pointer); ok {
typ = ptr.Elem()
isptr = true
} else {
isptr = lhs.(*LLVMValue).pointer != nil
}
method := c.methods(typ).lookup(name, isptr)
if method != nil {
recv := lhs.(*LLVMValue)
if isptr && typ == lhs.Type() {
recv = recv.pointer
}
if f, ok := method.(*types.Func); ok {
method = c.methodfunc(f)
}
methodValue := c.Resolve(c.objectdata[method].Ident).LLVMValue()
methodValue = c.builder.CreateExtractValue(methodValue, 0, "")
recvValue := recv.LLVMValue()
types := []llvm.Type{methodValue.Type(), recvValue.Type()}
structType := llvm.StructType(types, false)
value := llvm.Undef(structType)
value = c.builder.CreateInsertValue(value, methodValue, 0, "")
value = c.builder.CreateInsertValue(value, recvValue, 1, "")
return c.NewValue(value, method.Type())
}
}
// Otherwise, search for field, recursing through embedded types.
var result selectorCandidate
curr := []selectorCandidate{{nil, lhs.Type()}}
for result.Type == nil && len(curr) > 0 {
var next []selectorCandidate
for _, candidate := range curr {
indices := candidate.Indices[:]
t := candidate.Type
if ptr, ok := t.(*types.Pointer); ok {
indices = append(indices, -1)
t = ptr.Elem()
}
if t, ok := t.Underlying().(*types.Struct); ok {
if i := fieldIndex(t, name); i != -1 {
result.Indices = append(indices, i)
//.........这里部分代码省略.........
开发者ID:hzmangel,项目名称:llgo,代码行数:101,代码来源:expr.go
注:本文中的code/google/com/p/go/tools/go/types.Func类示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论