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 / internal / passes / buildir / buildir.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 buildir defines an Analyzer that constructs the IR
6 // 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 buildir
12
13 import (
14         "go/ast"
15         "go/types"
16         "reflect"
17
18         "golang.org/x/tools/go/analysis"
19         "honnef.co/go/tools/ir"
20 )
21
22 type willExit struct{}
23 type willUnwind struct{}
24
25 func (*willExit) AFact()   {}
26 func (*willUnwind) AFact() {}
27
28 var Analyzer = &analysis.Analyzer{
29         Name:       "buildir",
30         Doc:        "build IR for later passes",
31         Run:        run,
32         ResultType: reflect.TypeOf(new(IR)),
33         FactTypes:  []analysis.Fact{new(willExit), new(willUnwind)},
34 }
35
36 // IR provides intermediate representation for all the
37 // non-blank source functions in the current package.
38 type IR struct {
39         Pkg      *ir.Package
40         SrcFuncs []*ir.Function
41 }
42
43 func run(pass *analysis.Pass) (interface{}, error) {
44         // Plundered from ssautil.BuildPackage.
45
46         // We must create a new Program for each Package because the
47         // analysis API provides no place to hang a Program shared by
48         // all Packages. Consequently, IR Packages and Functions do not
49         // have a canonical representation across an analysis session of
50         // multiple packages. This is unlikely to be a problem in
51         // practice because the analysis API essentially forces all
52         // packages to be analysed independently, so any given call to
53         // Analysis.Run on a package will see only IR objects belonging
54         // to a single Program.
55
56         mode := ir.GlobalDebug
57
58         prog := ir.NewProgram(pass.Fset, mode)
59
60         // Create IR packages for all imports.
61         // Order is not significant.
62         created := make(map[*types.Package]bool)
63         var createAll func(pkgs []*types.Package)
64         createAll = func(pkgs []*types.Package) {
65                 for _, p := range pkgs {
66                         if !created[p] {
67                                 created[p] = true
68                                 irpkg := prog.CreatePackage(p, nil, nil, true)
69                                 for _, fn := range irpkg.Functions {
70                                         if ast.IsExported(fn.Name()) {
71                                                 var exit willExit
72                                                 var unwind willUnwind
73                                                 if pass.ImportObjectFact(fn.Object(), &exit) {
74                                                         fn.WillExit = true
75                                                 }
76                                                 if pass.ImportObjectFact(fn.Object(), &unwind) {
77                                                         fn.WillUnwind = true
78                                                 }
79                                         }
80                                 }
81                                 createAll(p.Imports())
82                         }
83                 }
84         }
85         createAll(pass.Pkg.Imports())
86
87         // Create and build the primary package.
88         irpkg := prog.CreatePackage(pass.Pkg, pass.Files, pass.TypesInfo, false)
89         irpkg.Build()
90
91         // Compute list of source functions, including literals,
92         // in source order.
93         var addAnons func(f *ir.Function)
94         funcs := make([]*ir.Function, len(irpkg.Functions))
95         copy(funcs, irpkg.Functions)
96         addAnons = func(f *ir.Function) {
97                 for _, anon := range f.AnonFuncs {
98                         funcs = append(funcs, anon)
99                         addAnons(anon)
100                 }
101         }
102         for _, fn := range irpkg.Functions {
103                 addAnons(fn)
104                 if fn.WillExit {
105                         pass.ExportObjectFact(fn.Object(), new(willExit))
106                 }
107                 if fn.WillUnwind {
108                         pass.ExportObjectFact(fn.Object(), new(willUnwind))
109                 }
110         }
111
112         return &IR{Pkg: irpkg, SrcFuncs: funcs}, nil
113 }