package excfg

import "golang.org/x/tools/internal/excfg"

Package excfg constructs control-flow graphs of statements and expressions in a Go function, including intra-expression control flow.

Index

Types

type Block

type Block struct {
	Kind ExKind

	// Node is a statement, expression, or ast.ValueSpec.
	//
	// An expression may contain sub-expressions computed in preceding blocks of
	// type ExKindBool and ExKindCall. Each sub-expression block is used by
	// exactly one other block, though that block may not be an immediate
	// successor. All sub-expressions must be used at the end of an ExKindStmt
	// or ExKindIf block. A sub-expression block will have a lower Index than
	// the block that consumes the sub-expression.
	Node ast.Node

	// Succs is a list of successor nodes. The length and interpretation of this
	// depends on Kind.
	Succs []*Block

	// Use is set to the block that consumes the value of this sub-expression
	// block. Only set for ExKindSubExpr and ExKindBool.
	Use *Block

	// Index is the index of this block in ExCFG.Blocks.
	Index int32

	// CFGBlock is the index of the cfg.Block this expression block was derived
	// from.
	CFGBlock int32
	// contains filtered or unexported fields
}

func (*Block) String

func (b *Block) String() string

type CFG

type CFG struct {
	Blocks []*Block

	Fset *token.FileSet
	// contains filtered or unexported fields
}

CFG is a control flow graph over [ast.Node]s, including control flow within expressions. Beyond the statement-level control flow represented by cfg.CFG, this graph contains a separate block for every statement, every call (even within an expression), and for each branch of short-circuiting operators.

AST nodes that purely affect control flow may not appear in any block. For example, in "if x && y { ... }", neither the "if" statement nor the "&&" node will appear, as both are translated into pure control flow.

CFG implements graph.Graph[int] and is a compact graph.

func New

func New(cfg *cfg.CFG, fset *token.FileSet) *CFG

func (*CFG) IsCompact

func (c *CFG) IsCompact() bool

func (*CFG) Nodes

func (c *CFG) Nodes() iter.Seq[int]

Nodes yields the indexes of all blocks in c. This is simply the sequence [0, NumNodes()).

func (*CFG) NumNodes

func (c *CFG) NumNodes() int

NumNodes returns the number of blocks in c.

func (*CFG) Out

func (c *CFG) Out(block int) iter.Seq[int]

Out yields the indexes of the successors of block.

func (*CFG) String

func (cfg *CFG) String() string

String formats the control-flow graph for ease of debugging.

func (*CFG) Subexprs

func (g *CFG) Subexprs(b *Block) []*Block

Subexprs returns the preceding sub-expression blocks consumed by b. This is the inverse of [Block.Use]. The slice is in ast.Inspect order for b.Node.

type ExKind

type ExKind int8
const (
	ExKindInvalid ExKind = iota

	// An ExKindStmt ExBlock is a statement, expression, or ValueSpec with no
	// value. It has 0 or 1 successors. It consumes any preceding sub-expression
	// values.
	ExKindStmt

	// An ExKindIf ExBlock is a boolean-typed expression that branches to one of
	// two successors. Like ExKindStmt, it consumes any preceding
	// sub-expressions. Successor 0 is the true branch and successor 1 is the
	// false branch.
	ExKindIf

	// An ExKindSubExpr ExBlock is a sub-expression whose value is used as part
	// of another ExBlock. It has exactly one successor.
	ExKindSubExpr

	// An ExKindBool ExBlock is a sub-expression whose value is used as part of
	// another ExBlock, like ExKindSubExpr, but it branches to two successors
	// based on the value of the sub-expression. Successor 0 is the true branch
	// and successor 1 is the false branch.
	ExKindBool
)

func (ExKind) String

func (i ExKind) String() string

Source Files

excfg.go exkind_string.go format.go

Version
v0.44.0 (latest)
Published
Apr 9, 2026
Platform
linux/amd64
Imports
14 packages
Last checked
1 hour ago

Tools for package owners.