import_tracker.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package namer
  2. import (
  3. "sort"
  4. "go-common/app/tool/gengo/types"
  5. )
  6. // DefaultImportTracker is
  7. // ImportTracker may be passed to a namer.RawNamer, to track the imports needed
  8. // for the types it names.
  9. //
  10. // TODO: pay attention to the package name (instead of renaming every package).
  11. type DefaultImportTracker struct {
  12. pathToName map[string]string
  13. // forbidden names are in here. (e.g. "go" is a directory in which
  14. // there is code, but "go" is not a legal name for a package, so we put
  15. // it here to prevent us from naming any package "go")
  16. nameToPath map[string]string
  17. local types.Name
  18. // Returns true if a given types is an invalid type and should be ignored.
  19. IsInvalidType func(*types.Type) bool
  20. // Returns the final local name for the given name
  21. LocalName func(types.Name) string
  22. // Returns the "import" line for a given (path, name).
  23. PrintImport func(string, string) string
  24. }
  25. // NewDefaultImportTracker is
  26. func NewDefaultImportTracker(local types.Name) DefaultImportTracker {
  27. return DefaultImportTracker{
  28. pathToName: map[string]string{},
  29. nameToPath: map[string]string{},
  30. local: local,
  31. }
  32. }
  33. // AddTypes is
  34. func (tracker *DefaultImportTracker) AddTypes(types ...*types.Type) {
  35. for _, t := range types {
  36. tracker.AddType(t)
  37. }
  38. }
  39. // AddType is
  40. func (tracker *DefaultImportTracker) AddType(t *types.Type) {
  41. if tracker.local.Package == t.Name.Package {
  42. return
  43. }
  44. if tracker.IsInvalidType(t) {
  45. if t.Kind == types.Builtin {
  46. return
  47. }
  48. if _, ok := tracker.nameToPath[t.Name.Package]; !ok {
  49. tracker.nameToPath[t.Name.Package] = ""
  50. }
  51. return
  52. }
  53. if len(t.Name.Package) == 0 {
  54. return
  55. }
  56. path := t.Name.Path
  57. if len(path) == 0 {
  58. path = t.Name.Package
  59. }
  60. if _, ok := tracker.pathToName[path]; ok {
  61. return
  62. }
  63. name := tracker.LocalName(t.Name)
  64. tracker.nameToPath[name] = path
  65. tracker.pathToName[path] = name
  66. }
  67. // ImportLines is
  68. func (tracker *DefaultImportTracker) ImportLines() []string {
  69. importPaths := []string{}
  70. for path := range tracker.pathToName {
  71. importPaths = append(importPaths, path)
  72. }
  73. sort.Sort(sort.StringSlice(importPaths))
  74. out := []string{}
  75. for _, path := range importPaths {
  76. out = append(out, tracker.PrintImport(path, tracker.pathToName[path]))
  77. }
  78. return out
  79. }
  80. // LocalNameOf returns the name you would use to refer to the package at the
  81. // specified path within the body of a file.
  82. func (tracker *DefaultImportTracker) LocalNameOf(path string) string {
  83. return tracker.pathToName[path]
  84. }
  85. // PathOf returns the path that a given localName is referring to within the
  86. // body of a file.
  87. func (tracker *DefaultImportTracker) PathOf(localName string) (string, bool) {
  88. name, ok := tracker.nameToPath[localName]
  89. return name, ok
  90. }