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