oracle: factor part of the initial setup for PTA queries

The check for len(argv)==0 now only applies to these modes.

Also, more consistent variable naming.

Change-Id: I9adb6bebc819eb43d54ddf63c42d952671ce9236
Reviewed-on: https://go-review.googlesource.com/8244
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
Alan Donovan 2015-03-30 15:44:25 -04:00
parent b28839e4bd
commit a27f5b3448
8 changed files with 50 additions and 69 deletions

View File

@ -122,11 +122,6 @@ func main() {
os.Exit(2) os.Exit(2)
} }
if len(args) == 0 && mode != "what" {
fmt.Fprint(os.Stderr, "oracle: no package arguments.\n"+useHelp)
os.Exit(2)
}
// Set up points-to analysis log file. // Set up points-to analysis log file.
var ptalog io.Writer var ptalog io.Writer
if *ptalogFlag != "" { if *ptalogFlag != "" {

View File

@ -22,14 +22,9 @@ import (
func callees(q *Query) error { func callees(q *Query) error {
lconf := loader.Config{Build: q.Build} lconf := loader.Config{Build: q.Build}
// Determine initial packages for PTA. if err := setPTAScope(&lconf, q.Scope); err != nil {
args, err := lconf.FromArgs(q.Scope, true)
if err != nil {
return err return err
} }
if len(args) > 0 {
return fmt.Errorf("surplus arguments: %q", args)
}
// Load/parse/type-check the program. // Load/parse/type-check the program.
lprog, err := lconf.Load() lprog, err := lconf.Load()

View File

@ -17,33 +17,28 @@ import (
// Callers reports the possible callers of the function // Callers reports the possible callers of the function
// immediately enclosing the specified source location. // immediately enclosing the specified source location.
// //
func callers(conf *Query) error { func callers(q *Query) error {
lconf := loader.Config{Build: conf.Build} lconf := loader.Config{Build: q.Build}
// Determine initial packages for PTA. if err := setPTAScope(&lconf, q.Scope); err != nil {
args, err := lconf.FromArgs(conf.Scope, true)
if err != nil {
return err return err
} }
if len(args) > 0 {
return fmt.Errorf("surplus arguments: %q", args)
}
// Load/parse/type-check the program. // Load/parse/type-check the program.
lprog, err := lconf.Load() lprog, err := lconf.Load()
if err != nil { if err != nil {
return err return err
} }
conf.Fset = lprog.Fset q.Fset = lprog.Fset
qpos, err := parseQueryPos(lprog, conf.Pos, false) qpos, err := parseQueryPos(lprog, q.Pos, false)
if err != nil { if err != nil {
return err return err
} }
prog := ssa.Create(lprog, 0) prog := ssa.Create(lprog, 0)
ptaConfig, err := setupPTA(prog, lprog, conf.PTALog, conf.Reflection) ptaConfig, err := setupPTA(prog, lprog, q.PTALog, q.Reflection)
if err != nil { if err != nil {
return err return err
} }
@ -72,7 +67,7 @@ func callers(conf *Query) error {
edges := cg.CreateNode(target).In edges := cg.CreateNode(target).In
// TODO(adonovan): sort + dedup calls to ensure test determinism. // TODO(adonovan): sort + dedup calls to ensure test determinism.
conf.result = &callersResult{ q.result = &callersResult{
target: target, target: target,
callgraph: cg, callgraph: cg,
edges: edges, edges: edges,

View File

@ -24,18 +24,13 @@ import (
// TODO(adonovan): permit user to specify a starting point other than // TODO(adonovan): permit user to specify a starting point other than
// the analysis root. // the analysis root.
// //
func callstack(conf *Query) error { func callstack(q *Query) error {
fset := token.NewFileSet() fset := token.NewFileSet()
lconf := loader.Config{Fset: fset, Build: conf.Build} lconf := loader.Config{Fset: fset, Build: q.Build}
// Determine initial packages for PTA. if err := setPTAScope(&lconf, q.Scope); err != nil {
args, err := lconf.FromArgs(conf.Scope, true)
if err != nil {
return err return err
} }
if len(args) > 0 {
return fmt.Errorf("surplus arguments: %q", args)
}
// Load/parse/type-check the program. // Load/parse/type-check the program.
lprog, err := lconf.Load() lprog, err := lconf.Load()
@ -43,14 +38,14 @@ func callstack(conf *Query) error {
return err return err
} }
qpos, err := parseQueryPos(lprog, conf.Pos, false) qpos, err := parseQueryPos(lprog, q.Pos, false)
if err != nil { if err != nil {
return err return err
} }
prog := ssa.Create(lprog, 0) prog := ssa.Create(lprog, 0)
ptaConfig, err := setupPTA(prog, lprog, conf.PTALog, conf.Reflection) ptaConfig, err := setupPTA(prog, lprog, q.PTALog, q.Reflection)
if err != nil { if err != nil {
return err return err
} }
@ -84,8 +79,8 @@ func callstack(conf *Query) error {
callpath = callpath[1:] // remove synthetic edge from <root> callpath = callpath[1:] // remove synthetic edge from <root>
} }
conf.Fset = fset q.Fset = fset
conf.result = &callstackResult{ q.result = &callstackResult{
qpos: qpos, qpos: qpos,
target: target, target: target,
callpath: callpath, callpath: callpath,

View File

@ -77,7 +77,7 @@ type Query struct {
Build *build.Context // package loading configuration Build *build.Context // package loading configuration
// pointer analysis options // pointer analysis options
Scope []string // main package in (*loader.Config).FromArgs syntax Scope []string // main packages in (*loader.Config).FromArgs syntax
PTALog io.Writer // (optional) pointer-analysis log file PTALog io.Writer // (optional) pointer-analysis log file
Reflection bool // model reflection soundly (currently slow). Reflection bool // model reflection soundly (currently slow).
@ -105,37 +105,53 @@ func (q *Query) WriteTo(out io.Writer) {
} }
// Run runs an oracle query and populates its Fset and Result. // Run runs an oracle query and populates its Fset and Result.
func Run(conf *Query) error { func Run(q *Query) error {
switch conf.Mode { switch q.Mode {
case "callees": case "callees":
return callees(conf) return callees(q)
case "callers": case "callers":
return callers(conf) return callers(q)
case "callstack": case "callstack":
return callstack(conf) return callstack(q)
case "peers": case "peers":
return peers(conf) return peers(q)
case "pointsto": case "pointsto":
return pointsto(conf) return pointsto(q)
case "whicherrs": case "whicherrs":
return whicherrs(conf) return whicherrs(q)
case "definition": case "definition":
return definition(conf) return definition(q)
case "describe": case "describe":
return describe(conf) return describe(q)
case "freevars": case "freevars":
return freevars(conf) return freevars(q)
case "implements": case "implements":
return implements(conf) return implements(q)
case "referrers": case "referrers":
return referrers(conf) return referrers(q)
case "what": case "what":
return what(conf) return what(q)
default: default:
return fmt.Errorf("invalid mode: %q", conf.Mode) return fmt.Errorf("invalid mode: %q", q.Mode)
} }
} }
func setPTAScope(lconf *loader.Config, scope []string) error {
if len(scope) == 0 {
return fmt.Errorf("no packages specified for pointer analysis scope")
}
// Determine initial packages for PTA.
args, err := lconf.FromArgs(scope, true)
if err != nil {
return err
}
if len(args) > 0 {
return fmt.Errorf("surplus arguments: %q", args)
}
return nil
}
// Create a pointer.Config whose scope is the initial packages of lprog // Create a pointer.Config whose scope is the initial packages of lprog
// and their dependencies. // and their dependencies.
func setupPTA(prog *ssa.Program, lprog *loader.Program, ptaLog io.Writer, reflection bool) (*pointer.Config, error) { func setupPTA(prog *ssa.Program, lprog *loader.Program, ptaLog io.Writer, reflection bool) (*pointer.Config, error) {

View File

@ -26,14 +26,9 @@ import (
func peers(q *Query) error { func peers(q *Query) error {
lconf := loader.Config{Build: q.Build} lconf := loader.Config{Build: q.Build}
// Determine initial packages for PTA. if err := setPTAScope(&lconf, q.Scope); err != nil {
args, err := lconf.FromArgs(q.Scope, true)
if err != nil {
return err return err
} }
if len(args) > 0 {
return fmt.Errorf("surplus arguments: %q", args)
}
// Load/parse/type-check the program. // Load/parse/type-check the program.
lprog, err := lconf.Load() lprog, err := lconf.Load()

View File

@ -28,14 +28,9 @@ import (
func pointsto(q *Query) error { func pointsto(q *Query) error {
lconf := loader.Config{Build: q.Build} lconf := loader.Config{Build: q.Build}
// Determine initial packages for PTA. if err := setPTAScope(&lconf, q.Scope); err != nil {
args, err := lconf.FromArgs(q.Scope, true)
if err != nil {
return err return err
} }
if len(args) > 0 {
return fmt.Errorf("surplus arguments: %q", args)
}
// Load/parse/type-check the program. // Load/parse/type-check the program.
lprog, err := lconf.Load() lprog, err := lconf.Load()

View File

@ -31,14 +31,9 @@ var builtinErrorType = types.Universe.Lookup("error").Type()
func whicherrs(q *Query) error { func whicherrs(q *Query) error {
lconf := loader.Config{Build: q.Build} lconf := loader.Config{Build: q.Build}
// Determine initial packages for PTA. if err := setPTAScope(&lconf, q.Scope); err != nil {
args, err := lconf.FromArgs(q.Scope, true)
if err != nil {
return err return err
} }
if len(args) > 0 {
return fmt.Errorf("surplus arguments: %q", args)
}
// Load/parse/type-check the program. // Load/parse/type-check the program.
lprog, err := lconf.Load() lprog, err := lconf.Load()