Source file src/cmd/vendor/golang.org/x/tools/internal/stdlib/import.go

     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  

View as plain text