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  

View as plain text