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:
parent
b28839e4bd
commit
a27f5b3448
|
|
@ -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 != "" {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue