...
Source file src/cmd/vendor/golang.org/x/tools/go/analysis/passes/internal/analysisutil/util.go
1
2
3 package analysisutil
4
5 import (
6 "bytes"
7 "go/ast"
8 "go/printer"
9 "go/token"
10 "go/types"
11 "io/ioutil"
12 )
13
14
15 func Format(fset *token.FileSet, x ast.Expr) string {
16 var b bytes.Buffer
17 printer.Fprint(&b, fset, x)
18 return b.String()
19 }
20
21
22 func HasSideEffects(info *types.Info, e ast.Expr) bool {
23 safe := true
24 ast.Inspect(e, func(node ast.Node) bool {
25 switch n := node.(type) {
26 case *ast.CallExpr:
27 typVal := info.Types[n.Fun]
28 switch {
29 case typVal.IsType():
30
31 case typVal.IsBuiltin():
32
33
34 safe = false
35 return false
36 default:
37
38
39
40 safe = false
41 return false
42 }
43 case *ast.UnaryExpr:
44 if n.Op == token.ARROW {
45 safe = false
46 return false
47 }
48 }
49 return true
50 })
51 return !safe
52 }
53
54
55 func Unparen(e ast.Expr) ast.Expr {
56 for {
57 p, ok := e.(*ast.ParenExpr)
58 if !ok {
59 return e
60 }
61 e = p.X
62 }
63 }
64
65
66
67 func ReadFile(fset *token.FileSet, filename string) ([]byte, *token.File, error) {
68 content, err := ioutil.ReadFile(filename)
69 if err != nil {
70 return nil, nil, err
71 }
72 tf := fset.AddFile(filename, -1, len(content))
73 tf.SetLinesForContent(content)
74 return content, tf, nil
75 }
76
77
78
79 func LineStart(f *token.File, line int) token.Pos {
80
81
82
83
84
85
86 min := 0
87 max := f.Size()
88 for {
89 offset := (min + max) / 2
90 pos := f.Pos(offset)
91 posn := f.Position(pos)
92 if posn.Line == line {
93 return pos - (token.Pos(posn.Column) - 1)
94 }
95
96 if min+1 >= max {
97 return token.NoPos
98 }
99
100 if posn.Line < line {
101 min = offset
102 } else {
103 max = offset
104 }
105 }
106 }
107
View as plain text