Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / analysis / passes / buildssa / buildssa.go
1 // Copyright 2018 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 buildssa defines an Analyzer that constructs the SSA
6 // representation of an error-free package and returns the set of all
7 // functions within it. It does not report any diagnostics itself but
8 // may be used as an input to other analyzers.
9 //
10 // THIS INTERFACE IS EXPERIMENTAL AND MAY BE SUBJECT TO INCOMPATIBLE CHANGE.
11 package buildssa
12
13 import (
14         "go/ast"
15         "go/types"
16         "reflect"
17
18         "golang.org/x/tools/go/analysis"
19         "golang.org/x/tools/go/ssa"
20 )
21
22 var Analyzer = &analysis.Analyzer{
23         Name:       "buildssa",
24         Doc:        "build SSA-form IR for later passes",
25         Run:        run,
26         ResultType: reflect.TypeOf(new(SSA)),
27 }
28
29 // SSA provides SSA-form intermediate representation for all the
30 // non-blank source functions in the current package.
31 type SSA struct {
32         Pkg      *ssa.Package
33         SrcFuncs []*ssa.Function
34 }
35
36 func run(pass *analysis.Pass) (interface{}, error) {
37         // Plundered from ssautil.BuildPackage.
38
39         // We must create a new Program for each Package because the
40         // analysis API provides no place to hang a Program shared by
41         // all Packages. Consequently, SSA Packages and Functions do not
42         // have a canonical representation across an analysis session of
43         // multiple packages. This is unlikely to be a problem in
44         // practice because the analysis API essentially forces all
45         // packages to be analysed independently, so any given call to
46         // Analysis.Run on a package will see only SSA objects belonging
47         // to a single Program.
48
49         // Some Analyzers may need GlobalDebug, in which case we'll have
50         // to set it globally, but let's wait till we need it.
51         mode := ssa.BuilderMode(0)
52
53         prog := ssa.NewProgram(pass.Fset, mode)
54
55         // Create SSA packages for all imports.
56         // Order is not significant.
57         created := make(map[*types.Package]bool)
58         var createAll func(pkgs []*types.Package)
59         createAll = func(pkgs []*types.Package) {
60                 for _, p := range pkgs {
61                         if !created[p] {
62                                 created[p] = true
63                                 prog.CreatePackage(p, nil, nil, true)
64                                 createAll(p.Imports())
65                         }
66                 }
67         }
68         createAll(pass.Pkg.Imports())
69
70         // Create and build the primary package.
71         ssapkg := prog.CreatePackage(pass.Pkg, pass.Files, pass.TypesInfo, false)
72         ssapkg.Build()
73
74         // Compute list of source functions, including literals,
75         // in source order.
76         var funcs []*ssa.Function
77         for _, f := range pass.Files {
78                 for _, decl := range f.Decls {
79                         if fdecl, ok := decl.(*ast.FuncDecl); ok {
80
81                                 // SSA will not build a Function
82                                 // for a FuncDecl named blank.
83                                 // That's arguably too strict but
84                                 // relaxing it would break uniqueness of
85                                 // names of package members.
86                                 if fdecl.Name.Name == "_" {
87                                         continue
88                                 }
89
90                                 // (init functions have distinct Func
91                                 // objects named "init" and distinct
92                                 // ssa.Functions named "init#1", ...)
93
94                                 fn := pass.TypesInfo.Defs[fdecl.Name].(*types.Func)
95                                 if fn == nil {
96                                         panic(fn)
97                                 }
98
99                                 f := ssapkg.Prog.FuncValue(fn)
100                                 if f == nil {
101                                         panic(fn)
102                                 }
103
104                                 var addAnons func(f *ssa.Function)
105                                 addAnons = func(f *ssa.Function) {
106                                         funcs = append(funcs, f)
107                                         for _, anon := range f.AnonFuncs {
108                                                 addAnons(anon)
109                                         }
110                                 }
111                                 addAnons(f)
112                         }
113                 }
114         }
115
116         return &SSA{Pkg: ssapkg, SrcFuncs: funcs}, nil
117 }