vendor: golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f

full diff: 701f63a606...2d47ceb269

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-02-07 01:18:22 +01:00
parent 5176c38115
commit 689bea7963
50 changed files with 2738 additions and 862 deletions

12
vendor/golang.org/x/tools/cmd/stringer/gotypesalias.go generated vendored Normal file
View File

@ -0,0 +1,12 @@
// Copyright 2024 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.
//go:build go1.23
//go:debug gotypesalias=1
package main
// Materialize aliases whenever the go toolchain version is after 1.23 (#69772).
// Remove this file after go.mod >= 1.23 (which implies gotypesalias=1).

View File

@ -58,6 +58,11 @@
// where t is the lower-cased name of the first type listed. It can be overridden
// with the -output flag.
//
// Types can also be declared in tests, in which case type declarations in the
// non-test package or its test variant are preferred over types defined in the
// package with suffix "_test".
// The default output file for type declarations in tests is t_string_test.go with t picked as above.
//
// The -linecomment flag tells stringer to generate the text of any line comment, trimmed
// of leading spaces, instead of the constant name. For instance, if the constants above had a
// Pill prefix, one could write
@ -128,10 +133,6 @@ func main() {
// Parse the package once.
var dir string
g := Generator{
trimPrefix: *trimprefix,
lineComment: *linecomment,
}
// TODO(suzmue): accept other patterns for packages (directories, list of files, import paths, etc).
if len(args) == 1 && isDirectory(args[0]) {
dir = args[0]
@ -142,33 +143,90 @@ func main() {
dir = filepath.Dir(args[0])
}
g.parsePackage(args, tags)
// For each type, generate code in the first package where the type is declared.
// The order of packages is as follows:
// package x
// package x compiled for tests
// package x_test
//
// Each package pass could result in a separate generated file.
// These files must have the same package and test/not-test nature as the types
// from which they were generated.
//
// Types will be excluded when generated, to avoid repetitions.
pkgs := loadPackages(args, tags, *trimprefix, *linecomment, nil /* logf */)
sort.Slice(pkgs, func(i, j int) bool {
// Put x_test packages last.
iTest := strings.HasSuffix(pkgs[i].name, "_test")
jTest := strings.HasSuffix(pkgs[j].name, "_test")
if iTest != jTest {
return !iTest
}
// Print the header and package clause.
g.Printf("// Code generated by \"stringer %s\"; DO NOT EDIT.\n", strings.Join(os.Args[1:], " "))
g.Printf("\n")
g.Printf("package %s", g.pkg.name)
g.Printf("\n")
g.Printf("import \"strconv\"\n") // Used by all methods.
return len(pkgs[i].files) < len(pkgs[j].files)
})
for _, pkg := range pkgs {
g := Generator{
pkg: pkg,
}
// Run generate for each type.
for _, typeName := range types {
g.generate(typeName)
// Print the header and package clause.
g.Printf("// Code generated by \"stringer %s\"; DO NOT EDIT.\n", strings.Join(os.Args[1:], " "))
g.Printf("\n")
g.Printf("package %s", g.pkg.name)
g.Printf("\n")
g.Printf("import \"strconv\"\n") // Used by all methods.
// Run generate for types that can be found. Keep the rest for the remainingTypes iteration.
var foundTypes, remainingTypes []string
for _, typeName := range types {
values := findValues(typeName, pkg)
if len(values) > 0 {
g.generate(typeName, values)
foundTypes = append(foundTypes, typeName)
} else {
remainingTypes = append(remainingTypes, typeName)
}
}
if len(foundTypes) == 0 {
// This package didn't have any of the relevant types, skip writing a file.
continue
}
if len(remainingTypes) > 0 && output != nil && *output != "" {
log.Fatalf("cannot write to single file (-output=%q) when matching types are found in multiple packages", *output)
}
types = remainingTypes
// Format the output.
src := g.format()
// Write to file.
outputName := *output
if outputName == "" {
// Type names will be unique across packages since only the first
// match is picked.
// So there won't be collisions between a package compiled for tests
// and the separate package of tests (package foo_test).
outputName = filepath.Join(dir, baseName(pkg, foundTypes[0]))
}
err := os.WriteFile(outputName, src, 0644)
if err != nil {
log.Fatalf("writing output: %s", err)
}
}
// Format the output.
src := g.format()
if len(types) > 0 {
log.Fatalf("no values defined for types: %s", strings.Join(types, ","))
}
}
// Write to file.
outputName := *output
if outputName == "" {
baseName := fmt.Sprintf("%s_string.go", types[0])
outputName = filepath.Join(dir, strings.ToLower(baseName))
}
err := os.WriteFile(outputName, src, 0644)
if err != nil {
log.Fatalf("writing output: %s", err)
// baseName that will put the generated code together with pkg.
func baseName(pkg *Package, typename string) string {
suffix := "string.go"
if pkg.hasTestFiles {
suffix = "string_test.go"
}
return fmt.Sprintf("%s_%s", strings.ToLower(typename), suffix)
}
// isDirectory reports whether the named file is a directory.
@ -186,9 +244,6 @@ type Generator struct {
buf bytes.Buffer // Accumulated output.
pkg *Package // Package we are scanning.
trimPrefix string
lineComment bool
logf func(format string, args ...interface{}) // test logging hook; nil when not testing
}
@ -209,54 +264,74 @@ type File struct {
}
type Package struct {
name string
defs map[*ast.Ident]types.Object
files []*File
name string
defs map[*ast.Ident]types.Object
files []*File
hasTestFiles bool
}
// parsePackage analyzes the single package constructed from the patterns and tags.
// parsePackage exits if there is an error.
func (g *Generator) parsePackage(patterns []string, tags []string) {
// loadPackages analyzes the single package constructed from the patterns and tags.
// loadPackages exits if there is an error.
//
// Returns all variants (such as tests) of the package.
//
// logf is a test logging hook. It can be nil when not testing.
func loadPackages(
patterns, tags []string,
trimPrefix string, lineComment bool,
logf func(format string, args ...interface{}),
) []*Package {
cfg := &packages.Config{
Mode: packages.NeedName | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedSyntax,
// TODO: Need to think about constants in test files. Maybe write type_string_test.go
// in a separate pass? For later.
Tests: false,
Mode: packages.NeedName | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedSyntax | packages.NeedFiles,
// Tests are included, let the caller decide how to fold them in.
Tests: true,
BuildFlags: []string{fmt.Sprintf("-tags=%s", strings.Join(tags, " "))},
Logf: g.logf,
Logf: logf,
}
pkgs, err := packages.Load(cfg, patterns...)
if err != nil {
log.Fatal(err)
}
if len(pkgs) != 1 {
log.Fatalf("error: %d packages matching %v", len(pkgs), strings.Join(patterns, " "))
}
g.addPackage(pkgs[0])
}
// addPackage adds a type checked Package and its syntax files to the generator.
func (g *Generator) addPackage(pkg *packages.Package) {
g.pkg = &Package{
name: pkg.Name,
defs: pkg.TypesInfo.Defs,
files: make([]*File, len(pkg.Syntax)),
if len(pkgs) == 0 {
log.Fatalf("error: no packages matching %v", strings.Join(patterns, " "))
}
for i, file := range pkg.Syntax {
g.pkg.files[i] = &File{
file: file,
pkg: g.pkg,
trimPrefix: g.trimPrefix,
lineComment: g.lineComment,
out := make([]*Package, len(pkgs))
for i, pkg := range pkgs {
p := &Package{
name: pkg.Name,
defs: pkg.TypesInfo.Defs,
files: make([]*File, len(pkg.Syntax)),
}
for j, file := range pkg.Syntax {
p.files[j] = &File{
file: file,
pkg: p,
trimPrefix: trimPrefix,
lineComment: lineComment,
}
}
// Keep track of test files, since we might want to generated
// code that ends up in that kind of package.
// Can be replaced once https://go.dev/issue/38445 lands.
for _, f := range pkg.GoFiles {
if strings.HasSuffix(f, "_test.go") {
p.hasTestFiles = true
break
}
}
out[i] = p
}
return out
}
// generate produces the String method for the named type.
func (g *Generator) generate(typeName string) {
func findValues(typeName string, pkg *Package) []Value {
values := make([]Value, 0, 100)
for _, file := range g.pkg.files {
for _, file := range pkg.files {
// Set the state for this run of the walker.
file.typeName = typeName
file.values = nil
@ -265,10 +340,11 @@ func (g *Generator) generate(typeName string) {
values = append(values, file.values...)
}
}
return values
}
if len(values) == 0 {
log.Fatalf("no values defined for type %s", typeName)
}
// generate produces the String method for the named type.
func (g *Generator) generate(typeName string, values []Value) {
// Generate code that will fail if the constants change value.
g.Printf("func _() {\n")
g.Printf("\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n")