1
// Copyright 2013 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
7
// This file defines tests of source utilities.
16
"code.google.com/p/go.tools/astutil"
17
"code.google.com/p/go.tools/go/loader"
18
"code.google.com/p/go.tools/go/ssa"
21
// findInterval parses input and returns the [start, end) positions of
22
// the first occurrence of substr in input. f==nil indicates failure;
23
// an error has already been reported in that case.
25
func findInterval(t *testing.T, fset *token.FileSet, input, substr string) (f *ast.File, start, end token.Pos) {
26
f, err := parser.ParseFile(fset, "<input>", input, 0)
28
t.Errorf("parse error: %s", err)
32
i := strings.Index(input, substr)
34
t.Errorf("%q is not a substring of input", substr)
39
filePos := fset.File(f.Package)
40
return f, filePos.Pos(i), filePos.Pos(i + len(substr))
43
func TestEnclosingFunction(t *testing.T) {
45
input string // the input file
46
substr string // first occurrence of this string denotes interval
47
fn string // name of expected containing function
49
// We use distinctive numbers as syntactic landmarks.
53
func f() { println(1003) }`,
58
func (t T) f() { println(200) }`,
62
func f() { println(func() { print(300) }) }`,
66
func f() { println(func() { print(func() { print(350) })})}`,
68
// Implicit init for package-level var initializer.
69
{"package main; var a = 400", "400", "main.init"},
70
// No code for constants:
71
{"package main; const a = 500", "500", "(none)"},
73
{"package main; func init() { println(600) }", "600", "main.init$1"},
74
// Multiple explicit init functions:
76
func init() { println("foo") }
77
func init() { println(800) }`,
78
"800", "main.init$2"},
79
// init() containing FuncLit.
81
func init() { println(func(){print(900)}) }`,
84
for _, test := range tests {
85
conf := loader.Config{Fset: token.NewFileSet()}
86
f, start, end := findInterval(t, conf.Fset, test.input, test.substr)
90
path, exact := astutil.PathEnclosingInterval(f, start, end)
92
t.Errorf("EnclosingFunction(%q) not exact", test.substr)
96
conf.CreateFromFiles("main", f)
98
iprog, err := conf.Load()
103
prog := ssa.Create(iprog, 0)
104
pkg := prog.Package(iprog.Created[0].Pkg)
108
fn := ssa.EnclosingFunction(pkg, path)
114
t.Errorf("EnclosingFunction(%q in %q) got %s, want %s",
115
test.substr, test.input, name, test.fn)
119
// While we're here: test HasEnclosingFunction.
120
if has := ssa.HasEnclosingFunction(pkg, path); has != (fn != nil) {
121
t.Errorf("HasEnclosingFunction(%q in %q) got %v, want %v",
122
test.substr, test.input, has, fn != nil)