support type switches with symbolic vars

pull/22/head
Daniel Martí 5 years ago
parent 766bb47b82
commit aba66758ca

@ -2,4 +2,7 @@ module mvdan.cc/garble
go 1.14
require github.com/rogpeppe/go-internal v1.5.0
require (
github.com/rogpeppe/go-internal v1.5.0
golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd
)

@ -1,8 +1,19 @@
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/rogpeppe/go-internal v1.5.0 h1:Usqs0/lDK/NqTkvrmKSwA/3XkZAs7ZAW/eLeQ2MVBTw=
github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd h1:Zc7EU2PqpsNeIfOoVA7hvQX4cS3YDJEs5KlfatT3hLo=
golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=

@ -22,6 +22,8 @@ import (
"os/exec"
"path/filepath"
"strings"
"golang.org/x/tools/go/ast/astutil"
)
var flagSet = flag.NewFlagSet("garble", flag.ContinueOnError)
@ -186,8 +188,9 @@ func transformCompile(args []string) ([]string, error) {
return nil, fmt.Errorf("typecheck error: %v", err)
}
for i, file := range files {
file := transformGoFile(file, info)
args = flags
for _, file := range files {
file := transformGo(file, info)
f, err := ioutil.TempFile("", "garble")
if err != nil {
return nil, err
@ -203,9 +206,9 @@ func transformCompile(args []string) ([]string, error) {
deferred = append(deferred, func() error {
return os.Remove(f.Name())
})
paths[i] = f.Name()
args = append(args, f.Name())
}
return append(flags, paths...), nil
return args, nil
}
func readBuildIDs(flags []string) error {
@ -284,12 +287,14 @@ func hashWith(salt, value string) string {
return "z" + sum[:length]
}
// transformGoFile creates a garbled copy of the Go file at path, and returns
// the path to the copy.
func transformGoFile(file *ast.File, info *types.Info) *ast.File {
ast.Inspect(file, func(node ast.Node) bool {
switch node := node.(type) {
// transformGo garbles the provided Go syntax node.
func transformGo(node ast.Node, info *types.Info) ast.Node {
pre := func(cursor *astutil.Cursor) bool {
switch node := cursor.Node().(type) {
case *ast.Ident:
if node.Name == "_" {
return true // unnamed remains unnamed
}
obj := info.ObjectOf(node)
switch obj.(type) {
case *types.Var:
@ -300,28 +305,36 @@ func transformGoFile(file *ast.File, info *types.Info) *ast.File {
case "main", "init":
return true // don't break them
}
case nil:
switch cursor.Parent().(type) {
case *ast.AssignStmt:
// symbolic var v in v := expr.(type)
default:
return true
}
default:
return true // we only want to rename the above
}
pkg := obj.Pkg()
if pkg == nil {
return true // universe scope
}
path := pkg.Path()
if !strings.Contains(path, ".") {
return true // std isn't transformed
}
buildID := buildInfo.buildID
if id := buildInfo.imports[path].buildID; id != "" {
buildID = id
if obj != nil {
pkg := obj.Pkg()
if pkg == nil {
return true // universe scope
}
path := pkg.Path()
if !strings.Contains(path, ".") {
return true // std isn't transformed
}
if id := buildInfo.imports[path].buildID; id != "" {
buildID = id
}
}
// log.Printf("%#v\n", node.Obj)
node.Name = hashWith(buildID, node.Name)
}
return true
})
return file
}
return astutil.Apply(node, pre, nil)
}
func transformLink(args []string) ([]string, error) {

@ -0,0 +1,19 @@
garble build main.go
exec ./main
cmp stderr main.stderr
-- main.go --
package main
var V interface{}
func main() {
switch V := V.(type) {
case int:
var _ int = V
case nil:
println("nil case")
}
}
-- main.stderr --
nil case
Loading…
Cancel
Save