1// Copyright 2018 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package typeutil 6 7import ( 8 "go/ast" 9 "go/types" 10 11 "golang.org/x/tools/go/ast/astutil" 12) 13 14// Callee returns the named target of a function call, if any: 15// a function, method, builtin, or variable. 16func Callee(info *types.Info, call *ast.CallExpr) types.Object { 17 var obj types.Object 18 switch fun := astutil.Unparen(call.Fun).(type) { 19 case *ast.Ident: 20 obj = info.Uses[fun] // type, var, builtin, or declared func 21 case *ast.SelectorExpr: 22 if sel, ok := info.Selections[fun]; ok { 23 obj = sel.Obj() // method or field 24 } else { 25 obj = info.Uses[fun.Sel] // qualified identifier? 26 } 27 } 28 if _, ok := obj.(*types.TypeName); ok { 29 return nil // T(x) is a conversion, not a call 30 } 31 return obj 32} 33 34// StaticCallee returns the target (function or method) of a static 35// function call, if any. It returns nil for calls to builtins. 36func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func { 37 if f, ok := Callee(info, call).(*types.Func); ok && !interfaceMethod(f) { 38 return f 39 } 40 return nil 41} 42 43func interfaceMethod(f *types.Func) bool { 44 recv := f.Type().(*types.Signature).Recv() 45 return recv != nil && types.IsInterface(recv.Type()) 46} 47