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)
|
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.
|
// Set up points-to analysis log file.
|
||||||
var ptalog io.Writer
|
var ptalog io.Writer
|
||||||
if *ptalogFlag != "" {
|
if *ptalogFlag != "" {
|
||||||
|
|
|
||||||
|
|
@ -22,14 +22,9 @@ import (
|
||||||
func callees(q *Query) error {
|
func callees(q *Query) error {
|
||||||
lconf := loader.Config{Build: q.Build}
|
lconf := loader.Config{Build: q.Build}
|
||||||
|
|
||||||
// Determine initial packages for PTA.
|
if err := setPTAScope(&lconf, q.Scope); err != nil {
|
||||||
args, err := lconf.FromArgs(q.Scope, true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(args) > 0 {
|
|
||||||
return fmt.Errorf("surplus arguments: %q", args)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load/parse/type-check the program.
|
// Load/parse/type-check the program.
|
||||||
lprog, err := lconf.Load()
|
lprog, err := lconf.Load()
|
||||||
|
|
|
||||||
|
|
@ -17,33 +17,28 @@ import (
|
||||||
// Callers reports the possible callers of the function
|
// Callers reports the possible callers of the function
|
||||||
// immediately enclosing the specified source location.
|
// immediately enclosing the specified source location.
|
||||||
//
|
//
|
||||||
func callers(conf *Query) error {
|
func callers(q *Query) error {
|
||||||
lconf := loader.Config{Build: conf.Build}
|
lconf := loader.Config{Build: q.Build}
|
||||||
|
|
||||||
// Determine initial packages for PTA.
|
if err := setPTAScope(&lconf, q.Scope); err != nil {
|
||||||
args, err := lconf.FromArgs(conf.Scope, true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(args) > 0 {
|
|
||||||
return fmt.Errorf("surplus arguments: %q", args)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load/parse/type-check the program.
|
// Load/parse/type-check the program.
|
||||||
lprog, err := lconf.Load()
|
lprog, err := lconf.Load()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
prog := ssa.Create(lprog, 0)
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +67,7 @@ func callers(conf *Query) error {
|
||||||
edges := cg.CreateNode(target).In
|
edges := cg.CreateNode(target).In
|
||||||
// TODO(adonovan): sort + dedup calls to ensure test determinism.
|
// TODO(adonovan): sort + dedup calls to ensure test determinism.
|
||||||
|
|
||||||
conf.result = &callersResult{
|
q.result = &callersResult{
|
||||||
target: target,
|
target: target,
|
||||||
callgraph: cg,
|
callgraph: cg,
|
||||||
edges: edges,
|
edges: edges,
|
||||||
|
|
|
||||||
|
|
@ -24,18 +24,13 @@ import (
|
||||||
// TODO(adonovan): permit user to specify a starting point other than
|
// TODO(adonovan): permit user to specify a starting point other than
|
||||||
// the analysis root.
|
// the analysis root.
|
||||||
//
|
//
|
||||||
func callstack(conf *Query) error {
|
func callstack(q *Query) error {
|
||||||
fset := token.NewFileSet()
|
fset := token.NewFileSet()
|
||||||
lconf := loader.Config{Fset: fset, Build: conf.Build}
|
lconf := loader.Config{Fset: fset, Build: q.Build}
|
||||||
|
|
||||||
// Determine initial packages for PTA.
|
if err := setPTAScope(&lconf, q.Scope); err != nil {
|
||||||
args, err := lconf.FromArgs(conf.Scope, true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(args) > 0 {
|
|
||||||
return fmt.Errorf("surplus arguments: %q", args)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load/parse/type-check the program.
|
// Load/parse/type-check the program.
|
||||||
lprog, err := lconf.Load()
|
lprog, err := lconf.Load()
|
||||||
|
|
@ -43,14 +38,14 @@ func callstack(conf *Query) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
qpos, err := parseQueryPos(lprog, conf.Pos, false)
|
qpos, err := parseQueryPos(lprog, q.Pos, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
prog := ssa.Create(lprog, 0)
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -84,8 +79,8 @@ func callstack(conf *Query) error {
|
||||||
callpath = callpath[1:] // remove synthetic edge from <root>
|
callpath = callpath[1:] // remove synthetic edge from <root>
|
||||||
}
|
}
|
||||||
|
|
||||||
conf.Fset = fset
|
q.Fset = fset
|
||||||
conf.result = &callstackResult{
|
q.result = &callstackResult{
|
||||||
qpos: qpos,
|
qpos: qpos,
|
||||||
target: target,
|
target: target,
|
||||||
callpath: callpath,
|
callpath: callpath,
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ type Query struct {
|
||||||
Build *build.Context // package loading configuration
|
Build *build.Context // package loading configuration
|
||||||
|
|
||||||
// pointer analysis options
|
// 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
|
PTALog io.Writer // (optional) pointer-analysis log file
|
||||||
Reflection bool // model reflection soundly (currently slow).
|
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.
|
// Run runs an oracle query and populates its Fset and Result.
|
||||||
func Run(conf *Query) error {
|
func Run(q *Query) error {
|
||||||
switch conf.Mode {
|
switch q.Mode {
|
||||||
case "callees":
|
case "callees":
|
||||||
return callees(conf)
|
return callees(q)
|
||||||
case "callers":
|
case "callers":
|
||||||
return callers(conf)
|
return callers(q)
|
||||||
case "callstack":
|
case "callstack":
|
||||||
return callstack(conf)
|
return callstack(q)
|
||||||
case "peers":
|
case "peers":
|
||||||
return peers(conf)
|
return peers(q)
|
||||||
case "pointsto":
|
case "pointsto":
|
||||||
return pointsto(conf)
|
return pointsto(q)
|
||||||
case "whicherrs":
|
case "whicherrs":
|
||||||
return whicherrs(conf)
|
return whicherrs(q)
|
||||||
case "definition":
|
case "definition":
|
||||||
return definition(conf)
|
return definition(q)
|
||||||
case "describe":
|
case "describe":
|
||||||
return describe(conf)
|
return describe(q)
|
||||||
case "freevars":
|
case "freevars":
|
||||||
return freevars(conf)
|
return freevars(q)
|
||||||
case "implements":
|
case "implements":
|
||||||
return implements(conf)
|
return implements(q)
|
||||||
case "referrers":
|
case "referrers":
|
||||||
return referrers(conf)
|
return referrers(q)
|
||||||
case "what":
|
case "what":
|
||||||
return what(conf)
|
return what(q)
|
||||||
default:
|
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
|
// Create a pointer.Config whose scope is the initial packages of lprog
|
||||||
// and their dependencies.
|
// and their dependencies.
|
||||||
func setupPTA(prog *ssa.Program, lprog *loader.Program, ptaLog io.Writer, reflection bool) (*pointer.Config, error) {
|
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 {
|
func peers(q *Query) error {
|
||||||
lconf := loader.Config{Build: q.Build}
|
lconf := loader.Config{Build: q.Build}
|
||||||
|
|
||||||
// Determine initial packages for PTA.
|
if err := setPTAScope(&lconf, q.Scope); err != nil {
|
||||||
args, err := lconf.FromArgs(q.Scope, true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(args) > 0 {
|
|
||||||
return fmt.Errorf("surplus arguments: %q", args)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load/parse/type-check the program.
|
// Load/parse/type-check the program.
|
||||||
lprog, err := lconf.Load()
|
lprog, err := lconf.Load()
|
||||||
|
|
|
||||||
|
|
@ -28,14 +28,9 @@ import (
|
||||||
func pointsto(q *Query) error {
|
func pointsto(q *Query) error {
|
||||||
lconf := loader.Config{Build: q.Build}
|
lconf := loader.Config{Build: q.Build}
|
||||||
|
|
||||||
// Determine initial packages for PTA.
|
if err := setPTAScope(&lconf, q.Scope); err != nil {
|
||||||
args, err := lconf.FromArgs(q.Scope, true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(args) > 0 {
|
|
||||||
return fmt.Errorf("surplus arguments: %q", args)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load/parse/type-check the program.
|
// Load/parse/type-check the program.
|
||||||
lprog, err := lconf.Load()
|
lprog, err := lconf.Load()
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,9 @@ var builtinErrorType = types.Universe.Lookup("error").Type()
|
||||||
func whicherrs(q *Query) error {
|
func whicherrs(q *Query) error {
|
||||||
lconf := loader.Config{Build: q.Build}
|
lconf := loader.Config{Build: q.Build}
|
||||||
|
|
||||||
// Determine initial packages for PTA.
|
if err := setPTAScope(&lconf, q.Scope); err != nil {
|
||||||
args, err := lconf.FromArgs(q.Scope, true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(args) > 0 {
|
|
||||||
return fmt.Errorf("surplus arguments: %q", args)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load/parse/type-check the program.
|
// Load/parse/type-check the program.
|
||||||
lprog, err := lconf.Load()
|
lprog, err := lconf.Load()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue