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>
diff --git a/cmd/oracle/main.go b/cmd/oracle/main.go
index f950472..da411f6 100644
--- a/cmd/oracle/main.go
+++ b/cmd/oracle/main.go
@@ -122,11 +122,6 @@
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.
var ptalog io.Writer
if *ptalogFlag != "" {
diff --git a/oracle/callees.go b/oracle/callees.go
index e4b9f83..ee1d432 100644
--- a/oracle/callees.go
+++ b/oracle/callees.go
@@ -22,14 +22,9 @@
func callees(q *Query) error {
lconf := loader.Config{Build: q.Build}
- // Determine initial packages for PTA.
- args, err := lconf.FromArgs(q.Scope, true)
- if err != nil {
+ if err := setPTAScope(&lconf, q.Scope); err != nil {
return err
}
- if len(args) > 0 {
- return fmt.Errorf("surplus arguments: %q", args)
- }
// Load/parse/type-check the program.
lprog, err := lconf.Load()
diff --git a/oracle/callers.go b/oracle/callers.go
index e6836de..9633a0c 100644
--- a/oracle/callers.go
+++ b/oracle/callers.go
@@ -17,33 +17,28 @@
// Callers reports the possible callers of the function
// immediately enclosing the specified source location.
//
-func callers(conf *Query) error {
- lconf := loader.Config{Build: conf.Build}
+func callers(q *Query) error {
+ lconf := loader.Config{Build: q.Build}
- // Determine initial packages for PTA.
- args, err := lconf.FromArgs(conf.Scope, true)
- if err != nil {
+ if err := setPTAScope(&lconf, q.Scope); err != nil {
return err
}
- if len(args) > 0 {
- return fmt.Errorf("surplus arguments: %q", args)
- }
// Load/parse/type-check the program.
lprog, err := lconf.Load()
if err != nil {
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 {
return err
}
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 {
return err
}
@@ -72,7 +67,7 @@
edges := cg.CreateNode(target).In
// TODO(adonovan): sort + dedup calls to ensure test determinism.
- conf.result = &callersResult{
+ q.result = &callersResult{
target: target,
callgraph: cg,
edges: edges,
diff --git a/oracle/callstack.go b/oracle/callstack.go
index 5144a0c..05b6ae9 100644
--- a/oracle/callstack.go
+++ b/oracle/callstack.go
@@ -24,18 +24,13 @@
// TODO(adonovan): permit user to specify a starting point other than
// the analysis root.
//
-func callstack(conf *Query) error {
+func callstack(q *Query) error {
fset := token.NewFileSet()
- lconf := loader.Config{Fset: fset, Build: conf.Build}
+ lconf := loader.Config{Fset: fset, Build: q.Build}
- // Determine initial packages for PTA.
- args, err := lconf.FromArgs(conf.Scope, true)
- if err != nil {
+ if err := setPTAScope(&lconf, q.Scope); err != nil {
return err
}
- if len(args) > 0 {
- return fmt.Errorf("surplus arguments: %q", args)
- }
// Load/parse/type-check the program.
lprog, err := lconf.Load()
@@ -43,14 +38,14 @@
return err
}
- qpos, err := parseQueryPos(lprog, conf.Pos, false)
+ qpos, err := parseQueryPos(lprog, q.Pos, false)
if err != nil {
return err
}
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 {
return err
}
@@ -84,8 +79,8 @@
callpath = callpath[1:] // remove synthetic edge from <root>
}
- conf.Fset = fset
- conf.result = &callstackResult{
+ q.Fset = fset
+ q.result = &callstackResult{
qpos: qpos,
target: target,
callpath: callpath,
diff --git a/oracle/oracle.go b/oracle/oracle.go
index 7dda91c..0a30ad3 100644
--- a/oracle/oracle.go
+++ b/oracle/oracle.go
@@ -77,7 +77,7 @@
Build *build.Context // package loading configuration
// 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
Reflection bool // model reflection soundly (currently slow).
@@ -105,37 +105,53 @@
}
// Run runs an oracle query and populates its Fset and Result.
-func Run(conf *Query) error {
- switch conf.Mode {
+func Run(q *Query) error {
+ switch q.Mode {
case "callees":
- return callees(conf)
+ return callees(q)
case "callers":
- return callers(conf)
+ return callers(q)
case "callstack":
- return callstack(conf)
+ return callstack(q)
case "peers":
- return peers(conf)
+ return peers(q)
case "pointsto":
- return pointsto(conf)
+ return pointsto(q)
case "whicherrs":
- return whicherrs(conf)
+ return whicherrs(q)
case "definition":
- return definition(conf)
+ return definition(q)
case "describe":
- return describe(conf)
+ return describe(q)
case "freevars":
- return freevars(conf)
+ return freevars(q)
case "implements":
- return implements(conf)
+ return implements(q)
case "referrers":
- return referrers(conf)
+ return referrers(q)
case "what":
- return what(conf)
+ return what(q)
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
// and their dependencies.
func setupPTA(prog *ssa.Program, lprog *loader.Program, ptaLog io.Writer, reflection bool) (*pointer.Config, error) {
diff --git a/oracle/peers.go b/oracle/peers.go
index bcf56bc..350159c 100644
--- a/oracle/peers.go
+++ b/oracle/peers.go
@@ -26,14 +26,9 @@
func peers(q *Query) error {
lconf := loader.Config{Build: q.Build}
- // Determine initial packages for PTA.
- args, err := lconf.FromArgs(q.Scope, true)
- if err != nil {
+ if err := setPTAScope(&lconf, q.Scope); err != nil {
return err
}
- if len(args) > 0 {
- return fmt.Errorf("surplus arguments: %q", args)
- }
// Load/parse/type-check the program.
lprog, err := lconf.Load()
diff --git a/oracle/pointsto.go b/oracle/pointsto.go
index 949554a..eacd810 100644
--- a/oracle/pointsto.go
+++ b/oracle/pointsto.go
@@ -28,14 +28,9 @@
func pointsto(q *Query) error {
lconf := loader.Config{Build: q.Build}
- // Determine initial packages for PTA.
- args, err := lconf.FromArgs(q.Scope, true)
- if err != nil {
+ if err := setPTAScope(&lconf, q.Scope); err != nil {
return err
}
- if len(args) > 0 {
- return fmt.Errorf("surplus arguments: %q", args)
- }
// Load/parse/type-check the program.
lprog, err := lconf.Load()
diff --git a/oracle/whicherrs.go b/oracle/whicherrs.go
index 45fa143..3ca3fc9 100644
--- a/oracle/whicherrs.go
+++ b/oracle/whicherrs.go
@@ -31,14 +31,9 @@
func whicherrs(q *Query) error {
lconf := loader.Config{Build: q.Build}
- // Determine initial packages for PTA.
- args, err := lconf.FromArgs(q.Scope, true)
- if err != nil {
+ if err := setPTAScope(&lconf, q.Scope); err != nil {
return err
}
- if len(args) > 0 {
- return fmt.Errorf("surplus arguments: %q", args)
- }
// Load/parse/type-check the program.
lprog, err := lconf.Load()