Source file src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.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 analysis 6 7 import ( 8 "flag" 9 "fmt" 10 "go/ast" 11 "go/token" 12 "go/types" 13 "reflect" 14 "time" 15 ) 16 17 // An Analyzer describes an analysis function and its options. 18 type Analyzer struct { 19 // The Name of the analyzer must be a valid Go identifier 20 // as it may appear in command-line flags, URLs, and so on. 21 Name string 22 23 // Doc is the documentation for the analyzer. 24 // The part before the first "\n\n" is the title 25 // (no capital or period, max ~60 letters). 26 Doc string 27 28 // URL holds an optional link to a web page with additional 29 // documentation for this analyzer. 30 URL string 31 32 // Flags defines any flags accepted by the analyzer. 33 // The manner in which these flags are exposed to the user 34 // depends on the driver which runs the analyzer. 35 Flags flag.FlagSet 36 37 // Run applies the analyzer to a package. 38 // It returns an error if the analyzer failed. 39 // 40 // On success, the Run function may return a result 41 // computed by the Analyzer; its type must match ResultType. 42 // The driver makes this result available as an input to 43 // another Analyzer that depends directly on this one (see 44 // Requires) when it analyzes the same package. 45 // 46 // To pass analysis results between packages (and thus 47 // potentially between address spaces), use Facts, which are 48 // serializable. 49 Run func(*Pass) (any, error) 50 51 // RunDespiteErrors allows the driver to invoke 52 // the Run method of this analyzer even on a 53 // package that contains parse or type errors. 54 // The [Pass.TypeErrors] field may consequently be non-empty. 55 RunDespiteErrors bool 56 57 // Requires is a set of analyzers that must run successfully 58 // before this one on a given package. This analyzer may inspect 59 // the outputs produced by each analyzer in Requires. 60 // The graph over analyzers implied by Requires edges must be acyclic. 61 // 62 // Requires establishes a "horizontal" dependency between 63 // analysis passes (different analyzers, same package). 64 Requires []*Analyzer 65 66 // ResultType is the type of the optional result of the Run function. 67 ResultType reflect.Type 68 69 // FactTypes indicates that this analyzer imports and exports 70 // Facts of the specified concrete types. 71 // An analyzer that uses facts may assume that its import 72 // dependencies have been similarly analyzed before it runs. 73 // Facts must be pointers. 74 // 75 // FactTypes establishes a "vertical" dependency between 76 // analysis passes (same analyzer, different packages). 77 FactTypes []Fact 78 } 79 80 func (a *Analyzer) String() string { return a.Name } 81 82 // A Pass provides information to the Run function that 83 // applies a specific analyzer to a single Go package. 84 // 85 // It forms the interface between the analysis logic and the driver 86 // program, and has both input and an output components. 87 // 88 // As in a compiler, one pass may depend on the result computed by another. 89 // 90 // The Run function should not call any of the Pass functions concurrently. 91 type Pass struct { 92 Analyzer *Analyzer // the identity of the current analyzer 93 94 // syntax and type information 95 Fset *token.FileSet // file position information; Run may add new files 96 Files []*ast.File // the abstract syntax tree of each file 97 OtherFiles []string // names of non-Go files of this package 98 IgnoredFiles []string // names of ignored source files in this package 99 Pkg *types.Package // type information about the package 100 TypesInfo *types.Info // type information about the syntax trees 101 TypesSizes types.Sizes // function for computing sizes of types 102 TypeErrors []types.Error // type errors (only if Analyzer.RunDespiteErrors) 103 104 Module *Module // the package's enclosing module (possibly nil in some drivers) 105 106 // Report reports a Diagnostic, a finding about a specific location 107 // in the analyzed source code such as a potential mistake. 108 // It may be called by the Run function. 109 Report func(Diagnostic) 110 111 // ResultOf provides the inputs to this analysis pass, which are 112 // the corresponding results of its prerequisite analyzers. 113 // The map keys are the elements of Analysis.Required, 114 // and the type of each corresponding value is the required 115 // analysis's ResultType. 116 ResultOf map[*Analyzer]any 117 118 // ReadFile returns the contents of the named file. 119 // 120 // The only valid file names are the elements of OtherFiles 121 // and IgnoredFiles, and names returned by 122 // Fset.File(f.FileStart).Name() for each f in Files. 123 // 124 // Analyzers must use this function (if provided) instead of 125 // accessing the file system directly. This allows a driver to 126 // provide a virtualized file tree (including, for example, 127 // unsaved editor buffers) and to track dependencies precisely 128 // to avoid unnecessary recomputation. 129 ReadFile func(filename string) ([]byte, error) 130 131 // -- facts -- 132 133 // ImportObjectFact retrieves a fact associated with obj. 134 // Given a value ptr of type *T, where *T satisfies Fact, 135 // ImportObjectFact copies the value to *ptr. 136 // 137 // ImportObjectFact panics if called after the pass is complete. 138 // ImportObjectFact is not concurrency-safe. 139 ImportObjectFact func(obj types.Object, fact Fact) bool 140 141 // ImportPackageFact retrieves a fact associated with package pkg, 142 // which must be this package or one of its dependencies. 143 // See comments for ImportObjectFact. 144 ImportPackageFact func(pkg *types.Package, fact Fact) bool 145 146 // ExportObjectFact associates a fact of type *T with the obj, 147 // replacing any previous fact of that type. 148 // 149 // ExportObjectFact panics if it is called after the pass is 150 // complete, or if obj does not belong to the package being analyzed. 151 // ExportObjectFact is not concurrency-safe. 152 ExportObjectFact func(obj types.Object, fact Fact) 153 154 // ExportPackageFact associates a fact with the current package. 155 // See comments for ExportObjectFact. 156 ExportPackageFact func(fact Fact) 157 158 // AllPackageFacts returns a new slice containing all package 159 // facts of the analysis's FactTypes in unspecified order. 160 // See comments for AllObjectFacts. 161 AllPackageFacts func() []PackageFact 162 163 // AllObjectFacts returns a new slice containing all object 164 // facts of the analysis's FactTypes in unspecified order. 165 // 166 // The result includes all facts exported by packages 167 // whose symbols are referenced by the current package 168 // (by qualified identifiers or field/method selections). 169 // And it includes all facts exported from the current 170 // package by the current analysis pass. 171 AllObjectFacts func() []ObjectFact 172 173 /* Further fields may be added in future. */ 174 } 175 176 // PackageFact is a package together with an associated fact. 177 type PackageFact struct { 178 Package *types.Package 179 Fact Fact 180 } 181 182 // ObjectFact is an object together with an associated fact. 183 type ObjectFact struct { 184 Object types.Object 185 Fact Fact 186 } 187 188 // Reportf is a helper function that reports a Diagnostic using the 189 // specified position and formatted error message. 190 func (pass *Pass) Reportf(pos token.Pos, format string, args ...any) { 191 msg := fmt.Sprintf(format, args...) 192 pass.Report(Diagnostic{Pos: pos, Message: msg}) 193 } 194 195 // The Range interface provides a range. It's equivalent to and satisfied by 196 // ast.Node. 197 type Range interface { 198 Pos() token.Pos // position of first character belonging to the node 199 End() token.Pos // position of first character immediately after the node 200 } 201 202 // ReportRangef is a helper function that reports a Diagnostic using the 203 // range provided. ast.Node values can be passed in as the range because 204 // they satisfy the Range interface. 205 func (pass *Pass) ReportRangef(rng Range, format string, args ...any) { 206 msg := fmt.Sprintf(format, args...) 207 pass.Report(Diagnostic{Pos: rng.Pos(), End: rng.End(), Message: msg}) 208 } 209 210 func (pass *Pass) String() string { 211 return fmt.Sprintf("%s@%s", pass.Analyzer.Name, pass.Pkg.Path()) 212 } 213 214 // A Fact is an intermediate fact produced during analysis. 215 // 216 // Each fact is associated with a named declaration (a types.Object) or 217 // with a package as a whole. A single object or package may have 218 // multiple associated facts, but only one of any particular fact type. 219 // 220 // A Fact represents a predicate such as "never returns", but does not 221 // represent the subject of the predicate such as "function F" or "package P". 222 // 223 // Facts may be produced in one analysis pass and consumed by another 224 // analysis pass even if these are in different address spaces. 225 // If package P imports Q, all facts about Q produced during 226 // analysis of that package will be available during later analysis of P. 227 // Facts are analogous to type export data in a build system: 228 // just as export data enables separate compilation of several passes, 229 // facts enable "separate analysis". 230 // 231 // Each pass (a, p) starts with the set of facts produced by the 232 // same analyzer a applied to the packages directly imported by p. 233 // The analysis may add facts to the set, and they may be exported in turn. 234 // An analysis's Run function may retrieve facts by calling 235 // Pass.Import{Object,Package}Fact and update them using 236 // Pass.Export{Object,Package}Fact. 237 // 238 // A fact is logically private to its Analysis. To pass values 239 // between different analyzers, use the results mechanism; 240 // see Analyzer.Requires, Analyzer.ResultType, and Pass.ResultOf. 241 // 242 // A Fact type must be a pointer. 243 // Facts are encoded and decoded using encoding/gob. 244 // A Fact may implement the GobEncoder/GobDecoder interfaces 245 // to customize its encoding. Fact encoding should not fail. 246 // 247 // A Fact should not be modified once exported. 248 type Fact interface { 249 AFact() // dummy method to avoid type errors 250 } 251 252 // A Module describes the module to which a package belongs. 253 type Module struct { 254 Path string // module path 255 Version string // module version ("" if unknown, such as for workspace modules) 256 Replace *Module // replaced by this module 257 Time *time.Time // time version was created 258 Main bool // is this the main module? 259 Indirect bool // is this module only an indirect dependency of main module? 260 Dir string // directory holding files for this module, if any 261 GoMod string // path to go.mod file used when loading this module, if any 262 GoVersion string // go version used in module (e.g. "go1.22.0") 263 Error *ModuleError // error loading module 264 } 265 266 // ModuleError holds errors loading a module. 267 type ModuleError struct { 268 Err string // the error itself 269 } 270