summaryrefslogtreecommitdiff
path: root/src/cmd/gofmt/rewrite.go
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-01-17 12:40:45 +0100
committerOndřej Surý <ondrej@sury.org>2011-01-17 12:40:45 +0100
commit3e45412327a2654a77944249962b3652e6142299 (patch)
treebc3bf69452afa055423cbe0c5cfa8ca357df6ccf /src/cmd/gofmt/rewrite.go
parentc533680039762cacbc37db8dc7eed074c3e497be (diff)
downloadgolang-upstream/2011.01.12.tar.gz
Imported Upstream version 2011.01.12upstream/2011.01.12
Diffstat (limited to 'src/cmd/gofmt/rewrite.go')
-rw-r--r--src/cmd/gofmt/rewrite.go61
1 files changed, 42 insertions, 19 deletions
diff --git a/src/cmd/gofmt/rewrite.go b/src/cmd/gofmt/rewrite.go
index a89146ca0..8ea5334e9 100644
--- a/src/cmd/gofmt/rewrite.go
+++ b/src/cmd/gofmt/rewrite.go
@@ -37,7 +37,7 @@ func initRewrite() {
// but there are problems with preserving formatting and also
// with what a wildcard for a statement looks like.
func parseExpr(s string, what string) ast.Expr {
- x, err := parser.ParseExpr("input", s, nil)
+ x, err := parser.ParseExpr(fset, "input", s)
if err != nil {
fmt.Fprintf(os.Stderr, "parsing %s %s: %s\n", what, s, err)
os.Exit(2)
@@ -66,13 +66,19 @@ func rewriteFile(pattern, replace ast.Expr, p *ast.File) *ast.File {
}
-var positionType = reflect.Typeof(token.Position{})
-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.
@@ -109,17 +125,20 @@ func match(m map[string]reflect.Value, pattern, val reflect.Value) bool {
// times in the pattern, it must match the same expression
// each time.
if m != nil && pattern.Type() == identType {
- name := pattern.Interface().(*ast.Ident).Name()
+ name := pattern.Interface().(*ast.Ident).Name
if isWildcard(name) {
- if old, ok := m[name]; ok {
- return match(nil, old, val)
+ // wildcards only match expressions
+ if _, ok := val.Interface().(ast.Expr); ok {
+ if old, ok := m[name]; ok {
+ return match(nil, old, val)
+ }
+ m[name] = val
+ return true
}
- m[name] = val
- return true
}
}
- // Otherwise, the expressions must match recursively.
+ // Otherwise, pattern and val must match recursively.
if pattern == nil || val == nil {
return pattern == nil && val == nil
}
@@ -139,7 +158,7 @@ func match(m map[string]reflect.Value, pattern, val reflect.Value) bool {
// of recursing down any further via reflection.
p := pattern.Interface().(*ast.Ident)
v := val.Interface().(*ast.Ident)
- return p == nil && v == nil || p != nil && v != nil && p.Name() == v.Name()
+ return p == nil && v == nil || p != nil && v != nil && p.Name == v.Name
}
p := reflect.Indirect(pattern)
@@ -194,7 +213,7 @@ func subst(m map[string]reflect.Value, pattern reflect.Value, pos reflect.Value)
// Wildcard gets replaced with map value.
if m != nil && pattern.Type() == identType {
- name := pattern.Interface().(*ast.Ident).Name()
+ name := pattern.Interface().(*ast.Ident).Name
if isWildcard(name) {
if old, ok := m[name]; ok {
return subst(nil, old, nil)
@@ -203,6 +222,10 @@ func subst(m map[string]reflect.Value, pattern reflect.Value, pos reflect.Value)
}
if pos != nil && pattern.Type() == positionType {
+ // use new position only if old position was valid in the first place
+ if old := pattern.Interface().(token.Pos); !old.IsValid() {
+ return pattern
+ }
return pos
}