...

Package analysisinternal

import "cmd/vendor/golang.org/x/tools/internal/analysisinternal"
Overview
Index

Overview ▾

Package analysisinternal provides gopls' internal analyses with a number of helper functions that operate on typed syntax trees.

func AddImport

func AddImport(info *types.Info, file *ast.File, pos token.Pos, pkgpath, preferredName string) (name string, newImport analysis.TextEdit)

AddImport checks whether this file already imports pkgpath and that import is in scope at pos. If so, it returns the name under which it was imported and a zero edit. Otherwise, it adds a new import of pkgpath, using a name derived from the preferred name, and returns the chosen name along with the edit for the new import.

It does not mutate its arguments.

func CheckReadable

func CheckReadable(pass *analysis.Pass, filename string) error

CheckReadable enforces the access policy defined by the ReadFile field of analysis.Pass.

func ExtractDoc

func ExtractDoc(content, name string) (string, error)

ExtractDoc extracts a section of a package doc comment from the provided contents of an analyzer package's doc.go file.

A section is a portion of the comment between one heading and the next, using this form:

# Analyzer NAME

NAME: SUMMARY

Full description...

where NAME matches the name argument, and SUMMARY is a brief verb-phrase that describes the analyzer. The following lines, up until the next heading or the end of the comment, contain the full description. ExtractDoc returns the portion following the colon, which is the form expected by Analyzer.Doc.

Example:

# Analyzer printf

printf: checks consistency of calls to printf

The printf analyzer checks consistency of calls to printf.
Here is the complete description...

This notation allows a single doc comment to provide documentation for multiple analyzers, each in its own section. The HTML anchors generated for each heading are predictable.

It returns an error if the content was not a valid Go source file containing a package doc comment with a heading of the required form.

This machinery enables the package documentation (typically accessible via the web at https://pkg.go.dev/) and the command documentation (typically printed to a terminal) to be derived from the same source and formatted appropriately.

func IsZeroValue

func IsZeroValue(expr ast.Expr) bool

IsZeroValue checks whether the given expression is a 'zero value' (as determined by output of analysisinternal.ZeroValue)

func MakeReadFile

func MakeReadFile(pass *analysis.Pass) func(filename string) ([]byte, error)

MakeReadFile returns a simple implementation of the Pass.ReadFile function.

func MatchingIdents

func MatchingIdents(typs []types.Type, node ast.Node, pos token.Pos, info *types.Info, pkg *types.Package) map[types.Type][]string

MatchingIdents finds the names of all identifiers in 'node' that match any of the given types. 'pos' represents the position at which the identifiers may be inserted. 'pos' must be within the scope of each of identifier we select. Otherwise, we will insert a variable at 'pos' that is unrecognized.

func MustExtractDoc

func MustExtractDoc(content, name string) string

MustExtractDoc is like ExtractDoc but it panics on error.

To use, define a doc.go file such as:

// Package halting defines an analyzer of program termination.
//
// # Analyzer halting
//
// halting: reports whether execution will halt.
//
// The halting analyzer reports a diagnostic for functions
// that run forever. To suppress the diagnostics, try inserting
// a 'break' statement into each loop.
package halting

import _ "embed"

//go:embed doc.go
var doc string

And declare your analyzer as:

var Analyzer = &analysis.Analyzer{
	Name:             "halting",
	Doc:              analysisutil.MustExtractDoc(doc, "halting"),
	...
}

func StmtToInsertVarBefore

func StmtToInsertVarBefore(path []ast.Node) ast.Stmt

StmtToInsertVarBefore returns the ast.Stmt before which we can safely insert a new variable. Some examples:

Basic Example: z := 1 y := z + x If x is undeclared, then this function would return `y := z + x`, so that we can insert `x := ` on the line before `y := z + x`.

If stmt example: if z == 1 { } else if z == y {} If y is undeclared, then this function would return `if z == 1 {`, because we cannot insert a statement between an if and an else if statement. As a result, we need to find the top of the if chain to insert `y := ` before.

func TypeErrorEndPos

func TypeErrorEndPos(fset *token.FileSet, src []byte, start token.Pos) token.Pos

func TypeExpr

func TypeExpr(f *ast.File, pkg *types.Package, typ types.Type) ast.Expr

TypeExpr returns syntax for the specified type. References to named types from packages other than pkg are qualified by an appropriate package name, as defined by the import environment of file.

func WalkASTWithParent

func WalkASTWithParent(n ast.Node, f func(n ast.Node, parent ast.Node) bool)

WalkASTWithParent walks the AST rooted at n. The semantics are similar to ast.Inspect except it does not call f(nil).

func ZeroValue

func ZeroValue(f *ast.File, pkg *types.Package, typ types.Type) ast.Expr