go/ssa: convert tests to new annotation system
Change-Id: I4f44da4fa6a4976b790b6707300cd4facf99c9a5 Reviewed-on: https://go-review.googlesource.com/c/144738 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
6dfe7efaa9
commit
89e258047f
|
@ -20,6 +20,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"golang.org/x/tools/go/ast/astutil"
|
"golang.org/x/tools/go/ast/astutil"
|
||||||
|
"golang.org/x/tools/go/expect"
|
||||||
"golang.org/x/tools/go/loader"
|
"golang.org/x/tools/go/loader"
|
||||||
"golang.org/x/tools/go/ssa"
|
"golang.org/x/tools/go/ssa"
|
||||||
"golang.org/x/tools/go/ssa/ssautil"
|
"golang.org/x/tools/go/ssa/ssautil"
|
||||||
|
@ -232,37 +233,41 @@ func testValueForExpr(t *testing.T, testfile string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the actual AST node for each canonical position.
|
var parenExprs []*ast.ParenExpr
|
||||||
parenExprByPos := make(map[token.Pos]*ast.ParenExpr)
|
|
||||||
ast.Inspect(f, func(n ast.Node) bool {
|
ast.Inspect(f, func(n ast.Node) bool {
|
||||||
if n != nil {
|
if n != nil {
|
||||||
if e, ok := n.(*ast.ParenExpr); ok {
|
if e, ok := n.(*ast.ParenExpr); ok {
|
||||||
parenExprByPos[e.Pos()] = e
|
parenExprs = append(parenExprs, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
// Find all annotations of form /*@kind*/.
|
notes, err := expect.Extract(prog.Fset, f)
|
||||||
for _, c := range f.Comments {
|
if err != nil {
|
||||||
text := strings.TrimSpace(c.Text())
|
t.Fatal(err)
|
||||||
if text == "" || text[0] != '@' {
|
}
|
||||||
continue
|
for _, n := range notes {
|
||||||
|
want := n.Name
|
||||||
|
if want == "nil" {
|
||||||
|
want = "<nil>"
|
||||||
}
|
}
|
||||||
text = text[1:]
|
position := prog.Fset.Position(n.Pos)
|
||||||
pos := c.End() + 1
|
|
||||||
position := prog.Fset.Position(pos)
|
|
||||||
var e ast.Expr
|
var e ast.Expr
|
||||||
if target := parenExprByPos[pos]; target == nil {
|
for _, paren := range parenExprs {
|
||||||
t.Errorf("%s: annotation doesn't precede ParenExpr: %q", position, text)
|
if paren.Pos() > n.Pos {
|
||||||
|
e = paren.X
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if e == nil {
|
||||||
|
t.Errorf("%s: note doesn't precede ParenExpr: %q", position, want)
|
||||||
continue
|
continue
|
||||||
} else {
|
|
||||||
e = target.X
|
|
||||||
}
|
}
|
||||||
|
|
||||||
path, _ := astutil.PathEnclosingInterval(f, pos, pos)
|
path, _ := astutil.PathEnclosingInterval(f, n.Pos, n.Pos)
|
||||||
if path == nil {
|
if path == nil {
|
||||||
t.Errorf("%s: can't find AST path from root to comment: %s", position, text)
|
t.Errorf("%s: can't find AST path from root to comment: %s", position, want)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +279,7 @@ func testValueForExpr(t *testing.T, testfile string) {
|
||||||
|
|
||||||
v, gotAddr := fn.ValueForExpr(e) // (may be nil)
|
v, gotAddr := fn.ValueForExpr(e) // (may be nil)
|
||||||
got := strings.TrimPrefix(fmt.Sprintf("%T", v), "*ssa.")
|
got := strings.TrimPrefix(fmt.Sprintf("%T", v), "*ssa.")
|
||||||
if want := text; got != want {
|
if got != want {
|
||||||
t.Errorf("%s: got value %q, want %q", position, got, want)
|
t.Errorf("%s: got value %q, want %q", position, got, want)
|
||||||
}
|
}
|
||||||
if v != nil {
|
if v != nil {
|
||||||
|
|
|
@ -10,12 +10,13 @@ package main
|
||||||
func f(spilled, unspilled int) {
|
func f(spilled, unspilled int) {
|
||||||
_ = /*@UnOp*/ (spilled)
|
_ = /*@UnOp*/ (spilled)
|
||||||
_ = /*@Parameter*/ (unspilled)
|
_ = /*@Parameter*/ (unspilled)
|
||||||
_ = /*@<nil>*/ (1 + 2) // (constant)
|
_ = /*@nil*/ (1 + 2) // (constant)
|
||||||
i := 0
|
i := 0
|
||||||
|
|
||||||
f := func() (int, int) { return 0, 0 }
|
f := func() (int, int) { return 0, 0 }
|
||||||
|
|
||||||
/*@Call*/ (print( /*@BinOp*/ (i + 1)))
|
/*@Call*/
|
||||||
|
(print( /*@BinOp*/ (i + 1)))
|
||||||
_, _ = /*@Call*/ (f())
|
_, _ = /*@Call*/ (f())
|
||||||
ch := /*@MakeChan*/ (make(chan int))
|
ch := /*@MakeChan*/ (make(chan int))
|
||||||
/*@UnOp*/ (<-ch)
|
/*@UnOp*/ (<-ch)
|
||||||
|
@ -43,7 +44,7 @@ func f(spilled, unspilled int) {
|
||||||
sl := []int{}
|
sl := []int{}
|
||||||
_ = /*@Slice*/ (sl[:0])
|
_ = /*@Slice*/ (sl[:0])
|
||||||
|
|
||||||
_ = /*@<nil>*/ (new(int)) // optimized away
|
_ = /*@nil*/ (new(int)) // optimized away
|
||||||
tmp := /*@Alloc*/ (new(int))
|
tmp := /*@Alloc*/ (new(int))
|
||||||
_ = tmp
|
_ = tmp
|
||||||
var iface interface{}
|
var iface interface{}
|
||||||
|
@ -88,7 +89,7 @@ func complit() {
|
||||||
_, _, _ = sl1, sl2, sl3
|
_, _, _ = sl1, sl2, sl3
|
||||||
|
|
||||||
_ = /*@Slice*/ ([]int{})
|
_ = /*@Slice*/ ([]int{})
|
||||||
_ = /*@<nil>*/ (& /*@Slice*/ ([]int{})) // & optimized away
|
_ = /*@nil*/ (& /*@Slice*/ ([]int{})) // & optimized away
|
||||||
_ = & /*@Slice*/ ([]int{})
|
_ = & /*@Slice*/ ([]int{})
|
||||||
|
|
||||||
// 2. Arrays
|
// 2. Arrays
|
||||||
|
@ -117,7 +118,7 @@ func complit() {
|
||||||
_, _, _ = m1, m2, m3
|
_, _, _ = m1, m2, m3
|
||||||
|
|
||||||
_ = /*@MakeMap*/ (M{})
|
_ = /*@MakeMap*/ (M{})
|
||||||
_ = /*@<nil>*/ (& /*@MakeMap*/ (M{})) // & optimized away
|
_ = /*@nil*/ (& /*@MakeMap*/ (M{})) // & optimized away
|
||||||
_ = & /*@MakeMap*/ (M{})
|
_ = & /*@MakeMap*/ (M{})
|
||||||
|
|
||||||
// 4. Structs
|
// 4. Structs
|
||||||
|
|
Loading…
Reference in New Issue