Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.0.1-2020.1.5 / go / types / typeutil / callee_test.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
5 package typeutil_test
6
7 import (
8         "go/ast"
9         "go/importer"
10         "go/parser"
11         "go/token"
12         "go/types"
13         "strings"
14         "testing"
15
16         "honnef.co/go/tools/go/types/typeutil"
17 )
18
19 func TestStaticCallee(t *testing.T) {
20         const src = `package p
21
22 import "fmt"
23
24 type T int
25
26 func g(int)
27
28 var f = g
29
30 var x int
31
32 type s struct{ f func(int) }
33 func (s) g(int)
34
35 type I interface{ f(int) }
36
37 var a struct{b struct{c s}}
38
39 func calls() {
40         g(x)           // a declared func
41         s{}.g(x)       // a concrete method
42         a.b.c.g(x)     // same
43         fmt.Println(x) // declared func, qualified identifier
44 }
45
46 func noncalls() {
47         _ = T(x)    // a type
48         f(x)        // a var
49         panic(x)    // a built-in
50         s{}.f(x)    // a field
51         I(nil).f(x) // interface method
52 }
53 `
54         // parse
55         fset := token.NewFileSet()
56         f, err := parser.ParseFile(fset, "p.go", src, 0)
57         if err != nil {
58                 t.Fatal(err)
59         }
60
61         // type-check
62         info := &types.Info{
63                 Uses:       make(map[*ast.Ident]types.Object),
64                 Selections: make(map[*ast.SelectorExpr]*types.Selection),
65         }
66         cfg := &types.Config{Importer: importer.For("source", nil)}
67         if _, err := cfg.Check("p", fset, []*ast.File{f}, info); err != nil {
68                 t.Fatal(err)
69         }
70
71         for _, decl := range f.Decls {
72                 if decl, ok := decl.(*ast.FuncDecl); ok && strings.HasSuffix(decl.Name.Name, "calls") {
73                         wantCallee := decl.Name.Name == "calls" // false within func noncalls()
74                         ast.Inspect(decl.Body, func(n ast.Node) bool {
75                                 if call, ok := n.(*ast.CallExpr); ok {
76                                         fn := typeutil.StaticCallee(info, call)
77                                         if fn == nil && wantCallee {
78                                                 t.Errorf("%s: StaticCallee returned nil",
79                                                         fset.Position(call.Lparen))
80                                         } else if fn != nil && !wantCallee {
81                                                 t.Errorf("%s: StaticCallee returned %s, want nil",
82                                                         fset.Position(call.Lparen), fn)
83                                         }
84                                 }
85                                 return true
86                         })
87                 }
88         }
89 }