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 / example_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 package ir_test
6
7 import (
8         "fmt"
9         "go/ast"
10         "go/importer"
11         "go/parser"
12         "go/token"
13         "go/types"
14         "log"
15         "os"
16
17         "golang.org/x/tools/go/packages"
18         "honnef.co/go/tools/ir"
19         "honnef.co/go/tools/ir/irutil"
20 )
21
22 const hello = `
23 package main
24
25 import "fmt"
26
27 const message = "Hello, World!"
28
29 func main() {
30         fmt.Println(message)
31 }
32 `
33
34 // This program demonstrates how to run the IR builder on a single
35 // package of one or more already-parsed files.  Its dependencies are
36 // loaded from compiler export data.  This is what you'd typically use
37 // for a compiler; it does not depend on golang.org/x/tools/go/loader.
38 //
39 // It shows the printed representation of packages, functions, and
40 // instructions.  Within the function listing, the name of each
41 // BasicBlock such as ".0.entry" is printed left-aligned, followed by
42 // the block's Instructions.
43 //
44 // For each instruction that defines an IR virtual register
45 // (i.e. implements Value), the type of that value is shown in the
46 // right column.
47 //
48 // Build and run the irdump.go program if you want a standalone tool
49 // with similar functionality. It is located at
50 // honnef.co/go/tools/internal/cmd/irdump.
51 //
52 func Example_buildPackage() {
53         // Parse the source files.
54         fset := token.NewFileSet()
55         f, err := parser.ParseFile(fset, "hello.go", hello, parser.ParseComments)
56         if err != nil {
57                 fmt.Print(err) // parse error
58                 return
59         }
60         files := []*ast.File{f}
61
62         // Create the type-checker's package.
63         pkg := types.NewPackage("hello", "")
64
65         // Type-check the package, load dependencies.
66         // Create and build the IR program.
67         hello, _, err := irutil.BuildPackage(
68                 &types.Config{Importer: importer.Default()}, fset, pkg, files, ir.SanityCheckFunctions)
69         if err != nil {
70                 fmt.Print(err) // type error in some package
71                 return
72         }
73
74         // Print out the package.
75         hello.WriteTo(os.Stdout)
76
77         // Print out the package-level functions.
78         hello.Func("init").WriteTo(os.Stdout)
79         hello.Func("main").WriteTo(os.Stdout)
80
81         // Output:
82         // package hello:
83         //   func  init       func()
84         //   var   init$guard bool
85         //   func  main       func()
86         //   const message    message = Const <untyped string> {"Hello, World!"}
87         //
88         // # Name: hello.init
89         // # Package: hello
90         // # Synthetic: package initializer
91         // func init():
92         // b0: # entry
93         //      t1 = Const <bool> {true}
94         //      t2 = Load <bool> init$guard
95         //      If t2 → b1 b2
96         //
97         // b1: ← b0 b2 # exit
98         //      Return
99         //
100         // b2: ← b0 # init.start
101         //      Store {bool} init$guard t1
102         //      t6 = Call <()> fmt.init
103         //      Jump → b1
104         //
105         // # Name: hello.main
106         // # Package: hello
107         // # Location: hello.go:8:1
108         // func main():
109         // b0: # entry
110         //      t1 = Const <string> {"Hello, World!"}
111         //      t2 = Const <int> {0}
112         //      t3 = HeapAlloc <*[1]interface{}>
113         //      t4 = IndexAddr <*interface{}> t3 t2
114         //      t5 = MakeInterface <interface{}> t1
115         //      Store {interface{}} t4 t5
116         //      t7 = Slice <[]interface{}> t3 <nil> <nil> <nil>
117         //      t8 = Call <(n int, err error)> fmt.Println t7
118         //      Jump → b1
119         //
120         // b1: ← b0 # exit
121         //      Return
122 }
123
124 // This example builds IR code for a set of packages using the
125 // x/tools/go/packages API. This is what you would typically use for a
126 // analysis capable of operating on a single package.
127 func Example_loadPackages() {
128         // Load, parse, and type-check the initial packages.
129         cfg := &packages.Config{Mode: packages.LoadSyntax}
130         initial, err := packages.Load(cfg, "fmt", "net/http")
131         if err != nil {
132                 log.Fatal(err)
133         }
134
135         // Stop if any package had errors.
136         // This step is optional; without it, the next step
137         // will create IR for only a subset of packages.
138         if packages.PrintErrors(initial) > 0 {
139                 log.Fatalf("packages contain errors")
140         }
141
142         // Create IR packages for all well-typed packages.
143         prog, pkgs := irutil.Packages(initial, ir.PrintPackages, nil)
144         _ = prog
145
146         // Build IR code for the well-typed initial packages.
147         for _, p := range pkgs {
148                 if p != nil {
149                         p.Build()
150                 }
151         }
152 }
153
154 // This example builds IR code for a set of packages plus all their dependencies,
155 // using the x/tools/go/packages API.
156 // This is what you'd typically use for a whole-program analysis.
157 func Example_loadWholeProgram() {
158         // Load, parse, and type-check the whole program.
159         cfg := packages.Config{Mode: packages.LoadAllSyntax}
160         initial, err := packages.Load(&cfg, "fmt", "net/http")
161         if err != nil {
162                 log.Fatal(err)
163         }
164
165         // Create IR packages for well-typed packages and their dependencies.
166         prog, pkgs := irutil.AllPackages(initial, ir.PrintPackages, nil)
167         _ = pkgs
168
169         // Build IR code for the whole program.
170         prog.Build()
171 }