github.com/acwpower/studygo@v0.0.0-20220210033106-9f3f6e60fdcc/pkg/mod/golang.org/x/tools@v0.1.1/refactor/rename/util.go (about) 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 // 87 func sameFile(x, y string) bool { 88 if runtime.GOOS == "windows" { 89 x = filepath.ToSlash(x) 90 y = filepath.ToSlash(y) 91 } 92 if x == y { 93 return true 94 } 95 if filepath.Base(x) == filepath.Base(y) { // (optimisation) 96 if xi, err := os.Stat(x); err == nil { 97 if yi, err := os.Stat(y); err == nil { 98 return os.SameFile(xi, yi) 99 } 100 } 101 } 102 return false 103 } 104 105 func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) }