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