You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

imports.go 2.0KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright 2018 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. package facts
  5. import "go/types"
  6. // importMap computes the import map for a package by traversing the
  7. // entire exported API each of its imports.
  8. //
  9. // This is a workaround for the fact that we cannot access the map used
  10. // internally by the types.Importer returned by go/importer. The entries
  11. // in this map are the packages and objects that may be relevant to the
  12. // current analysis unit.
  13. //
  14. // Packages in the map that are only indirectly imported may be
  15. // incomplete (!pkg.Complete()).
  16. //
  17. func importMap(imports []*types.Package) map[string]*types.Package {
  18. objects := make(map[types.Object]bool)
  19. packages := make(map[string]*types.Package)
  20. var addObj func(obj types.Object) bool
  21. var addType func(T types.Type)
  22. addObj = func(obj types.Object) bool {
  23. if !objects[obj] {
  24. objects[obj] = true
  25. addType(obj.Type())
  26. if pkg := obj.Pkg(); pkg != nil {
  27. packages[pkg.Path()] = pkg
  28. }
  29. return true
  30. }
  31. return false
  32. }
  33. addType = func(T types.Type) {
  34. switch T := T.(type) {
  35. case *types.Basic:
  36. // nop
  37. case *types.Named:
  38. if addObj(T.Obj()) {
  39. for i := 0; i < T.NumMethods(); i++ {
  40. addObj(T.Method(i))
  41. }
  42. }
  43. case *types.Pointer:
  44. addType(T.Elem())
  45. case *types.Slice:
  46. addType(T.Elem())
  47. case *types.Array:
  48. addType(T.Elem())
  49. case *types.Chan:
  50. addType(T.Elem())
  51. case *types.Map:
  52. addType(T.Key())
  53. addType(T.Elem())
  54. case *types.Signature:
  55. addType(T.Params())
  56. addType(T.Results())
  57. case *types.Struct:
  58. for i := 0; i < T.NumFields(); i++ {
  59. addObj(T.Field(i))
  60. }
  61. case *types.Tuple:
  62. for i := 0; i < T.Len(); i++ {
  63. addObj(T.At(i))
  64. }
  65. case *types.Interface:
  66. for i := 0; i < T.NumMethods(); i++ {
  67. addObj(T.Method(i))
  68. }
  69. }
  70. }
  71. for _, imp := range imports {
  72. packages[imp.Path()] = imp
  73. scope := imp.Scope()
  74. for _, name := range scope.Names() {
  75. addObj(scope.Lookup(name))
  76. }
  77. }
  78. return packages
  79. }