~ubuntu-branches/ubuntu/utopic/golang/utopic

« back to all changes in this revision

Viewing changes to src/cmd/fix/mapdelete.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2011 The Go Authors.  All rights reserved.
2
 
// Use of this source code is governed by a BSD-style
3
 
// license that can be found in the LICENSE file.
4
 
 
5
 
package main
6
 
 
7
 
import "go/ast"
8
 
 
9
 
func init() {
10
 
        register(mapdeleteFix)
11
 
}
12
 
 
13
 
var mapdeleteFix = fix{
14
 
        "mapdelete",
15
 
        "2011-10-18",
16
 
        mapdelete,
17
 
        `Use delete(m, k) instead of m[k] = 0, false.
18
 
 
19
 
http://codereview.appspot.com/5272045
20
 
`,
21
 
}
22
 
 
23
 
func mapdelete(f *ast.File) bool {
24
 
        fixed := false
25
 
        walk(f, func(n interface{}) {
26
 
                stmt, ok := n.(*ast.Stmt)
27
 
                if !ok {
28
 
                        return
29
 
                }
30
 
                as, ok := (*stmt).(*ast.AssignStmt)
31
 
                if !ok || len(as.Lhs) != 1 || len(as.Rhs) != 2 {
32
 
                        return
33
 
                }
34
 
                ix, ok := as.Lhs[0].(*ast.IndexExpr)
35
 
                if !ok {
36
 
                        return
37
 
                }
38
 
                if !isTopName(as.Rhs[1], "false") {
39
 
                        warn(as.Pos(), "two-element map assignment with non-false second value")
40
 
                        return
41
 
                }
42
 
                if !canDrop(as.Rhs[0]) {
43
 
                        warn(as.Pos(), "two-element map assignment with non-trivial first value")
44
 
                        return
45
 
                }
46
 
                *stmt = &ast.ExprStmt{
47
 
                        X: &ast.CallExpr{
48
 
                                Fun: &ast.Ident{
49
 
                                        NamePos: as.Pos(),
50
 
                                        Name:    "delete",
51
 
                                },
52
 
                                Args: []ast.Expr{ix.X, ix.Index},
53
 
                        },
54
 
                }
55
 
                fixed = true
56
 
        })
57
 
        return fixed
58
 
}
59
 
 
60
 
// canDrop reports whether it is safe to drop the
61
 
// evaluation of n from the program.
62
 
// It is very conservative.
63
 
func canDrop(n ast.Expr) bool {
64
 
        switch n := n.(type) {
65
 
        case *ast.Ident, *ast.BasicLit:
66
 
                return true
67
 
        case *ast.ParenExpr:
68
 
                return canDrop(n.X)
69
 
        case *ast.SelectorExpr:
70
 
                return canDrop(n.X)
71
 
        case *ast.CompositeLit:
72
 
                if !canDrop(n.Type) {
73
 
                        return false
74
 
                }
75
 
                for _, e := range n.Elts {
76
 
                        if !canDrop(e) {
77
 
                                return false
78
 
                        }
79
 
                }
80
 
                return true
81
 
        case *ast.StarExpr:
82
 
                // Dropping *x is questionable,
83
 
                // but we have to be able to drop (*T)(nil).
84
 
                return canDrop(n.X)
85
 
        case *ast.ArrayType, *ast.ChanType, *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.StructType:
86
 
                return true
87
 
        }
88
 
        return false
89
 
}