| // Copyright 2025 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package stdlib | |
| // This file provides the API for the import graph of the standard library. | |
| // | |
| // Be aware that the compiler-generated code for every package | |
| // implicitly depends on package "runtime" and a handful of others | |
| // (see runtimePkgs in GOROOT/src/cmd/internal/objabi/pkgspecial.go). | |
| import ( | |
| "encoding/binary" | |
| "iter" | |
| "slices" | |
| "strings" | |
| ) | |
| // Imports returns the sequence of packages directly imported by the | |
| // named standard packages, in name order. | |
| // The imports of an unknown package are the empty set. | |
| // | |
| // The graph is built into the application and may differ from the | |
| // graph in the Go source tree being analyzed by the application. | |
| func Imports(pkgs ...string) iter.Seq[string] { | |
| return func(yield func(string) bool) { | |
| for _, pkg := range pkgs { | |
| if i, ok := find(pkg); ok { | |
| var depIndex uint64 | |
| for data := []byte(deps[i].deps); len(data) > 0; { | |
| delta, n := binary.Uvarint(data) | |
| depIndex += delta | |
| if !yield(deps[depIndex].name) { | |
| return | |
| } | |
| data = data[n:] | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // Dependencies returns the set of all dependencies of the named | |
| // standard packages, including the initial package, | |
| // in a deterministic topological order. | |
| // The dependencies of an unknown package are the empty set. | |
| // | |
| // The graph is built into the application and may differ from the | |
| // graph in the Go source tree being analyzed by the application. | |
| func Dependencies(pkgs ...string) iter.Seq[string] { | |
| return func(yield func(string) bool) { | |
| for _, pkg := range pkgs { | |
| if i, ok := find(pkg); ok { | |
| var seen [1 + len(deps)/8]byte // bit set of seen packages | |
| var visit func(i int) bool | |
| visit = func(i int) bool { | |
| bit := byte(1) << (i % 8) | |
| if seen[i/8]&bit == 0 { | |
| seen[i/8] |= bit | |
| var depIndex uint64 | |
| for data := []byte(deps[i].deps); len(data) > 0; { | |
| delta, n := binary.Uvarint(data) | |
| depIndex += delta | |
| if !visit(int(depIndex)) { | |
| return false | |
| } | |
| data = data[n:] | |
| } | |
| if !yield(deps[i].name) { | |
| return false | |
| } | |
| } | |
| return true | |
| } | |
| if !visit(i) { | |
| return | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // find returns the index of pkg in the deps table. | |
| func find(pkg string) (int, bool) { | |
| return slices.BinarySearchFunc(deps[:], pkg, func(p pkginfo, n string) int { | |
| return strings.Compare(p.name, n) | |
| }) | |
| } | |
| // IsBootstrapPackage reports whether pkg is one of the low-level | |
| // packages in the Go distribution that must compile with the older | |
| // language version specified by [BootstrapVersion] during toolchain | |
| // bootstrapping; see golang.org/s/go15bootstrap. | |
| func IsBootstrapPackage(pkg string) bool { | |
| return bootstrap[pkg] | |
| } |