src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

import.go (2840B)


      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 }