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