1 | // Copyright 2014 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 rename |
6 | |
7 | import ( |
8 | "go/ast" |
9 | "go/token" |
10 | "go/types" |
11 | "os" |
12 | "path/filepath" |
13 | "reflect" |
14 | "runtime" |
15 | "strings" |
16 | "unicode" |
17 | |
18 | "golang.org/x/tools/go/ast/astutil" |
19 | ) |
20 | |
21 | func objectKind(obj types.Object) string { |
22 | switch obj := obj.(type) { |
23 | case *types.PkgName: |
24 | return "imported package name" |
25 | case *types.TypeName: |
26 | return "type" |
27 | case *types.Var: |
28 | if obj.IsField() { |
29 | return "field" |
30 | } |
31 | case *types.Func: |
32 | if obj.Type().(*types.Signature).Recv() != nil { |
33 | return "method" |
34 | } |
35 | } |
36 | // label, func, var, const |
37 | return strings.ToLower(strings.TrimPrefix(reflect.TypeOf(obj).String(), "*types.")) |
38 | } |
39 | |
40 | func typeKind(T types.Type) string { |
41 | return strings.ToLower(strings.TrimPrefix(reflect.TypeOf(T.Underlying()).String(), "*types.")) |
42 | } |
43 | |
44 | // NB: for renamings, blank is not considered valid. |
45 | func isValidIdentifier(id string) bool { |
46 | if id == "" || id == "_" { |
47 | return false |
48 | } |
49 | for i, r := range id { |
50 | if !isLetter(r) && (i == 0 || !isDigit(r)) { |
51 | return false |
52 | } |
53 | } |
54 | return token.Lookup(id) == token.IDENT |
55 | } |
56 | |
57 | // isLocal reports whether obj is local to some function. |
58 | // Precondition: not a struct field or interface method. |
59 | func isLocal(obj types.Object) bool { |
60 | // [... 5=stmt 4=func 3=file 2=pkg 1=universe] |
61 | var depth int |
62 | for scope := obj.Parent(); scope != nil; scope = scope.Parent() { |
63 | depth++ |
64 | } |
65 | return depth >= 4 |
66 | } |
67 | |
68 | func isPackageLevel(obj types.Object) bool { |
69 | return obj.Pkg().Scope().Lookup(obj.Name()) == obj |
70 | } |
71 | |
72 | // -- Plundered from go/scanner: --------------------------------------- |
73 | |
74 | func isLetter(ch rune) bool { |
75 | return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch) |
76 | } |
77 | |
78 | func isDigit(ch rune) bool { |
79 | return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch) |
80 | } |
81 | |
82 | // -- Plundered from golang.org/x/tools/cmd/guru ----------------- |
83 | |
84 | // sameFile returns true if x and y have the same basename and denote |
85 | // the same file. |
86 | func sameFile(x, y string) bool { |
87 | if runtime.GOOS == "windows" { |
88 | x = filepath.ToSlash(x) |
89 | y = filepath.ToSlash(y) |
90 | } |
91 | if x == y { |
92 | return true |
93 | } |
94 | if filepath.Base(x) == filepath.Base(y) { // (optimisation) |
95 | if xi, err := os.Stat(x); err == nil { |
96 | if yi, err := os.Stat(y); err == nil { |
97 | return os.SameFile(xi, yi) |
98 | } |
99 | } |
100 | } |
101 | return false |
102 | } |
103 | |
104 | func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) } |
105 |
Members