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()