本文整理汇总了Golang中code/google/com/p/go/tools/ssa.NewProgram函数的典型用法代码示例。如果您正苦于以下问题:Golang NewProgram函数的具体用法?Golang NewProgram怎么用?Golang NewProgram使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了NewProgram函数的19个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: toSSA
// toSSA converts go source to SSA
func toSSA(source io.Reader, fileName, packageName string, debug bool) ([]byte, error) {
// adopted from saa package example
imp := importer.New(&importer.Config{Build: &build.Default})
file, err := parser.ParseFile(imp.Fset, fileName, source, 0)
if err != nil {
return nil, err
}
mainInfo := imp.CreatePackage(packageName, file)
var mode ssa.BuilderMode
prog := ssa.NewProgram(imp.Fset, mode)
if err := prog.CreatePackages(imp); err != nil {
return nil, err
}
mainPkg := prog.Package(mainInfo.Pkg)
out := new(bytes.Buffer)
mainPkg.SetDebugMode(debug)
mainPkg.DumpTo(out)
mainPkg.Build()
// grab just the functions
funcs := members([]ssa.Member{})
for _, obj := range mainPkg.Members {
if obj.Token() == token.FUNC {
funcs = append(funcs, obj)
}
}
// sort by Pos()
sort.Sort(funcs)
for _, f := range funcs {
mainPkg.Func(f.Name()).DumpTo(out)
}
return out.Bytes(), nil
}
开发者ID:jackspirou,项目名称:ssaview,代码行数:34,代码来源:ssaview.go
示例2: run
func run(t *testing.T, dir, input string) bool {
fmt.Printf("Input: %s\n", input)
start := time.Now()
var inputs []string
for _, i := range strings.Split(input, " ") {
inputs = append(inputs, dir+i)
}
imp := importer.New(&importer.Config{Build: &build.Default})
// TODO(adonovan): use LoadInitialPackages, then un-export ParseFiles.
files, err := importer.ParseFiles(imp.Fset, ".", inputs...)
if err != nil {
t.Errorf("ssa.ParseFiles(%s) failed: %s", inputs, err.Error())
return false
}
// Print a helpful hint if we don't make it to the end.
var hint string
defer func() {
if hint != "" {
fmt.Println("FAIL")
fmt.Println(hint)
} else {
fmt.Println("PASS")
}
}()
hint = fmt.Sprintf("To dump SSA representation, run:\n%% go build code.google.com/p/go.tools/cmd/ssadump && ./ssadump -build=CFP %s\n", input)
mainInfo := imp.LoadMainPackage(files...)
prog := ssa.NewProgram(imp.Fset, ssa.SanityCheckFunctions)
if err := prog.CreatePackages(imp); err != nil {
t.Errorf("CreatePackages failed: %s", err)
return false
}
prog.BuildAll()
mainPkg := prog.Package(mainInfo.Pkg)
mainPkg.CreateTestMainFunction() // (no-op if main already exists)
hint = fmt.Sprintf("To trace execution, run:\n%% go build code.google.com/p/go.tools/cmd/ssadump && ./ssadump -build=C -run --interp=T %s\n", input)
if exitCode := interp.Interpret(mainPkg, 0, inputs[0], []string{}); exitCode != 0 {
t.Errorf("interp.Interpret(%s) exited with code %d, want zero", inputs, exitCode)
return false
}
hint = "" // call off the hounds
if false {
fmt.Println(input, time.Since(start)) // test profiling
}
return true
}
开发者ID:nagyistge,项目名称:hm-workspace,代码行数:56,代码来源:interp_test.go
示例3: TestSwitches
func TestSwitches(t *testing.T) {
imp := importer.New(new(importer.Config)) // (uses GCImporter)
f, err := parser.ParseFile(imp.Fset, "testdata/switches.go", nil, parser.ParseComments)
if err != nil {
t.Error(err)
return
}
mainInfo := imp.CreatePackage("main", f)
prog := ssa.NewProgram(imp.Fset, 0)
if err := prog.CreatePackages(imp); err != nil {
t.Error(err)
return
}
mainPkg := prog.Package(mainInfo.Pkg)
mainPkg.Build()
for _, mem := range mainPkg.Members {
if fn, ok := mem.(*ssa.Function); ok {
if fn.Synthetic != "" {
continue // e.g. init()
}
// Each (multi-line) "switch" comment within
// this function must match the printed form
// of a ConstSwitch.
var wantSwitches []string
for _, c := range f.Comments {
if fn.Syntax().Pos() <= c.Pos() && c.Pos() < fn.Syntax().End() {
text := strings.TrimSpace(c.Text())
if strings.HasPrefix(text, "switch ") {
wantSwitches = append(wantSwitches, text)
}
}
}
switches := ssautil.Switches(fn)
if len(switches) != len(wantSwitches) {
t.Errorf("in %s, found %d switches, want %d", fn, len(switches), len(wantSwitches))
}
for i, sw := range switches {
got := sw.String()
if i >= len(wantSwitches) {
continue
}
want := wantSwitches[i]
if got != want {
t.Errorf("in %s, found switch %d: got <<%s>>, want <<%s>>", fn, i, got, want)
}
}
}
}
}
开发者ID:ufo22940268,项目名称:two-server-others,代码行数:53,代码来源:switch_test.go
示例4: TestNullTestmainPackage
// CreateTestMainPackage should return nil if there were no tests.
func TestNullTestmainPackage(t *testing.T) {
imp := importer.New(&importer.Config{Build: &build.Default})
files, err := importer.ParseFiles(imp.Fset, ".", "testdata/b_test.go")
if err != nil {
t.Fatalf("ParseFiles failed: %s", err)
}
mainInfo := imp.CreatePackage("b", files...)
prog := ssa.NewProgram(imp.Fset, ssa.SanityCheckFunctions)
if err := prog.CreatePackages(imp); err != nil {
t.Fatalf("CreatePackages failed: %s", err)
}
mainPkg := prog.Package(mainInfo.Pkg)
if mainPkg.Func("main") != nil {
t.Fatalf("unexpected main function")
}
if prog.CreateTestMainPackage(mainPkg) != nil {
t.Fatalf("CreateTestMainPackage returned non-nil")
}
}
开发者ID:Bosh-for-Cpi,项目名称:bosh-2605,代码行数:20,代码来源:interp_test.go
示例5: doOneInput
func doOneInput(input, filename string) bool {
impctx := &importer.Config{Build: &build.Default}
imp := importer.New(impctx)
// Parsing.
f, err := parser.ParseFile(imp.Fset, filename, input, 0)
if err != nil {
// TODO(adonovan): err is a scanner error list;
// display all errors not just first?
fmt.Println(err)
return false
}
// Create single-file main package and import its dependencies.
info := imp.CreatePackage("main", f)
// SSA creation + building.
prog := ssa.NewProgram(imp.Fset, ssa.SanityCheckFunctions)
if err := prog.CreatePackages(imp); err != nil {
fmt.Println(err)
return false
}
prog.BuildAll()
mainpkg := prog.Package(info.Pkg)
ptrmain := mainpkg // main package for the pointer analysis
if mainpkg.Func("main") == nil {
// No main function; assume it's a test.
ptrmain = prog.CreateTestMainPackage(mainpkg)
}
ok := true
lineMapping := make(map[string]string) // maps "file:line" to @line tag
// Parse expectations in this input.
var exps []*expectation
re := regexp.MustCompile("// *@([a-z]*) *(.*)$")
lines := strings.Split(input, "\n")
for linenum, line := range lines {
linenum++ // make it 1-based
if matches := re.FindAllStringSubmatch(line, -1); matches != nil {
match := matches[0]
kind, rest := match[1], match[2]
e := &expectation{kind: kind, filename: filename, linenum: linenum}
if kind == "line" {
if rest == "" {
ok = false
e.errorf("@%s expectation requires identifier", kind)
} else {
lineMapping[fmt.Sprintf("%s:%d", filename, linenum)] = rest
}
continue
}
if e.needsProbe() && !strings.Contains(line, "print(") {
ok = false
e.errorf("@%s expectation must follow call to print(x)", kind)
continue
}
switch kind {
case "pointsto":
e.args = split(rest, "|")
case "types":
for _, typstr := range split(rest, "|") {
var t types.Type = types.Typ[types.Invalid] // means "..."
if typstr != "..." {
texpr, err := parser.ParseExpr(typstr)
if err != nil {
ok = false
// Don't print err since its location is bad.
e.errorf("'%s' is not a valid type", typstr)
continue
}
mainFileScope := mainpkg.Object.Scope().Child(0)
t, _, err = types.EvalNode(imp.Fset, texpr, mainpkg.Object, mainFileScope)
if err != nil {
ok = false
// Don't print err since its location is bad.
e.errorf("'%s' is not a valid type: %s", typstr, err)
continue
}
}
e.types = append(e.types, t)
}
case "calls":
e.args = split(rest, "->")
// TODO(adonovan): eagerly reject the
// expectation if fn doesn't denote
// existing function, rather than fail
// the expectation after analysis.
if len(e.args) != 2 {
ok = false
e.errorf("@calls expectation wants 'caller -> callee' arguments")
continue
}
//.........这里部分代码省略.........
开发者ID:amulyas,项目名称:bosh-cloudstack-cpi,代码行数:101,代码来源:pointer_test.go
示例6: TestObjValueLookup
func TestObjValueLookup(t *testing.T) {
imp := importer.New(new(importer.Config)) // (uses GCImporter)
f, err := parser.ParseFile(imp.Fset, "testdata/objlookup.go", nil, parser.ParseComments)
if err != nil {
t.Error(err)
return
}
// Maps each var Ident (represented "name:linenum") to the
// kind of ssa.Value we expect (represented "Constant", "&Alloc").
expectations := make(map[string]string)
// Find all annotations of form x::BinOp, &y::Alloc, etc.
re := regexp.MustCompile(`(\b|&)?(\w*)::(\w*)\b`)
for _, c := range f.Comments {
text := c.Text()
pos := imp.Fset.Position(c.Pos())
for _, m := range re.FindAllStringSubmatch(text, -1) {
key := fmt.Sprintf("%s:%d", m[2], pos.Line)
value := m[1] + m[3]
expectations[key] = value
}
}
mainInfo := imp.CreatePackage("main", f)
prog := ssa.NewProgram(imp.Fset, 0 /*|ssa.LogFunctions*/)
if err := prog.CreatePackages(imp); err != nil {
t.Error(err)
return
}
mainPkg := prog.Package(mainInfo.Pkg)
mainPkg.SetDebugMode(true)
mainPkg.Build()
// Gather all idents and objects in file.
objs := make(map[types.Object]bool)
var ids []*ast.Ident
ast.Inspect(f, func(n ast.Node) bool {
if id, ok := n.(*ast.Ident); ok {
ids = append(ids, id)
if obj := mainInfo.ObjectOf(id); obj != nil {
objs[obj] = true
}
}
return true
})
// Check invariants for func and const objects.
for obj := range objs {
switch obj := obj.(type) {
case *types.Func:
checkFuncValue(t, prog, obj)
case *types.Const:
checkConstValue(t, prog, obj)
}
}
// Check invariants for var objects.
// The result varies based on the specific Ident.
for _, id := range ids {
if id.Name == "_" {
continue
}
if obj, ok := mainInfo.ObjectOf(id).(*types.Var); ok {
ref, _ := importer.PathEnclosingInterval(f, id.Pos(), id.Pos())
pos := imp.Fset.Position(id.Pos())
exp := expectations[fmt.Sprintf("%s:%d", id.Name, pos.Line)]
if exp == "" {
t.Errorf("%s: no expectation for var ident %s ", pos, id.Name)
continue
}
wantAddr := false
if exp[0] == '&' {
wantAddr = true
exp = exp[1:]
}
checkVarValue(t, prog, mainPkg, ref, obj, exp, wantAddr)
}
}
}
开发者ID:amulyas,项目名称:bosh-cloudstack-cpi,代码行数:82,代码来源:source_test.go
示例7: TestValueForExpr
// Ensure that, in debug mode, we can determine the ssa.Value
// corresponding to every ast.Expr.
func TestValueForExpr(t *testing.T) {
imp := importer.New(new(importer.Config)) // (uses GCImporter)
f, err := parser.ParseFile(imp.Fset, "testdata/valueforexpr.go", nil, parser.ParseComments)
if err != nil {
t.Error(err)
return
}
mainInfo := imp.CreatePackage("main", f)
prog := ssa.NewProgram(imp.Fset, 0)
if err := prog.CreatePackages(imp); err != nil {
t.Error(err)
return
}
mainPkg := prog.Package(mainInfo.Pkg)
mainPkg.SetDebugMode(true)
mainPkg.Build()
if false {
// debugging
for _, mem := range mainPkg.Members {
if fn, ok := mem.(*ssa.Function); ok {
fn.DumpTo(os.Stderr)
}
}
}
// Find the actual AST node for each canonical position.
parenExprByPos := make(map[token.Pos]*ast.ParenExpr)
ast.Inspect(f, func(n ast.Node) bool {
if n != nil {
if e, ok := n.(*ast.ParenExpr); ok {
parenExprByPos[e.Pos()] = e
}
}
return true
})
// Find all annotations of form /*@kind*/.
for _, c := range f.Comments {
text := strings.TrimSpace(c.Text())
if text == "" || text[0] != '@' {
continue
}
text = text[1:]
pos := c.End() + 1
position := imp.Fset.Position(pos)
var e ast.Expr
if target := parenExprByPos[pos]; target == nil {
t.Errorf("%s: annotation doesn't precede ParenExpr: %q", position, text)
continue
} else {
e = target.X
}
path, _ := importer.PathEnclosingInterval(f, pos, pos)
if path == nil {
t.Errorf("%s: can't find AST path from root to comment: %s", position, text)
continue
}
fn := ssa.EnclosingFunction(mainPkg, path)
if fn == nil {
t.Errorf("%s: can't find enclosing function", position)
continue
}
v, gotAddr := fn.ValueForExpr(e) // (may be nil)
got := strings.TrimPrefix(fmt.Sprintf("%T", v), "*ssa.")
if want := text; got != want {
t.Errorf("%s: got value %q, want %q", position, got, want)
}
if v != nil {
T := v.Type()
if gotAddr {
T = T.Underlying().(*types.Pointer).Elem() // deref
}
if !types.IsIdentical(T, mainInfo.TypeOf(e)) {
t.Errorf("%s: got type %s, want %s", position, mainInfo.TypeOf(e), T)
}
}
}
}
开发者ID:amulyas,项目名称:bosh-cloudstack-cpi,代码行数:86,代码来源:source_test.go
示例8: Example
// This program demonstrates how to run the SSA builder on a "Hello,
// World!" program and shows the printed representation of packages,
// functions and instructions.
//
// Within the function listing, the name of each BasicBlock such as
// ".0.entry" is printed left-aligned, followed by the block's
// Instructions.
//
// For each instruction that defines an SSA virtual register
// (i.e. implements Value), the type of that value is shown in the
// right column.
//
// Build and run the ssadump.go program in this package if you want a
// standalone tool with similar functionality.
//
func Example() {
const hello = `
package main
import "fmt"
const message = "Hello, World!"
func main() {
fmt.Println(message)
}
`
// Construct an importer. Imports will be loaded as if by 'go build'.
imp := importer.New(&importer.Config{Build: &build.Default})
// Parse the input file.
file, err := parser.ParseFile(imp.Fset, "hello.go", hello, 0)
if err != nil {
fmt.Print(err) // parse error
return
}
// Create single-file main package and import its dependencies.
mainInfo := imp.CreatePackage("main", file)
// Create SSA-form program representation.
var mode ssa.BuilderMode
prog := ssa.NewProgram(imp.Fset, mode)
if err := prog.CreatePackages(imp); err != nil {
fmt.Print(err) // type error in some package
return
}
mainPkg := prog.Package(mainInfo.Pkg)
// Print out the package.
mainPkg.DumpTo(os.Stdout)
// Build SSA code for bodies of functions in mainPkg.
mainPkg.Build()
// Print out the package-level functions.
mainPkg.Func("init").DumpTo(os.Stdout)
mainPkg.Func("main").DumpTo(os.Stdout)
// Output:
//
// package main:
// func init func()
// var init$guard bool
// func main func()
// const message message = "Hello, World!":untyped string
//
// # Name: main.init
// # Package: main
// # Synthetic: package initializer
// func init():
// .0.entry: P:0 S:2
// t0 = *init$guard bool
// if t0 goto 2.init.done else 1.init.start
// .1.init.start: P:1 S:1
// *init$guard = true:bool
// t1 = fmt.init() ()
// jump 2.init.done
// .2.init.done: P:2 S:0
// return
//
// # Name: main.main
// # Package: main
// # Location: hello.go:8:6
// func main():
// .0.entry: P:0 S:0
// t0 = new [1]interface{} (varargs) *[1]interface{}
// t1 = &t0[0:untyped integer] *interface{}
// t2 = make interface{} <- string ("Hello, World!":string) interface{}
// *t1 = t2
// t3 = slice t0[:] []interface{}
// t4 = fmt.Println(t3) (n int, err error)
// return
}
开发者ID:amulyas,项目名称:bosh-cloudstack-cpi,代码行数:94,代码来源:example_test.go
示例9: TestStdlib
func TestStdlib(t *testing.T) {
impctx := importer.Config{Build: &build.Default}
// Load, parse and type-check the program.
t0 := time.Now()
imp := importer.New(&impctx)
if _, _, err := imp.LoadInitialPackages(allPackages()); err != nil {
t.Errorf("LoadInitialPackages failed: %s", err)
return
}
t1 := time.Now()
runtime.GC()
var memstats runtime.MemStats
runtime.ReadMemStats(&memstats)
alloc := memstats.Alloc
// Create SSA packages.
prog := ssa.NewProgram(imp.Fset, ssa.SanityCheckFunctions)
if err := prog.CreatePackages(imp); err != nil {
t.Errorf("CreatePackages failed: %s", err)
return
}
// Enable debug mode globally.
for _, info := range imp.AllPackages() {
prog.Package(info.Pkg).SetDebugMode(debugMode)
}
t2 := time.Now()
// Build SSA IR... if it's safe.
prog.BuildAll()
t3 := time.Now()
runtime.GC()
runtime.ReadMemStats(&memstats)
numPkgs := len(prog.AllPackages())
if want := 140; numPkgs < want {
t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want)
}
// Dump some statistics.
allFuncs := ssa.AllFunctions(prog)
var numInstrs int
for fn := range allFuncs {
for _, b := range fn.Blocks {
numInstrs += len(b.Instrs)
}
}
t.Log("GOMAXPROCS: ", runtime.GOMAXPROCS(0))
t.Log("Load/parse/typecheck: ", t1.Sub(t0))
t.Log("SSA create: ", t2.Sub(t1))
t.Log("SSA build: ", t3.Sub(t2))
// SSA stats:
t.Log("#Packages: ", numPkgs)
t.Log("#Functions: ", len(allFuncs))
t.Log("#Instructions: ", numInstrs)
t.Log("#MB: ", (memstats.Alloc-alloc)/1000000)
}
开发者ID:nagyistge,项目名称:hm-workspace,代码行数:66,代码来源:stdlib_test.go
示例10: Example
// This program demonstrates how to use the pointer analysis to
// obtain a conservative call-graph of a Go program.
//
func Example() {
const myprog = `
package main
import "fmt"
type I interface {
f()
}
type C struct{}
func (C) f() {
fmt.Println("C.f()")
}
func main() {
var i I = C{}
i.f() // dynamic method call
}
`
// Construct an importer.
// Imports will be loaded as if by 'go build'.
imp := importer.New(&importer.Config{Build: &build.Default})
// Parse the input file.
file, err := parser.ParseFile(imp.Fset, "myprog.go", myprog, parser.DeclarationErrors)
if err != nil {
fmt.Print(err) // parse error
return
}
// Create a "main" package containing one file.
mainInfo := imp.LoadMainPackage(file)
// Create SSA-form program representation.
var mode ssa.BuilderMode
prog := ssa.NewProgram(imp.Fset, mode)
if err := prog.CreatePackages(imp); err != nil {
fmt.Print(err) // type error in some package
return
}
mainPkg := prog.Package(mainInfo.Pkg)
// Build SSA code for bodies of all functions in the whole program.
prog.BuildAll()
// Run the pointer analysis and build the complete callgraph.
config := &pointer.Config{
Mains: []*ssa.Package{mainPkg},
BuildCallGraph: true,
}
result := pointer.Analyze(config)
// Find edges originating from the main package.
// By converting to strings, we de-duplicate nodes
// representing the same function due to context sensitivity.
var edges []string
call.GraphVisitEdges(result.CallGraph, func(edge call.Edge) error {
caller := edge.Caller.Func()
if caller.Pkg == mainPkg {
edges = append(edges, fmt.Sprint(caller, " --> ", edge.Callee.Func()))
}
return nil
})
// Print the edges in sorted order.
sort.Strings(edges)
for _, edge := range edges {
fmt.Println(edge)
}
// Output:
// (main.C).f --> fmt.Println
// main.init --> fmt.init
// main.main --> (main.C).f
}
开发者ID:nagyistge,项目名称:hm-workspace,代码行数:80,代码来源:example_test.go
示例11: TestExternalPackages
// Tests that programs partially loaded from gc object files contain
// functions with no code for the external portions, but are otherwise ok.
func TestExternalPackages(t *testing.T) {
test := `
package main
import (
"bytes"
"io"
"testing"
)
func main() {
var t testing.T
t.Parallel() // static call to external declared method
t.Fail() // static call to promoted external declared method
testing.Short() // static call to external package-level function
var w io.Writer = new(bytes.Buffer)
w.Write(nil) // interface invoke of external declared method
}
`
imp := importer.New(new(importer.Config)) // no go/build.Context; uses GC importer
f, err := parser.ParseFile(imp.Fset, "<input>", test, parser.DeclarationErrors)
if err != nil {
t.Error(err)
return
}
mainInfo := imp.LoadMainPackage(f)
prog := ssa.NewProgram(imp.Fset, ssa.SanityCheckFunctions)
if err := prog.CreatePackages(imp); err != nil {
t.Error(err)
return
}
mainPkg := prog.Package(mainInfo.Pkg)
mainPkg.Build()
// Only the main package and its immediate dependencies are loaded.
deps := []string{"bytes", "io", "testing"}
all := prog.AllPackages()
if len(all) != 1+len(deps) {
t.Errorf("unexpected set of loaded packages: %q", all)
}
for _, path := range deps {
pkg := prog.ImportedPackage(path)
if pkg == nil {
t.Errorf("package not loaded: %q", path)
continue
}
// External packages should have no function bodies (except for wrappers).
isExt := pkg != mainPkg
// init()
if isExt && !isEmpty(pkg.Func("init")) {
t.Errorf("external package %s has non-empty init", pkg)
} else if !isExt && isEmpty(pkg.Func("init")) {
t.Errorf("main package %s has empty init", pkg)
}
for _, mem := range pkg.Members {
switch mem := mem.(type) {
case *ssa.Function:
// Functions at package level.
if isExt && !isEmpty(mem) {
t.Errorf("external function %s is non-empty", mem)
} else if !isExt && isEmpty(mem) {
t.Errorf("function %s is empty", mem)
}
case *ssa.Type:
// Methods of named types T.
// (In this test, all exported methods belong to *T not T.)
if !isExt {
t.Fatalf("unexpected name type in main package: %s", mem)
}
mset := types.NewPointer(mem.Type()).MethodSet()
for i, n := 0, mset.Len(); i < n; i++ {
m := prog.Method(mset.At(i))
// For external types, only synthetic wrappers have code.
expExt := !strings.Contains(m.Synthetic, "wrapper")
if expExt && !isEmpty(m) {
t.Errorf("external method %s is non-empty: %s",
m, m.Synthetic)
} else if !expExt && isEmpty(m) {
t.Errorf("method function %s is empty: %s",
m, m.Synthetic)
}
}
}
}
}
expectedCallee := []string{
"(*testing.T).Parallel",
"(*testing.common).Fail",
"testing.Short",
//.........这里部分代码省略.........
开发者ID:nagyistge,项目名称:hm-workspace,代码行数:101,代码来源:builder_test.go
示例12: TestTypesWithMethodSets
// TestMethodSets tests that Package.TypesWithMethodSets includes all necessary types.
func TestTypesWithMethodSets(t *testing.T) {
tests := []struct {
input string
want []string
}{
// An exported package-level type is needed.
{`package p; type T struct{}; func (T) f() {}`,
[]string{"*p.T", "p.T"},
},
// An unexported package-level type is not needed.
{`package p; type t struct{}; func (t) f() {}`,
nil,
},
// Subcomponents of type of exported package-level var are needed.
{`package p; import "bytes"; var V struct {*bytes.Buffer}`,
[]string{"struct{*bytes.Buffer}"},
},
// Subcomponents of type of unexported package-level var are not needed.
{`package p; import "bytes"; var v struct {*bytes.Buffer}`,
nil,
},
// Subcomponents of type of exported package-level function are needed.
{`package p; import "bytes"; func F(struct {*bytes.Buffer}) {}`,
[]string{"struct{*bytes.Buffer}"},
},
// Subcomponents of type of unexported package-level function are not needed.
{`package p; import "bytes"; func f(struct {*bytes.Buffer}) {}`,
nil,
},
// Subcomponents of type of exported method are needed.
{`package p; import "bytes"; type x struct{}; func (x) G(struct {*bytes.Buffer}) {}`,
[]string{"*p.x", "p.x", "struct{*bytes.Buffer}"},
},
// Subcomponents of type of unexported method are not needed.
{`package p; import "bytes"; type X struct{}; func (X) G(struct {*bytes.Buffer}) {}`,
[]string{"*p.X", "p.X", "struct{*bytes.Buffer}"},
},
// Local types aren't needed.
{`package p; import "bytes"; func f() { type T struct {*bytes.Buffer}; var t T; _ = t }`,
nil,
},
// ...unless used by MakeInterface.
{`package p; import "bytes"; func f() { type T struct {*bytes.Buffer}; _ = interface{}(T{}) }`,
[]string{"*p.T", "p.T"},
},
// Types used as operand of MakeInterface are needed.
{`package p; import "bytes"; func f() { _ = interface{}(struct{*bytes.Buffer}{}) }`,
[]string{"struct{*bytes.Buffer}"},
},
// MakeInterface is optimized away when storing to a blank.
{`package p; import "bytes"; var _ interface{} = struct{*bytes.Buffer}{}`,
nil,
},
}
for i, test := range tests {
imp := importer.New(new(importer.Config)) // no go/build.Context; uses GC importer
f, err := parser.ParseFile(imp.Fset, "<input>", test.input, 0)
if err != nil {
t.Errorf("test %d: %s", i, err)
continue
}
mainInfo := imp.CreatePackage("p", f)
prog := ssa.NewProgram(imp.Fset, ssa.SanityCheckFunctions)
if err := prog.CreatePackages(imp); err != nil {
t.Errorf("test %d: %s", i, err)
continue
}
mainPkg := prog.Package(mainInfo.Pkg)
prog.BuildAll()
var typstrs []string
for _, T := range mainPkg.TypesWithMethodSets() {
typstrs = append(typstrs, T.String())
}
sort.Strings(typstrs)
if !reflect.DeepEqual(typstrs, test.want) {
t.Errorf("test %d: got %q, want %q", i, typstrs, test.want)
}
}
}
开发者ID:amulyas,项目名称:bosh-cloudstack-cpi,代码行数:84,代码来源:builder_test.go
示例13: Compile
func (compiler *compiler) Compile(filenames []string, importpath string) (m *Module, err error) {
// FIXME create a compilation state, rather than storing in 'compiler'.
compiler.llvmtypes = NewLLVMTypeMap(compiler.target)
buildctx, err := llgobuild.ContextFromTriple(compiler.TargetTriple)
if err != nil {
return nil, err
}
impcfg := &goimporter.Config{
TypeChecker: types.Config{
Import: llgoimporter.NewImporter(buildctx).Import,
Sizes: compiler.llvmtypes,
},
Build: &buildctx.Context,
}
compiler.typechecker = &impcfg.TypeChecker
compiler.importer = goimporter.New(impcfg)
program := ssa.NewProgram(compiler.importer.Fset, 0)
astFiles, err := parseFiles(compiler.importer.Fset, filenames)
if err != nil {
return nil, err
}
// If no import path is specified, or the package's
// name (not path) is "main", then set the import
// path to be the same as the package's name.
if pkgname := astFiles[0].Name.String(); importpath == "" || pkgname == "main" {
importpath = pkgname
}
mainPkginfo := compiler.importer.CreatePackage(importpath, astFiles...)
if mainPkginfo.Err != nil {
return nil, mainPkginfo.Err
}
// First call CreatePackages to resolve imports, and then CreatePackage
// to obtain the main package. The latter simply returns the package
// created by the former.
if err := program.CreatePackages(compiler.importer); err != nil {
return nil, err
}
mainpkg := program.CreatePackage(mainPkginfo)
// Create a Module, which contains the LLVM bitcode. Dispose it on panic,
// otherwise we'll set a finalizer at the end. The caller may invoke
// Dispose manually, which will render the finalizer a no-op.
modulename := importpath
compiler.module = &Module{llvm.NewModule(modulename), modulename, false}
compiler.module.SetTarget(compiler.TargetTriple)
compiler.module.SetDataLayout(compiler.target.String())
// Map runtime types and functions.
runtimePkginfo := mainPkginfo
runtimePkg := mainpkg
if importpath != "runtime" {
astFiles, err := parseRuntime(&buildctx.Context, compiler.importer.Fset)
if err != nil {
return nil, err
}
runtimePkginfo = compiler.importer.CreatePackage("runtime", astFiles...)
if runtimePkginfo.Err != nil {
return nil, err
}
runtimePkg = program.CreatePackage(runtimePkginfo)
}
// Create a new translation unit.
unit := newUnit(compiler, mainpkg)
// Create the runtime interface.
compiler.runtime, err = newRuntimeInterface(
runtimePkg.Object,
compiler.module.Module,
compiler.llvmtypes,
FuncResolver(unit),
)
if err != nil {
return nil, err
}
// Create a struct responsible for mapping static types to LLVM types,
// and to runtime/dynamic type values.
compiler.types = NewTypeMap(
importpath,
compiler.llvmtypes,
compiler.module.Module,
compiler.runtime,
MethodResolver(unit),
)
// Create a Builder, for building LLVM instructions.
compiler.builder = llvm.GlobalContext().NewBuilder()
defer compiler.builder.Dispose()
mainpkg.Build()
unit.translatePackage(mainpkg)
compiler.processAnnotations(unit, mainPkginfo)
if runtimePkginfo != mainPkginfo {
compiler.processAnnotations(unit, runtimePkginfo)
}
/*
compiler.debug_info = &llvm.DebugInfo{}
//.........这里部分代码省略.........
开发者ID:pcc,项目名称:llgo,代码行数:101,代码来源:compiler.go
示例14: run
func run(t *testing.T, dir, input string, success successPredicate) bool {
fmt.Printf("Input: %s\n", input)
start := time.Now()
var inputs []string
for _, i := range strings.Split(input, " ") {
inputs = append(inputs, dir+i)
}
imp := importer.New(&importer.Config{Build: &build.Default})
// TODO(adonovan): use LoadInitialPackages, then un-export ParseFiles.
// Then add the following packages' tests, which pass:
// "flag", "unicode", "unicode/utf8", "testing", "log", "path".
files, err := importer.ParseFiles(imp.Fset, ".", inputs...)
if err != nil {
t.Errorf("ssa.ParseFiles(%s) failed: %s", inputs, err.Error())
return false
}
// Print a helpful hint if we don't make it to the end.
var hint string
defer func() {
if hint != "" {
fmt.Println("FAIL")
fmt.Println(hint)
} else {
fmt.Println("PASS")
}
interp.CapturedOutput = nil
}()
hint = fmt.Sprintf("To dump SSA representation, run:\n%% go build code.google.com/p/go.tools/cmd/ssadump && ./ssadump -build=CFP %s\n", input)
mainInfo := imp.CreatePackage(files[0].Name.Name, files...)
if _, err := imp.LoadPackage("runtime"); err != nil {
t.Errorf("LoadPackage(runtime) failed: %s", err)
}
prog := ssa.NewProgram(imp.Fset, ssa.SanityCheckFunctions)
if err := prog.CreatePackages(imp); err != nil {
t.Errorf("CreatePackages failed: %s", err)
return false
}
prog.BuildAll()
mainPkg := prog.Package(mainInfo.Pkg)
if mainPkg.Func("main") == nil {
testmainPkg := prog.CreateTestMainPackage(mainPkg)
if testmainPkg == nil {
t.Errorf("CreateTestMainPackage(%s) returned nil", mainPkg)
return false
}
if testmainPkg.Func("main") == nil {
t.Errorf("synthetic testmain package has no main")
return false
}
mainPkg = testmainPkg
}
var out bytes.Buffer
interp.CapturedOutput = &out
hint = fmt.Sprintf("To trace execution, run:\n%% go build code.google.com/p/go.tools/cmd/ssadump && ./ssadump -build=C -run --interp=T %s\n", input)
exitCode := interp.Interpret(mainPkg, 0, inputs[0], []string{})
// The definition of success varies with each file.
if err := success(exitCode, out.String()); err != nil {
t.Errorf("interp.Interpret(%s) failed: %s", inputs, err)
return false
}
hint = "" // call off the hounds
if false {
fmt.Println(input, time.Since(start)) // test profiling
}
return true
}
开发者ID:Bosh-for-Cpi,项目名称:bosh-2605,代码行数:81,代码来源:interp_test.go
示例15: newOracle
func newOracle(imp *importer.Importer, args []string, ptalog io.Writer, needs int, reflection bool) (*Oracle, error) {
o := &Oracle{fset: imp.Fset}
// Load/parse/type-check program from args.
initialPkgInfos, args, err := imp.LoadInitialPackages(args)
if err != nil {
return nil, err // I/O or parser error
}
if len(args) > 0 {
return nil, fmt.Errorf("surplus arguments: %q", args)
}
// Retain type info for all ASTs in the program.
if needs&needRetainTypeInfo != 0 {
m := make(map[*types.Package]*importer.PackageInfo)
for _, p := range imp.AllPackages() {
m[p.Pkg] = p
}
o.typeInfo = m
}
// Create SSA package for the initial packages and their dependencies.
if needs&needSSA != 0 {
prog := ssa.NewProgram(o.fset, 0)
// Create SSA packages.
if err := prog.CreatePackages(imp); err != nil {
return nil, err
}
// For each initial package (specified on the command line),
// if it has a main function, analyze that,
// otherwise analyze its tests, if any.
var testPkgs, mains []*ssa.Package
for _, info := range initialPkgInfos {
initialPkg := prog.Package(info.Pkg)
// Add package to the pointer analysis scope.
if initialPkg.Func("main") != nil {
mains = append(mains, initialPkg)
} else {
testPkgs = append(testPkgs, initialPkg)
}
}
if testPkgs != nil {
if p := prog.CreateTestMainPackage(testPkgs...); p != nil {
mains = append(mains, p)
}
}
if mains == nil {
return nil, fmt.Errorf("analysis scope has no main and no tests")
}
o.ptaConfig.Log = ptalog
o.ptaConfig.Reflection = reflection
o.ptaConfig.Mains = mains
if needs&needSSADebug != 0 {
for _, pkg := range prog.AllPackages() {
pkg.SetDebugMode(true)
}
}
o.prog = prog
}
return o, nil
}
开发者ID:ufo22940268,项目名称:two-server-others,代码行数:67,代码来源:oracle.go
示例16: TestValueForExpr
// Ensure that, in debug mode, we can determine the ssa.Value
// corresponding to every ast.Expr.
func TestValueForExpr(t *testing.T) {
imp := importer.New(new(importer.Config)) // (uses GCImporter)
f, err := parser.ParseFile(imp.Fset, "testdata/valueforexpr.go", nil,
parser.DeclarationErrors|parser.ParseComments)
if err != nil {
t.Error(err)
return
}
mainInfo := imp.LoadMainPackage(f)
prog := ssa.NewProgram(imp.Fset, 0)
if err := prog.CreatePackages(imp); err != nil {
t.Error(err)
return
}
mainPkg := prog.Package(mainInfo.Pkg)
mainPkg.SetDebugMode(true)
mainPkg.Build()
fn := mainPkg.Func("f")
if false {
fn.DumpTo(os.Stderr) // debugging
}
// Find the actual AST node for each canonical position.
parenExprByPos := make(map[token.Pos]*ast.ParenExpr)
ast.Inspect(f, func(n ast.Node) bool {
if n != nil {
if e, ok := n.(*ast.ParenExpr); ok {
parenExprByPos[e.Pos()] = e
}
}
return true
})
// Find all annotations of form /*@kind*/.
for _, c := range f.Comments {
text := strings.TrimSpace(c.Text())
if text == "" || text[0] != '@' {
continue
}
text = text[1:]
pos := c.End() + 1
position := imp.Fset.Position(pos)
var e ast.Expr
if target := parenExprByPos[pos]; target == nil {
t.Errorf("%s: annotation doesn't precede ParenExpr: %q", position, text)
continue
} else {
e = target.X
}
v := fn.ValueForExpr(e) // (may be nil)
got := strings.TrimPrefix(fmt.Sprintf("%T", v), "*ssa.")
if want := text; got != want {
t.Errorf("%s: got value %q, want %q", position, got, want)
}
if v != nil {
if !types.IsIdentical(v.Type(), mainInfo.TypeOf(e)) {
t.Errorf("%s: got type %s, want %s", position, mainInfo.TypeOf(e), v.Type())
}
}
}
}
开发者ID:nagyistge,项目名称:hm-workspace,代码行数:68,代码来源:source_test.go
示例17: main
func main() {
flag.Parse()
args := flag.Args()
impctx := importer.Config{Build: &build.Default}
var debugMode bool
var mode ssa.BuilderMode
for _, c := range *buildFlag {
switch c {
case 'D':
debugMode = true
case 'P':
mode |= ssa.LogPackages | ssa.BuildSerially
case 'F':
mode |= ssa.LogFunctions | ssa.BuildSerially
case 'S':
mode |= ssa.LogSource | ssa.BuildSerially
case 'C':
mode |= ssa.SanityCheckFunctions
case 'N':
mode |= ssa.NaiveForm
case 'G':
impctx.Build = nil
case 'L':
mode |= ssa.BuildSerially
default:
log.Fatalf("Unknown -build option: '%c'.", c)
}
}
var interpMode interp.Mode
for _, c := range *interpFlag {
switch c {
case 'T':
interpMode |= interp.EnableTracing
case 'R':
interpMode |= interp.DisableRecover
default:
log.Fatalf("Unknown -interp option: '%c'.", c)
}
}
if len(args) == 0 {
fmt.Fprint(os.Stderr, usage)
os.Exit(1)
}
// Profiling support.
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
// Load, parse and type-check the program.
imp := importer.New(&impctx)
infos, args, err := imp.LoadInitialPackages(args)
if err != nil {
log.Fatal(err)
}
// Create and build SSA-form program representation.
prog := ssa.NewProgram(imp.Fset, mode)
if err := prog.CreatePackages(imp); err != nil {
log.Fatal(err)
}
if debugMode {
for _, pkg := range prog.AllPackages() {
pkg.SetDebugMode(true)
}
}
prog.BuildAll()
// Run the interpreter on the first package with a main function.
if *runFlag {
var main *ssa.Package
for _, info := range infos {
pkg := prog.Package(info.Pkg)
if pkg.Func("main") != nil || pkg.CreateTestMainFunction() != nil {
main = pkg
break
}
}
if main == nil {
log.Fatal("No main function")
}
interp.Interpret(main, interpMode, main.Object.Path(), args)
}
}
开发者ID:nagyistge,项目名称:hm-workspace,代码行数:93,代码来源:main.go
示例18: TestEnclosingFunction
// TODO(adonovan): move this test into ssa.
func TestEnclosingFunction(t *testing.T) {
tests := []struct {
input string // the input file
substr string // first occurrence of this string denotes interval
fn string // name of expected containing function
}{
// We use distinctive numbers as syntactic landmarks.
// Ordinary function:
{`package main
func f() { println(1003) }`,
"100", "main.f"},
// Methods:
{`package main
type T int
func (t T) f() { println(200) }`,
"200", "(main.T).f"},
// Function literal:
{`package main
func f() { println(func() { print(300) }) }`,
"300", "[email protected]"},
// Doubly nested
{`package main
func f() { println(func() { print(func() { print(350) })})}`,
"350", "[email protected]"},
// Implicit init for package-level var initializer.
{"package main; var a = 400", "400", "main.init"},
// No code for constants:
{"package main; const a = 500", "500", "(none)"},
// Explicit init()
{"package main; func init() { println(600) }", "600", "main.init$1"},
// Multiple explicit init functions:
{`package main
func init() { println("foo") }
func init() { println(800) }`,
"800", "main.init$2"},
// init() containing FuncLit.
{`package main
func init() { println(func(){print(900)}) }`,
"900", "[email protected]"},
}
for _, test := range tests {
imp := import
|
请发表评论