go.tools/call: rename package to go/callgraph

Was:		Now:
call.Graph	callgraph.Graph
call.GraphNode	callgraph.Node
call.Edge	callgraph.Edge

Though call.Graph was cute, the original naming was a mistake:
'call' is too useful a var name to waste on a package.

R=gri, crawshaw
CC=golang-codereviews
https://golang.org/cl/53190043
This commit is contained in:
Alan Donovan 2014-01-16 14:04:19 -05:00
parent 3fc0fc1310
commit b856247075
11 changed files with 62 additions and 62 deletions

View File

@ -4,7 +4,7 @@
/* /*
Package call defines the call graph abstraction and various algorithms Package callgraph defines the call graph abstraction and various algorithms
and utilities to operate on it. It does not provide a concrete and utilities to operate on it. It does not provide a concrete
implementation but permits other analyses (such as pointer analyses or implementation but permits other analyses (such as pointer analyses or
Rapid Type Analysis) to expose their own call graphs in a Rapid Type Analysis) to expose their own call graphs in a
@ -56,7 +56,7 @@ in the call graph; they are treated like built-in operators of the
language. language.
*/ */
package call package callgraph
import "code.google.com/p/go.tools/go/ssa" import "code.google.com/p/go.tools/go/ssa"
@ -67,14 +67,14 @@ import "code.google.com/p/go.tools/go/ssa"
// functions. // functions.
// //
type Graph interface { type Graph interface {
Root() GraphNode // the distinguished root node Root() Node // the distinguished root node
Nodes() []GraphNode // new unordered set of all nodes Nodes() []Node // new unordered set of all nodes
} }
// A GraphNode represents a node in a call graph. // A Node represents a node in a call graph.
// //
// If the call graph is context sensitive, there may be multiple // If the call graph is context sensitive, there may be multiple
// GraphNodes with the same Func(); the identity of the graph node // Nodes with the same Func(); the identity of the graph node
// indicates the context. // indicates the context.
// //
// Sites returns the set of syntactic call sites within this function. // Sites returns the set of syntactic call sites within this function.
@ -94,7 +94,7 @@ type Graph interface {
// //
// Clients should not mutate the node via the results of its methods. // Clients should not mutate the node via the results of its methods.
// //
type GraphNode interface { type Node interface {
Func() *ssa.Function // the function this node represents Func() *ssa.Function // the function this node represents
Sites() []ssa.CallInstruction // new unordered set of call sites within this function Sites() []ssa.CallInstruction // new unordered set of call sites within this function
Edges() []Edge // new unordered set of outgoing edges Edges() []Edge // new unordered set of outgoing edges
@ -102,7 +102,7 @@ type GraphNode interface {
// A Edge represents an edge in the call graph. // A Edge represents an edge in the call graph.
type Edge struct { type Edge struct {
Caller GraphNode Caller Node
Site ssa.CallInstruction Site ssa.CallInstruction
Callee GraphNode Callee Node
} }

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package call package callgraph
// This file provides various representation-independent utilities // This file provides various representation-independent utilities
// over call graphs, such as visitation and path search. // over call graphs, such as visitation and path search.
@ -13,7 +13,7 @@ package call
// FindSitesByPos(g Graph, lparen token.Pos) []Site // FindSitesByPos(g Graph, lparen token.Pos) []Site
// FindSitesByCallExpr(g Graph, expr *ast.CallExpr) []Site // FindSitesByCallExpr(g Graph, expr *ast.CallExpr) []Site
// FindSitesByInstr(g Graph, instr ssa.CallInstruction) []Site // FindSitesByInstr(g Graph, instr ssa.CallInstruction) []Site
// FindNodesByFunc(g Graph, fn *ssa.Function) []GraphNode // FindNodesByFunc(g Graph, fn *ssa.Function) []Node
// (Counterargument: they're all inefficient linear scans; if the // (Counterargument: they're all inefficient linear scans; if the
// caller does it explicitly there may be opportunities to optimize. // caller does it explicitly there may be opportunities to optimize.
// //
@ -22,8 +22,8 @@ package call
// CalleesOf returns a new set containing all direct callees of the // CalleesOf returns a new set containing all direct callees of the
// caller node. // caller node.
// //
func CalleesOf(caller GraphNode) map[GraphNode]bool { func CalleesOf(caller Node) map[Node]bool {
callees := make(map[GraphNode]bool) callees := make(map[Node]bool)
for _, e := range caller.Edges() { for _, e := range caller.Edges() {
callees[e.Callee] = true callees[e.Callee] = true
} }
@ -36,9 +36,9 @@ func CalleesOf(caller GraphNode) map[GraphNode]bool {
// value. // value.
// //
func GraphVisitEdges(g Graph, edge func(Edge) error) error { func GraphVisitEdges(g Graph, edge func(Edge) error) error {
seen := make(map[GraphNode]bool) seen := make(map[Node]bool)
var visit func(n GraphNode) error var visit func(n Node) error
visit = func(n GraphNode) error { visit = func(n Node) error {
if !seen[n] { if !seen[n] {
seen[n] = true seen[n] = true
for _, e := range n.Edges() { for _, e := range n.Edges() {
@ -65,11 +65,11 @@ func GraphVisitEdges(g Graph, edge func(Edge) error) error {
// PathSearch returns the path as an ordered list of edges; on // PathSearch returns the path as an ordered list of edges; on
// failure, it returns nil. // failure, it returns nil.
// //
func PathSearch(start GraphNode, isEnd func(GraphNode) bool) []Edge { func PathSearch(start Node, isEnd func(Node) bool) []Edge {
stack := make([]Edge, 0, 32) stack := make([]Edge, 0, 32)
seen := make(map[GraphNode]bool) seen := make(map[Node]bool)
var search func(n GraphNode) []Edge var search func(n Node) []Edge
search = func(n GraphNode) []Edge { search = func(n Node) []Edge {
if !seen[n] { if !seen[n] {
seen[n] = true seen[n] = true
if isEnd(n) { if isEnd(n) {

View File

@ -10,7 +10,7 @@ import (
"go/token" "go/token"
"io" "io"
"code.google.com/p/go.tools/call" "code.google.com/p/go.tools/go/callgraph"
"code.google.com/p/go.tools/go/ssa" "code.google.com/p/go.tools/go/ssa"
"code.google.com/p/go.tools/go/types/typemap" "code.google.com/p/go.tools/go/types/typemap"
) )
@ -107,7 +107,7 @@ type Warning struct {
// See Config for how to request the various Result components. // See Config for how to request the various Result components.
// //
type Result struct { type Result struct {
CallGraph call.Graph // discovered call graph CallGraph callgraph.Graph // discovered call graph
Queries map[ssa.Value][]Pointer // pts(v) for each v in Config.Queries. Queries map[ssa.Value][]Pointer // pts(v) for each v in Config.Queries.
IndirectQueries map[ssa.Value][]Pointer // pts(*v) for each v in Config.IndirectQueries. IndirectQueries map[ssa.Value][]Pointer // pts(*v) for each v in Config.IndirectQueries.
Warnings []Warning // warnings of unsoundness Warnings []Warning // warnings of unsoundness
@ -220,7 +220,7 @@ func (p Pointer) String() string {
// Context returns the context of this pointer, // Context returns the context of this pointer,
// if it corresponds to a local variable. // if it corresponds to a local variable.
func (p Pointer) Context() call.GraphNode { func (p Pointer) Context() callgraph.Node {
return p.cgn return p.cgn
} }

View File

@ -4,35 +4,35 @@
package pointer package pointer
// This file defines our implementation of the call.Graph API. // This file defines our implementation of the callgraph API.
import ( import (
"fmt" "fmt"
"go/token" "go/token"
"code.google.com/p/go.tools/call" "code.google.com/p/go.tools/go/callgraph"
"code.google.com/p/go.tools/go/ssa" "code.google.com/p/go.tools/go/ssa"
) )
// cgraph implements call.Graph. // cgraph implements callgraph.Graph.
type cgraph struct { type cgraph struct {
root *cgnode root *cgnode
nodes []*cgnode nodes []*cgnode
} }
func (g *cgraph) Nodes() []call.GraphNode { func (g *cgraph) Nodes() []callgraph.Node {
nodes := make([]call.GraphNode, len(g.nodes)) nodes := make([]callgraph.Node, len(g.nodes))
for i, node := range g.nodes { for i, node := range g.nodes {
nodes[i] = node nodes[i] = node
} }
return nodes return nodes
} }
func (g *cgraph) Root() call.GraphNode { func (g *cgraph) Root() callgraph.Node {
return g.root return g.root
} }
// cgnode implements call.GraphNode. // cgnode implements callgraph.Node.
type cgnode struct { type cgnode struct {
fn *ssa.Function fn *ssa.Function
obj nodeid // start of this contour's object block obj nodeid // start of this contour's object block
@ -52,16 +52,16 @@ func (n *cgnode) Sites() []ssa.CallInstruction {
return sites return sites
} }
func (n *cgnode) Edges() []call.Edge { func (n *cgnode) Edges() []callgraph.Edge {
var numEdges int var numEdges int
for _, site := range n.sites { for _, site := range n.sites {
numEdges += len(site.callees) numEdges += len(site.callees)
} }
edges := make([]call.Edge, 0, numEdges) edges := make([]callgraph.Edge, 0, numEdges)
for _, site := range n.sites { for _, site := range n.sites {
for _, callee := range site.callees { for _, callee := range site.callees {
edges = append(edges, call.Edge{Caller: n, Site: site.instr, Callee: callee}) edges = append(edges, callgraph.Edge{Caller: n, Site: site.instr, Callee: callee})
} }
} }
return edges return edges

View File

@ -8,7 +8,7 @@ import (
"fmt" "fmt"
"sort" "sort"
"code.google.com/p/go.tools/call" "code.google.com/p/go.tools/go/callgraph"
"code.google.com/p/go.tools/go/loader" "code.google.com/p/go.tools/go/loader"
"code.google.com/p/go.tools/go/pointer" "code.google.com/p/go.tools/go/pointer"
"code.google.com/p/go.tools/go/ssa" "code.google.com/p/go.tools/go/ssa"
@ -75,7 +75,7 @@ func main() {
// By converting to strings, we de-duplicate nodes // By converting to strings, we de-duplicate nodes
// representing the same function due to context sensitivity. // representing the same function due to context sensitivity.
var edges []string var edges []string
call.GraphVisitEdges(result.CallGraph, func(edge call.Edge) error { callgraph.GraphVisitEdges(result.CallGraph, func(edge callgraph.Edge) error {
caller := edge.Caller.Func() caller := edge.Caller.Func()
if caller.Pkg == mainPkg { if caller.Pkg == mainPkg {
edges = append(edges, fmt.Sprint(caller, " --> ", edge.Callee.Func())) edges = append(edges, fmt.Sprint(caller, " --> ", edge.Callee.Func()))

View File

@ -9,7 +9,7 @@ import (
"go/token" "go/token"
"strings" "strings"
"code.google.com/p/go.tools/call" "code.google.com/p/go.tools/go/callgraph"
"code.google.com/p/go.tools/go/ssa" "code.google.com/p/go.tools/go/ssa"
"code.google.com/p/go.tools/go/types" "code.google.com/p/go.tools/go/types"
) )
@ -57,7 +57,7 @@ func (l Label) ReflectType() types.Type {
// Context returns the analytic context in which this label's object was allocated, // Context returns the analytic context in which this label's object was allocated,
// or nil for global objects: global, const, and shared contours for functions. // or nil for global objects: global, const, and shared contours for functions.
// //
func (l Label) Context() call.GraphNode { func (l Label) Context() callgraph.Node {
return l.obj.cgn return l.obj.cgn
} }

View File

@ -21,7 +21,7 @@ import (
"strings" "strings"
"testing" "testing"
"code.google.com/p/go.tools/call" "code.google.com/p/go.tools/go/callgraph"
"code.google.com/p/go.tools/go/loader" "code.google.com/p/go.tools/go/loader"
"code.google.com/p/go.tools/go/pointer" "code.google.com/p/go.tools/go/pointer"
"code.google.com/p/go.tools/go/ssa" "code.google.com/p/go.tools/go/ssa"
@ -451,9 +451,9 @@ func checkTypesExpectation(e *expectation, ptr pointer.Pointer, typ types.Type)
var errOK = errors.New("OK") var errOK = errors.New("OK")
func checkCallsExpectation(prog *ssa.Program, e *expectation, callgraph call.Graph) bool { func checkCallsExpectation(prog *ssa.Program, e *expectation, cg callgraph.Graph) bool {
found := make(map[string]int) found := make(map[string]int)
err := call.GraphVisitEdges(callgraph, func(edge call.Edge) error { err := callgraph.GraphVisitEdges(cg, func(edge callgraph.Edge) error {
// Name-based matching is inefficient but it allows us to // Name-based matching is inefficient but it allows us to
// match functions whose names that would not appear in an // match functions whose names that would not appear in an
// index ("<root>") or which are not unique ("func@1.2"). // index ("<root>") or which are not unique ("func@1.2").

View File

@ -8,7 +8,7 @@ import (
"fmt" "fmt"
"go/token" "go/token"
"code.google.com/p/go.tools/call" "code.google.com/p/go.tools/go/callgraph"
"code.google.com/p/go.tools/go/ssa" "code.google.com/p/go.tools/go/ssa"
"code.google.com/p/go.tools/oracle/serial" "code.google.com/p/go.tools/oracle/serial"
) )
@ -37,9 +37,9 @@ func callers(o *Oracle, qpos *QueryPos) (queryResult, error) {
// Run the pointer analysis, recording each // Run the pointer analysis, recording each
// call found to originate from target. // call found to originate from target.
o.ptaConfig.BuildCallGraph = true o.ptaConfig.BuildCallGraph = true
callgraph := ptrAnalysis(o).CallGraph cg := ptrAnalysis(o).CallGraph
var edges []call.Edge var edges []callgraph.Edge
call.GraphVisitEdges(callgraph, func(edge call.Edge) error { callgraph.GraphVisitEdges(cg, func(edge callgraph.Edge) error {
if edge.Callee.Func() == target { if edge.Callee.Func() == target {
edges = append(edges, edge) edges = append(edges, edge)
} }
@ -49,15 +49,15 @@ func callers(o *Oracle, qpos *QueryPos) (queryResult, error) {
return &callersResult{ return &callersResult{
target: target, target: target,
callgraph: callgraph, callgraph: cg,
edges: edges, edges: edges,
}, nil }, nil
} }
type callersResult struct { type callersResult struct {
target *ssa.Function target *ssa.Function
callgraph call.Graph callgraph callgraph.Graph
edges []call.Edge edges []callgraph.Edge
} }
func (r *callersResult) display(printf printfFunc) { func (r *callersResult) display(printf printfFunc) {

View File

@ -8,12 +8,12 @@ import (
"go/token" "go/token"
"sort" "sort"
"code.google.com/p/go.tools/call" "code.google.com/p/go.tools/go/callgraph"
"code.google.com/p/go.tools/go/ssa" "code.google.com/p/go.tools/go/ssa"
"code.google.com/p/go.tools/oracle/serial" "code.google.com/p/go.tools/oracle/serial"
) )
// callgraph displays the entire callgraph of the current program. // doCallgraph displays the entire callgraph of the current program.
// //
// Nodes may be seem to appear multiple times due to (limited) // Nodes may be seem to appear multiple times due to (limited)
// context sensitivity. // context sensitivity.
@ -28,7 +28,7 @@ import (
// //
// TODO(adonovan): elide nodes for synthetic functions? // TODO(adonovan): elide nodes for synthetic functions?
// //
func callgraph(o *Oracle, _ *QueryPos) (queryResult, error) { func doCallgraph(o *Oracle, _ *QueryPos) (queryResult, error) {
buildSSA(o) buildSSA(o)
// Run the pointer analysis and build the complete callgraph. // Run the pointer analysis and build the complete callgraph.
@ -41,7 +41,7 @@ func callgraph(o *Oracle, _ *QueryPos) (queryResult, error) {
} }
type callgraphResult struct { type callgraphResult struct {
callgraph call.Graph callgraph callgraph.Graph
} }
func (r *callgraphResult) display(printf printfFunc) { func (r *callgraphResult) display(printf printfFunc) {
@ -57,9 +57,9 @@ Non-numbered nodes indicate back- or cross-edges to the node whose
ci := make(map[*ssa.Function]map[*ssa.Function]bool) ci := make(map[*ssa.Function]map[*ssa.Function]bool)
// 1. Visit the CS call graph and build the CI call graph. // 1. Visit the CS call graph and build the CI call graph.
visited := make(map[call.GraphNode]bool) visited := make(map[callgraph.Node]bool)
var visit func(caller call.GraphNode) var visit func(caller callgraph.Node)
visit = func(caller call.GraphNode) { visit = func(caller callgraph.Node) {
if !visited[caller] { if !visited[caller] {
visited[caller] = true visited[caller] = true
@ -113,7 +113,7 @@ func (s funcsByName) Less(i, j int) bool { return s[i].String() < s[j].String()
func (r *callgraphResult) toSerial(res *serial.Result, fset *token.FileSet) { func (r *callgraphResult) toSerial(res *serial.Result, fset *token.FileSet) {
nodes := r.callgraph.Nodes() nodes := r.callgraph.Nodes()
numbering := make(map[call.GraphNode]int) numbering := make(map[callgraph.Node]int)
for i, n := range nodes { for i, n := range nodes {
numbering[n] = i numbering[n] = i
} }
@ -124,7 +124,7 @@ func (r *callgraphResult) toSerial(res *serial.Result, fset *token.FileSet) {
fn := n.Func() fn := n.Func()
j.Name = fn.String() j.Name = fn.String()
j.Pos = fset.Position(fn.Pos()).String() j.Pos = fset.Position(fn.Pos()).String()
for callee := range call.CalleesOf(n) { for callee := range callgraph.CalleesOf(n) {
j.Children = append(j.Children, numbering[callee]) j.Children = append(j.Children, numbering[callee])
} }
sort.Ints(j.Children) sort.Ints(j.Children)

View File

@ -8,7 +8,7 @@ import (
"fmt" "fmt"
"go/token" "go/token"
"code.google.com/p/go.tools/call" "code.google.com/p/go.tools/go/callgraph"
"code.google.com/p/go.tools/go/ssa" "code.google.com/p/go.tools/go/ssa"
"code.google.com/p/go.tools/oracle/serial" "code.google.com/p/go.tools/oracle/serial"
) )
@ -42,11 +42,11 @@ func callstack(o *Oracle, qpos *QueryPos) (queryResult, error) {
// Run the pointer analysis and build the complete call graph. // Run the pointer analysis and build the complete call graph.
o.ptaConfig.BuildCallGraph = true o.ptaConfig.BuildCallGraph = true
callgraph := ptrAnalysis(o).CallGraph cg := ptrAnalysis(o).CallGraph
// Search for an arbitrary path from a root to the target function. // Search for an arbitrary path from a root to the target function.
isEnd := func(n call.GraphNode) bool { return n.Func() == target } isEnd := func(n callgraph.Node) bool { return n.Func() == target }
callpath := call.PathSearch(callgraph.Root(), isEnd) callpath := callgraph.PathSearch(cg.Root(), isEnd)
if callpath != nil { if callpath != nil {
callpath = callpath[1:] // remove synthetic edge from <root> callpath = callpath[1:] // remove synthetic edge from <root>
} }
@ -61,7 +61,7 @@ func callstack(o *Oracle, qpos *QueryPos) (queryResult, error) {
type callstackResult struct { type callstackResult struct {
qpos *QueryPos qpos *QueryPos
target *ssa.Function target *ssa.Function
callpath []call.Edge callpath []callgraph.Edge
} }
func (r *callstackResult) display(printf printfFunc) { func (r *callstackResult) display(printf printfFunc) {

View File

@ -97,7 +97,7 @@ var modes = []*modeInfo{
// Pointer analyses, whole program: // Pointer analyses, whole program:
{"callees", needPTA | needExactPos, callees}, {"callees", needPTA | needExactPos, callees},
{"callers", needPTA | needPos, callers}, {"callers", needPTA | needPos, callers},
{"callgraph", needPTA, callgraph}, {"callgraph", needPTA, doCallgraph},
{"callstack", needPTA | needPos, callstack}, {"callstack", needPTA | needPos, callstack},
{"peers", needPTA | needSSADebug | needPos, peers}, {"peers", needPTA | needSSADebug | needPos, peers},
{"pointsto", needPTA | needSSADebug | needExactPos, pointsto}, {"pointsto", needPTA | needSSADebug | needExactPos, pointsto},