import_tracker.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. Copyright 2015 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package namer
  14. import (
  15. "sort"
  16. "k8s.io/gengo/types"
  17. )
  18. // ImportTracker may be passed to a namer.RawNamer, to track the imports needed
  19. // for the types it names.
  20. //
  21. // TODO: pay attention to the package name (instead of renaming every package).
  22. type DefaultImportTracker struct {
  23. pathToName map[string]string
  24. // forbidden names are in here. (e.g. "go" is a directory in which
  25. // there is code, but "go" is not a legal name for a package, so we put
  26. // it here to prevent us from naming any package "go")
  27. nameToPath map[string]string
  28. local types.Name
  29. // Returns true if a given types is an invalid type and should be ignored.
  30. IsInvalidType func(*types.Type) bool
  31. // Returns the final local name for the given name
  32. LocalName func(types.Name) string
  33. // Returns the "import" line for a given (path, name).
  34. PrintImport func(string, string) string
  35. }
  36. func NewDefaultImportTracker(local types.Name) DefaultImportTracker {
  37. return DefaultImportTracker{
  38. pathToName: map[string]string{},
  39. nameToPath: map[string]string{},
  40. local: local,
  41. }
  42. }
  43. func (tracker *DefaultImportTracker) AddTypes(types ...*types.Type) {
  44. for _, t := range types {
  45. tracker.AddType(t)
  46. }
  47. }
  48. func (tracker *DefaultImportTracker) AddType(t *types.Type) {
  49. if tracker.local.Package == t.Name.Package {
  50. return
  51. }
  52. if tracker.IsInvalidType(t) {
  53. if t.Kind == types.Builtin {
  54. return
  55. }
  56. if _, ok := tracker.nameToPath[t.Name.Package]; !ok {
  57. tracker.nameToPath[t.Name.Package] = ""
  58. }
  59. return
  60. }
  61. if len(t.Name.Package) == 0 {
  62. return
  63. }
  64. path := t.Name.Path
  65. if len(path) == 0 {
  66. path = t.Name.Package
  67. }
  68. if _, ok := tracker.pathToName[path]; ok {
  69. return
  70. }
  71. name := tracker.LocalName(t.Name)
  72. tracker.nameToPath[name] = path
  73. tracker.pathToName[path] = name
  74. }
  75. func (tracker *DefaultImportTracker) ImportLines() []string {
  76. importPaths := []string{}
  77. for path := range tracker.pathToName {
  78. importPaths = append(importPaths, path)
  79. }
  80. sort.Sort(sort.StringSlice(importPaths))
  81. out := []string{}
  82. for _, path := range importPaths {
  83. out = append(out, tracker.PrintImport(path, tracker.pathToName[path]))
  84. }
  85. return out
  86. }
  87. // LocalNameOf returns the name you would use to refer to the package at the
  88. // specified path within the body of a file.
  89. func (tracker *DefaultImportTracker) LocalNameOf(path string) string {
  90. return tracker.pathToName[path]
  91. }
  92. // PathOf returns the path that a given localName is referring to within the
  93. // body of a file.
  94. func (tracker *DefaultImportTracker) PathOf(localName string) (string, bool) {
  95. name, ok := tracker.nameToPath[localName]
  96. return name, ok
  97. }