2013-08-27 16:49:13 -06:00
|
|
|
// Copyright 2013 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
2013-08-27 15:58:26 -06:00
|
|
|
package oracle
|
|
|
|
|
|
|
|
import (
|
2013-09-25 12:34:39 -06:00
|
|
|
"fmt"
|
2013-08-27 15:58:26 -06:00
|
|
|
"go/ast"
|
|
|
|
"go/token"
|
2013-09-03 13:29:02 -06:00
|
|
|
"sort"
|
2013-08-27 15:58:26 -06:00
|
|
|
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
"golang.org/x/tools/go/loader"
|
2014-11-09 14:50:40 -07:00
|
|
|
"golang.org/x/tools/go/ssa"
|
|
|
|
"golang.org/x/tools/go/ssa/ssautil"
|
|
|
|
"golang.org/x/tools/go/types"
|
|
|
|
"golang.org/x/tools/oracle/serial"
|
2013-08-27 15:58:26 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
// peers enumerates, for a given channel send (or receive) operation,
|
|
|
|
// the set of possible receives (or sends) that correspond to it.
|
|
|
|
//
|
2014-03-11 16:24:39 -06:00
|
|
|
// TODO(adonovan): support reflect.{Select,Recv,Send,Close}.
|
2013-08-27 15:58:26 -06:00
|
|
|
// TODO(adonovan): permit the user to query based on a MakeChan (not send/recv),
|
|
|
|
// or the implicit receive in "for v := range ch".
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
func peers(q *Query) error {
|
|
|
|
lconf := loader.Config{Build: q.Build}
|
|
|
|
|
2015-03-30 13:44:25 -06:00
|
|
|
if err := setPTAScope(&lconf, q.Scope); err != nil {
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load/parse/type-check the program.
|
|
|
|
lprog, err := lconf.Load()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
q.Fset = lprog.Fset
|
|
|
|
|
|
|
|
qpos, err := parseQueryPos(lprog, q.Pos, false)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
prog := ssa.Create(lprog, ssa.GlobalDebug)
|
|
|
|
|
|
|
|
ptaConfig, err := setupPTA(prog, lprog, q.PTALog, q.Reflection)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2014-10-12 08:08:28 -06:00
|
|
|
opPos := findOp(qpos)
|
|
|
|
if opPos == token.NoPos {
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
return fmt.Errorf("there is no channel operation here")
|
2013-08-27 15:58:26 -06:00
|
|
|
}
|
|
|
|
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
// Defer SSA construction till after errors are reported.
|
|
|
|
prog.BuildAll()
|
2013-08-27 15:58:26 -06:00
|
|
|
|
|
|
|
var queryOp chanOp // the originating send or receive operation
|
|
|
|
var ops []chanOp // all sends/receives of opposite direction
|
|
|
|
|
2014-10-12 08:08:28 -06:00
|
|
|
// Look at all channel operations in the whole ssa.Program.
|
|
|
|
// Build a list of those of same type as the query.
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
allFuncs := ssautil.AllFunctions(prog)
|
2013-08-27 15:58:26 -06:00
|
|
|
for fn := range allFuncs {
|
|
|
|
for _, b := range fn.Blocks {
|
|
|
|
for _, instr := range b.Instrs {
|
|
|
|
for _, op := range chanOps(instr) {
|
|
|
|
ops = append(ops, op)
|
2014-10-12 08:08:28 -06:00
|
|
|
if op.pos == opPos {
|
2013-08-27 15:58:26 -06:00
|
|
|
queryOp = op // we found the query op
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if queryOp.ch == nil {
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
return fmt.Errorf("ssa.Instruction for send/receive not found")
|
2013-08-27 15:58:26 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// Discard operations of wrong channel element type.
|
|
|
|
// Build set of channel ssa.Values as query to pointer analysis.
|
2013-09-03 13:29:02 -06:00
|
|
|
// We compare channels by element types, not channel types, to
|
|
|
|
// ignore both directionality and type names.
|
|
|
|
queryType := queryOp.ch.Type()
|
|
|
|
queryElemType := queryType.Underlying().(*types.Chan).Elem()
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
ptaConfig.AddQuery(queryOp.ch)
|
2013-08-27 15:58:26 -06:00
|
|
|
i := 0
|
|
|
|
for _, op := range ops {
|
2014-01-28 11:57:56 -07:00
|
|
|
if types.Identical(op.ch.Type().Underlying().(*types.Chan).Elem(), queryElemType) {
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
ptaConfig.AddQuery(op.ch)
|
2013-08-27 15:58:26 -06:00
|
|
|
ops[i] = op
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ops = ops[:i]
|
|
|
|
|
|
|
|
// Run the pointer analysis.
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
ptares := ptrAnalysis(ptaConfig)
|
2013-08-27 15:58:26 -06:00
|
|
|
|
2014-02-20 09:35:09 -07:00
|
|
|
// Find the points-to set.
|
|
|
|
queryChanPtr := ptares.Queries[queryOp.ch]
|
2013-08-27 15:58:26 -06:00
|
|
|
|
2013-09-03 13:29:02 -06:00
|
|
|
// Ascertain which make(chan) labels the query's channel can alias.
|
|
|
|
var makes []token.Pos
|
2014-02-20 09:35:09 -07:00
|
|
|
for _, label := range queryChanPtr.PointsTo().Labels() {
|
2013-09-03 13:29:02 -06:00
|
|
|
makes = append(makes, label.Pos())
|
|
|
|
}
|
|
|
|
sort.Sort(byPos(makes))
|
|
|
|
|
2014-10-12 08:08:28 -06:00
|
|
|
// Ascertain which channel operations can alias the same make(chan) labels.
|
|
|
|
var sends, receives, closes []token.Pos
|
2013-09-03 13:29:02 -06:00
|
|
|
for _, op := range ops {
|
2014-02-20 09:35:09 -07:00
|
|
|
if ptr, ok := ptares.Queries[op.ch]; ok && ptr.MayAlias(queryChanPtr) {
|
2014-10-12 08:08:28 -06:00
|
|
|
switch op.dir {
|
|
|
|
case types.SendOnly:
|
2014-02-20 09:35:09 -07:00
|
|
|
sends = append(sends, op.pos)
|
2014-10-12 08:08:28 -06:00
|
|
|
case types.RecvOnly:
|
2014-02-20 09:35:09 -07:00
|
|
|
receives = append(receives, op.pos)
|
2014-10-12 08:08:28 -06:00
|
|
|
case types.SendRecv:
|
|
|
|
closes = append(closes, op.pos)
|
2013-09-03 13:29:02 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sort.Sort(byPos(sends))
|
|
|
|
sort.Sort(byPos(receives))
|
2014-10-12 08:08:28 -06:00
|
|
|
sort.Sort(byPos(closes))
|
2013-09-03 13:29:02 -06:00
|
|
|
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
q.result = &peersResult{
|
2014-10-12 08:08:28 -06:00
|
|
|
queryPos: opPos,
|
2013-09-03 13:29:02 -06:00
|
|
|
queryType: queryType,
|
|
|
|
makes: makes,
|
|
|
|
sends: sends,
|
|
|
|
receives: receives,
|
2014-10-12 08:08:28 -06:00
|
|
|
closes: closes,
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
}
|
|
|
|
return nil
|
2013-08-27 15:58:26 -06:00
|
|
|
}
|
|
|
|
|
2014-10-12 08:08:28 -06:00
|
|
|
// findOp returns the position of the enclosing send/receive/close op.
|
|
|
|
// For send and receive operations, this is the position of the <- token;
|
|
|
|
// for close operations, it's the Lparen of the function call.
|
2013-08-29 19:36:59 -06:00
|
|
|
//
|
2014-10-12 08:08:28 -06:00
|
|
|
// TODO(adonovan): handle implicit receive operations from 'for...range chan' statements.
|
oracle: several major improvements
Features:
More robust: silently ignore type errors in modes that don't need
SSA form: describe, referrers, implements, freevars, description.
This makes the tool much more robust for everyday queries.
Less configuration: don't require a scope argument for all queries.
Only queries that do pointer analysis need it.
For the rest, the initial position is enough for
importQueryPackage to deduce the scope.
It now works for queries in GoFiles, TestGoFiles, or XTestGoFiles.
(It no longer works for ad-hoc main packages like
$GOROOT/src/net/http/triv.go)
More complete: "referrers" computes the scope automatically by
scanning the import graph of the entire workspace, using gorename's
refactor/importgraph package. This requires two passes at loading.
Faster: simplified start-up logic avoids unnecessary package loading
and SSA construction (a consequence of bad abstraction) in many
cases.
"callgraph": remove it. Unlike all the other commands it isn't
related to the current selection, and we have
golang.org/x/tools/cmdcallgraph now.
Internals:
Drop support for long-running clients (i.e., Pythia), since
godoc -analysis supports all the same features except "pointsto",
and precomputes all the results so latency is much lower.
Get rid of various unhelpful abstractions introduced to support
long-running clients. Expand out the set-up logic for each
subcommand. This is simpler, easier to read, and gives us more
control, at a small cost in duplication---the familiar story of
abstractions.
Discard PTA warnings. We weren't showing them (nor should we).
Split tests into separate directories (so that importgraph works).
Change-Id: I55d46b3ab33cdf7ac22436fcc2148fe04c901237
Reviewed-on: https://go-review.googlesource.com/8243
Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-03-30 09:21:48 -06:00
|
|
|
func findOp(qpos *queryPos) token.Pos {
|
go.tools/oracle: refactor Oracle API to allow repeated queries on same scope.
The existing standalone Query function builds an importer, ssa.Program, oracle,
and query position, executes the query and returns the result.
For clients (such as Frederik Zipp's web-based github.com/fzipp/pythia tool)
that wish to load the program once and make several queries, we now expose
these as separate operations too. Here's a client, in pseudocode:
o := oracle.New(...)
for ... {
qpos := o.ParseQueryPos(...)
res := o.Query(mode, qpos)
print result
}
NB: this is a slight deoptimisation in the one-shot case since we have to
build the entire SSA program with debug info, not just the query package,
since we now don't know the query package at that time.
The 'exact' param to ParseQueryPos needs more thought since its
ideal value is a function of the query mode. This will do for now.
Details:
- expose Oracle type, New() func and Query() method.
- expose QueryPos type and ParseQueryPos func.
- improved package doc comment.
- un-exposed the "needs" bits.
- added test.
R=crawshaw
CC=frederik.zipp, golang-dev
https://golang.org/cl/13810043
2013-09-23 13:02:18 -06:00
|
|
|
for _, n := range qpos.path {
|
2013-08-29 19:36:59 -06:00
|
|
|
switch n := n.(type) {
|
|
|
|
case *ast.UnaryExpr:
|
|
|
|
if n.Op == token.ARROW {
|
|
|
|
return n.OpPos
|
|
|
|
}
|
|
|
|
case *ast.SendStmt:
|
|
|
|
return n.Arrow
|
2014-10-12 08:08:28 -06:00
|
|
|
case *ast.CallExpr:
|
|
|
|
// close function call can only exist as a direct identifier
|
|
|
|
if close, ok := unparen(n.Fun).(*ast.Ident); ok {
|
|
|
|
if b, ok := qpos.info.Info.Uses[close].(*types.Builtin); ok && b.Name() == "close" {
|
|
|
|
return n.Lparen
|
|
|
|
}
|
|
|
|
}
|
2013-08-29 19:36:59 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return token.NoPos
|
|
|
|
}
|
|
|
|
|
2013-08-27 15:58:26 -06:00
|
|
|
// chanOp abstracts an ssa.Send, ssa.Unop(ARROW), or a SelectState.
|
|
|
|
type chanOp struct {
|
|
|
|
ch ssa.Value
|
2014-10-12 08:08:28 -06:00
|
|
|
dir types.ChanDir // SendOnly=send, RecvOnly=recv, SendRecv=close
|
2013-08-27 15:58:26 -06:00
|
|
|
pos token.Pos
|
|
|
|
}
|
|
|
|
|
|
|
|
// chanOps returns a slice of all the channel operations in the instruction.
|
|
|
|
func chanOps(instr ssa.Instruction) []chanOp {
|
2014-03-11 16:24:39 -06:00
|
|
|
// TODO(adonovan): handle calls to reflect.{Select,Recv,Send,Close} too.
|
2013-08-27 15:58:26 -06:00
|
|
|
var ops []chanOp
|
|
|
|
switch instr := instr.(type) {
|
|
|
|
case *ssa.UnOp:
|
|
|
|
if instr.Op == token.ARROW {
|
2013-12-17 16:45:01 -07:00
|
|
|
ops = append(ops, chanOp{instr.X, types.RecvOnly, instr.Pos()})
|
2013-08-27 15:58:26 -06:00
|
|
|
}
|
|
|
|
case *ssa.Send:
|
2013-12-17 16:45:01 -07:00
|
|
|
ops = append(ops, chanOp{instr.Chan, types.SendOnly, instr.Pos()})
|
2013-08-27 15:58:26 -06:00
|
|
|
case *ssa.Select:
|
|
|
|
for _, st := range instr.States {
|
|
|
|
ops = append(ops, chanOp{st.Chan, st.Dir, st.Pos})
|
|
|
|
}
|
2014-10-12 08:08:28 -06:00
|
|
|
case ssa.CallInstruction:
|
|
|
|
cc := instr.Common()
|
|
|
|
if b, ok := cc.Value.(*ssa.Builtin); ok && b.Name() == "close" {
|
|
|
|
ops = append(ops, chanOp{cc.Args[0], types.SendRecv, cc.Pos()})
|
|
|
|
}
|
2013-08-27 15:58:26 -06:00
|
|
|
}
|
|
|
|
return ops
|
|
|
|
}
|
|
|
|
|
|
|
|
type peersResult struct {
|
2014-10-12 08:08:28 -06:00
|
|
|
queryPos token.Pos // of queried channel op
|
|
|
|
queryType types.Type // type of queried channel
|
|
|
|
makes, sends, receives, closes []token.Pos // positions of aliased makechan/send/receive/close instrs
|
2013-08-27 15:58:26 -06:00
|
|
|
}
|
|
|
|
|
2013-09-03 13:29:02 -06:00
|
|
|
func (r *peersResult) display(printf printfFunc) {
|
|
|
|
if len(r.makes) == 0 {
|
|
|
|
printf(r.queryPos, "This channel can't point to anything.")
|
2013-08-27 15:58:26 -06:00
|
|
|
return
|
|
|
|
}
|
2013-09-03 13:29:02 -06:00
|
|
|
printf(r.queryPos, "This channel of type %s may be:", r.queryType)
|
|
|
|
for _, alloc := range r.makes {
|
|
|
|
printf(alloc, "\tallocated here")
|
|
|
|
}
|
|
|
|
for _, send := range r.sends {
|
|
|
|
printf(send, "\tsent to, here")
|
|
|
|
}
|
|
|
|
for _, receive := range r.receives {
|
|
|
|
printf(receive, "\treceived from, here")
|
2013-08-27 15:58:26 -06:00
|
|
|
}
|
2014-10-12 08:08:28 -06:00
|
|
|
for _, clos := range r.closes {
|
|
|
|
printf(clos, "\tclosed, here")
|
|
|
|
}
|
2013-09-03 13:29:02 -06:00
|
|
|
}
|
2013-08-27 15:58:26 -06:00
|
|
|
|
2013-09-24 13:08:14 -06:00
|
|
|
func (r *peersResult) toSerial(res *serial.Result, fset *token.FileSet) {
|
|
|
|
peers := &serial.Peers{
|
2013-09-03 13:29:02 -06:00
|
|
|
Pos: fset.Position(r.queryPos).String(),
|
|
|
|
Type: r.queryType.String(),
|
2013-08-27 15:58:26 -06:00
|
|
|
}
|
2013-09-03 13:29:02 -06:00
|
|
|
for _, alloc := range r.makes {
|
|
|
|
peers.Allocs = append(peers.Allocs, fset.Position(alloc).String())
|
|
|
|
}
|
|
|
|
for _, send := range r.sends {
|
|
|
|
peers.Sends = append(peers.Sends, fset.Position(send).String())
|
|
|
|
}
|
|
|
|
for _, receive := range r.receives {
|
|
|
|
peers.Receives = append(peers.Receives, fset.Position(receive).String())
|
|
|
|
}
|
2014-10-12 08:08:28 -06:00
|
|
|
for _, clos := range r.closes {
|
|
|
|
peers.Closes = append(peers.Closes, fset.Position(clos).String())
|
|
|
|
}
|
2013-09-03 13:29:02 -06:00
|
|
|
res.Peers = peers
|
2013-08-27 15:58:26 -06:00
|
|
|
}
|
2013-09-03 13:29:02 -06:00
|
|
|
|
|
|
|
// -------- utils --------
|
|
|
|
|
|
|
|
type byPos []token.Pos
|
|
|
|
|
|
|
|
func (p byPos) Len() int { return len(p) }
|
|
|
|
func (p byPos) Less(i, j int) bool { return p[i] < p[j] }
|
|
|
|
func (p byPos) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|