From a27f5b3448cac6aa82f9fd4c1d71dc245593ddd5 Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Mon, 30 Mar 2015 15:44:25 -0400 Subject: [PATCH] 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 --- cmd/oracle/main.go | 5 ----- oracle/callees.go | 7 +------ oracle/callers.go | 19 +++++++----------- oracle/callstack.go | 19 +++++++----------- oracle/oracle.go | 48 ++++++++++++++++++++++++++++++--------------- oracle/peers.go | 7 +------ oracle/pointsto.go | 7 +------ oracle/whicherrs.go | 7 +------ 8 files changed, 50 insertions(+), 69 deletions(-) diff --git a/cmd/oracle/main.go b/cmd/oracle/main.go index f950472a..da411f63 100644 --- a/cmd/oracle/main.go +++ b/cmd/oracle/main.go @@ -122,11 +122,6 @@ func main() { 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 e4b9f836..ee1d4326 100644 --- a/oracle/callees.go +++ b/oracle/callees.go @@ -22,14 +22,9 @@ import ( 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 e6836de3..9633a0c7 100644 --- a/oracle/callers.go +++ b/oracle/callers.go @@ -17,33 +17,28 @@ import ( // 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 @@ func callers(conf *Query) error { 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 5144a0cc..05b6ae99 100644 --- a/oracle/callstack.go +++ b/oracle/callstack.go @@ -24,18 +24,13 @@ import ( // 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 @@ func callstack(conf *Query) error { 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 @@ func callstack(conf *Query) error { callpath = callpath[1:] // remove synthetic edge from } - 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 7dda91c5..0a30ad38 100644 --- a/oracle/oracle.go +++ b/oracle/oracle.go @@ -77,7 +77,7 @@ type Query struct { 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 @@ func (q *Query) WriteTo(out io.Writer) { } // 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 bcf56bcd..350159c1 100644 --- a/oracle/peers.go +++ b/oracle/peers.go @@ -26,14 +26,9 @@ import ( 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 949554aa..eacd810c 100644 --- a/oracle/pointsto.go +++ b/oracle/pointsto.go @@ -28,14 +28,9 @@ import ( 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 45fa1434..3ca3fc9f 100644 --- a/oracle/whicherrs.go +++ b/oracle/whicherrs.go @@ -31,14 +31,9 @@ var builtinErrorType = types.Universe.Lookup("error").Type() 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()