.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.1-0.20210319172145-bda8f5cee399 / go / pointer / example_test.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.1-0.20210319172145-bda8f5cee399/go/pointer/example_test.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.1-0.20210319172145-bda8f5cee399/go/pointer/example_test.go
new file mode 100644 (file)
index 0000000..673de7a
--- /dev/null
@@ -0,0 +1,126 @@
+// Copyright 2013 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 pointer_test
+
+import (
+       "fmt"
+       "sort"
+
+       "golang.org/x/tools/go/callgraph"
+       "golang.org/x/tools/go/loader"
+       "golang.org/x/tools/go/pointer"
+       "golang.org/x/tools/go/ssa"
+       "golang.org/x/tools/go/ssa/ssautil"
+)
+
+// This program demonstrates how to use the pointer analysis to
+// obtain a conservative call-graph of a Go program.
+// It also shows how to compute the points-to set of a variable,
+// in this case, (C).f's ch parameter.
+//
+func Example() {
+       const myprog = `
+package main
+
+import "fmt"
+
+type I interface {
+       f(map[string]int)
+}
+
+type C struct{}
+
+func (C) f(m map[string]int) {
+       fmt.Println("C.f()")
+}
+
+func main() {
+       var i I = C{}
+       x := map[string]int{"one":1}
+       i.f(x) // dynamic method call
+}
+`
+       var conf loader.Config
+
+       // Parse the input file, a string.
+       // (Command-line tools should use conf.FromArgs.)
+       file, err := conf.ParseFile("myprog.go", myprog)
+       if err != nil {
+               fmt.Print(err) // parse error
+               return
+       }
+
+       // Create single-file main package and import its dependencies.
+       conf.CreateFromFiles("main", file)
+
+       iprog, err := conf.Load()
+       if err != nil {
+               fmt.Print(err) // type error in some package
+               return
+       }
+
+       // Create SSA-form program representation.
+       prog := ssautil.CreateProgram(iprog, 0)
+       mainPkg := prog.Package(iprog.Created[0].Pkg)
+
+       // Build SSA code for bodies of all functions in the whole program.
+       prog.Build()
+
+       // Configure the pointer analysis to build a call-graph.
+       config := &pointer.Config{
+               Mains:          []*ssa.Package{mainPkg},
+               BuildCallGraph: true,
+       }
+
+       // Query points-to set of (C).f's parameter m, a map.
+       C := mainPkg.Type("C").Type()
+       Cfm := prog.LookupMethod(C, mainPkg.Pkg, "f").Params[1]
+       config.AddQuery(Cfm)
+
+       // Run the pointer analysis.
+       result, err := pointer.Analyze(config)
+       if err != nil {
+               panic(err) // internal error in pointer analysis
+       }
+
+       // Find edges originating from the main package.
+       // By converting to strings, we de-duplicate nodes
+       // representing the same function due to context sensitivity.
+       var edges []string
+       callgraph.GraphVisitEdges(result.CallGraph, func(edge *callgraph.Edge) error {
+               caller := edge.Caller.Func
+               if caller.Pkg == mainPkg {
+                       edges = append(edges, fmt.Sprint(caller, " --> ", edge.Callee.Func))
+               }
+               return nil
+       })
+
+       // Print the edges in sorted order.
+       sort.Strings(edges)
+       for _, edge := range edges {
+               fmt.Println(edge)
+       }
+       fmt.Println()
+
+       // Print the labels of (C).f(m)'s points-to set.
+       fmt.Println("m may point to:")
+       var labels []string
+       for _, l := range result.Queries[Cfm].PointsTo().Labels() {
+               label := fmt.Sprintf("  %s: %s", prog.Fset.Position(l.Pos()), l)
+               labels = append(labels, label)
+       }
+       sort.Strings(labels)
+       for _, label := range labels {
+               fmt.Println(label)
+       }
+
+       // Output:
+       // (main.C).f --> fmt.Println
+       // main.init --> fmt.init
+       // main.main --> (main.C).f
+       //
+       // m may point to:
+       //   myprog.go:18:21: makemap
+}