]> Cypherpunks repositories - gostls13.git/commitdiff
gofmt: don't attempt certain illegal rewrites
authorRobert Griesemer <gri@golang.org>
Fri, 7 Jan 2011 23:04:41 +0000 (15:04 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 7 Jan 2011 23:04:41 +0000 (15:04 -0800)
(e.g.: echo 'package main' | gofmt -r 'x->7'
cannot change the package name to 7)

R=rsc
CC=golang-dev
https://golang.org/cl/3913041

src/cmd/gofmt/rewrite.go

index a87dbeb8cda1adcd51fcabfb345bf8c64e9558e0..8ea5334e97a7b616dccc6ae420fc452cdedbb93f 100644 (file)
@@ -66,13 +66,19 @@ func rewriteFile(pattern, replace ast.Expr, p *ast.File) *ast.File {
 }
 
 
-var positionType = reflect.Typeof(token.NoPos)
-var identType = reflect.Typeof((*ast.Ident)(nil))
-
-
-func isWildcard(s string) bool {
-       rune, size := utf8.DecodeRuneInString(s)
-       return size == len(s) && unicode.IsLower(rune)
+// setValue is a wrapper for x.SetValue(y); it protects
+// the caller from panics if x cannot be changed to y.
+func setValue(x, y reflect.Value) {
+       defer func() {
+               if x := recover(); x != nil {
+                       if s, ok := x.(string); ok && strings.HasPrefix(s, "type mismatch") {
+                               // x cannot be set to y - ignore this rewrite
+                               return
+                       }
+                       panic(x)
+               }
+       }()
+       x.SetValue(y)
 }
 
 
@@ -86,21 +92,31 @@ func apply(f func(reflect.Value) reflect.Value, val reflect.Value) reflect.Value
        case *reflect.SliceValue:
                for i := 0; i < v.Len(); i++ {
                        e := v.Elem(i)
-                       e.SetValue(f(e))
+                       setValue(e, f(e))
                }
        case *reflect.StructValue:
                for i := 0; i < v.NumField(); i++ {
                        e := v.Field(i)
-                       e.SetValue(f(e))
+                       setValue(e, f(e))
                }
        case *reflect.InterfaceValue:
                e := v.Elem()
-               v.SetValue(f(e))
+               setValue(v, f(e))
        }
        return val
 }
 
 
+var positionType = reflect.Typeof(token.NoPos)
+var identType = reflect.Typeof((*ast.Ident)(nil))
+
+
+func isWildcard(s string) bool {
+       rune, size := utf8.DecodeRuneInString(s)
+       return size == len(s) && unicode.IsLower(rune)
+}
+
+
 // match returns true if pattern matches val,
 // recording wildcard submatches in m.
 // If m == nil, match checks whether pattern == val.