.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.0 / go / types / typeutil / callee_test.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.0/go/types/typeutil/callee_test.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.0/go/types/typeutil/callee_test.go
new file mode 100644 (file)
index 0000000..272e1eb
--- /dev/null
@@ -0,0 +1,89 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeutil_test
+
+import (
+       "go/ast"
+       "go/importer"
+       "go/parser"
+       "go/token"
+       "go/types"
+       "strings"
+       "testing"
+
+       "golang.org/x/tools/go/types/typeutil"
+)
+
+func TestStaticCallee(t *testing.T) {
+       const src = `package p
+
+import "fmt"
+
+type T int
+
+func g(int)
+
+var f = g
+
+var x int
+
+type s struct{ f func(int) }
+func (s) g(int)
+
+type I interface{ f(int) }
+
+var a struct{b struct{c s}}
+
+func calls() {
+       g(x)           // a declared func
+       s{}.g(x)       // a concrete method
+       a.b.c.g(x)     // same
+       fmt.Println(x) // declared func, qualified identifier
+}
+
+func noncalls() {
+       _ = T(x)    // a type
+       f(x)        // a var
+       panic(x)    // a built-in
+       s{}.f(x)    // a field
+       I(nil).f(x) // interface method
+}
+`
+       // parse
+       fset := token.NewFileSet()
+       f, err := parser.ParseFile(fset, "p.go", src, 0)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // type-check
+       info := &types.Info{
+               Uses:       make(map[*ast.Ident]types.Object),
+               Selections: make(map[*ast.SelectorExpr]*types.Selection),
+       }
+       cfg := &types.Config{Importer: importer.ForCompiler(fset, "source", nil)}
+       if _, err := cfg.Check("p", fset, []*ast.File{f}, info); err != nil {
+               t.Fatal(err)
+       }
+
+       for _, decl := range f.Decls {
+               if decl, ok := decl.(*ast.FuncDecl); ok && strings.HasSuffix(decl.Name.Name, "calls") {
+                       wantCallee := decl.Name.Name == "calls" // false within func noncalls()
+                       ast.Inspect(decl.Body, func(n ast.Node) bool {
+                               if call, ok := n.(*ast.CallExpr); ok {
+                                       fn := typeutil.StaticCallee(info, call)
+                                       if fn == nil && wantCallee {
+                                               t.Errorf("%s: StaticCallee returned nil",
+                                                       fset.Position(call.Lparen))
+                                       } else if fn != nil && !wantCallee {
+                                               t.Errorf("%s: StaticCallee returned %s, want nil",
+                                                       fset.Position(call.Lparen), fn)
+                                       }
+                               }
+                               return true
+                       })
+               }
+       }
+}