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 / ir / stdlib_test.go
1 // Copyright 2013 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 //lint:file-ignore SA1019 go/ssa's test suite is built around the deprecated go/loader. We'll leave fixing that to upstream.
6
7 // Incomplete source tree on Android.
8
9 // +build !android
10
11 package ir_test
12
13 // This file runs the IR builder in sanity-checking mode on all
14 // packages beneath $GOROOT and prints some summary information.
15 //
16 // Run with "go test -cpu=8 to" set GOMAXPROCS.
17
18 import (
19         "go/ast"
20         "go/token"
21         "runtime"
22         "testing"
23         "time"
24
25         "golang.org/x/tools/go/packages"
26         "honnef.co/go/tools/ir"
27         "honnef.co/go/tools/ir/irutil"
28 )
29
30 func bytesAllocated() uint64 {
31         runtime.GC()
32         var stats runtime.MemStats
33         runtime.ReadMemStats(&stats)
34         return stats.TotalAlloc
35 }
36
37 func TestStdlib(t *testing.T) {
38         if testing.Short() {
39                 t.Skip("skipping in short mode; too slow (golang.org/issue/14113)")
40         }
41
42         var (
43                 numFuncs  int
44                 numInstrs int
45
46                 dLoad   time.Duration
47                 dCreate time.Duration
48                 dBuild  time.Duration
49
50                 allocLoad  uint64
51                 allocBuild uint64
52         )
53
54         // Load, parse and type-check the program.
55         t0 := time.Now()
56         alloc0 := bytesAllocated()
57
58         cfg := &packages.Config{
59                 Mode: packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedImports | packages.NeedDeps | packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo | packages.NeedTypesSizes,
60         }
61         pkgs, err := packages.Load(cfg, "std")
62         if err != nil {
63                 t.Fatalf("Load failed: %v", err)
64         }
65         allocLoad = bytesAllocated() - alloc0
66         dLoad = time.Since(t0)
67
68         alloc0 = bytesAllocated()
69         for _, pkg := range pkgs {
70                 if len(pkg.Errors) != 0 {
71                         t.Fatalf("Load failed: %v", pkg.Errors)
72                 }
73
74                 var mode ir.BuilderMode
75                 // Comment out these lines during benchmarking.  Approx IR build costs are noted.
76                 mode |= ir.SanityCheckFunctions // + 2% space, + 4% time
77                 mode |= ir.GlobalDebug          // +30% space, +18% time
78                 prog := ir.NewProgram(pkg.Fset, mode)
79
80                 t0 := time.Now()
81                 var irpkg *ir.Package
82                 for _, pkg2 := range pkgs {
83                         r := prog.CreatePackage(pkg2.Types, pkg2.Syntax, pkg2.TypesInfo, true)
84                         if pkg2 == pkg {
85                                 irpkg = r
86                         }
87                 }
88                 dCreate += time.Since(t0)
89
90                 t0 = time.Now()
91                 irpkg.Build()
92                 dBuild += time.Since(t0)
93
94                 allFuncs := irutil.AllFunctions(prog)
95                 numFuncs += len(allFuncs)
96
97                 // Check that all non-synthetic functions have distinct names.
98                 // Synthetic wrappers for exported methods should be distinct too,
99                 // except for unexported ones (explained at (*Function).RelString).
100                 byName := make(map[string]*ir.Function)
101                 for fn := range allFuncs {
102                         if fn.Synthetic == "" || ast.IsExported(fn.Name()) {
103                                 str := fn.String()
104                                 prev := byName[str]
105                                 byName[str] = fn
106                                 if prev != nil {
107                                         t.Errorf("%s: duplicate function named %s",
108                                                 prog.Fset.Position(fn.Pos()), str)
109                                         t.Errorf("%s:   (previously defined here)",
110                                                 prog.Fset.Position(prev.Pos()))
111                                 }
112                         }
113                 }
114
115                 // Dump some statistics.
116                 var numInstrs int
117                 for fn := range allFuncs {
118                         for _, b := range fn.Blocks {
119                                 numInstrs += len(b.Instrs)
120                         }
121                 }
122         }
123         allocBuild = bytesAllocated() - alloc0
124
125         // determine line count
126         var lineCount int
127         pkgs[0].Fset.Iterate(func(f *token.File) bool {
128                 lineCount += f.LineCount()
129                 return true
130         })
131
132         // NB: when benchmarking, don't forget to clear the debug +
133         // sanity builder flags for better performance.
134
135         t.Log("GOMAXPROCS:           ", runtime.GOMAXPROCS(0))
136         t.Log("#Source lines:        ", lineCount)
137         t.Log("Load/parse/typecheck: ", dLoad)
138         t.Log("IR create:           ", dCreate)
139         t.Log("IR build:            ", dBuild)
140
141         // IR stats:
142         t.Log("#Packages:            ", len(pkgs))
143         t.Log("#Functions:           ", numFuncs)
144         t.Log("#Instructions:        ", numInstrs)
145         t.Log("#MB AST+types:        ", allocLoad/1e6)
146         t.Log("#MB IR:              ", allocBuild/1e6)
147 }