github.com/jujuyuki/gospal@v1.0.1-0.20210215170718-af79fae13b20/ssa/print.go (about)

     1  package ssa
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"sort"
     7  
     8  	"golang.org/x/tools/go/ssa"
     9  )
    10  
    11  // members is slice of ssa.Member. Used only for sorting by Pos.
    12  type members []ssa.Member
    13  
    14  func (m members) Len() int           { return len(m) }
    15  func (m members) Less(i, j int) bool { return m[i].Pos() < m[j].Pos() }
    16  func (m members) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }
    17  
    18  // WriteTo writes Functions used by the Program to w in human readable SSA IR
    19  // instruction format.
    20  func (info *Info) WriteTo(w io.Writer) (int64, error) {
    21  	graph, err := info.BuildCallGraph("rta", false)
    22  	if err != nil {
    23  		return 0, err
    24  	}
    25  	funcs, err := graph.UsedFunctions()
    26  	if err != nil {
    27  		return 0, err
    28  	}
    29  	pkgFuncs := make(map[*ssa.Package]members)
    30  	ignoredPkg := make(map[string]bool)
    31  	for _, p := range info.IgnoredPkgs {
    32  		ignoredPkg[p] = true
    33  	}
    34  	for _, f := range funcs {
    35  		if _, ignored := ignoredPkg[f.Pkg.Pkg.Name()]; !ignored {
    36  			pkgFuncs[f.Pkg] = append(pkgFuncs[f.Pkg], f)
    37  		}
    38  	}
    39  	var n int64
    40  	for pkg := range pkgFuncs {
    41  		sort.Sort(pkgFuncs[pkg])
    42  		for _, f := range pkgFuncs[pkg] {
    43  			written, err := f.(*ssa.Function).WriteTo(w)
    44  			if err != nil {
    45  				return n, err
    46  			}
    47  			n += written
    48  		}
    49  	}
    50  	return n, nil
    51  }
    52  
    53  // WriteAll writes all Functions found in the Program to w in human readable SSA
    54  // IR instruction format.
    55  func (info *Info) WriteAll(w io.Writer) (int64, error) {
    56  	graph, err := info.BuildCallGraph("rta", false)
    57  	if err != nil {
    58  		return 0, err
    59  	}
    60  	funcs, err := graph.AllFunctions()
    61  	if err != nil {
    62  		return 0, err
    63  	}
    64  	pkgFuncs := make(map[*ssa.Package]members)
    65  	for _, f := range funcs {
    66  		pkgFuncs[f.Pkg] = append(pkgFuncs[f.Pkg], f)
    67  	}
    68  	var n int64
    69  	for pkg := range pkgFuncs {
    70  		sort.Sort(pkgFuncs[pkg])
    71  		for _, f := range pkgFuncs[pkg] {
    72  			written, err := f.(*ssa.Function).WriteTo(w)
    73  			if err != nil {
    74  				return n, err
    75  			}
    76  			n += written
    77  		}
    78  	}
    79  	return n, nil
    80  }
    81  
    82  // WriteFunc writes Functions specified by funcPath to w in human readable SSA
    83  // IR instruction format.
    84  func (info *Info) WriteFunc(w io.Writer, funcPath string) (int64, error) {
    85  	f, err := info.FindFunc(funcPath)
    86  	if err != nil {
    87  		return 0, err
    88  	}
    89  	if f == nil {
    90  		return 0, errors.New("function not found")
    91  	}
    92  	return f.WriteTo(w)
    93  }