You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
garble/internal/ctrlflow/trash_test.go

102 lines
2.4 KiB
Go

package ctrlflow
import (
"fmt"
"go/ast"
"go/importer"
"go/printer"
"go/token"
"go/types"
mathrand "math/rand"
"os"
"strconv"
"testing"
"golang.org/x/tools/go/ast/astutil"
"golang.org/x/tools/go/ssa"
"golang.org/x/tools/go/ssa/ssautil"
ah "mvdan.cc/garble/internal/asthelper"
)
// Test_generateTrashBlock tests correctness of generated trash code by generating and compiling a large number of statements
func Test_generateTrashBlock(t *testing.T) {
const (
seed = 7777
stmtCount = 1024
)
fset := token.NewFileSet()
buildPkg := func(f *ast.File) *ssa.Package {
ssaPkg, _, err := ssautil.BuildPackage(&types.Config{Importer: importer.Default()}, fset, types.NewPackage("test/main", ""), []*ast.File{f}, 0)
if err != nil {
t.Fatal(err)
}
return ssaPkg
}
body := &ast.BlockStmt{}
file := &ast.File{
Name: ast.NewIdent("main"),
Decls: []ast.Decl{
&ast.GenDecl{
Tok: token.IMPORT,
Specs: []ast.Spec{
&ast.ImportSpec{
Name: ast.NewIdent("_"),
Path: ah.StringLit("os"),
},
&ast.ImportSpec{
Name: ast.NewIdent("_"),
Path: ah.StringLit("math"),
},
&ast.ImportSpec{
Name: ast.NewIdent("_"),
Path: ah.StringLit("fmt"),
},
},
},
&ast.FuncDecl{
Name: ast.NewIdent("main"),
Type: &ast.FuncType{Params: &ast.FieldList{}},
Body: body,
},
},
}
beforeSsaPkg := buildPkg(file)
imports := make(map[string]string)
gen := newTrashGenerator(beforeSsaPkg.Prog, func(pkg *types.Package) *ast.Ident {
if pkg == nil || pkg.Path() == beforeSsaPkg.Pkg.Path() {
return nil
}
name, ok := imports[pkg.Path()]
if !ok {
name = importPrefix + strconv.Itoa(len(imports))
imports[pkg.Path()] = name
astutil.AddNamedImport(fset, file, name, pkg.Path())
}
return ast.NewIdent(name)
}, mathrand.New(mathrand.NewSource(seed)))
predefinedArgs := make(map[string]types.Type)
for i := types.Bool; i < types.UnsafePointer; i++ {
name, typ := fmt.Sprintf("v%d", i), types.Typ[i]
predefinedArgs[name] = typ
body.List = append(body.List,
&ast.DeclStmt{Decl: &ast.GenDecl{
Tok: token.VAR,
Specs: []ast.Spec{&ast.ValueSpec{
Names: []*ast.Ident{ast.NewIdent(name)},
Type: ast.NewIdent(typ.Name()),
}},
}},
ah.AssignStmt(ast.NewIdent("_"), ast.NewIdent(name)),
)
}
body.List = append(body.List, gen.Generate(stmtCount, predefinedArgs)...)
printer.Fprint(os.Stdout, fset, file)
buildPkg(file)
}