godoctor: github.com/godoctor/godoctor/analysis/dataflow Index | Examples | Files

package dataflow

import "github.com/godoctor/godoctor/analysis/dataflow"

Package dataflow provides data flow analyses that can be performed on a previously constructed control flow graph, including a reaching definitions analysis and a live variables analysis for local variables.



Package Files

dataflow.go live.go print_dot.go reaching.go

func DefUse Uses

func DefUse(cfg *cfg.CFG, info *loader.PackageInfo) map[ast.Stmt]map[ast.Stmt]struct{}

DefUse builds reaching definitions for a given control flow graph, returning a map that maps each statement that defines a variable (i.e., declares or assigns it) to the set of statements that use that variable.

Note: An assignment to a struct field or array element is treated as both a use and a definition of that variable, since only part of its value is assigned. For analysis purposes, it's treated as though the entire value is read, then part of it is modified, then the entire value is assigned back to the variable. (This is necessary for the analysis to produce correct results.)

No nodes from the cfg.Defers list will be returned in the output of this function as they are disjoint from a cfg's blocks. For analyzing the statements in the cfg.Defers list, each defer should be treated as though it has the same in and out sets as the cfg.Exit node.

func DefsReaching Uses

func DefsReaching(stmt ast.Stmt, cfg *cfg.CFG, info *loader.PackageInfo) map[ast.Stmt]struct{}

DefsReaching builds reaching definitions for a given control flow graph, returning the set of statements that define a variable (i.e., declare or assign it) where that definition reaches the given statement.

func LiveVars Uses

func LiveVars(cfg *cfg.CFG, info *loader.PackageInfo) (in, out map[ast.Stmt]map[*types.Var]struct{})

LiveAt returns the in and out set of live variables for each block in a given control flow graph (cfg) in the context of a loader.Program, including the cfg.Entry and cfg.Exit nodes.

The traditional approach of holding the live variables at the exit node to the empty set has been deviated from in order to handle defers. The live variables in set of the cfg.Exit node will be set to the variables used in all cfg.Defers. No liveness is analyzed for the cfg.Defers themselves.

More formally:

IN[EXIT] = USE(each d in cfg.Defers)
OUT[EXIT] = {}


src := `
package main

import "fmt"

func main() {
  a := 1
  b := 2
  c := 3
  a := b
  a, b := b, a
  c := a + b

// use own loader config, this is just necessary
var config loader.Config
f, err := config.ParseFile("testing", src)
if err != nil {
    return // probably don't proceed
config.CreateFromFiles("testing", f)
prog, err := config.Load()
if err != nil {

funcOne := f.Decls[1].(*ast.FuncDecl)
cfg := cfg.FromFunc(funcOne)
in, out := dataflow.LiveVars(cfg, prog.Created[0])

ast.Inspect(f, func(n ast.Node) bool {
    switch stmt := n.(type) {
    case ast.Stmt:
        _, _ = in[stmt], out[stmt]
        // do as you please
    return true

func PrintDefUseDot Uses

func PrintDefUseDot(f io.Writer, fset *token.FileSet, info *loader.PackageInfo, cfg *cfg.CFG)

PrintDefUseDot prints a GraphViz DOT file showing the control flow graph with definition-use links superimposed.

This is used by the debug refactoring.

func PrintLiveVarsDot Uses

func PrintLiveVarsDot(f io.Writer, fset *token.FileSet, info *loader.PackageInfo, cfg *cfg.CFG)

PrintLiveVarsDot prints a GraphViz DOT file showing the control flow graph with information about the liveness of local variables superimposed.

This is used by the debug refactoring.

func ReferencedVars Uses

func ReferencedVars(stmts []ast.Stmt, info *loader.PackageInfo) (asgt, updt, decl, use map[*types.Var]struct{})

ReferencedVars returns the sets of local variables that are defined or used within the given list of statements (based on syntax).

func Vars Uses

func Vars(node ast.Node, info *loader.PackageInfo) map[*types.Var]struct{}

Vars returns the set of variables appearing in node

Package dataflow imports 14 packages (graph) and is imported by 2 packages. Updated 2018-05-07. Refresh now. Tools for package owners.