.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.1-0.20210319172145-bda8f5cee399 / go / analysis / doc.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 /*
6
7 Package analysis defines the interface between a modular static
8 analysis and an analysis driver program.
9
10
11 Background
12
13 A static analysis is a function that inspects a package of Go code and
14 reports a set of diagnostics (typically mistakes in the code), and
15 perhaps produces other results as well, such as suggested refactorings
16 or other facts. An analysis that reports mistakes is informally called a
17 "checker". For example, the printf checker reports mistakes in
18 fmt.Printf format strings.
19
20 A "modular" analysis is one that inspects one package at a time but can
21 save information from a lower-level package and use it when inspecting a
22 higher-level package, analogous to separate compilation in a toolchain.
23 The printf checker is modular: when it discovers that a function such as
24 log.Fatalf delegates to fmt.Printf, it records this fact, and checks
25 calls to that function too, including calls made from another package.
26
27 By implementing a common interface, checkers from a variety of sources
28 can be easily selected, incorporated, and reused in a wide range of
29 driver programs including command-line tools (such as vet), text editors and
30 IDEs, build and test systems (such as go build, Bazel, or Buck), test
31 frameworks, code review tools, code-base indexers (such as SourceGraph),
32 documentation viewers (such as godoc), batch pipelines for large code
33 bases, and so on.
34
35
36 Analyzer
37
38 The primary type in the API is Analyzer. An Analyzer statically
39 describes an analysis function: its name, documentation, flags,
40 relationship to other analyzers, and of course, its logic.
41
42 To define an analysis, a user declares a (logically constant) variable
43 of type Analyzer. Here is a typical example from one of the analyzers in
44 the go/analysis/passes/ subdirectory:
45
46         package unusedresult
47
48         var Analyzer = &analysis.Analyzer{
49                 Name: "unusedresult",
50                 Doc:  "check for unused results of calls to some functions",
51                 Run:  run,
52                 ...
53         }
54
55         func run(pass *analysis.Pass) (interface{}, error) {
56                 ...
57         }
58
59 An analysis driver is a program such as vet that runs a set of
60 analyses and prints the diagnostics that they report.
61 The driver program must import the list of Analyzers it needs.
62 Typically each Analyzer resides in a separate package.
63 To add a new Analyzer to an existing driver, add another item to the list:
64
65         import ( "unusedresult"; "nilness"; "printf" )
66
67         var analyses = []*analysis.Analyzer{
68                 unusedresult.Analyzer,
69                 nilness.Analyzer,
70                 printf.Analyzer,
71         }
72
73 A driver may use the name, flags, and documentation to provide on-line
74 help that describes the analyses it performs.
75 The doc comment contains a brief one-line summary,
76 optionally followed by paragraphs of explanation.
77
78 The Analyzer type has more fields besides those shown above:
79
80         type Analyzer struct {
81                 Name             string
82                 Doc              string
83                 Flags            flag.FlagSet
84                 Run              func(*Pass) (interface{}, error)
85                 RunDespiteErrors bool
86                 ResultType       reflect.Type
87                 Requires         []*Analyzer
88                 FactTypes        []Fact
89         }
90
91 The Flags field declares a set of named (global) flag variables that
92 control analysis behavior. Unlike vet, analysis flags are not declared
93 directly in the command line FlagSet; it is up to the driver to set the
94 flag variables. A driver for a single analysis, a, might expose its flag
95 f directly on the command line as -f, whereas a driver for multiple
96 analyses might prefix the flag name by the analysis name (-a.f) to avoid
97 ambiguity. An IDE might expose the flags through a graphical interface,
98 and a batch pipeline might configure them from a config file.
99 See the "findcall" analyzer for an example of flags in action.
100
101 The RunDespiteErrors flag indicates whether the analysis is equipped to
102 handle ill-typed code. If not, the driver will skip the analysis if
103 there were parse or type errors.
104 The optional ResultType field specifies the type of the result value
105 computed by this analysis and made available to other analyses.
106 The Requires field specifies a list of analyses upon which
107 this one depends and whose results it may access, and it constrains the
108 order in which a driver may run analyses.
109 The FactTypes field is discussed in the section on Modularity.
110 The analysis package provides a Validate function to perform basic
111 sanity checks on an Analyzer, such as that its Requires graph is
112 acyclic, its fact and result types are unique, and so on.
113
114 Finally, the Run field contains a function to be called by the driver to
115 execute the analysis on a single package. The driver passes it an
116 instance of the Pass type.
117
118
119 Pass
120
121 A Pass describes a single unit of work: the application of a particular
122 Analyzer to a particular package of Go code.
123 The Pass provides information to the Analyzer's Run function about the
124 package being analyzed, and provides operations to the Run function for
125 reporting diagnostics and other information back to the driver.
126
127         type Pass struct {
128                 Fset         *token.FileSet
129                 Files        []*ast.File
130                 OtherFiles   []string
131                 IgnoredFiles []string
132                 Pkg          *types.Package
133                 TypesInfo    *types.Info
134                 ResultOf     map[*Analyzer]interface{}
135                 Report       func(Diagnostic)
136                 ...
137         }
138
139 The Fset, Files, Pkg, and TypesInfo fields provide the syntax trees,
140 type information, and source positions for a single package of Go code.
141
142 The OtherFiles field provides the names, but not the contents, of non-Go
143 files such as assembly that are part of this package. See the "asmdecl"
144 or "buildtags" analyzers for examples of loading non-Go files and reporting
145 diagnostics against them.
146
147 The IgnoredFiles field provides the names, but not the contents,
148 of ignored Go and non-Go source files that are not part of this package
149 with the current build configuration but may be part of other build
150 configurations. See the "buildtags" analyzer for an example of loading
151 and checking IgnoredFiles.
152
153 The ResultOf field provides the results computed by the analyzers
154 required by this one, as expressed in its Analyzer.Requires field. The
155 driver runs the required analyzers first and makes their results
156 available in this map. Each Analyzer must return a value of the type
157 described in its Analyzer.ResultType field.
158 For example, the "ctrlflow" analyzer returns a *ctrlflow.CFGs, which
159 provides a control-flow graph for each function in the package (see
160 golang.org/x/tools/go/cfg); the "inspect" analyzer returns a value that
161 enables other Analyzers to traverse the syntax trees of the package more
162 efficiently; and the "buildssa" analyzer constructs an SSA-form
163 intermediate representation.
164 Each of these Analyzers extends the capabilities of later Analyzers
165 without adding a dependency to the core API, so an analysis tool pays
166 only for the extensions it needs.
167
168 The Report function emits a diagnostic, a message associated with a
169 source position. For most analyses, diagnostics are their primary
170 result.
171 For convenience, Pass provides a helper method, Reportf, to report a new
172 diagnostic by formatting a string.
173 Diagnostic is defined as:
174
175         type Diagnostic struct {
176                 Pos      token.Pos
177                 Category string // optional
178                 Message  string
179         }
180
181 The optional Category field is a short identifier that classifies the
182 kind of message when an analysis produces several kinds of diagnostic.
183
184 Many analyses want to associate diagnostics with a severity level.
185 Because Diagnostic does not have a severity level field, an Analyzer's
186 diagnostics effectively all have the same severity level. To separate which
187 diagnostics are high severity and which are low severity, expose multiple
188 Analyzers instead. Analyzers should also be separated when their
189 diagnostics belong in different groups, or could be tagged differently
190 before being shown to the end user. Analyzers should document their severity
191 level to help downstream tools surface diagnostics properly.
192
193 Most Analyzers inspect typed Go syntax trees, but a few, such as asmdecl
194 and buildtag, inspect the raw text of Go source files or even non-Go
195 files such as assembly. To report a diagnostic against a line of a
196 raw text file, use the following sequence:
197
198         content, err := ioutil.ReadFile(filename)
199         if err != nil { ... }
200         tf := fset.AddFile(filename, -1, len(content))
201         tf.SetLinesForContent(content)
202         ...
203         pass.Reportf(tf.LineStart(line), "oops")
204
205
206 Modular analysis with Facts
207
208 To improve efficiency and scalability, large programs are routinely
209 built using separate compilation: units of the program are compiled
210 separately, and recompiled only when one of their dependencies changes;
211 independent modules may be compiled in parallel. The same technique may
212 be applied to static analyses, for the same benefits. Such analyses are
213 described as "modular".
214
215 A compiler’s type checker is an example of a modular static analysis.
216 Many other checkers we would like to apply to Go programs can be
217 understood as alternative or non-standard type systems. For example,
218 vet's printf checker infers whether a function has the "printf wrapper"
219 type, and it applies stricter checks to calls of such functions. In
220 addition, it records which functions are printf wrappers for use by
221 later analysis passes to identify other printf wrappers by induction.
222 A result such as “f is a printf wrapper” that is not interesting by
223 itself but serves as a stepping stone to an interesting result (such as
224 a diagnostic) is called a "fact".
225
226 The analysis API allows an analysis to define new types of facts, to
227 associate facts of these types with objects (named entities) declared
228 within the current package, or with the package as a whole, and to query
229 for an existing fact of a given type associated with an object or
230 package.
231
232 An Analyzer that uses facts must declare their types:
233
234         var Analyzer = &analysis.Analyzer{
235                 Name:      "printf",
236                 FactTypes: []analysis.Fact{new(isWrapper)},
237                 ...
238         }
239
240         type isWrapper struct{} // => *types.Func f “is a printf wrapper”
241
242 The driver program ensures that facts for a pass’s dependencies are
243 generated before analyzing the package and is responsible for propagating
244 facts from one package to another, possibly across address spaces.
245 Consequently, Facts must be serializable. The API requires that drivers
246 use the gob encoding, an efficient, robust, self-describing binary
247 protocol. A fact type may implement the GobEncoder/GobDecoder interfaces
248 if the default encoding is unsuitable. Facts should be stateless.
249
250 The Pass type has functions to import and export facts,
251 associated either with an object or with a package:
252
253         type Pass struct {
254                 ...
255                 ExportObjectFact func(types.Object, Fact)
256                 ImportObjectFact func(types.Object, Fact) bool
257
258                 ExportPackageFact func(fact Fact)
259                 ImportPackageFact func(*types.Package, Fact) bool
260         }
261
262 An Analyzer may only export facts associated with the current package or
263 its objects, though it may import facts from any package or object that
264 is an import dependency of the current package.
265
266 Conceptually, ExportObjectFact(obj, fact) inserts fact into a hidden map keyed by
267 the pair (obj, TypeOf(fact)), and the ImportObjectFact function
268 retrieves the entry from this map and copies its value into the variable
269 pointed to by fact. This scheme assumes that the concrete type of fact
270 is a pointer; this assumption is checked by the Validate function.
271 See the "printf" analyzer for an example of object facts in action.
272
273 Some driver implementations (such as those based on Bazel and Blaze) do
274 not currently apply analyzers to packages of the standard library.
275 Therefore, for best results, analyzer authors should not rely on
276 analysis facts being available for standard packages.
277 For example, although the printf checker is capable of deducing during
278 analysis of the log package that log.Printf is a printf wrapper,
279 this fact is built in to the analyzer so that it correctly checks
280 calls to log.Printf even when run in a driver that does not apply
281 it to standard packages. We would like to remove this limitation in future.
282
283
284 Testing an Analyzer
285
286 The analysistest subpackage provides utilities for testing an Analyzer.
287 In a few lines of code, it is possible to run an analyzer on a package
288 of testdata files and check that it reported all the expected
289 diagnostics and facts (and no more). Expectations are expressed using
290 "// want ..." comments in the input code.
291
292
293 Standalone commands
294
295 Analyzers are provided in the form of packages that a driver program is
296 expected to import. The vet command imports a set of several analyzers,
297 but users may wish to define their own analysis commands that perform
298 additional checks. To simplify the task of creating an analysis command,
299 either for a single analyzer or for a whole suite, we provide the
300 singlechecker and multichecker subpackages.
301
302 The singlechecker package provides the main function for a command that
303 runs one analyzer. By convention, each analyzer such as
304 go/passes/findcall should be accompanied by a singlechecker-based
305 command such as go/analysis/passes/findcall/cmd/findcall, defined in its
306 entirety as:
307
308         package main
309
310         import (
311                 "golang.org/x/tools/go/analysis/passes/findcall"
312                 "golang.org/x/tools/go/analysis/singlechecker"
313         )
314
315         func main() { singlechecker.Main(findcall.Analyzer) }
316
317 A tool that provides multiple analyzers can use multichecker in a
318 similar way, giving it the list of Analyzers.
319
320 */
321 package analysis