Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / go / ssa / testmain.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/go/ssa/testmain.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/go/ssa/testmain.go
new file mode 100644 (file)
index 0000000..c4256d1
--- /dev/null
@@ -0,0 +1,274 @@
+// 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 ssa
+
+// CreateTestMainPackage synthesizes a main package that runs all the
+// tests of the supplied packages.
+// It is closely coupled to $GOROOT/src/cmd/go/test.go and $GOROOT/src/testing.
+//
+// TODO(adonovan): throws this all away now that x/tools/go/packages
+// provides access to the actual synthetic test main files.
+
+import (
+       "bytes"
+       "fmt"
+       "go/ast"
+       "go/parser"
+       "go/types"
+       "log"
+       "os"
+       "strings"
+       "text/template"
+)
+
+// FindTests returns the Test, Benchmark, and Example functions
+// (as defined by "go test") defined in the specified package,
+// and its TestMain function, if any.
+//
+// Deprecated: Use golang.org/x/tools/go/packages to access synthetic
+// testmain packages.
+func FindTests(pkg *Package) (tests, benchmarks, examples []*Function, main *Function) {
+       prog := pkg.Prog
+
+       // The first two of these may be nil: if the program doesn't import "testing",
+       // it can't contain any tests, but it may yet contain Examples.
+       var testSig *types.Signature                              // func(*testing.T)
+       var benchmarkSig *types.Signature                         // func(*testing.B)
+       var exampleSig = types.NewSignature(nil, nil, nil, false) // func()
+
+       // Obtain the types from the parameters of testing.MainStart.
+       if testingPkg := prog.ImportedPackage("testing"); testingPkg != nil {
+               mainStart := testingPkg.Func("MainStart")
+               params := mainStart.Signature.Params()
+               testSig = funcField(params.At(1).Type())
+               benchmarkSig = funcField(params.At(2).Type())
+
+               // Does the package define this function?
+               //   func TestMain(*testing.M)
+               if f := pkg.Func("TestMain"); f != nil {
+                       sig := f.Type().(*types.Signature)
+                       starM := mainStart.Signature.Results().At(0).Type() // *testing.M
+                       if sig.Results().Len() == 0 &&
+                               sig.Params().Len() == 1 &&
+                               types.Identical(sig.Params().At(0).Type(), starM) {
+                               main = f
+                       }
+               }
+       }
+
+       // TODO(adonovan): use a stable order, e.g. lexical.
+       for _, mem := range pkg.Members {
+               if f, ok := mem.(*Function); ok &&
+                       ast.IsExported(f.Name()) &&
+                       strings.HasSuffix(prog.Fset.Position(f.Pos()).Filename, "_test.go") {
+
+                       switch {
+                       case testSig != nil && isTestSig(f, "Test", testSig):
+                               tests = append(tests, f)
+                       case benchmarkSig != nil && isTestSig(f, "Benchmark", benchmarkSig):
+                               benchmarks = append(benchmarks, f)
+                       case isTestSig(f, "Example", exampleSig):
+                               examples = append(examples, f)
+                       default:
+                               continue
+                       }
+               }
+       }
+       return
+}
+
+// Like isTest, but checks the signature too.
+func isTestSig(f *Function, prefix string, sig *types.Signature) bool {
+       return isTest(f.Name(), prefix) && types.Identical(f.Signature, sig)
+}
+
+// Given the type of one of the three slice parameters of testing.Main,
+// returns the function type.
+func funcField(slice types.Type) *types.Signature {
+       return slice.(*types.Slice).Elem().Underlying().(*types.Struct).Field(1).Type().(*types.Signature)
+}
+
+// isTest tells whether name looks like a test (or benchmark, according to prefix).
+// It is a Test (say) if there is a character after Test that is not a lower-case letter.
+// We don't want TesticularCancer.
+// Plundered from $GOROOT/src/cmd/go/test.go
+func isTest(name, prefix string) bool {
+       if !strings.HasPrefix(name, prefix) {
+               return false
+       }
+       if len(name) == len(prefix) { // "Test" is ok
+               return true
+       }
+       return ast.IsExported(name[len(prefix):])
+}
+
+// CreateTestMainPackage creates and returns a synthetic "testmain"
+// package for the specified package if it defines tests, benchmarks or
+// executable examples, or nil otherwise.  The new package is named
+// "main" and provides a function named "main" that runs the tests,
+// similar to the one that would be created by the 'go test' tool.
+//
+// Subsequent calls to prog.AllPackages include the new package.
+// The package pkg must belong to the program prog.
+//
+// Deprecated: Use golang.org/x/tools/go/packages to access synthetic
+// testmain packages.
+func (prog *Program) CreateTestMainPackage(pkg *Package) *Package {
+       if pkg.Prog != prog {
+               log.Fatal("Package does not belong to Program")
+       }
+
+       // Template data
+       var data struct {
+               Pkg                         *Package
+               Tests, Benchmarks, Examples []*Function
+               Main                        *Function
+               Go18                        bool
+       }
+       data.Pkg = pkg
+
+       // Enumerate tests.
+       data.Tests, data.Benchmarks, data.Examples, data.Main = FindTests(pkg)
+       if data.Main == nil &&
+               data.Tests == nil && data.Benchmarks == nil && data.Examples == nil {
+               return nil
+       }
+
+       // Synthesize source for testmain package.
+       path := pkg.Pkg.Path() + "$testmain"
+       tmpl := testmainTmpl
+       if testingPkg := prog.ImportedPackage("testing"); testingPkg != nil {
+               // In Go 1.8, testing.MainStart's first argument is an interface, not a func.
+               data.Go18 = types.IsInterface(testingPkg.Func("MainStart").Signature.Params().At(0).Type())
+       } else {
+               // The program does not import "testing", but FindTests
+               // returned non-nil, which must mean there were Examples
+               // but no Test, Benchmark, or TestMain functions.
+
+               // We'll simply call them from testmain.main; this will
+               // ensure they don't panic, but will not check any
+               // "Output:" comments.
+               // (We should not execute an Example that has no
+               // "Output:" comment, but it's impossible to tell here.)
+               tmpl = examplesOnlyTmpl
+       }
+       var buf bytes.Buffer
+       if err := tmpl.Execute(&buf, data); err != nil {
+               log.Fatalf("internal error expanding template for %s: %v", path, err)
+       }
+       if false { // debugging
+               fmt.Fprintln(os.Stderr, buf.String())
+       }
+
+       // Parse and type-check the testmain package.
+       f, err := parser.ParseFile(prog.Fset, path+".go", &buf, parser.Mode(0))
+       if err != nil {
+               log.Fatalf("internal error parsing %s: %v", path, err)
+       }
+       conf := types.Config{
+               DisableUnusedImportCheck: true,
+               Importer:                 importer{pkg},
+       }
+       files := []*ast.File{f}
+       info := &types.Info{
+               Types:      make(map[ast.Expr]types.TypeAndValue),
+               Defs:       make(map[*ast.Ident]types.Object),
+               Uses:       make(map[*ast.Ident]types.Object),
+               Implicits:  make(map[ast.Node]types.Object),
+               Scopes:     make(map[ast.Node]*types.Scope),
+               Selections: make(map[*ast.SelectorExpr]*types.Selection),
+       }
+       testmainPkg, err := conf.Check(path, prog.Fset, files, info)
+       if err != nil {
+               log.Fatalf("internal error type-checking %s: %v", path, err)
+       }
+
+       // Create and build SSA code.
+       testmain := prog.CreatePackage(testmainPkg, files, info, false)
+       testmain.SetDebugMode(false)
+       testmain.Build()
+       testmain.Func("main").Synthetic = "test main function"
+       testmain.Func("init").Synthetic = "package initializer"
+       return testmain
+}
+
+// An implementation of types.Importer for an already loaded SSA program.
+type importer struct {
+       pkg *Package // package under test; may be non-importable
+}
+
+func (imp importer) Import(path string) (*types.Package, error) {
+       if p := imp.pkg.Prog.ImportedPackage(path); p != nil {
+               return p.Pkg, nil
+       }
+       if path == imp.pkg.Pkg.Path() {
+               return imp.pkg.Pkg, nil
+       }
+       return nil, fmt.Errorf("not found") // can't happen
+}
+
+var testmainTmpl = template.Must(template.New("testmain").Parse(`
+package main
+
+import "io"
+import "os"
+import "testing"
+import p {{printf "%q" .Pkg.Pkg.Path}}
+
+{{if .Go18}}
+type deps struct{}
+
+func (deps) ImportPath() string { return "" }
+func (deps) MatchString(pat, str string) (bool, error) { return true, nil }
+func (deps) SetPanicOnExit0(bool) {}
+func (deps) StartCPUProfile(io.Writer) error { return nil }
+func (deps) StartTestLog(io.Writer) {}
+func (deps) StopCPUProfile() {}
+func (deps) StopTestLog() error { return nil }
+func (deps) WriteHeapProfile(io.Writer) error { return nil }
+func (deps) WriteProfileTo(string, io.Writer, int) error { return nil }
+
+var match deps
+{{else}}
+func match(_, _ string) (bool, error) { return true, nil }
+{{end}}
+
+func main() {
+       tests := []testing.InternalTest{
+{{range .Tests}}
+               { {{printf "%q" .Name}}, p.{{.Name}} },
+{{end}}
+       }
+       benchmarks := []testing.InternalBenchmark{
+{{range .Benchmarks}}
+               { {{printf "%q" .Name}}, p.{{.Name}} },
+{{end}}
+       }
+       examples := []testing.InternalExample{
+{{range .Examples}}
+               {Name: {{printf "%q" .Name}}, F: p.{{.Name}}},
+{{end}}
+       }
+       m := testing.MainStart(match, tests, benchmarks, examples)
+{{with .Main}}
+       p.{{.Name}}(m)
+{{else}}
+       os.Exit(m.Run())
+{{end}}
+}
+
+`))
+
+var examplesOnlyTmpl = template.Must(template.New("examples").Parse(`
+package main
+
+import p {{printf "%q" .Pkg.Pkg.Path}}
+
+func main() {
+{{range .Examples}}
+       p.{{.Name}}()
+{{end}}
+}
+`))