golang.org/x/tools@v0.21.1-0.20240520172518-788d39e776b1/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: // defined type | alias | type parameter 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 // NB: for renamings, blank is not considered valid. 41 func isValidIdentifier(id string) bool { 42 if id == "" || id == "_" { 43 return false 44 } 45 for i, r := range id { 46 if !isLetter(r) && (i == 0 || !isDigit(r)) { 47 return false 48 } 49 } 50 return token.Lookup(id) == token.IDENT 51 } 52 53 // isLocal reports whether obj is local to some function. 54 // Precondition: not a struct field or interface method. 55 func isLocal(obj types.Object) bool { 56 // [... 5=stmt 4=func 3=file 2=pkg 1=universe] 57 var depth int 58 for scope := obj.Parent(); scope != nil; scope = scope.Parent() { 59 depth++ 60 } 61 return depth >= 4 62 } 63 64 func isPackageLevel(obj types.Object) bool { 65 return obj.Pkg().Scope().Lookup(obj.Name()) == obj 66 } 67 68 // -- Plundered from go/scanner: --------------------------------------- 69 70 func isLetter(ch rune) bool { 71 return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch) 72 } 73 74 func isDigit(ch rune) bool { 75 return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch) 76 } 77 78 // -- Plundered from golang.org/x/tools/cmd/guru ----------------- 79 80 // sameFile returns true if x and y have the same basename and denote 81 // the same file. 82 func sameFile(x, y string) bool { 83 if runtime.GOOS == "windows" { 84 x = filepath.ToSlash(x) 85 y = filepath.ToSlash(y) 86 } 87 if x == y { 88 return true 89 } 90 if filepath.Base(x) == filepath.Base(y) { // (optimisation) 91 if xi, err := os.Stat(x); err == nil { 92 if yi, err := os.Stat(y); err == nil { 93 return os.SameFile(xi, yi) 94 } 95 } 96 } 97 return false 98 } 99 100 func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) } 101 102 func is[T any](x any) bool { 103 _, ok := x.(T) 104 return ok 105 }