gitee.com/wgliang/goreporter@v0.0.0-20180902115603-df1b20f7c5d0/linters/simpler/ssa/example_test.go (about)

     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.
     4  
     5  // +build go1.5
     6  
     7  package ssa_test
     8  
     9  import (
    10  	"fmt"
    11  	"go/ast"
    12  	"go/importer"
    13  	"go/parser"
    14  	"go/token"
    15  	"go/types"
    16  	"os"
    17  
    18  	"github.com/360EntSecGroup-Skylar/goreporter/linters/simpler/ssa"
    19  	"github.com/360EntSecGroup-Skylar/goreporter/linters/simpler/ssa/ssautil"
    20  	"golang.org/x/tools/go/loader"
    21  )
    22  
    23  const hello = `
    24  package main
    25  
    26  import "fmt"
    27  
    28  const message = "Hello, World!"
    29  
    30  func main() {
    31  	fmt.Println(message)
    32  }
    33  `
    34  
    35  // This program demonstrates how to run the SSA builder on a single
    36  // package of one or more already-parsed files.  Its dependencies are
    37  // loaded from compiler export data.  This is what you'd typically use
    38  // for a compiler; it does not depend on golang.org/x/tools/go/loader.
    39  //
    40  // It shows the printed representation of packages, functions, and
    41  // instructions.  Within the function listing, the name of each
    42  // BasicBlock such as ".0.entry" is printed left-aligned, followed by
    43  // the block's Instructions.
    44  //
    45  // For each instruction that defines an SSA virtual register
    46  // (i.e. implements Value), the type of that value is shown in the
    47  // right column.
    48  //
    49  // Build and run the ssadump.go program if you want a standalone tool
    50  // with similar functionality. It is located at
    51  // golang.org/x/tools/cmd/ssadump.
    52  //
    53  func ExampleBuildPackage() {
    54  	// Parse the source files.
    55  	fset := token.NewFileSet()
    56  	f, err := parser.ParseFile(fset, "hello.go", hello, parser.ParseComments)
    57  	if err != nil {
    58  		fmt.Print(err) // parse error
    59  		return
    60  	}
    61  	files := []*ast.File{f}
    62  
    63  	// Create the type-checker's package.
    64  	pkg := types.NewPackage("hello", "")
    65  
    66  	// Type-check the package, load dependencies.
    67  	// Create and build the SSA program.
    68  	hello, _, err := ssautil.BuildPackage(
    69  		&types.Config{Importer: importer.Default()}, fset, pkg, files, ssa.SanityCheckFunctions)
    70  	if err != nil {
    71  		fmt.Print(err) // type error in some package
    72  		return
    73  	}
    74  
    75  	// Print out the package.
    76  	hello.WriteTo(os.Stdout)
    77  
    78  	// Print out the package-level functions.
    79  	hello.Func("init").WriteTo(os.Stdout)
    80  	hello.Func("main").WriteTo(os.Stdout)
    81  
    82  	// Output:
    83  	//
    84  	// package hello:
    85  	//   func  init       func()
    86  	//   var   init$guard bool
    87  	//   func  main       func()
    88  	//   const message    message = "Hello, World!":untyped string
    89  	//
    90  	// # Name: hello.init
    91  	// # Package: hello
    92  	// # Synthetic: package initializer
    93  	// func init():
    94  	// 0:                                                                entry P:0 S:2
    95  	// 	t0 = *init$guard                                                   bool
    96  	// 	if t0 goto 2 else 1
    97  	// 1:                                                           init.start P:1 S:1
    98  	// 	*init$guard = true:bool
    99  	// 	t1 = fmt.init()                                                      ()
   100  	// 	jump 2
   101  	// 2:                                                            init.done P:2 S:0
   102  	// 	return
   103  	//
   104  	// # Name: hello.main
   105  	// # Package: hello
   106  	// # Location: hello.go:8:6
   107  	// func main():
   108  	// 0:                                                                entry P:0 S:0
   109  	// 	t0 = new [1]interface{} (varargs)                       *[1]interface{}
   110  	// 	t1 = &t0[0:int]                                            *interface{}
   111  	// 	t2 = make interface{} <- string ("Hello, World!":string)    interface{}
   112  	// 	*t1 = t2
   113  	// 	t3 = slice t0[:]                                          []interface{}
   114  	// 	t4 = fmt.Println(t3...)                              (n int, err error)
   115  	// 	return
   116  }
   117  
   118  // This program shows how to load a main package (cmd/cover) and all its
   119  // dependencies from source, using the loader, and then build SSA code
   120  // for the entire program.  This is what you'd typically use for a
   121  // whole-program analysis.
   122  //
   123  func ExampleLoadProgram() {
   124  	// Load cmd/cover and its dependencies.
   125  	var conf loader.Config
   126  	conf.Import("cmd/cover")
   127  	lprog, err := conf.Load()
   128  	if err != nil {
   129  		fmt.Print(err) // type error in some package
   130  		return
   131  	}
   132  
   133  	// Create SSA-form program representation.
   134  	prog := ssautil.CreateProgram(lprog, ssa.SanityCheckFunctions)
   135  
   136  	// Build SSA code for the entire cmd/cover program.
   137  	prog.Build()
   138  
   139  	// Output:
   140  }