github.com/jd-ly/tools@v0.5.7/go/ssa/ssautil/load_test.go (about)

     1  // Copyright 2015 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.
     4  
     5  package ssautil_test
     6  
     7  import (
     8  	"bytes"
     9  	"go/ast"
    10  	"go/importer"
    11  	"go/parser"
    12  	"go/token"
    13  	"go/types"
    14  	"os"
    15  	"strings"
    16  	"testing"
    17  
    18  	"github.com/jd-ly/tools/go/packages"
    19  	"github.com/jd-ly/tools/go/ssa/ssautil"
    20  	"github.com/jd-ly/tools/internal/testenv"
    21  )
    22  
    23  const hello = `package main
    24  
    25  import "fmt"
    26  
    27  func main() {
    28  	fmt.Println("Hello, world")
    29  }
    30  `
    31  
    32  func TestBuildPackage(t *testing.T) {
    33  	// There is a more substantial test of BuildPackage and the
    34  	// SSA program it builds in ../ssa/builder_test.go.
    35  
    36  	fset := token.NewFileSet()
    37  	f, err := parser.ParseFile(fset, "hello.go", hello, 0)
    38  	if err != nil {
    39  		t.Fatal(err)
    40  	}
    41  
    42  	pkg := types.NewPackage("hello", "")
    43  	ssapkg, _, err := ssautil.BuildPackage(&types.Config{Importer: importer.Default()}, fset, pkg, []*ast.File{f}, 0)
    44  	if err != nil {
    45  		t.Fatal(err)
    46  	}
    47  	if pkg.Name() != "main" {
    48  		t.Errorf("pkg.Name() = %s, want main", pkg.Name())
    49  	}
    50  	if ssapkg.Func("main") == nil {
    51  		ssapkg.WriteTo(os.Stderr)
    52  		t.Errorf("ssapkg has no main function")
    53  	}
    54  }
    55  
    56  func TestPackages(t *testing.T) {
    57  	testenv.NeedsGoPackages(t)
    58  
    59  	cfg := &packages.Config{Mode: packages.LoadSyntax}
    60  	initial, err := packages.Load(cfg, "bytes")
    61  	if err != nil {
    62  		t.Fatal(err)
    63  	}
    64  	if packages.PrintErrors(initial) > 0 {
    65  		t.Fatal("there were errors")
    66  	}
    67  
    68  	prog, pkgs := ssautil.Packages(initial, 0)
    69  	bytesNewBuffer := pkgs[0].Func("NewBuffer")
    70  	bytesNewBuffer.Pkg.Build()
    71  
    72  	// We'll dump the SSA of bytes.NewBuffer because it is small and stable.
    73  	out := new(bytes.Buffer)
    74  	bytesNewBuffer.WriteTo(out)
    75  
    76  	// For determinism, sanitize the location.
    77  	location := prog.Fset.Position(bytesNewBuffer.Pos()).String()
    78  	got := strings.Replace(out.String(), location, "$GOROOT/src/bytes/buffer.go:1", -1)
    79  
    80  	want := `
    81  # Name: bytes.NewBuffer
    82  # Package: bytes
    83  # Location: $GOROOT/src/bytes/buffer.go:1
    84  func NewBuffer(buf []byte) *Buffer:
    85  0:                                                                entry P:0 S:0
    86  	t0 = new Buffer (complit)                                       *Buffer
    87  	t1 = &t0.buf [#0]                                               *[]byte
    88  	*t1 = buf
    89  	return t0
    90  
    91  `[1:]
    92  	if got != want {
    93  		t.Errorf("bytes.NewBuffer SSA = <<%s>>, want <<%s>>", got, want)
    94  	}
    95  }
    96  
    97  func TestBuildPackage_MissingImport(t *testing.T) {
    98  	fset := token.NewFileSet()
    99  	f, err := parser.ParseFile(fset, "bad.go", `package bad; import "missing"`, 0)
   100  	if err != nil {
   101  		t.Fatal(err)
   102  	}
   103  
   104  	pkg := types.NewPackage("bad", "")
   105  	ssapkg, _, err := ssautil.BuildPackage(new(types.Config), fset, pkg, []*ast.File{f}, 0)
   106  	if err == nil || ssapkg != nil {
   107  		t.Fatal("BuildPackage succeeded unexpectedly")
   108  	}
   109  }
   110  
   111  func TestIssue28106(t *testing.T) {
   112  	testenv.NeedsGoPackages(t)
   113  
   114  	// In go1.10, go/packages loads all packages from source, not
   115  	// export data, but does not type check function bodies of
   116  	// imported packages. This test ensures that we do not attempt
   117  	// to run the SSA builder on functions without type information.
   118  	cfg := &packages.Config{Mode: packages.LoadSyntax}
   119  	pkgs, err := packages.Load(cfg, "runtime")
   120  	if err != nil {
   121  		t.Fatal(err)
   122  	}
   123  	prog, _ := ssautil.Packages(pkgs, 0)
   124  	prog.Build() // no crash
   125  }