Skip to content

Commit

Permalink
Fixes #3
Browse files Browse the repository at this point in the history
- allow focus option as import path with pkg name as fallback
- now shows error when focus pkg not found
- fixed some coloring issues when focusing pkg in stdlib
- minor changes in coloring
  • Loading branch information
ondrajz committed Jan 15, 2017
1 parent 2f87717 commit 9f1dd3b
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 58 deletions.
2 changes: 1 addition & 1 deletion dot.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const tmplGraph = `digraph gocallvis {
fontname="Ubuntu";
fontsize="13";
rankdir="LR";
bgcolor="gainsboro";
bgcolor="lightgray";
style="solid";
penwidth="0.5";
pad="0.0";
Expand Down
Binary file modified examples/images/main.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/images/syncthing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/images/syncthing_focus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/images/syncthing_group.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/images/syncthing_ignore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
90 changes: 54 additions & 36 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,52 +71,58 @@ func main() {
}
}

func run(ctxt *build.Context, focusPkg, limitPath string, groupBy map[string]bool, ignorePaths []string, tests bool, args []string) error {
conf := loader.Config{Build: ctxt}

func run(ctxt *build.Context, focus, limitPath string, groupBy map[string]bool, ignorePaths []string, tests bool, args []string) error {
if len(args) == 0 {
return fmt.Errorf("missing arguments")
}

t0 := time.Now()
conf := loader.Config{Build: ctxt}
_, err := conf.FromArgs(args, tests)
if err != nil {
return err
}
iprog, err := conf.Load()
load, err := conf.Load()
if err != nil {
return err
}
logf("load took: %v", time.Since(t0))
logf("loading took: %v", time.Since(t0))
logf("%d imported (%d created)", len(load.Imported), len(load.Created))

t0 = time.Now()
prog := ssautil.CreateProgram(iprog, 0)
prog := ssautil.CreateProgram(load, 0)
prog.Build()
logf("build took: %v", time.Since(t0))

t0 = time.Now()
mains, err := mainPackages(prog, tests)
if err != nil {
return err
}
logf("%d mains", len(mains))
ptrcfg := &pointer.Config{
Mains: mains,
BuildCallGraph: true,
}
result, err := pointer.Analyze(ptrcfg)
if err != nil {
return err
}
logf("analysis took: %v", time.Since(t0))

return printOutput(mains[0].Pkg, result.CallGraph,
focusPkg, limitPath, ignorePaths, groupBy)
}

func mainPackages(prog *ssa.Program, tests bool) ([]*ssa.Package, error) {
pkgs := prog.AllPackages()
logf("%d packages", len(pkgs))
logf("building took: %v", time.Since(t0))

var focusPkg *build.Package
if focus != "" {
focusPkg, err = conf.Build.Import(focus, "", 0)
if err != nil {
if strings.Contains(focus, "/") {
return err
}
// try to find package by name
var foundPaths []string
for _, p := range pkgs {
if p.Pkg.Name() == focus {
foundPaths = append(foundPaths, p.Pkg.Path())
}
}
if len(foundPaths) == 0 {
return err
} else if len(foundPaths) > 1 {
for _, p := range foundPaths {
fmt.Fprintf(os.Stderr, " - %s\n", p)
}
return fmt.Errorf("found %d packages with name %q, use import path not name", len(foundPaths), focus)
}
if focusPkg, err = conf.Build.Import(foundPaths[0], "", 0); err != nil {
return err
}
}
logf("focusing: %v", focusPkg.ImportPath)
}

var mains []*ssa.Package
if tests {
Expand All @@ -126,17 +132,29 @@ func mainPackages(prog *ssa.Program, tests bool) ([]*ssa.Package, error) {
}
}
if mains == nil {
return nil, fmt.Errorf("no tests")
return fmt.Errorf("no tests")
}
} else {
mains = append(mains, ssautil.MainPackages(pkgs)...)
if len(mains) == 0 {
return fmt.Errorf("no main packages")
}
return mains, nil
}
logf("%d packages (%d main)", len(pkgs), len(mains))

mains = append(mains, ssautil.MainPackages(pkgs)...)
if len(mains) == 0 {
return nil, fmt.Errorf("no main packages")
t0 = time.Now()
ptrcfg := &pointer.Config{
Mains: mains,
BuildCallGraph: true,
}
result, err := pointer.Analyze(ptrcfg)
if err != nil {
return err
}
logf("analysis took: %v", time.Since(t0))

return mains, nil
return printOutput(mains[0].Pkg, result.CallGraph,
focusPkg, limitPath, ignorePaths, groupBy)
}

func logf(f string, a ...interface{}) {
Expand Down
46 changes: 25 additions & 21 deletions output.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,22 @@ import (

var output io.Writer = os.Stdout

func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg, limitPath string, ignorePaths []string, groupBy map[string]bool) error {
func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg *build.Package, limitPath string, ignorePaths []string, groupBy map[string]bool) error {
groupType := groupBy["type"]
groupPkg := groupBy["pkg"]

cluster := NewDotCluster("focus")
cluster.Attrs = dotAttrs{
"label": focusPkg,
"bgcolor": "aliceblue",
"bgcolor": "white",
"label": "",
"labelloc": "t",
"labeljust": "c",
"fontsize": "18",
}
if focusPkg != nil {
cluster.Attrs["bgcolor"] = "#e6ecfa"
cluster.Attrs["label"] = focusPkg.Name
}

nodes := []*dotNode{}
edges := []*dotEdge{}
Expand All @@ -48,8 +52,8 @@ func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg, limitPat
calleePkg := callee.Func.Pkg.Pkg

// focus specific pkg
if focusPkg != "" &&
!(callerPkg.Name() == focusPkg || calleePkg.Name() == focusPkg) {
if focusPkg != nil &&
!(callerPkg.Path() == focusPkg.ImportPath || calleePkg.Path() == focusPkg.ImportPath) {
return nil
}

Expand All @@ -74,6 +78,8 @@ func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg, limitPat
return n
}

isFocused := focusPkg != nil &&
node.Func.Pkg.Pkg.Path() == focusPkg.ImportPath
attrs := make(dotAttrs)

// node label
Expand All @@ -93,16 +99,16 @@ func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg, limitPat

pkg, _ := build.Import(node.Func.Pkg.Pkg.Path(), "", 0)
// set node color
if pkg.Goroot {
attrs["fillcolor"] = "#adedad"
} else if node.Func.Pkg.Pkg.Name() == focusPkg {
if isFocused {
attrs["fillcolor"] = "lightblue"
} else if pkg.Goroot {
attrs["fillcolor"] = "#adedad"
} else {
attrs["fillcolor"] = "wheat"
attrs["fillcolor"] = "moccasin"
}

// include pkg name
if !groupPkg && node.Func.Pkg.Pkg.Name() != focusPkg {
if !groupPkg && !isFocused {
label = fmt.Sprintf("%s\n%s", node.Func.Pkg.Pkg.Name(), label)
}

Expand All @@ -120,7 +126,7 @@ func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg, limitPat
c := cluster

// group by pkg
if groupPkg && node.Func.Pkg.Pkg.Name() != focusPkg {
if groupPkg && !isFocused {
label := node.Func.Pkg.Pkg.Name()
if pkg.Goroot {
label = node.Func.Pkg.Pkg.Path()
Expand All @@ -135,7 +141,7 @@ func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg, limitPat
"fontsize": "16",
"label": label,
"style": "filled",
"fillcolor": "snow",
"fillcolor": "lightyellow",
},
}
if pkg.Goroot {
Expand All @@ -148,10 +154,6 @@ func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg, limitPat
// group by type
if groupType && sign.Recv() != nil {
label := strings.Split(node.Func.RelString(node.Func.Pkg.Pkg), ".")[0]
fillclr := "lemonchiffon"
if node.Func.Pkg.Pkg.Name() == focusPkg {
fillclr = "lavender"
}
key := sign.Recv().Type().String()
if _, ok := c.Clusters[key]; !ok {
c.Clusters[key] = &dotCluster{
Expand All @@ -164,11 +166,13 @@ func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg, limitPat
"label": label,
"labelloc": "b",
"style": "rounded,filled",
"fillcolor": fillclr,
"fillcolor": "wheat2",
},
}
if pkg.Goroot {
c.Clusters[key].Attrs["fillcolor"] = "#c4ecc4"
if isFocused {
c.Clusters[key].Attrs["fillcolor"] = "lightsteelblue"
} else if pkg.Goroot {
c.Clusters[key].Attrs["fillcolor"] = "#c2e3c2"
}
}
c = c.Clusters[key]
Expand Down Expand Up @@ -208,8 +212,8 @@ func printOutput(mainPkg *types.Package, cg *callgraph.Graph, focusPkg, limitPat
}

// colorize calls outside focused pkg
if focusPkg != "" &&
(calleePkg.Name() != focusPkg || callerPkg.Name() != focusPkg) {
if focusPkg != nil &&
(calleePkg.Path() != focusPkg.ImportPath || callerPkg.Path() != focusPkg.ImportPath) {
attrs["color"] = "saddlebrown"
}

Expand Down

0 comments on commit 9f1dd3b

Please sign in to comment.