diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:40 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:40 +0200 |
commit | 5ff4c17907d5b19510a62e08fd8d3b11e62b431d (patch) | |
tree | c0650497e988f47be9c6f2324fa692a52dea82e1 /src/cmd/gofmt/simplify.go | |
parent | 80f18fc933cf3f3e829c5455a1023d69f7b86e52 (diff) | |
download | golang-upstream/60.tar.gz |
Imported Upstream version 60upstream/60
Diffstat (limited to 'src/cmd/gofmt/simplify.go')
-rw-r--r-- | src/cmd/gofmt/simplify.go | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/cmd/gofmt/simplify.go b/src/cmd/gofmt/simplify.go new file mode 100644 index 000000000..d9afc0e7b --- /dev/null +++ b/src/cmd/gofmt/simplify.go @@ -0,0 +1,65 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "go/ast" + "reflect" +) + +type simplifier struct{} + +func (s *simplifier) Visit(node ast.Node) ast.Visitor { + switch n := node.(type) { + case *ast.CompositeLit: + // array, slice, and map composite literals may be simplified + outer := n + var eltType ast.Expr + switch typ := outer.Type.(type) { + case *ast.ArrayType: + eltType = typ.Elt + case *ast.MapType: + eltType = typ.Value + } + + if eltType != nil { + typ := reflect.ValueOf(eltType) + for _, x := range outer.Elts { + // look at value of indexed/named elements + if t, ok := x.(*ast.KeyValueExpr); ok { + x = t.Value + } + simplify(x) + // if the element is a composite literal and its literal type + // matches the outer literal's element type exactly, the inner + // literal type may be omitted + if inner, ok := x.(*ast.CompositeLit); ok { + if match(nil, typ, reflect.ValueOf(inner.Type)) { + inner.Type = nil + } + } + } + + // node was simplified - stop walk (there are no subnodes to simplify) + return nil + } + + case *ast.RangeStmt: + // range of the form: for x, _ = range v {...} + // can be simplified to: for x = range v {...} + if n.Value != nil { + if ident, ok := n.Value.(*ast.Ident); ok && ident.Name == "_" { + n.Value = nil + } + } + } + + return s +} + +func simplify(node ast.Node) { + var s simplifier + ast.Walk(&s, node) +} |