Go Analysis Framework: modular static analysis by go team

AbuAssar3 pts0 comments

analysis package - golang.org/x/tools/go/analysis - Go Packages

analysis

package

Version:<br>v0.48.0

Opens a new window with list of versions in this module.

Latest

Latest

This package is not in the latest version of its module.

Go to latest

Published: Jul 9, 2026

License: BSD-3-Clause

Opens a new window with license information.

Imports: 9

Opens a new window with list of imports.

Imported by: 6,564

Opens a new window with list of known importers.

Main

Versions

Licenses

Imports

Imported By

Details

Valid go.mod file

The Go module system was introduced in Go 1.11 and is the official dependency management<br>solution for Go.

Redistributable license

Redistributable licenses place minimal restrictions on how software can be used,<br>modified, and redistributed.

Tagged version

Modules with tagged versions give importers more predictable builds.

Stable version

When a project reaches major version v1 it is considered stable.

Learn more about best practices

Repository

cs.opensource.google/go/x/tools

Links

Report a Vulnerability

Open Source Insights

Code Wiki

Documentation

Overview ¶

Background

Analyzer

Pass

Modular analysis with Facts

Testing an Analyzer

Standalone commands

Package analysis defines the interface between a modular static<br>analysis and an analysis driver program.

Background ¶<br>A static analysis is a function that inspects a package of Go code and<br>reports a set of diagnostics (typically mistakes in the code), and<br>perhaps produces other results as well, such as suggested refactorings<br>or other facts. An analysis that reports mistakes is informally called a<br>"checker". For example, the printf checker reports mistakes in<br>fmt.Printf format strings.

A "modular" analysis is one that inspects one package at a time but can<br>save information from a lower-level package and use it when inspecting a<br>higher-level package, analogous to separate compilation in a toolchain.<br>The printf checker is modular: when it discovers that a function such as<br>log.Fatalf delegates to fmt.Printf, it records this fact, and checks<br>calls to that function too, including calls made from another package.

By implementing a common interface, checkers from a variety of sources<br>can be easily selected, incorporated, and reused in a wide range of<br>driver programs including command-line tools (such as vet), text editors and<br>IDEs, build and test systems (such as go build, Bazel, or Buck), test<br>frameworks, code review tools, code-base indexers (such as SourceGraph),<br>documentation viewers (such as godoc), batch pipelines for large code<br>bases, and so on.

Analyzer ¶<br>The primary type in the API is Analyzer. An Analyzer statically<br>describes an analysis function: its name, documentation, flags,<br>relationship to other analyzers, and of course, its logic.

To define an analysis, a user declares a (logically constant) variable<br>of type Analyzer. Here is a typical example from one of the analyzers in<br>the go/analysis/passes/ subdirectory:

package unusedresult

var Analyzer = &analysis.Analyzer{<br>Name: "unusedresult",<br>Doc: "check for unused results of calls to some functions",<br>Run: run,<br>...

func run(pass *analysis.Pass) (interface{}, error) {<br>...<br>An analysis driver is a program such as vet that runs a set of<br>analyses and prints the diagnostics that they report.<br>The driver program must import the list of Analyzers it needs.<br>Typically each Analyzer resides in a separate package.<br>To add a new Analyzer to an existing driver, add another item to the list:

import ( "unusedresult"; "nilness"; "printf" )

var analyses = []*analysis.Analyzer{<br>unusedresult.Analyzer,<br>nilness.Analyzer,<br>printf.Analyzer,<br>A driver may use the name, flags, and documentation to provide on-line<br>help that describes the analyses it performs.<br>The doc comment contains a brief one-line summary,<br>optionally followed by paragraphs of explanation.

The Analyzer type has more fields besides those shown above:

type Analyzer struct {<br>Name string<br>Doc string<br>Flags flag.FlagSet<br>Run func(*Pass) (interface{}, error)<br>RunDespiteErrors bool<br>ResultType reflect.Type<br>Requires []*Analyzer<br>FactTypes []Fact<br>The Flags field declares a set of named (global) flag variables that<br>control analysis behavior. Unlike vet, analysis flags are not declared<br>directly in the command line FlagSet; it is up to the driver to set the<br>flag variables. A driver for a single analysis, a, might expose its flag<br>f directly on the command line as -f, whereas a driver for multiple<br>analyses might prefix the flag name by the analysis name (-a.f) to avoid<br>ambiguity. An IDE might expose the flags through a graphical interface,<br>and a batch pipeline might configure them from a config file.<br>See the "findcall" analyzer for an example of flags in action.

The RunDespiteErrors flag indicates whether the analysis is equipped to<br>handle ill-typed code. If not, the driver will skip the analysis if<br>there were parse or type errors.<br>The optional ResultType field specifies the type of the result value<br>computed by this analysis...

analysis analyzer package driver code type

Related Articles