LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2013 The Go Authors. All rights reserved. | 1 // Copyright 2013 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package oracle | 5 package oracle |
6 | 6 |
7 import ( | 7 import ( |
8 "fmt" | 8 "fmt" |
9 "go/ast" | 9 "go/ast" |
10 "go/token" | 10 "go/token" |
11 "sort" | 11 "sort" |
12 | 12 |
13 "code.google.com/p/go.tools/go/types" | 13 "code.google.com/p/go.tools/go/types" |
14 "code.google.com/p/go.tools/oracle/serial" | 14 "code.google.com/p/go.tools/oracle/serial" |
15 "code.google.com/p/go.tools/pointer" | 15 "code.google.com/p/go.tools/pointer" |
16 "code.google.com/p/go.tools/ssa" | 16 "code.google.com/p/go.tools/ssa" |
| 17 "code.google.com/p/go.tools/ssa/ssautil" |
17 ) | 18 ) |
18 | 19 |
19 // peers enumerates, for a given channel send (or receive) operation, | 20 // peers enumerates, for a given channel send (or receive) operation, |
20 // the set of possible receives (or sends) that correspond to it. | 21 // the set of possible receives (or sends) that correspond to it. |
21 // | 22 // |
22 // TODO(adonovan): support reflect.{Select,Recv,Send}. | 23 // TODO(adonovan): support reflect.{Select,Recv,Send}. |
23 // TODO(adonovan): permit the user to query based on a MakeChan (not send/recv), | 24 // TODO(adonovan): permit the user to query based on a MakeChan (not send/recv), |
24 // or the implicit receive in "for v := range ch". | 25 // or the implicit receive in "for v := range ch". |
25 // | 26 // |
26 func peers(o *Oracle, qpos *QueryPos) (queryResult, error) { | 27 func peers(o *Oracle, qpos *QueryPos) (queryResult, error) { |
27 arrowPos := findArrow(qpos) | 28 arrowPos := findArrow(qpos) |
28 if arrowPos == token.NoPos { | 29 if arrowPos == token.NoPos { |
29 return nil, fmt.Errorf("there is no send/receive here") | 30 return nil, fmt.Errorf("there is no send/receive here") |
30 } | 31 } |
31 | 32 |
32 buildSSA(o) | 33 buildSSA(o) |
33 | 34 |
34 var queryOp chanOp // the originating send or receive operation | 35 var queryOp chanOp // the originating send or receive operation |
35 var ops []chanOp // all sends/receives of opposite direction | 36 var ops []chanOp // all sends/receives of opposite direction |
36 | 37 |
37 // Look at all send/receive instructions in the whole ssa.Program. | 38 // Look at all send/receive instructions in the whole ssa.Program. |
38 // Build a list of those of same type to query. | 39 // Build a list of those of same type to query. |
39 » allFuncs := ssa.AllFunctions(o.prog) | 40 » allFuncs := ssautil.AllFunctions(o.prog) |
40 for fn := range allFuncs { | 41 for fn := range allFuncs { |
41 for _, b := range fn.Blocks { | 42 for _, b := range fn.Blocks { |
42 for _, instr := range b.Instrs { | 43 for _, instr := range b.Instrs { |
43 for _, op := range chanOps(instr) { | 44 for _, op := range chanOps(instr) { |
44 ops = append(ops, op) | 45 ops = append(ops, op) |
45 if op.pos == arrowPos { | 46 if op.pos == arrowPos { |
46 queryOp = op // we found the que
ry op | 47 queryOp = op // we found the que
ry op |
47 } | 48 } |
48 } | 49 } |
49 } | 50 } |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 res.Peers = peers | 193 res.Peers = peers |
193 } | 194 } |
194 | 195 |
195 // -------- utils -------- | 196 // -------- utils -------- |
196 | 197 |
197 type byPos []token.Pos | 198 type byPos []token.Pos |
198 | 199 |
199 func (p byPos) Len() int { return len(p) } | 200 func (p byPos) Len() int { return len(p) } |
200 func (p byPos) Less(i, j int) bool { return p[i] < p[j] } | 201 func (p byPos) Less(i, j int) bool { return p[i] < p[j] } |
201 func (p byPos) Swap(i, j int) { p[i], p[j] = p[j], p[i] } | 202 func (p byPos) Swap(i, j int) { p[i], p[j] = p[j], p[i] } |
LEFT | RIGHT |