summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/tools/go/packages/visit.go
diff options
context:
space:
mode:
authorLibravatar kim <grufwub@gmail.com>2025-10-13 16:49:53 +0200
committerLibravatar tobi <tobi.smethurst@protonmail.com>2025-10-17 15:32:55 +0200
commitea7eeada77a52fd58a9e1a949a39eccc7bce955a (patch)
treeede9f651d0bd7782b565883f9384341530f8320f /vendor/golang.org/x/tools/go/packages/visit.go
parent[bugfix] repeated posts on timeline endpoints (#4494) (diff)
downloadgotosocial-ea7eeada77a52fd58a9e1a949a39eccc7bce955a.tar.xz
[chore] update dependencies (#4495)
- github.com/coreos/go-oidc/v3: v3.15.0 -> v3.16.0 - github.com/go-playground/form/v4: v4.2.1 -> v4.3.0 - github.com/go-swagger/go-swagger: v0.32.3 -> v0.33.1 - golang.org/x/crypto: v0.42.0 -> v0.43.0 - golang.org/x/image: v0.31.0 -> v0.32.0 - golang.org/x/net: v0.45.0 -> v0.46.0 - golang.org/x/oauth2: v0.31.0 -> v0.32.0 - golang.org/x/sys: v0.36.0 -> v0.37.0 - golang.org/x/text: v0.29.0 -> v0.30.0 - modernc.org/sqlite: v1.39.0 -> v1.39.1 (w/ concurrency workaround) Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4495 Co-authored-by: kim <grufwub@gmail.com> Co-committed-by: kim <grufwub@gmail.com>
Diffstat (limited to 'vendor/golang.org/x/tools/go/packages/visit.go')
-rw-r--r--vendor/golang.org/x/tools/go/packages/visit.go85
1 files changed, 75 insertions, 10 deletions
diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go
index df14ffd94..af6a60d75 100644
--- a/vendor/golang.org/x/tools/go/packages/visit.go
+++ b/vendor/golang.org/x/tools/go/packages/visit.go
@@ -5,9 +5,11 @@
package packages
import (
+ "cmp"
"fmt"
+ "iter"
"os"
- "sort"
+ "slices"
)
// Visit visits all the packages in the import graph whose roots are
@@ -16,6 +18,20 @@ import (
// package's dependencies have been visited (postorder).
// The boolean result of pre(pkg) determines whether
// the imports of package pkg are visited.
+//
+// Example:
+//
+// pkgs, err := Load(...)
+// if err != nil { ... }
+// Visit(pkgs, nil, func(pkg *Package) {
+// log.Println(pkg)
+// })
+//
+// In most cases, it is more convenient to use [Postorder]:
+//
+// for pkg := range Postorder(pkgs) {
+// log.Println(pkg)
+// }
func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
seen := make(map[*Package]bool)
var visit func(*Package)
@@ -24,13 +40,8 @@ func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
seen[pkg] = true
if pre == nil || pre(pkg) {
- paths := make([]string, 0, len(pkg.Imports))
- for path := range pkg.Imports {
- paths = append(paths, path)
- }
- sort.Strings(paths) // Imports is a map, this makes visit stable
- for _, path := range paths {
- visit(pkg.Imports[path])
+ for _, imp := range sorted(pkg.Imports) { // for determinism
+ visit(imp)
}
}
@@ -50,7 +61,7 @@ func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
func PrintErrors(pkgs []*Package) int {
var n int
errModules := make(map[*Module]bool)
- Visit(pkgs, nil, func(pkg *Package) {
+ for pkg := range Postorder(pkgs) {
for _, err := range pkg.Errors {
fmt.Fprintln(os.Stderr, err)
n++
@@ -63,6 +74,60 @@ func PrintErrors(pkgs []*Package) int {
fmt.Fprintln(os.Stderr, mod.Error.Err)
n++
}
- })
+ }
return n
}
+
+// Postorder returns an iterator over the the packages in
+// the import graph whose roots are pkg.
+// Packages are enumerated in dependencies-first order.
+func Postorder(pkgs []*Package) iter.Seq[*Package] {
+ return func(yield func(*Package) bool) {
+ seen := make(map[*Package]bool)
+ var visit func(*Package) bool
+ visit = func(pkg *Package) bool {
+ if !seen[pkg] {
+ seen[pkg] = true
+ for _, imp := range sorted(pkg.Imports) { // for determinism
+ if !visit(imp) {
+ return false
+ }
+ }
+ if !yield(pkg) {
+ return false
+ }
+ }
+ return true
+ }
+ for _, pkg := range pkgs {
+ if !visit(pkg) {
+ break
+ }
+ }
+ }
+}
+
+// -- copied from golang.org.x/tools/gopls/internal/util/moremaps --
+
+// sorted returns an iterator over the entries of m in key order.
+func sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] {
+ // TODO(adonovan): use maps.Sorted if proposal #68598 is accepted.
+ return func(yield func(K, V) bool) {
+ keys := keySlice(m)
+ slices.Sort(keys)
+ for _, k := range keys {
+ if !yield(k, m[k]) {
+ break
+ }
+ }
+ }
+}
+
+// KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)).
+func keySlice[M ~map[K]V, K comparable, V any](m M) []K {
+ r := make([]K, 0, len(m))
+ for k := range m {
+ r = append(r, k)
+ }
+ return r
+}