GoPLS Viewer

Home|gopls/go/types/typeutil/callee.go
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    "golang.org/x/tools/internal/typeparams"
13)
14
15// Callee returns the named target of a function call, if any:
16// a function, method, builtin, or variable.
17//
18// Functions and methods may potentially have type parameters.
19func Callee(info *types.Infocall *ast.CallExprtypes.Object {
20    fun := astutil.Unparen(call.Fun)
21
22    // Look through type instantiation if necessary.
23    isInstance := false
24    switch fun.(type) {
25    case *ast.IndexExpr, *typeparams.IndexListExpr:
26        // When extracting the callee from an *IndexExpr, we need to check that
27        // it is a *types.Func and not a *types.Var.
28        // Example: Don't match a slice m within the expression `m[0]()`.
29        isInstance = true
30        fun___ = typeparams.UnpackIndexExpr(fun)
31    }
32
33    var obj types.Object
34    switch fun := fun.(type) {
35    case *ast.Ident:
36        obj = info.Uses[fun// type, var, builtin, or declared func
37    case *ast.SelectorExpr:
38        if selok := info.Selections[fun]; ok {
39            obj = sel.Obj() // method or field
40        } else {
41            obj = info.Uses[fun.Sel// qualified identifier?
42        }
43    }
44    if _ok := obj.(*types.TypeName); ok {
45        return nil // T(x) is a conversion, not a call
46    }
47    // A Func is required to match instantiations.
48    if _ok := obj.(*types.Func); isInstance && !ok {
49        return nil // Was not a Func.
50    }
51    return obj
52}
53
54// StaticCallee returns the target (function or method) of a static function
55// call, if any. It returns nil for calls to builtins.
56//
57// Note: for calls of instantiated functions and methods, StaticCallee returns
58// the corresponding generic function or method on the generic type.
59func StaticCallee(info *types.Infocall *ast.CallExpr) *types.Func {
60    if fok := Callee(infocall).(*types.Func); ok && !interfaceMethod(f) {
61        return f
62    }
63    return nil
64}
65
66func interfaceMethod(f *types.Funcbool {
67    recv := f.Type().(*types.Signature).Recv()
68    return recv != nil && types.IsInterface(recv.Type())
69}
70
MembersX
StaticCallee.call
interfaceMethod.recv
types
Callee.isInstance
Callee.obj
interfaceMethod
Callee
Callee.info
Callee.call
StaticCallee.info
typeparams
Callee.fun
StaticCallee
ast
astutil
interfaceMethod.f
Members
X