import.go raw

   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