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)
}
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 != "" {

View File

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

View File

@ -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,

View File

@ -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 <root>
}
conf.Fset = fset
conf.result = &callstackResult{
q.Fset = fset
q.result = &callstackResult{
qpos: qpos,
target: target,
callpath: callpath,

View File

@ -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) {

View File

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

View File

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

View File

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