import.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Copyright 2025 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 stdlib
  5. // This file provides the API for the import graph of the standard library.
  6. //
  7. // Be aware that the compiler-generated code for every package
  8. // implicitly depends on package "runtime" and a handful of others
  9. // (see runtimePkgs in GOROOT/src/cmd/internal/objabi/pkgspecial.go).
  10. import (
  11. "encoding/binary"
  12. "iter"
  13. "slices"
  14. "strings"
  15. )
  16. // Imports returns the sequence of packages directly imported by the
  17. // named standard packages, in name order.
  18. // The imports of an unknown package are the empty set.
  19. //
  20. // The graph is built into the application and may differ from the
  21. // graph in the Go source tree being analyzed by the application.
  22. func Imports(pkgs ...string) iter.Seq[string] {
  23. return func(yield func(string) bool) {
  24. for _, pkg := range pkgs {
  25. if i, ok := find(pkg); ok {
  26. var depIndex uint64
  27. for data := []byte(deps[i].deps); len(data) > 0; {
  28. delta, n := binary.Uvarint(data)
  29. depIndex += delta
  30. if !yield(deps[depIndex].name) {
  31. return
  32. }
  33. data = data[n:]
  34. }
  35. }
  36. }
  37. }
  38. }
  39. // Dependencies returns the set of all dependencies of the named
  40. // standard packages, including the initial package,
  41. // in a deterministic topological order.
  42. // The dependencies of an unknown package are the empty set.
  43. //
  44. // The graph is built into the application and may differ from the
  45. // graph in the Go source tree being analyzed by the application.
  46. func Dependencies(pkgs ...string) iter.Seq[string] {
  47. return func(yield func(string) bool) {
  48. for _, pkg := range pkgs {
  49. if i, ok := find(pkg); ok {
  50. var seen [1 + len(deps)/8]byte // bit set of seen packages
  51. var visit func(i int) bool
  52. visit = func(i int) bool {
  53. bit := byte(1) << (i % 8)
  54. if seen[i/8]&bit == 0 {
  55. seen[i/8] |= bit
  56. var depIndex uint64
  57. for data := []byte(deps[i].deps); len(data) > 0; {
  58. delta, n := binary.Uvarint(data)
  59. depIndex += delta
  60. if !visit(int(depIndex)) {
  61. return false
  62. }
  63. data = data[n:]
  64. }
  65. if !yield(deps[i].name) {
  66. return false
  67. }
  68. }
  69. return true
  70. }
  71. if !visit(i) {
  72. return
  73. }
  74. }
  75. }
  76. }
  77. }
  78. // find returns the index of pkg in the deps table.
  79. func find(pkg string) (int, bool) {
  80. return slices.BinarySearchFunc(deps[:], pkg, func(p pkginfo, n string) int {
  81. return strings.Compare(p.name, n)
  82. })
  83. }