]> Cypherpunks repositories - gostls13.git/commitdiff
all: update golang.org/x/tools to v0.27.0
authorXiaolin Zhao <zhaoxiaolin@loongson.cn>
Fri, 18 Oct 2024 09:16:00 +0000 (17:16 +0800)
committerGopher Robot <gobot@golang.org>
Thu, 21 Nov 2024 21:19:12 +0000 (21:19 +0000)
Commands run:
cd $GOROOT/src/cmd
go get golang.org/x/tools@v0.27.0
go mod tidy
go mod vendor

Needed for CL 623475. Introduced ABIInternal syscall support.

Change-Id: I03d7576747826243c25658f360b24ef9b84f0f04
Reviewed-on: https://go-review.googlesource.com/c/go/+/620738
Reviewed-by: Meidan Li <limeidan@loongson.cn>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: David Chase <drchase@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
58 files changed:
src/cmd/go.mod
src/cmd/go.sum
src/cmd/vendor/golang.org/x/mod/sumdb/server.go
src/cmd/vendor/golang.org/x/mod/sumdb/tlog/note.go
src/cmd/vendor/golang.org/x/mod/zip/zip.go
src/cmd/vendor/golang.org/x/tools/cmd/bisect/go119.go [deleted file]
src/cmd/vendor/golang.org/x/tools/cmd/bisect/go120.go
src/cmd/vendor/golang.org/x/tools/cmd/bisect/rand.go [deleted file]
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/assign/assign.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/bools/bools.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/cgocall/cgocall.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/composite/composite.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/copylock/copylock.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/httpresponse/httpresponse.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/internal/analysisutil/util.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/lostcancel/doc.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/lostcancel/lostcancel.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/types.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/shift/shift.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/slog/slog.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/stringintconv/string.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine/testinggoroutine.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine/util.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unsafeptr/unsafeptr.go
src/cmd/vendor/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go
src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
src/cmd/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go [deleted file]
src/cmd/vendor/golang.org/x/tools/go/ast/astutil/imports.go [deleted file]
src/cmd/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go [deleted file]
src/cmd/vendor/golang.org/x/tools/go/ast/astutil/util.go [deleted file]
src/cmd/vendor/golang.org/x/tools/go/ast/inspector/inspector.go
src/cmd/vendor/golang.org/x/tools/go/ast/inspector/iter.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
src/cmd/vendor/golang.org/x/tools/go/types/typeutil/callee.go
src/cmd/vendor/golang.org/x/tools/go/types/typeutil/map.go
src/cmd/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go
src/cmd/vendor/golang.org/x/tools/go/types/typeutil/ui.go
src/cmd/vendor/golang.org/x/tools/internal/aliases/aliases.go
src/cmd/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go [deleted file]
src/cmd/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go
src/cmd/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go
src/cmd/vendor/golang.org/x/tools/internal/facts/imports.go
src/cmd/vendor/golang.org/x/tools/internal/typeparams/common.go
src/cmd/vendor/golang.org/x/tools/internal/typeparams/free.go
src/cmd/vendor/golang.org/x/tools/internal/typesinternal/element.go [new file with mode: 0644]
src/cmd/vendor/golang.org/x/tools/internal/typesinternal/recv.go
src/cmd/vendor/golang.org/x/tools/internal/typesinternal/types.go
src/cmd/vendor/golang.org/x/tools/internal/versions/toolchain.go [deleted file]
src/cmd/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go [deleted file]
src/cmd/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go [deleted file]
src/cmd/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go [deleted file]
src/cmd/vendor/golang.org/x/tools/internal/versions/types.go
src/cmd/vendor/golang.org/x/tools/internal/versions/types_go121.go [deleted file]
src/cmd/vendor/golang.org/x/tools/internal/versions/types_go122.go [deleted file]
src/cmd/vendor/modules.txt

index 9686e4a4a871fa73b84206bff403e0e19b91d903..8488e0a47addff43c35a944f8984cf84a6384b3c 100644 (file)
@@ -6,12 +6,12 @@ require (
        github.com/google/pprof v0.0.0-20241101162523-b92577c0c142
        golang.org/x/arch v0.11.1-0.20241106162200-f977c2e4e3f4
        golang.org/x/build v0.0.0-20240722200705-b9910f320300
-       golang.org/x/mod v0.20.0
-       golang.org/x/sync v0.8.0
+       golang.org/x/mod v0.22.0
+       golang.org/x/sync v0.9.0
        golang.org/x/sys v0.27.0
        golang.org/x/telemetry v0.0.0-20240828202201-a797f331ea97
        golang.org/x/term v0.22.1-0.20240716160707-d4346f0be292
-       golang.org/x/tools v0.24.1-0.20240904143311-70f56264139c
+       golang.org/x/tools v0.27.0
 )
 
 require (
index 5f704d5a14c8c1b2bb166f2bba71713beb3e9bf9..7ad2cb7f9447a06a7eb070986a7d711927bf8813 100644 (file)
@@ -10,10 +10,10 @@ golang.org/x/arch v0.11.1-0.20241106162200-f977c2e4e3f4 h1:B9d6SEXeIaY1QC4c7Gsf8
 golang.org/x/arch v0.11.1-0.20241106162200-f977c2e4e3f4/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
 golang.org/x/build v0.0.0-20240722200705-b9910f320300 h1:2Cqg4LnvfD2ZpG8+6KbyYUkweWhNS3SgfcN/eeVseJ0=
 golang.org/x/build v0.0.0-20240722200705-b9910f320300/go.mod h1:YsGhg4JUVUWLzdqU2wCrtpRrOveOql6w56FLDHq/CJ4=
-golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
-golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
-golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
+golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
+golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
+golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
 golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/telemetry v0.0.0-20240828202201-a797f331ea97 h1:5xPN7d0u5VdgF2gFFXUDaeD3NP1pPgFMHocnCQGAh5M=
@@ -22,7 +22,7 @@ golang.org/x/term v0.22.1-0.20240716160707-d4346f0be292 h1:BOrQi08eIX3cDgGcMgFON
 golang.org/x/term v0.22.1-0.20240716160707-d4346f0be292/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
 golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
 golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
-golang.org/x/tools v0.24.1-0.20240904143311-70f56264139c h1:JImdv91aqIPqamNg5sOTUjNQD++5KkvchZi2BcYlNoE=
-golang.org/x/tools v0.24.1-0.20240904143311-70f56264139c/go.mod h1:IV2Kidsnn7A8K7hHxn/wcUfHXkViw0LLHdu8LnpT8LU=
+golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
+golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
 rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef h1:mqLYrXCXYEZOop9/Dbo6RPX11539nwiCNBb1icVPmw8=
 rsc.io/markdown v0.0.0-20240306144322-0bf8f97ee8ef/go.mod h1:8xcPgWmwlZONN1D9bjxtHEjrUtSEa3fakVF8iaewYKQ=
index 1e1779d025a9ac7e608277ef931201760c801d00..216a2562c268bb03897639badc047d351614c26e 100644 (file)
@@ -6,6 +6,7 @@
 package sumdb
 
 import (
+       "bytes"
        "context"
        "net/http"
        "os"
@@ -150,6 +151,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
                                        http.Error(w, err.Error(), http.StatusInternalServerError)
                                        return
                                }
+                               // Data tiles contain formatted records without the first line with record ID.
+                               _, msg, _ = bytes.Cut(msg, []byte{'\n'})
                                data = append(data, msg...)
                        }
                        w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
index ce5353e0feb7198ac455f89564108378ac54f79c..fc6d5fa0a3bfa7bc3457007fe5d331dc99a31306 100644 (file)
@@ -73,13 +73,16 @@ func ParseTree(text []byte) (tree Tree, err error) {
 var errMalformedRecord = errors.New("malformed record data")
 
 // FormatRecord formats a record for serving to a client
-// in a lookup response or data tile.
+// in a lookup response.
 //
 // The encoded form is the record ID as a single number,
 // then the text of the record, and then a terminating blank line.
 // Record text must be valid UTF-8 and must not contain any ASCII control
 // characters (those below U+0020) other than newline (U+000A).
 // It must end in a terminating newline and not contain any blank lines.
+//
+// Responses to data tiles consist of concatenated formatted records from each of
+// which the first line, with the record ID, is removed.
 func FormatRecord(id int64, text []byte) (msg []byte, err error) {
        if !isValidRecordText(text) {
                return nil, errMalformedRecord
index 574f83f2202dee39caf4a7e76148fd561a9ee4ef..3673db4997018706f7d87be714a6d9a3d964327c 100644 (file)
@@ -50,6 +50,7 @@ import (
        "bytes"
        "errors"
        "fmt"
+       "go/version"
        "io"
        "os"
        "os/exec"
@@ -60,6 +61,7 @@ import (
        "unicode"
        "unicode/utf8"
 
+       "golang.org/x/mod/modfile"
        "golang.org/x/mod/module"
 )
 
@@ -193,6 +195,20 @@ func CheckFiles(files []File) (CheckedFiles, error) {
        return cf, cf.Err()
 }
 
+// parseGoVers extracts the Go version specified in the given go.mod file.
+// It returns an empty string if the version is not found or if an error
+// occurs during file parsing.
+//
+// The version string is in Go toolchain name syntax, prefixed with "go".
+// Examples: "go1.21", "go1.22rc2", "go1.23.0"
+func parseGoVers(file string, data []byte) string {
+       mfile, err := modfile.ParseLax(file, data, nil)
+       if err != nil || mfile.Go == nil {
+               return ""
+       }
+       return "go" + mfile.Go.Version
+}
+
 // checkFiles implements CheckFiles and also returns lists of valid files and
 // their sizes, corresponding to cf.Valid. It omits files in submodules, files
 // in vendored packages, symlinked files, and various other unwanted files.
@@ -217,6 +233,7 @@ func checkFiles(files []File) (cf CheckedFiles, validFiles []File, validSizes []
        // Files in these directories will be omitted.
        // These directories will not be included in the output zip.
        haveGoMod := make(map[string]bool)
+       var vers string
        for _, f := range files {
                p := f.Path()
                dir, base := path.Split(p)
@@ -226,8 +243,21 @@ func checkFiles(files []File) (cf CheckedFiles, validFiles []File, validSizes []
                                addError(p, false, err)
                                continue
                        }
-                       if info.Mode().IsRegular() {
-                               haveGoMod[dir] = true
+                       if !info.Mode().IsRegular() {
+                               continue
+                       }
+                       haveGoMod[dir] = true
+                       // Extract the Go language version from the root "go.mod" file.
+                       // This ensures we correctly interpret Go version-specific file omissions.
+                       // We use f.Open() to handle potential custom Open() implementations
+                       // that the underlying File type might have.
+                       if base == "go.mod" && dir == "" {
+                               if file, err := f.Open(); err == nil {
+                                       if data, err := io.ReadAll(file); err == nil {
+                                               vers = version.Lang(parseGoVers("go.mod", data))
+                                       }
+                                       file.Close()
+                               }
                        }
                }
        }
@@ -257,7 +287,7 @@ func checkFiles(files []File) (cf CheckedFiles, validFiles []File, validSizes []
                        addError(p, false, errPathNotRelative)
                        continue
                }
-               if isVendoredPackage(p) {
+               if isVendoredPackage(p, vers) {
                        // Skip files in vendored packages.
                        addError(p, true, errVendored)
                        continue
@@ -573,7 +603,9 @@ func CreateFromDir(w io.Writer, m module.Version, dir string) (err error) {
 // VCS repository stored locally. The zip content is written to w.
 //
 // repoRoot must be an absolute path to the base of the repository, such as
-// "/Users/some-user/some-repo".
+// "/Users/some-user/some-repo". If the repository is a Git repository,
+// this path is expected to point to its worktree: it can't be a bare git
+// repo.
 //
 // revision is the revision of the repository to create the zip from. Examples
 // include HEAD or SHA sums for git repositories.
@@ -754,20 +786,42 @@ func (fi dataFileInfo) Sys() interface{}   { return nil }
 // in a package whose import path contains (but does not end with) the component
 // "vendor".
 //
-// Unfortunately, isVendoredPackage reports false positives for files in any
-// non-top-level package whose import path ends in "vendor".
-func isVendoredPackage(name string) bool {
+// The 'vers' parameter specifies the Go version declared in the module's
+// go.mod file and must be a valid Go version according to the
+// go/version.IsValid function.
+// Vendoring behavior has evolved across Go versions, so this function adapts
+// its logic accordingly.
+func isVendoredPackage(name string, vers string) bool {
+       // vendor/modules.txt is a vendored package but was included in 1.23 and earlier.
+       // Remove vendor/modules.txt only for 1.24 and beyond to preserve older checksums.
+       if version.Compare(vers, "go1.24") >= 0 && name == "vendor/modules.txt" {
+               return true
+       }
        var i int
        if strings.HasPrefix(name, "vendor/") {
                i += len("vendor/")
        } else if j := strings.Index(name, "/vendor/"); j >= 0 {
-               // This offset looks incorrect; this should probably be
+               // Calculate the correct starting position within the import path
+               // to determine if a package is vendored.
+               //
+               // Due to a bug in Go versions before 1.24
+               // (see https://golang.org/issue/37397), the "/vendor/" prefix within
+               // a package path was not always correctly interpreted.
+               //
+               // This bug affected how vendored packages were identified in cases like:
                //
-               //      i = j + len("/vendor/")
+               //   - "pkg/vendor/vendor.go"   (incorrectly identified as vendored in pre-1.24)
+               //   - "pkg/vendor/foo/foo.go" (correctly identified as vendored)
                //
-               // (See https://golang.org/issue/31562 and https://golang.org/issue/37397.)
-               // Unfortunately, we can't fix it without invalidating module checksums.
-               i += len("/vendor/")
+               // To correct this, in Go 1.24 and later, we skip the entire "/vendor/" prefix
+               // when it's part of a nested package path (as in the first example above).
+               // In earlier versions, we only skipped the length of "/vendor/", leading
+               // to the incorrect behavior.
+               if version.Compare(vers, "go1.24") >= 0 {
+                       i = j + len("/vendor/")
+               } else {
+                       i += len("/vendor/")
+               }
        } else {
                return false
        }
@@ -892,6 +946,12 @@ func (cc collisionChecker) check(p string, isDir bool) error {
 // files, as well as a list of directories and files that were skipped (for
 // example, nested modules and symbolic links).
 func listFilesInDir(dir string) (files []File, omitted []FileError, err error) {
+       // Extract the Go language version from the root "go.mod" file.
+       // This ensures we correctly interpret Go version-specific file omissions.
+       var vers string
+       if data, err := os.ReadFile(filepath.Join(dir, "go.mod")); err == nil {
+               vers = version.Lang(parseGoVers("go.mod", data))
+       }
        err = filepath.Walk(dir, func(filePath string, info os.FileInfo, err error) error {
                if err != nil {
                        return err
@@ -902,11 +962,10 @@ func listFilesInDir(dir string) (files []File, omitted []FileError, err error) {
                }
                slashPath := filepath.ToSlash(relPath)
 
-               // Skip some subdirectories inside vendor, but maintain bug
-               // golang.org/issue/31562, described in isVendoredPackage.
+               // Skip some subdirectories inside vendor.
                // We would like Create and CreateFromDir to produce the same result
                // for a set of files, whether expressed as a directory tree or zip.
-               if isVendoredPackage(slashPath) {
+               if isVendoredPackage(slashPath, vers) {
                        omitted = append(omitted, FileError{Path: slashPath, Err: errVendored})
                        return nil
                }
diff --git a/src/cmd/vendor/golang.org/x/tools/cmd/bisect/go119.go b/src/cmd/vendor/golang.org/x/tools/cmd/bisect/go119.go
deleted file mode 100644 (file)
index debe4e0..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2023 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.20
-
-package main
-
-import "os/exec"
-
-func cmdInterrupt(cmd *exec.Cmd) {
-       // cmd.Cancel and cmd.WaitDelay not available before Go 1.20.
-}
index c85edf7b5753a99c7938135d363a64b33ba3e655..d2cf382684d2db93719c1dbff31cf6c7b88a55b7 100644 (file)
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build go1.20
-
 package main
 
 import (
diff --git a/src/cmd/vendor/golang.org/x/tools/cmd/bisect/rand.go b/src/cmd/vendor/golang.org/x/tools/cmd/bisect/rand.go
deleted file mode 100644 (file)
index daa01d3..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2023 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.
-
-// Starting in Go 1.20, the global rand is auto-seeded,
-// with a better value than the current Unix nanoseconds.
-// Only seed if we're using older versions of Go.
-
-//go:build !go1.20
-
-package main
-
-import (
-       "math/rand"
-       "time"
-)
-
-func init() {
-       rand.Seed(time.Now().UnixNano())
-}
index c9ba1a375d315aa2bf3fdaa07a0cb2b0b74eb99f..b622dfdf3a06aa9a39c75cf73b46b1cbfdcbd345 100644 (file)
@@ -57,6 +57,8 @@ type asmArch struct {
        // include the first integer register and first floating-point register. Accessing
        // any of them counts as writing to result.
        retRegs []string
+       // writeResult is a list of instructions that will change result register implicity.
+       writeResult []string
        // calculated during initialization
        sizes    types.Sizes
        intSize  int
@@ -85,18 +87,18 @@ type asmVar struct {
 var (
        asmArch386      = asmArch{name: "386", bigEndian: false, stack: "SP", lr: false}
        asmArchArm      = asmArch{name: "arm", bigEndian: false, stack: "R13", lr: true}
-       asmArchArm64    = asmArch{name: "arm64", bigEndian: false, stack: "RSP", lr: true, retRegs: []string{"R0", "F0"}}
-       asmArchAmd64    = asmArch{name: "amd64", bigEndian: false, stack: "SP", lr: false, retRegs: []string{"AX", "X0"}}
+       asmArchArm64    = asmArch{name: "arm64", bigEndian: false, stack: "RSP", lr: true, retRegs: []string{"R0", "F0"}, writeResult: []string{"SVC"}}
+       asmArchAmd64    = asmArch{name: "amd64", bigEndian: false, stack: "SP", lr: false, retRegs: []string{"AX", "X0"}, writeResult: []string{"SYSCALL"}}
        asmArchMips     = asmArch{name: "mips", bigEndian: true, stack: "R29", lr: true}
        asmArchMipsLE   = asmArch{name: "mipsle", bigEndian: false, stack: "R29", lr: true}
        asmArchMips64   = asmArch{name: "mips64", bigEndian: true, stack: "R29", lr: true}
        asmArchMips64LE = asmArch{name: "mips64le", bigEndian: false, stack: "R29", lr: true}
-       asmArchPpc64    = asmArch{name: "ppc64", bigEndian: true, stack: "R1", lr: true, retRegs: []string{"R3", "F1"}}
-       asmArchPpc64LE  = asmArch{name: "ppc64le", bigEndian: false, stack: "R1", lr: true, retRegs: []string{"R3", "F1"}}
-       asmArchRISCV64  = asmArch{name: "riscv64", bigEndian: false, stack: "SP", lr: true, retRegs: []string{"X10", "F10"}}
+       asmArchPpc64    = asmArch{name: "ppc64", bigEndian: true, stack: "R1", lr: true, retRegs: []string{"R3", "F1"}, writeResult: []string{"SYSCALL"}}
+       asmArchPpc64LE  = asmArch{name: "ppc64le", bigEndian: false, stack: "R1", lr: true, retRegs: []string{"R3", "F1"}, writeResult: []string{"SYSCALL"}}
+       asmArchRISCV64  = asmArch{name: "riscv64", bigEndian: false, stack: "SP", lr: true, retRegs: []string{"X10", "F10"}, writeResult: []string{"ECALL"}}
        asmArchS390X    = asmArch{name: "s390x", bigEndian: true, stack: "R15", lr: true}
        asmArchWasm     = asmArch{name: "wasm", bigEndian: false, stack: "SP", lr: false}
-       asmArchLoong64  = asmArch{name: "loong64", bigEndian: false, stack: "R3", lr: true, retRegs: []string{"R4", "F0"}}
+       asmArchLoong64  = asmArch{name: "loong64", bigEndian: false, stack: "R3", lr: true, retRegs: []string{"R4", "F0"}, writeResult: []string{"SYSCALL"}}
 
        arches = []*asmArch{
                &asmArch386,
@@ -351,6 +353,12 @@ Files:
                        }
 
                        if abi == "ABIInternal" && !haveRetArg {
+                               for _, ins := range archDef.writeResult {
+                                       if strings.Contains(line, ins) {
+                                               haveRetArg = true
+                                               break
+                                       }
+                               }
                                for _, reg := range archDef.retRegs {
                                        if strings.Contains(line, reg) {
                                                haveRetArg = true
index 3bfd501226f2662c31c0c285642bbae921b42365..0d95fefcb5a2869b2021bb6f205b144fb70dc078 100644 (file)
@@ -18,7 +18,6 @@ import (
        "golang.org/x/tools/go/analysis"
        "golang.org/x/tools/go/analysis/passes/inspect"
        "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
-       "golang.org/x/tools/go/ast/astutil"
        "golang.org/x/tools/go/ast/inspector"
 )
 
@@ -78,7 +77,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
 
 // isMapIndex returns true if e is a map index expression.
 func isMapIndex(info *types.Info, e ast.Expr) bool {
-       if idx, ok := astutil.Unparen(e).(*ast.IndexExpr); ok {
+       if idx, ok := ast.Unparen(e).(*ast.IndexExpr); ok {
                if typ := info.Types[idx.X].Type; typ != nil {
                        _, ok := typ.Underlying().(*types.Map)
                        return ok
index 564329774ef1fdd73b2cbb2037cabe3ebaa9c0d3..8cec6e8224a5dc0a04a724456a926f70fa101a78 100644 (file)
@@ -14,7 +14,6 @@ import (
        "golang.org/x/tools/go/analysis"
        "golang.org/x/tools/go/analysis/passes/inspect"
        "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
-       "golang.org/x/tools/go/ast/astutil"
        "golang.org/x/tools/go/ast/inspector"
 )
 
@@ -169,7 +168,7 @@ func (op boolOp) checkSuspect(pass *analysis.Pass, exprs []ast.Expr) {
 // seen[e] is already true; any newly processed exprs are added to seen.
 func (op boolOp) split(e ast.Expr, seen map[*ast.BinaryExpr]bool) (exprs []ast.Expr) {
        for {
-               e = astutil.Unparen(e)
+               e = ast.Unparen(e)
                if b, ok := e.(*ast.BinaryExpr); ok && b.Op == op.tok {
                        seen[b] = true
                        exprs = append(exprs, op.split(b.Y, seen)...)
index 4e864397574c265a43c4089b485a1a89b9d9e3c4..613583a1a64909c40b39950431a8b7f72c2f617f 100644 (file)
@@ -19,7 +19,6 @@ import (
 
        "golang.org/x/tools/go/analysis"
        "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
-       "golang.org/x/tools/go/ast/astutil"
 )
 
 const debug = false
@@ -65,7 +64,7 @@ func checkCgo(fset *token.FileSet, f *ast.File, info *types.Info, reportf func(t
 
                // Is this a C.f() call?
                var name string
-               if sel, ok := astutil.Unparen(call.Fun).(*ast.SelectorExpr); ok {
+               if sel, ok := ast.Unparen(call.Fun).(*ast.SelectorExpr); ok {
                        if id, ok := sel.X.(*ast.Ident); ok && id.Name == "C" {
                                name = sel.Sel.Name
                        }
@@ -180,7 +179,7 @@ func typeCheckCgoSourceFiles(fset *token.FileSet, pkg *types.Package, files []*a
        for _, raw := range files {
                // If f is a cgo-generated file, Position reports
                // the original file, honoring //line directives.
-               filename := fset.Position(raw.Pos()).Filename
+               filename := fset.Position(raw.Pos()).Filename // sic: Pos, not FileStart
                f, err := parser.ParseFile(fset, filename, nil, parser.SkipObjectResolution)
                if err != nil {
                        return nil, nil, fmt.Errorf("can't parse raw cgo file: %v", err)
index 8cc6c4a058b53dea2e66a68f4e9504eb52935df7..f56c3e622fbc940b19fe112aeb986d84ec805ce7 100644 (file)
@@ -15,7 +15,6 @@ import (
        "golang.org/x/tools/go/analysis"
        "golang.org/x/tools/go/analysis/passes/inspect"
        "golang.org/x/tools/go/ast/inspector"
-       "golang.org/x/tools/internal/aliases"
        "golang.org/x/tools/internal/typeparams"
 )
 
@@ -72,7 +71,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
                        return
                }
                var structuralTypes []types.Type
-               switch typ := aliases.Unalias(typ).(type) {
+               switch typ := types.Unalias(typ).(type) {
                case *types.TypeParam:
                        terms, err := typeparams.StructuralTerms(typ)
                        if err != nil {
@@ -146,7 +145,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
 // isLocalType reports whether typ belongs to the same package as pass.
 // TODO(adonovan): local means "internal to a function"; rename to isSamePackageType.
 func isLocalType(pass *analysis.Pass, typ types.Type) bool {
-       switch x := aliases.Unalias(typ).(type) {
+       switch x := types.Unalias(typ).(type) {
        case *types.Struct:
                // struct literals are local types
                return true
index 0d63cd16124c7c6516f8b108d333c8d79f0904b4..03496cb3037d14258af3f3ff03d919624dd8a497 100644 (file)
@@ -16,9 +16,7 @@ import (
        "golang.org/x/tools/go/analysis"
        "golang.org/x/tools/go/analysis/passes/inspect"
        "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
-       "golang.org/x/tools/go/ast/astutil"
        "golang.org/x/tools/go/ast/inspector"
-       "golang.org/x/tools/internal/aliases"
        "golang.org/x/tools/internal/typeparams"
        "golang.org/x/tools/internal/versions"
 )
@@ -253,7 +251,7 @@ func (path typePath) String() string {
 }
 
 func lockPathRhs(pass *analysis.Pass, x ast.Expr) typePath {
-       x = astutil.Unparen(x) // ignore parens on rhs
+       x = ast.Unparen(x) // ignore parens on rhs
 
        if _, ok := x.(*ast.CompositeLit); ok {
                return nil
@@ -263,7 +261,7 @@ func lockPathRhs(pass *analysis.Pass, x ast.Expr) typePath {
                return nil
        }
        if star, ok := x.(*ast.StarExpr); ok {
-               if _, ok := astutil.Unparen(star.X).(*ast.CallExpr); ok {
+               if _, ok := ast.Unparen(star.X).(*ast.CallExpr); ok {
                        // A call may return a pointer to a zero value.
                        return nil
                }
@@ -287,7 +285,7 @@ func lockPath(tpkg *types.Package, typ types.Type, seen map[types.Type]bool) typ
        }
        seen[typ] = true
 
-       if tpar, ok := aliases.Unalias(typ).(*types.TypeParam); ok {
+       if tpar, ok := types.Unalias(typ).(*types.TypeParam); ok {
                terms, err := typeparams.StructuralTerms(tpar)
                if err != nil {
                        return nil // invalid type
index e1ca9b2f514cb3879b93c812f33040dd94d20b14..91ebe29de117a34b36518fe7707078b441ca8e66 100644 (file)
@@ -14,7 +14,6 @@ import (
        "golang.org/x/tools/go/analysis/passes/inspect"
        "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
        "golang.org/x/tools/go/ast/inspector"
-       "golang.org/x/tools/internal/aliases"
        "golang.org/x/tools/internal/typesinternal"
 )
 
@@ -137,7 +136,7 @@ func isHTTPFuncOrMethodOnClient(info *types.Info, expr *ast.CallExpr) bool {
        if analysisutil.IsNamedType(typ, "net/http", "Client") {
                return true // method on http.Client.
        }
-       ptr, ok := aliases.Unalias(typ).(*types.Pointer)
+       ptr, ok := types.Unalias(typ).(*types.Pointer)
        return ok && analysisutil.IsNamedType(ptr.Elem(), "net/http", "Client") // method on *http.Client.
 }
 
index f7f071dc8be98f730476f0b08b415e1ba095f4bd..a4fa8d31c4ed5bbc7e50a4079e04b20037436238 100644 (file)
@@ -15,7 +15,6 @@ import (
        "os"
 
        "golang.org/x/tools/go/analysis"
-       "golang.org/x/tools/internal/aliases"
        "golang.org/x/tools/internal/analysisinternal"
 )
 
@@ -121,7 +120,7 @@ func Imports(pkg *types.Package, path string) bool {
 // This function avoids allocating the concatenation of "pkg.Name",
 // which is important for the performance of syntax matching.
 func IsNamedType(t types.Type, pkgPath string, names ...string) bool {
-       n, ok := aliases.Unalias(t).(*types.Named)
+       n, ok := types.Unalias(t).(*types.Named)
        if !ok {
                return false
        }
index 28bf6c7e264246bb90aa73bbc53de1af5e5f468e..f789bdc811150f410b638a2105e80e8412c288a6 100644 (file)
@@ -10,7 +10,7 @@
 // lostcancel: check cancel func returned by context.WithCancel is called
 //
 // The cancellation function returned by context.WithCancel, WithTimeout,
-// and WithDeadline must be called or the new context will remain live
-// until its parent context is cancelled.
+// WithDeadline and variants such as WithCancelCause must be called,
+// or the new context will remain live until its parent context is cancelled.
 // (The background context is never cancelled.)
 package lostcancel
index bf56a5c06f68c6063a2bc762054fe38550d4e2f5..26fdc1206f805542426b73e1daca06e519e3dbfa 100644 (file)
@@ -198,7 +198,9 @@ func isContextWithCancel(info *types.Info, n ast.Node) bool {
                return false
        }
        switch sel.Sel.Name {
-       case "WithCancel", "WithTimeout", "WithDeadline":
+       case "WithCancel", "WithCancelCause",
+               "WithTimeout", "WithTimeoutCause",
+               "WithDeadline", "WithDeadlineCause":
        default:
                return false
        }
index c548cb1c1dca93fc8a5d0faf6930bcccc76ce447..2d79d0b03342c9d1eb03ce98ac51f655f908feb8 100644 (file)
@@ -24,7 +24,6 @@ import (
        "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
        "golang.org/x/tools/go/ast/inspector"
        "golang.org/x/tools/go/types/typeutil"
-       "golang.org/x/tools/internal/aliases"
        "golang.org/x/tools/internal/typeparams"
 )
 
@@ -161,7 +160,7 @@ func maybePrintfWrapper(info *types.Info, decl ast.Decl) *printfWrapper {
 
        // Check final parameter is "args ...interface{}".
        args := params.At(nparams - 1)
-       iface, ok := aliases.Unalias(args.Type().(*types.Slice).Elem()).(*types.Interface)
+       iface, ok := types.Unalias(args.Type().(*types.Slice).Elem()).(*types.Interface)
        if !ok || !iface.Empty() {
                return nil
        }
@@ -515,7 +514,7 @@ func checkPrintf(pass *analysis.Pass, kind Kind, call *ast.CallExpr, fn *types.F
                // non-constant format string and no arguments:
                // if msg contains "%", misformatting occurs.
                // Report the problem and suggest a fix: fmt.Printf("%s", msg).
-               if idx == len(call.Args)-1 {
+               if !suppressNonconstants && idx == len(call.Args)-1 {
                        pass.Report(analysis.Diagnostic{
                                Pos: formatArg.Pos(),
                                End: formatArg.End(),
@@ -1013,7 +1012,7 @@ func checkPrint(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) {
 
                typ := params.At(firstArg).Type()
                typ = typ.(*types.Slice).Elem()
-               it, ok := aliases.Unalias(typ).(*types.Interface)
+               it, ok := types.Unalias(typ).(*types.Interface)
                if !ok || !it.Empty() {
                        // Skip variadic functions accepting non-interface{} args.
                        return
@@ -1101,3 +1100,12 @@ func (ss stringSet) Set(flag string) error {
        }
        return nil
 }
+
+// suppressNonconstants suppresses reporting printf calls with
+// non-constant formatting strings (proposal #60529) when true.
+//
+// This variable is to allow for staging the transition to newer
+// versions of x/tools by vendoring.
+//
+// Remove this after the 1.24 release.
+var suppressNonconstants bool
index 017c8a247ecf18edf3c62aa4b02ca1bd94cfc28a..f7e50f98a9dee32aa210acfc0484048f8ef11a7c 100644 (file)
@@ -10,7 +10,6 @@ import (
        "go/types"
 
        "golang.org/x/tools/go/analysis"
-       "golang.org/x/tools/internal/aliases"
        "golang.org/x/tools/internal/typeparams"
 )
 
@@ -73,7 +72,7 @@ func (m *argMatcher) match(typ types.Type, topLevel bool) bool {
                return true
        }
 
-       if typ, _ := aliases.Unalias(typ).(*types.TypeParam); typ != nil {
+       if typ, _ := types.Unalias(typ).(*types.TypeParam); typ != nil {
                // Avoid infinite recursion through type parameters.
                if m.seen[typ] {
                        return true
@@ -276,7 +275,7 @@ func (m *argMatcher) match(typ types.Type, topLevel bool) bool {
 }
 
 func isConvertibleToString(typ types.Type) bool {
-       if bt, ok := aliases.Unalias(typ).(*types.Basic); ok && bt.Kind() == types.UntypedNil {
+       if bt, ok := types.Unalias(typ).(*types.Basic); ok && bt.Kind() == types.UntypedNil {
                // We explicitly don't want untyped nil, which is
                // convertible to both of the interfaces below, as it
                // would just panic anyway.
index d01eb1eebe56904f1a926e283194cc7014c5971e..759ed0043ff17cd531cd813885d3bcdedf5f6b0e 100644 (file)
@@ -21,7 +21,6 @@ import (
        "golang.org/x/tools/go/analysis/passes/inspect"
        "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
        "golang.org/x/tools/go/ast/inspector"
-       "golang.org/x/tools/internal/aliases"
        "golang.org/x/tools/internal/typeparams"
 )
 
@@ -100,7 +99,7 @@ func checkLongShift(pass *analysis.Pass, node ast.Node, x, y ast.Expr) {
                return
        }
        var structuralTypes []types.Type
-       switch t := aliases.Unalias(t).(type) {
+       switch t := types.Unalias(t).(type) {
        case *types.TypeParam:
                terms, err := typeparams.StructuralTerms(t)
                if err != nil {
index 0cade7bad7e100ee983e66a6c3bb79073b4fcdcb..0129102a33695b6b13b7646f2d62fe80090e6de9 100644 (file)
@@ -203,7 +203,7 @@ func kvFuncSkipArgs(fn *types.Func) (int, bool) {
 // order to get to the ones that match the ...any parameter.
 // The first key is the dereferenced receiver type name, or "" for a function.
 var kvFuncs = map[string]map[string]int{
-       "": map[string]int{
+       "": {
                "Debug":        1,
                "Info":         1,
                "Warn":         1,
@@ -215,7 +215,7 @@ var kvFuncs = map[string]map[string]int{
                "Log":          3,
                "Group":        1,
        },
-       "Logger": map[string]int{
+       "Logger": {
                "Debug":        1,
                "Info":         1,
                "Warn":         1,
@@ -227,7 +227,7 @@ var kvFuncs = map[string]map[string]int{
                "Log":          3,
                "With":         0,
        },
-       "Record": map[string]int{
+       "Record": {
                "Add": 0,
        },
 }
index a3afbf696e170e6f40655107fed279998a2c4c56..108600a2baf1a86be3893b4cdcc3cd63de58927c 100644 (file)
@@ -15,7 +15,6 @@ import (
        "golang.org/x/tools/go/analysis/passes/inspect"
        "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
        "golang.org/x/tools/go/ast/inspector"
-       "golang.org/x/tools/internal/aliases"
        "golang.org/x/tools/internal/analysisinternal"
        "golang.org/x/tools/internal/typeparams"
 )
@@ -248,7 +247,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
 
 func structuralTypes(t types.Type) ([]types.Type, error) {
        var structuralTypes []types.Type
-       if tp, ok := aliases.Unalias(t).(*types.TypeParam); ok {
+       if tp, ok := types.Unalias(t).(*types.TypeParam); ok {
                terms, err := typeparams.StructuralTerms(tp)
                if err != nil {
                        return nil, err
index 828f95bc8620677d492201de55b2c2ad28a653e1..effcdc5700b16d3309d5aa85d7304646ad7ee6ab 100644 (file)
@@ -14,10 +14,8 @@ import (
        "golang.org/x/tools/go/analysis"
        "golang.org/x/tools/go/analysis/passes/inspect"
        "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
-       "golang.org/x/tools/go/ast/astutil"
        "golang.org/x/tools/go/ast/inspector"
        "golang.org/x/tools/go/types/typeutil"
-       "golang.org/x/tools/internal/aliases"
 )
 
 //go:embed doc.go
@@ -186,7 +184,7 @@ func withinScope(scope ast.Node, x *types.Var) bool {
 func goAsyncCall(info *types.Info, goStmt *ast.GoStmt, toDecl func(*types.Func) *ast.FuncDecl) *asyncCall {
        call := goStmt.Call
 
-       fun := astutil.Unparen(call.Fun)
+       fun := ast.Unparen(call.Fun)
        if id := funcIdent(fun); id != nil {
                if lit := funcLitInScope(id); lit != nil {
                        return &asyncCall{region: lit, async: goStmt, scope: nil, fun: fun}
@@ -213,7 +211,7 @@ func tRunAsyncCall(info *types.Info, call *ast.CallExpr) *asyncCall {
                return nil
        }
 
-       fun := astutil.Unparen(call.Args[1])
+       fun := ast.Unparen(call.Args[1])
        if lit, ok := fun.(*ast.FuncLit); ok { // function lit?
                return &asyncCall{region: lit, async: call, scope: lit, fun: fun}
        }
@@ -243,7 +241,7 @@ var forbidden = []string{
 // Returns (nil, nil, nil) if call is not of this form.
 func forbiddenMethod(info *types.Info, call *ast.CallExpr) (*types.Var, *types.Selection, *types.Func) {
        // Compare to typeutil.StaticCallee.
-       fun := astutil.Unparen(call.Fun)
+       fun := ast.Unparen(call.Fun)
        selExpr, ok := fun.(*ast.SelectorExpr)
        if !ok {
                return nil, nil, nil
@@ -254,7 +252,7 @@ func forbiddenMethod(info *types.Info, call *ast.CallExpr) (*types.Var, *types.S
        }
 
        var x *types.Var
-       if id, ok := astutil.Unparen(selExpr.X).(*ast.Ident); ok {
+       if id, ok := ast.Unparen(selExpr.X).(*ast.Ident); ok {
                x, _ = info.Uses[id].(*types.Var)
        }
        if x == nil {
@@ -271,7 +269,7 @@ func forbiddenMethod(info *types.Info, call *ast.CallExpr) (*types.Var, *types.S
 func formatMethod(sel *types.Selection, fn *types.Func) string {
        var ptr string
        rtype := sel.Recv()
-       if p, ok := aliases.Unalias(rtype).(*types.Pointer); ok {
+       if p, ok := types.Unalias(rtype).(*types.Pointer); ok {
                ptr = "*"
                rtype = p.Elem()
        }
index ad815f190105719ce46b354c4bd55fabee13f71d..8c7a51ca525dda1b6bfdd2f2313830e888077273 100644 (file)
@@ -8,7 +8,6 @@ import (
        "go/ast"
        "go/types"
 
-       "golang.org/x/tools/go/ast/astutil"
        "golang.org/x/tools/internal/typeparams"
 )
 
@@ -56,7 +55,7 @@ func isMethodNamed(f *types.Func, pkgPath string, names ...string) bool {
 }
 
 func funcIdent(fun ast.Expr) *ast.Ident {
-       switch fun := astutil.Unparen(fun).(type) {
+       switch fun := ast.Unparen(fun).(type) {
        case *ast.IndexExpr, *ast.IndexListExpr:
                x, _, _, _ := typeparams.UnpackIndexExpr(fun) // necessary?
                id, _ := x.(*ast.Ident)
index 5b4598235cfa1a16433680b50c91a11fafd6cb82..36f2c43eb64d3029e26fb982378411ddcb67ff27 100644 (file)
@@ -48,7 +48,7 @@ var acceptedFuzzTypes = []types.Type{
 
 func run(pass *analysis.Pass) (interface{}, error) {
        for _, f := range pass.Files {
-               if !strings.HasSuffix(pass.Fset.File(f.Pos()).Name(), "_test.go") {
+               if !strings.HasSuffix(pass.Fset.File(f.FileStart).Name(), "_test.go") {
                        continue
                }
                for _, decl := range f.Decls {
index 14e4a6c1e4b853fc7ce964253d594933800e9988..272ae7fe045e3e2f9a4955a55ec14afa163e2acb 100644 (file)
@@ -15,9 +15,7 @@ import (
        "golang.org/x/tools/go/analysis"
        "golang.org/x/tools/go/analysis/passes/inspect"
        "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
-       "golang.org/x/tools/go/ast/astutil"
        "golang.org/x/tools/go/ast/inspector"
-       "golang.org/x/tools/internal/aliases"
 )
 
 //go:embed doc.go
@@ -70,7 +68,7 @@ func isSafeUintptr(info *types.Info, x ast.Expr) bool {
        // Check unsafe.Pointer safety rules according to
        // https://golang.org/pkg/unsafe/#Pointer.
 
-       switch x := astutil.Unparen(x).(type) {
+       switch x := ast.Unparen(x).(type) {
        case *ast.SelectorExpr:
                // "(6) Conversion of a reflect.SliceHeader or
                // reflect.StringHeader Data field to or from Pointer."
@@ -89,7 +87,7 @@ func isSafeUintptr(info *types.Info, x ast.Expr) bool {
                // by the time we get to the conversion at the end.
                // For now approximate by saying that *Header is okay
                // but Header is not.
-               pt, ok := aliases.Unalias(info.Types[x.X].Type).(*types.Pointer)
+               pt, ok := types.Unalias(info.Types[x.X].Type).(*types.Pointer)
                if ok && isReflectHeader(pt.Elem()) {
                        return true
                }
@@ -119,7 +117,7 @@ func isSafeUintptr(info *types.Info, x ast.Expr) bool {
 // isSafeArith reports whether x is a pointer arithmetic expression that is safe
 // to convert to unsafe.Pointer.
 func isSafeArith(info *types.Info, x ast.Expr) bool {
-       switch x := astutil.Unparen(x).(type) {
+       switch x := ast.Unparen(x).(type) {
        case *ast.CallExpr:
                // Base case: initial conversion from unsafe.Pointer to uintptr.
                return len(x.Args) == 1 &&
index 76f42b052e4594001af34ce151b19bea62ca5d63..c27d26dd6ec010cb06c3dcb4094a54aee3f9f4e8 100644 (file)
@@ -24,7 +24,6 @@ import (
        "golang.org/x/tools/go/analysis"
        "golang.org/x/tools/go/analysis/passes/inspect"
        "golang.org/x/tools/go/analysis/passes/internal/analysisutil"
-       "golang.org/x/tools/go/ast/astutil"
        "golang.org/x/tools/go/ast/inspector"
        "golang.org/x/tools/go/types/typeutil"
 )
@@ -101,7 +100,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
                (*ast.ExprStmt)(nil),
        }
        inspect.Preorder(nodeFilter, func(n ast.Node) {
-               call, ok := astutil.Unparen(n.(*ast.ExprStmt).X).(*ast.CallExpr)
+               call, ok := ast.Unparen(n.(*ast.ExprStmt).X).(*ast.CallExpr)
                if !ok {
                        return // not a call statement
                }
index 71ebbfaef1586b25e18bb0560fd8f699c3c2be0b..2301ccfc0e4e7cf2d3c8febe46c666b0f9c55ed4 100644 (file)
@@ -51,7 +51,6 @@ import (
        "golang.org/x/tools/go/analysis/internal/analysisflags"
        "golang.org/x/tools/internal/analysisinternal"
        "golang.org/x/tools/internal/facts"
-       "golang.org/x/tools/internal/versions"
 )
 
 // A Config describes a compilation unit to be analyzed.
@@ -257,15 +256,15 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re
                GoVersion: cfg.GoVersion,
        }
        info := &types.Info{
-               Types:      make(map[ast.Expr]types.TypeAndValue),
-               Defs:       make(map[*ast.Ident]types.Object),
-               Uses:       make(map[*ast.Ident]types.Object),
-               Implicits:  make(map[ast.Node]types.Object),
-               Instances:  make(map[*ast.Ident]types.Instance),
-               Scopes:     make(map[ast.Node]*types.Scope),
-               Selections: make(map[*ast.SelectorExpr]*types.Selection),
+               Types:        make(map[ast.Expr]types.TypeAndValue),
+               Defs:         make(map[*ast.Ident]types.Object),
+               Uses:         make(map[*ast.Ident]types.Object),
+               Implicits:    make(map[ast.Node]types.Object),
+               Instances:    make(map[*ast.Ident]types.Instance),
+               Scopes:       make(map[ast.Node]*types.Scope),
+               Selections:   make(map[*ast.SelectorExpr]*types.Selection),
+               FileVersions: make(map[*ast.File]string),
        }
-       versions.InitFileVersions(info)
 
        pkg, err := tc.Check(cfg.ImportPath, fset, files, info)
        if err != nil {
diff --git a/src/cmd/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go b/src/cmd/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
deleted file mode 100644 (file)
index 6e34df4..0000000
+++ /dev/null
@@ -1,654 +0,0 @@
-// Copyright 2013 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.
-
-package astutil
-
-// This file defines utilities for working with source positions.
-
-import (
-       "fmt"
-       "go/ast"
-       "go/token"
-       "sort"
-)
-
-// PathEnclosingInterval returns the node that encloses the source
-// interval [start, end), and all its ancestors up to the AST root.
-//
-// The definition of "enclosing" used by this function considers
-// additional whitespace abutting a node to be enclosed by it.
-// In this example:
-//
-//     z := x + y // add them
-//          <-A->
-//         <----B----->
-//
-// the ast.BinaryExpr(+) node is considered to enclose interval B
-// even though its [Pos()..End()) is actually only interval A.
-// This behaviour makes user interfaces more tolerant of imperfect
-// input.
-//
-// This function treats tokens as nodes, though they are not included
-// in the result. e.g. PathEnclosingInterval("+") returns the
-// enclosing ast.BinaryExpr("x + y").
-//
-// If start==end, the 1-char interval following start is used instead.
-//
-// The 'exact' result is true if the interval contains only path[0]
-// and perhaps some adjacent whitespace.  It is false if the interval
-// overlaps multiple children of path[0], or if it contains only
-// interior whitespace of path[0].
-// In this example:
-//
-//     z := x + y // add them
-//       <--C-->     <---E-->
-//         ^
-//         D
-//
-// intervals C, D and E are inexact.  C is contained by the
-// z-assignment statement, because it spans three of its children (:=,
-// x, +).  So too is the 1-char interval D, because it contains only
-// interior whitespace of the assignment.  E is considered interior
-// whitespace of the BlockStmt containing the assignment.
-//
-// The resulting path is never empty; it always contains at least the
-// 'root' *ast.File.  Ideally PathEnclosingInterval would reject
-// intervals that lie wholly or partially outside the range of the
-// file, but unfortunately ast.File records only the token.Pos of
-// the 'package' keyword, but not of the start of the file itself.
-func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Node, exact bool) {
-       // fmt.Printf("EnclosingInterval %d %d\n", start, end) // debugging
-
-       // Precondition: node.[Pos..End) and adjoining whitespace contain [start, end).
-       var visit func(node ast.Node) bool
-       visit = func(node ast.Node) bool {
-               path = append(path, node)
-
-               nodePos := node.Pos()
-               nodeEnd := node.End()
-
-               // fmt.Printf("visit(%T, %d, %d)\n", node, nodePos, nodeEnd) // debugging
-
-               // Intersect [start, end) with interval of node.
-               if start < nodePos {
-                       start = nodePos
-               }
-               if end > nodeEnd {
-                       end = nodeEnd
-               }
-
-               // Find sole child that contains [start, end).
-               children := childrenOf(node)
-               l := len(children)
-               for i, child := range children {
-                       // [childPos, childEnd) is unaugmented interval of child.
-                       childPos := child.Pos()
-                       childEnd := child.End()
-
-                       // [augPos, augEnd) is whitespace-augmented interval of child.
-                       augPos := childPos
-                       augEnd := childEnd
-                       if i > 0 {
-                               augPos = children[i-1].End() // start of preceding whitespace
-                       }
-                       if i < l-1 {
-                               nextChildPos := children[i+1].Pos()
-                               // Does [start, end) lie between child and next child?
-                               if start >= augEnd && end <= nextChildPos {
-                                       return false // inexact match
-                               }
-                               augEnd = nextChildPos // end of following whitespace
-                       }
-
-                       // fmt.Printf("\tchild %d: [%d..%d)\tcontains interval [%d..%d)?\n",
-                       //      i, augPos, augEnd, start, end) // debugging
-
-                       // Does augmented child strictly contain [start, end)?
-                       if augPos <= start && end <= augEnd {
-                               if is[tokenNode](child) {
-                                       return true
-                               }
-
-                               // childrenOf elides the FuncType node beneath FuncDecl.
-                               // Add it back here for TypeParams, Params, Results,
-                               // all FieldLists). But we don't add it back for the "func" token
-                               // even though it is is the tree at FuncDecl.Type.Func.
-                               if decl, ok := node.(*ast.FuncDecl); ok {
-                                       if fields, ok := child.(*ast.FieldList); ok && fields != decl.Recv {
-                                               path = append(path, decl.Type)
-                                       }
-                               }
-
-                               return visit(child)
-                       }
-
-                       // Does [start, end) overlap multiple children?
-                       // i.e. left-augmented child contains start
-                       // but LR-augmented child does not contain end.
-                       if start < childEnd && end > augEnd {
-                               break
-                       }
-               }
-
-               // No single child contained [start, end),
-               // so node is the result.  Is it exact?
-
-               // (It's tempting to put this condition before the
-               // child loop, but it gives the wrong result in the
-               // case where a node (e.g. ExprStmt) and its sole
-               // child have equal intervals.)
-               if start == nodePos && end == nodeEnd {
-                       return true // exact match
-               }
-
-               return false // inexact: overlaps multiple children
-       }
-
-       // Ensure [start,end) is nondecreasing.
-       if start > end {
-               start, end = end, start
-       }
-
-       if start < root.End() && end > root.Pos() {
-               if start == end {
-                       end = start + 1 // empty interval => interval of size 1
-               }
-               exact = visit(root)
-
-               // Reverse the path:
-               for i, l := 0, len(path); i < l/2; i++ {
-                       path[i], path[l-1-i] = path[l-1-i], path[i]
-               }
-       } else {
-               // Selection lies within whitespace preceding the
-               // first (or following the last) declaration in the file.
-               // The result nonetheless always includes the ast.File.
-               path = append(path, root)
-       }
-
-       return
-}
-
-// tokenNode is a dummy implementation of ast.Node for a single token.
-// They are used transiently by PathEnclosingInterval but never escape
-// this package.
-type tokenNode struct {
-       pos token.Pos
-       end token.Pos
-}
-
-func (n tokenNode) Pos() token.Pos {
-       return n.pos
-}
-
-func (n tokenNode) End() token.Pos {
-       return n.end
-}
-
-func tok(pos token.Pos, len int) ast.Node {
-       return tokenNode{pos, pos + token.Pos(len)}
-}
-
-// childrenOf returns the direct non-nil children of ast.Node n.
-// It may include fake ast.Node implementations for bare tokens.
-// it is not safe to call (e.g.) ast.Walk on such nodes.
-func childrenOf(n ast.Node) []ast.Node {
-       var children []ast.Node
-
-       // First add nodes for all true subtrees.
-       ast.Inspect(n, func(node ast.Node) bool {
-               if node == n { // push n
-                       return true // recur
-               }
-               if node != nil { // push child
-                       children = append(children, node)
-               }
-               return false // no recursion
-       })
-
-       // Then add fake Nodes for bare tokens.
-       switch n := n.(type) {
-       case *ast.ArrayType:
-               children = append(children,
-                       tok(n.Lbrack, len("[")),
-                       tok(n.Elt.End(), len("]")))
-
-       case *ast.AssignStmt:
-               children = append(children,
-                       tok(n.TokPos, len(n.Tok.String())))
-
-       case *ast.BasicLit:
-               children = append(children,
-                       tok(n.ValuePos, len(n.Value)))
-
-       case *ast.BinaryExpr:
-               children = append(children, tok(n.OpPos, len(n.Op.String())))
-
-       case *ast.BlockStmt:
-               children = append(children,
-                       tok(n.Lbrace, len("{")),
-                       tok(n.Rbrace, len("}")))
-
-       case *ast.BranchStmt:
-               children = append(children,
-                       tok(n.TokPos, len(n.Tok.String())))
-
-       case *ast.CallExpr:
-               children = append(children,
-                       tok(n.Lparen, len("(")),
-                       tok(n.Rparen, len(")")))
-               if n.Ellipsis != 0 {
-                       children = append(children, tok(n.Ellipsis, len("...")))
-               }
-
-       case *ast.CaseClause:
-               if n.List == nil {
-                       children = append(children,
-                               tok(n.Case, len("default")))
-               } else {
-                       children = append(children,
-                               tok(n.Case, len("case")))
-               }
-               children = append(children, tok(n.Colon, len(":")))
-
-       case *ast.ChanType:
-               switch n.Dir {
-               case ast.RECV:
-                       children = append(children, tok(n.Begin, len("<-chan")))
-               case ast.SEND:
-                       children = append(children, tok(n.Begin, len("chan<-")))
-               case ast.RECV | ast.SEND:
-                       children = append(children, tok(n.Begin, len("chan")))
-               }
-
-       case *ast.CommClause:
-               if n.Comm == nil {
-                       children = append(children,
-                               tok(n.Case, len("default")))
-               } else {
-                       children = append(children,
-                               tok(n.Case, len("case")))
-               }
-               children = append(children, tok(n.Colon, len(":")))
-
-       case *ast.Comment:
-               // nop
-
-       case *ast.CommentGroup:
-               // nop
-
-       case *ast.CompositeLit:
-               children = append(children,
-                       tok(n.Lbrace, len("{")),
-                       tok(n.Rbrace, len("{")))
-
-       case *ast.DeclStmt:
-               // nop
-
-       case *ast.DeferStmt:
-               children = append(children,
-                       tok(n.Defer, len("defer")))
-
-       case *ast.Ellipsis:
-               children = append(children,
-                       tok(n.Ellipsis, len("...")))
-
-       case *ast.EmptyStmt:
-               // nop
-
-       case *ast.ExprStmt:
-               // nop
-
-       case *ast.Field:
-               // TODO(adonovan): Field.{Doc,Comment,Tag}?
-
-       case *ast.FieldList:
-               children = append(children,
-                       tok(n.Opening, len("(")), // or len("[")
-                       tok(n.Closing, len(")"))) // or len("]")
-
-       case *ast.File:
-               // TODO test: Doc
-               children = append(children,
-                       tok(n.Package, len("package")))
-
-       case *ast.ForStmt:
-               children = append(children,
-                       tok(n.For, len("for")))
-
-       case *ast.FuncDecl:
-               // TODO(adonovan): FuncDecl.Comment?
-
-               // Uniquely, FuncDecl breaks the invariant that
-               // preorder traversal yields tokens in lexical order:
-               // in fact, FuncDecl.Recv precedes FuncDecl.Type.Func.
-               //
-               // As a workaround, we inline the case for FuncType
-               // here and order things correctly.
-               // We also need to insert the elided FuncType just
-               // before the 'visit' recursion.
-               //
-               children = nil // discard ast.Walk(FuncDecl) info subtrees
-               children = append(children, tok(n.Type.Func, len("func")))
-               if n.Recv != nil {
-                       children = append(children, n.Recv)
-               }
-               children = append(children, n.Name)
-               if tparams := n.Type.TypeParams; tparams != nil {
-                       children = append(children, tparams)
-               }
-               if n.Type.Params != nil {
-                       children = append(children, n.Type.Params)
-               }
-               if n.Type.Results != nil {
-                       children = append(children, n.Type.Results)
-               }
-               if n.Body != nil {
-                       children = append(children, n.Body)
-               }
-
-       case *ast.FuncLit:
-               // nop
-
-       case *ast.FuncType:
-               if n.Func != 0 {
-                       children = append(children,
-                               tok(n.Func, len("func")))
-               }
-
-       case *ast.GenDecl:
-               children = append(children,
-                       tok(n.TokPos, len(n.Tok.String())))
-               if n.Lparen != 0 {
-                       children = append(children,
-                               tok(n.Lparen, len("(")),
-                               tok(n.Rparen, len(")")))
-               }
-
-       case *ast.GoStmt:
-               children = append(children,
-                       tok(n.Go, len("go")))
-
-       case *ast.Ident:
-               children = append(children,
-                       tok(n.NamePos, len(n.Name)))
-
-       case *ast.IfStmt:
-               children = append(children,
-                       tok(n.If, len("if")))
-
-       case *ast.ImportSpec:
-               // TODO(adonovan): ImportSpec.{Doc,EndPos}?
-
-       case *ast.IncDecStmt:
-               children = append(children,
-                       tok(n.TokPos, len(n.Tok.String())))
-
-       case *ast.IndexExpr:
-               children = append(children,
-                       tok(n.Lbrack, len("[")),
-                       tok(n.Rbrack, len("]")))
-
-       case *ast.IndexListExpr:
-               children = append(children,
-                       tok(n.Lbrack, len("[")),
-                       tok(n.Rbrack, len("]")))
-
-       case *ast.InterfaceType:
-               children = append(children,
-                       tok(n.Interface, len("interface")))
-
-       case *ast.KeyValueExpr:
-               children = append(children,
-                       tok(n.Colon, len(":")))
-
-       case *ast.LabeledStmt:
-               children = append(children,
-                       tok(n.Colon, len(":")))
-
-       case *ast.MapType:
-               children = append(children,
-                       tok(n.Map, len("map")))
-
-       case *ast.ParenExpr:
-               children = append(children,
-                       tok(n.Lparen, len("(")),
-                       tok(n.Rparen, len(")")))
-
-       case *ast.RangeStmt:
-               children = append(children,
-                       tok(n.For, len("for")),
-                       tok(n.TokPos, len(n.Tok.String())))
-
-       case *ast.ReturnStmt:
-               children = append(children,
-                       tok(n.Return, len("return")))
-
-       case *ast.SelectStmt:
-               children = append(children,
-                       tok(n.Select, len("select")))
-
-       case *ast.SelectorExpr:
-               // nop
-
-       case *ast.SendStmt:
-               children = append(children,
-                       tok(n.Arrow, len("<-")))
-
-       case *ast.SliceExpr:
-               children = append(children,
-                       tok(n.Lbrack, len("[")),
-                       tok(n.Rbrack, len("]")))
-
-       case *ast.StarExpr:
-               children = append(children, tok(n.Star, len("*")))
-
-       case *ast.StructType:
-               children = append(children, tok(n.Struct, len("struct")))
-
-       case *ast.SwitchStmt:
-               children = append(children, tok(n.Switch, len("switch")))
-
-       case *ast.TypeAssertExpr:
-               children = append(children,
-                       tok(n.Lparen-1, len(".")),
-                       tok(n.Lparen, len("(")),
-                       tok(n.Rparen, len(")")))
-
-       case *ast.TypeSpec:
-               // TODO(adonovan): TypeSpec.{Doc,Comment}?
-
-       case *ast.TypeSwitchStmt:
-               children = append(children, tok(n.Switch, len("switch")))
-
-       case *ast.UnaryExpr:
-               children = append(children, tok(n.OpPos, len(n.Op.String())))
-
-       case *ast.ValueSpec:
-               // TODO(adonovan): ValueSpec.{Doc,Comment}?
-
-       case *ast.BadDecl, *ast.BadExpr, *ast.BadStmt:
-               // nop
-       }
-
-       // TODO(adonovan): opt: merge the logic of ast.Inspect() into
-       // the switch above so we can make interleaved callbacks for
-       // both Nodes and Tokens in the right order and avoid the need
-       // to sort.
-       sort.Sort(byPos(children))
-
-       return children
-}
-
-type byPos []ast.Node
-
-func (sl byPos) Len() int {
-       return len(sl)
-}
-func (sl byPos) Less(i, j int) bool {
-       return sl[i].Pos() < sl[j].Pos()
-}
-func (sl byPos) Swap(i, j int) {
-       sl[i], sl[j] = sl[j], sl[i]
-}
-
-// NodeDescription returns a description of the concrete type of n suitable
-// for a user interface.
-//
-// TODO(adonovan): in some cases (e.g. Field, FieldList, Ident,
-// StarExpr) we could be much more specific given the path to the AST
-// root.  Perhaps we should do that.
-func NodeDescription(n ast.Node) string {
-       switch n := n.(type) {
-       case *ast.ArrayType:
-               return "array type"
-       case *ast.AssignStmt:
-               return "assignment"
-       case *ast.BadDecl:
-               return "bad declaration"
-       case *ast.BadExpr:
-               return "bad expression"
-       case *ast.BadStmt:
-               return "bad statement"
-       case *ast.BasicLit:
-               return "basic literal"
-       case *ast.BinaryExpr:
-               return fmt.Sprintf("binary %s operation", n.Op)
-       case *ast.BlockStmt:
-               return "block"
-       case *ast.BranchStmt:
-               switch n.Tok {
-               case token.BREAK:
-                       return "break statement"
-               case token.CONTINUE:
-                       return "continue statement"
-               case token.GOTO:
-                       return "goto statement"
-               case token.FALLTHROUGH:
-                       return "fall-through statement"
-               }
-       case *ast.CallExpr:
-               if len(n.Args) == 1 && !n.Ellipsis.IsValid() {
-                       return "function call (or conversion)"
-               }
-               return "function call"
-       case *ast.CaseClause:
-               return "case clause"
-       case *ast.ChanType:
-               return "channel type"
-       case *ast.CommClause:
-               return "communication clause"
-       case *ast.Comment:
-               return "comment"
-       case *ast.CommentGroup:
-               return "comment group"
-       case *ast.CompositeLit:
-               return "composite literal"
-       case *ast.DeclStmt:
-               return NodeDescription(n.Decl) + " statement"
-       case *ast.DeferStmt:
-               return "defer statement"
-       case *ast.Ellipsis:
-               return "ellipsis"
-       case *ast.EmptyStmt:
-               return "empty statement"
-       case *ast.ExprStmt:
-               return "expression statement"
-       case *ast.Field:
-               // Can be any of these:
-               // struct {x, y int}  -- struct field(s)
-               // struct {T}         -- anon struct field
-               // interface {I}      -- interface embedding
-               // interface {f()}    -- interface method
-               // func (A) func(B) C -- receiver, param(s), result(s)
-               return "field/method/parameter"
-       case *ast.FieldList:
-               return "field/method/parameter list"
-       case *ast.File:
-               return "source file"
-       case *ast.ForStmt:
-               return "for loop"
-       case *ast.FuncDecl:
-               return "function declaration"
-       case *ast.FuncLit:
-               return "function literal"
-       case *ast.FuncType:
-               return "function type"
-       case *ast.GenDecl:
-               switch n.Tok {
-               case token.IMPORT:
-                       return "import declaration"
-               case token.CONST:
-                       return "constant declaration"
-               case token.TYPE:
-                       return "type declaration"
-               case token.VAR:
-                       return "variable declaration"
-               }
-       case *ast.GoStmt:
-               return "go statement"
-       case *ast.Ident:
-               return "identifier"
-       case *ast.IfStmt:
-               return "if statement"
-       case *ast.ImportSpec:
-               return "import specification"
-       case *ast.IncDecStmt:
-               if n.Tok == token.INC {
-                       return "increment statement"
-               }
-               return "decrement statement"
-       case *ast.IndexExpr:
-               return "index expression"
-       case *ast.IndexListExpr:
-               return "index list expression"
-       case *ast.InterfaceType:
-               return "interface type"
-       case *ast.KeyValueExpr:
-               return "key/value association"
-       case *ast.LabeledStmt:
-               return "statement label"
-       case *ast.MapType:
-               return "map type"
-       case *ast.Package:
-               return "package"
-       case *ast.ParenExpr:
-               return "parenthesized " + NodeDescription(n.X)
-       case *ast.RangeStmt:
-               return "range loop"
-       case *ast.ReturnStmt:
-               return "return statement"
-       case *ast.SelectStmt:
-               return "select statement"
-       case *ast.SelectorExpr:
-               return "selector"
-       case *ast.SendStmt:
-               return "channel send"
-       case *ast.SliceExpr:
-               return "slice expression"
-       case *ast.StarExpr:
-               return "*-operation" // load/store expr or pointer type
-       case *ast.StructType:
-               return "struct type"
-       case *ast.SwitchStmt:
-               return "switch statement"
-       case *ast.TypeAssertExpr:
-               return "type assertion"
-       case *ast.TypeSpec:
-               return "type specification"
-       case *ast.TypeSwitchStmt:
-               return "type switch"
-       case *ast.UnaryExpr:
-               return fmt.Sprintf("unary %s operation", n.Op)
-       case *ast.ValueSpec:
-               return "value specification"
-
-       }
-       panic(fmt.Sprintf("unexpected node type: %T", n))
-}
-
-func is[T any](x any) bool {
-       _, ok := x.(T)
-       return ok
-}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/ast/astutil/imports.go b/src/cmd/vendor/golang.org/x/tools/go/ast/astutil/imports.go
deleted file mode 100644 (file)
index 18d1adb..0000000
+++ /dev/null
@@ -1,485 +0,0 @@
-// Copyright 2013 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.
-
-// Package astutil contains common utilities for working with the Go AST.
-package astutil // import "golang.org/x/tools/go/ast/astutil"
-
-import (
-       "fmt"
-       "go/ast"
-       "go/token"
-       "strconv"
-       "strings"
-)
-
-// AddImport adds the import path to the file f, if absent.
-func AddImport(fset *token.FileSet, f *ast.File, path string) (added bool) {
-       return AddNamedImport(fset, f, "", path)
-}
-
-// AddNamedImport adds the import with the given name and path to the file f, if absent.
-// If name is not empty, it is used to rename the import.
-//
-// For example, calling
-//
-//     AddNamedImport(fset, f, "pathpkg", "path")
-//
-// adds
-//
-//     import pathpkg "path"
-func AddNamedImport(fset *token.FileSet, f *ast.File, name, path string) (added bool) {
-       if imports(f, name, path) {
-               return false
-       }
-
-       newImport := &ast.ImportSpec{
-               Path: &ast.BasicLit{
-                       Kind:  token.STRING,
-                       Value: strconv.Quote(path),
-               },
-       }
-       if name != "" {
-               newImport.Name = &ast.Ident{Name: name}
-       }
-
-       // Find an import decl to add to.
-       // The goal is to find an existing import
-       // whose import path has the longest shared
-       // prefix with path.
-       var (
-               bestMatch  = -1         // length of longest shared prefix
-               lastImport = -1         // index in f.Decls of the file's final import decl
-               impDecl    *ast.GenDecl // import decl containing the best match
-               impIndex   = -1         // spec index in impDecl containing the best match
-
-               isThirdPartyPath = isThirdParty(path)
-       )
-       for i, decl := range f.Decls {
-               gen, ok := decl.(*ast.GenDecl)
-               if ok && gen.Tok == token.IMPORT {
-                       lastImport = i
-                       // Do not add to import "C", to avoid disrupting the
-                       // association with its doc comment, breaking cgo.
-                       if declImports(gen, "C") {
-                               continue
-                       }
-
-                       // Match an empty import decl if that's all that is available.
-                       if len(gen.Specs) == 0 && bestMatch == -1 {
-                               impDecl = gen
-                       }
-
-                       // Compute longest shared prefix with imports in this group and find best
-                       // matched import spec.
-                       // 1. Always prefer import spec with longest shared prefix.
-                       // 2. While match length is 0,
-                       // - for stdlib package: prefer first import spec.
-                       // - for third party package: prefer first third party import spec.
-                       // We cannot use last import spec as best match for third party package
-                       // because grouped imports are usually placed last by goimports -local
-                       // flag.
-                       // See issue #19190.
-                       seenAnyThirdParty := false
-                       for j, spec := range gen.Specs {
-                               impspec := spec.(*ast.ImportSpec)
-                               p := importPath(impspec)
-                               n := matchLen(p, path)
-                               if n > bestMatch || (bestMatch == 0 && !seenAnyThirdParty && isThirdPartyPath) {
-                                       bestMatch = n
-                                       impDecl = gen
-                                       impIndex = j
-                               }
-                               seenAnyThirdParty = seenAnyThirdParty || isThirdParty(p)
-                       }
-               }
-       }
-
-       // If no import decl found, add one after the last import.
-       if impDecl == nil {
-               impDecl = &ast.GenDecl{
-                       Tok: token.IMPORT,
-               }
-               if lastImport >= 0 {
-                       impDecl.TokPos = f.Decls[lastImport].End()
-               } else {
-                       // There are no existing imports.
-                       // Our new import, preceded by a blank line,  goes after the package declaration
-                       // and after the comment, if any, that starts on the same line as the
-                       // package declaration.
-                       impDecl.TokPos = f.Package
-
-                       file := fset.File(f.Package)
-                       pkgLine := file.Line(f.Package)
-                       for _, c := range f.Comments {
-                               if file.Line(c.Pos()) > pkgLine {
-                                       break
-                               }
-                               // +2 for a blank line
-                               impDecl.TokPos = c.End() + 2
-                       }
-               }
-               f.Decls = append(f.Decls, nil)
-               copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:])
-               f.Decls[lastImport+1] = impDecl
-       }
-
-       // Insert new import at insertAt.
-       insertAt := 0
-       if impIndex >= 0 {
-               // insert after the found import
-               insertAt = impIndex + 1
-       }
-       impDecl.Specs = append(impDecl.Specs, nil)
-       copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:])
-       impDecl.Specs[insertAt] = newImport
-       pos := impDecl.Pos()
-       if insertAt > 0 {
-               // If there is a comment after an existing import, preserve the comment
-               // position by adding the new import after the comment.
-               if spec, ok := impDecl.Specs[insertAt-1].(*ast.ImportSpec); ok && spec.Comment != nil {
-                       pos = spec.Comment.End()
-               } else {
-                       // Assign same position as the previous import,
-                       // so that the sorter sees it as being in the same block.
-                       pos = impDecl.Specs[insertAt-1].Pos()
-               }
-       }
-       if newImport.Name != nil {
-               newImport.Name.NamePos = pos
-       }
-       newImport.Path.ValuePos = pos
-       newImport.EndPos = pos
-
-       // Clean up parens. impDecl contains at least one spec.
-       if len(impDecl.Specs) == 1 {
-               // Remove unneeded parens.
-               impDecl.Lparen = token.NoPos
-       } else if !impDecl.Lparen.IsValid() {
-               // impDecl needs parens added.
-               impDecl.Lparen = impDecl.Specs[0].Pos()
-       }
-
-       f.Imports = append(f.Imports, newImport)
-
-       if len(f.Decls) <= 1 {
-               return true
-       }
-
-       // Merge all the import declarations into the first one.
-       var first *ast.GenDecl
-       for i := 0; i < len(f.Decls); i++ {
-               decl := f.Decls[i]
-               gen, ok := decl.(*ast.GenDecl)
-               if !ok || gen.Tok != token.IMPORT || declImports(gen, "C") {
-                       continue
-               }
-               if first == nil {
-                       first = gen
-                       continue // Don't touch the first one.
-               }
-               // We now know there is more than one package in this import
-               // declaration. Ensure that it ends up parenthesized.
-               first.Lparen = first.Pos()
-               // Move the imports of the other import declaration to the first one.
-               for _, spec := range gen.Specs {
-                       spec.(*ast.ImportSpec).Path.ValuePos = first.Pos()
-                       first.Specs = append(first.Specs, spec)
-               }
-               f.Decls = append(f.Decls[:i], f.Decls[i+1:]...)
-               i--
-       }
-
-       return true
-}
-
-func isThirdParty(importPath string) bool {
-       // Third party package import path usually contains "." (".com", ".org", ...)
-       // This logic is taken from golang.org/x/tools/imports package.
-       return strings.Contains(importPath, ".")
-}
-
-// DeleteImport deletes the import path from the file f, if present.
-// If there are duplicate import declarations, all matching ones are deleted.
-func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool) {
-       return DeleteNamedImport(fset, f, "", path)
-}
-
-// DeleteNamedImport deletes the import with the given name and path from the file f, if present.
-// If there are duplicate import declarations, all matching ones are deleted.
-func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool) {
-       var delspecs []*ast.ImportSpec
-       var delcomments []*ast.CommentGroup
-
-       // Find the import nodes that import path, if any.
-       for i := 0; i < len(f.Decls); i++ {
-               decl := f.Decls[i]
-               gen, ok := decl.(*ast.GenDecl)
-               if !ok || gen.Tok != token.IMPORT {
-                       continue
-               }
-               for j := 0; j < len(gen.Specs); j++ {
-                       spec := gen.Specs[j]
-                       impspec := spec.(*ast.ImportSpec)
-                       if importName(impspec) != name || importPath(impspec) != path {
-                               continue
-                       }
-
-                       // We found an import spec that imports path.
-                       // Delete it.
-                       delspecs = append(delspecs, impspec)
-                       deleted = true
-                       copy(gen.Specs[j:], gen.Specs[j+1:])
-                       gen.Specs = gen.Specs[:len(gen.Specs)-1]
-
-                       // If this was the last import spec in this decl,
-                       // delete the decl, too.
-                       if len(gen.Specs) == 0 {
-                               copy(f.Decls[i:], f.Decls[i+1:])
-                               f.Decls = f.Decls[:len(f.Decls)-1]
-                               i--
-                               break
-                       } else if len(gen.Specs) == 1 {
-                               if impspec.Doc != nil {
-                                       delcomments = append(delcomments, impspec.Doc)
-                               }
-                               if impspec.Comment != nil {
-                                       delcomments = append(delcomments, impspec.Comment)
-                               }
-                               for _, cg := range f.Comments {
-                                       // Found comment on the same line as the import spec.
-                                       if cg.End() < impspec.Pos() && fset.Position(cg.End()).Line == fset.Position(impspec.Pos()).Line {
-                                               delcomments = append(delcomments, cg)
-                                               break
-                                       }
-                               }
-
-                               spec := gen.Specs[0].(*ast.ImportSpec)
-
-                               // Move the documentation right after the import decl.
-                               if spec.Doc != nil {
-                                       for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Doc.Pos()).Line {
-                                               fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line)
-                                       }
-                               }
-                               for _, cg := range f.Comments {
-                                       if cg.End() < spec.Pos() && fset.Position(cg.End()).Line == fset.Position(spec.Pos()).Line {
-                                               for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Pos()).Line {
-                                                       fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line)
-                                               }
-                                               break
-                                       }
-                               }
-                       }
-                       if j > 0 {
-                               lastImpspec := gen.Specs[j-1].(*ast.ImportSpec)
-                               lastLine := fset.PositionFor(lastImpspec.Path.ValuePos, false).Line
-                               line := fset.PositionFor(impspec.Path.ValuePos, false).Line
-
-                               // We deleted an entry but now there may be
-                               // a blank line-sized hole where the import was.
-                               if line-lastLine > 1 || !gen.Rparen.IsValid() {
-                                       // There was a blank line immediately preceding the deleted import,
-                                       // so there's no need to close the hole. The right parenthesis is
-                                       // invalid after AddImport to an import statement without parenthesis.
-                                       // Do nothing.
-                               } else if line != fset.File(gen.Rparen).LineCount() {
-                                       // There was no blank line. Close the hole.
-                                       fset.File(gen.Rparen).MergeLine(line)
-                               }
-                       }
-                       j--
-               }
-       }
-
-       // Delete imports from f.Imports.
-       for i := 0; i < len(f.Imports); i++ {
-               imp := f.Imports[i]
-               for j, del := range delspecs {
-                       if imp == del {
-                               copy(f.Imports[i:], f.Imports[i+1:])
-                               f.Imports = f.Imports[:len(f.Imports)-1]
-                               copy(delspecs[j:], delspecs[j+1:])
-                               delspecs = delspecs[:len(delspecs)-1]
-                               i--
-                               break
-                       }
-               }
-       }
-
-       // Delete comments from f.Comments.
-       for i := 0; i < len(f.Comments); i++ {
-               cg := f.Comments[i]
-               for j, del := range delcomments {
-                       if cg == del {
-                               copy(f.Comments[i:], f.Comments[i+1:])
-                               f.Comments = f.Comments[:len(f.Comments)-1]
-                               copy(delcomments[j:], delcomments[j+1:])
-                               delcomments = delcomments[:len(delcomments)-1]
-                               i--
-                               break
-                       }
-               }
-       }
-
-       if len(delspecs) > 0 {
-               panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs))
-       }
-
-       return
-}
-
-// RewriteImport rewrites any import of path oldPath to path newPath.
-func RewriteImport(fset *token.FileSet, f *ast.File, oldPath, newPath string) (rewrote bool) {
-       for _, imp := range f.Imports {
-               if importPath(imp) == oldPath {
-                       rewrote = true
-                       // record old End, because the default is to compute
-                       // it using the length of imp.Path.Value.
-                       imp.EndPos = imp.End()
-                       imp.Path.Value = strconv.Quote(newPath)
-               }
-       }
-       return
-}
-
-// UsesImport reports whether a given import is used.
-func UsesImport(f *ast.File, path string) (used bool) {
-       spec := importSpec(f, path)
-       if spec == nil {
-               return
-       }
-
-       name := spec.Name.String()
-       switch name {
-       case "<nil>":
-               // If the package name is not explicitly specified,
-               // make an educated guess. This is not guaranteed to be correct.
-               lastSlash := strings.LastIndex(path, "/")
-               if lastSlash == -1 {
-                       name = path
-               } else {
-                       name = path[lastSlash+1:]
-               }
-       case "_", ".":
-               // Not sure if this import is used - err on the side of caution.
-               return true
-       }
-
-       ast.Walk(visitFn(func(n ast.Node) {
-               sel, ok := n.(*ast.SelectorExpr)
-               if ok && isTopName(sel.X, name) {
-                       used = true
-               }
-       }), f)
-
-       return
-}
-
-type visitFn func(node ast.Node)
-
-func (fn visitFn) Visit(node ast.Node) ast.Visitor {
-       fn(node)
-       return fn
-}
-
-// imports reports whether f has an import with the specified name and path.
-func imports(f *ast.File, name, path string) bool {
-       for _, s := range f.Imports {
-               if importName(s) == name && importPath(s) == path {
-                       return true
-               }
-       }
-       return false
-}
-
-// importSpec returns the import spec if f imports path,
-// or nil otherwise.
-func importSpec(f *ast.File, path string) *ast.ImportSpec {
-       for _, s := range f.Imports {
-               if importPath(s) == path {
-                       return s
-               }
-       }
-       return nil
-}
-
-// importName returns the name of s,
-// or "" if the import is not named.
-func importName(s *ast.ImportSpec) string {
-       if s.Name == nil {
-               return ""
-       }
-       return s.Name.Name
-}
-
-// importPath returns the unquoted import path of s,
-// or "" if the path is not properly quoted.
-func importPath(s *ast.ImportSpec) string {
-       t, err := strconv.Unquote(s.Path.Value)
-       if err != nil {
-               return ""
-       }
-       return t
-}
-
-// declImports reports whether gen contains an import of path.
-func declImports(gen *ast.GenDecl, path string) bool {
-       if gen.Tok != token.IMPORT {
-               return false
-       }
-       for _, spec := range gen.Specs {
-               impspec := spec.(*ast.ImportSpec)
-               if importPath(impspec) == path {
-                       return true
-               }
-       }
-       return false
-}
-
-// matchLen returns the length of the longest path segment prefix shared by x and y.
-func matchLen(x, y string) int {
-       n := 0
-       for i := 0; i < len(x) && i < len(y) && x[i] == y[i]; i++ {
-               if x[i] == '/' {
-                       n++
-               }
-       }
-       return n
-}
-
-// isTopName returns true if n is a top-level unresolved identifier with the given name.
-func isTopName(n ast.Expr, name string) bool {
-       id, ok := n.(*ast.Ident)
-       return ok && id.Name == name && id.Obj == nil
-}
-
-// Imports returns the file imports grouped by paragraph.
-func Imports(fset *token.FileSet, f *ast.File) [][]*ast.ImportSpec {
-       var groups [][]*ast.ImportSpec
-
-       for _, decl := range f.Decls {
-               genDecl, ok := decl.(*ast.GenDecl)
-               if !ok || genDecl.Tok != token.IMPORT {
-                       break
-               }
-
-               group := []*ast.ImportSpec{}
-
-               var lastLine int
-               for _, spec := range genDecl.Specs {
-                       importSpec := spec.(*ast.ImportSpec)
-                       pos := importSpec.Path.ValuePos
-                       line := fset.Position(pos).Line
-                       if lastLine > 0 && pos > 0 && line-lastLine > 1 {
-                               groups = append(groups, group)
-                               group = []*ast.ImportSpec{}
-                       }
-                       group = append(group, importSpec)
-                       lastLine = line
-               }
-               groups = append(groups, group)
-       }
-
-       return groups
-}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go b/src/cmd/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go
deleted file mode 100644 (file)
index 58934f7..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-// Copyright 2017 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.
-
-package astutil
-
-import (
-       "fmt"
-       "go/ast"
-       "reflect"
-       "sort"
-)
-
-// An ApplyFunc is invoked by Apply for each node n, even if n is nil,
-// before and/or after the node's children, using a Cursor describing
-// the current node and providing operations on it.
-//
-// The return value of ApplyFunc controls the syntax tree traversal.
-// See Apply for details.
-type ApplyFunc func(*Cursor) bool
-
-// Apply traverses a syntax tree recursively, starting with root,
-// and calling pre and post for each node as described below.
-// Apply returns the syntax tree, possibly modified.
-//
-// If pre is not nil, it is called for each node before the node's
-// children are traversed (pre-order). If pre returns false, no
-// children are traversed, and post is not called for that node.
-//
-// If post is not nil, and a prior call of pre didn't return false,
-// post is called for each node after its children are traversed
-// (post-order). If post returns false, traversal is terminated and
-// Apply returns immediately.
-//
-// Only fields that refer to AST nodes are considered children;
-// i.e., token.Pos, Scopes, Objects, and fields of basic types
-// (strings, etc.) are ignored.
-//
-// Children are traversed in the order in which they appear in the
-// respective node's struct definition. A package's files are
-// traversed in the filenames' alphabetical order.
-func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node) {
-       parent := &struct{ ast.Node }{root}
-       defer func() {
-               if r := recover(); r != nil && r != abort {
-                       panic(r)
-               }
-               result = parent.Node
-       }()
-       a := &application{pre: pre, post: post}
-       a.apply(parent, "Node", nil, root)
-       return
-}
-
-var abort = new(int) // singleton, to signal termination of Apply
-
-// A Cursor describes a node encountered during Apply.
-// Information about the node and its parent is available
-// from the Node, Parent, Name, and Index methods.
-//
-// If p is a variable of type and value of the current parent node
-// c.Parent(), and f is the field identifier with name c.Name(),
-// the following invariants hold:
-//
-//     p.f            == c.Node()  if c.Index() <  0
-//     p.f[c.Index()] == c.Node()  if c.Index() >= 0
-//
-// The methods Replace, Delete, InsertBefore, and InsertAfter
-// can be used to change the AST without disrupting Apply.
-type Cursor struct {
-       parent ast.Node
-       name   string
-       iter   *iterator // valid if non-nil
-       node   ast.Node
-}
-
-// Node returns the current Node.
-func (c *Cursor) Node() ast.Node { return c.node }
-
-// Parent returns the parent of the current Node.
-func (c *Cursor) Parent() ast.Node { return c.parent }
-
-// Name returns the name of the parent Node field that contains the current Node.
-// If the parent is a *ast.Package and the current Node is a *ast.File, Name returns
-// the filename for the current Node.
-func (c *Cursor) Name() string { return c.name }
-
-// Index reports the index >= 0 of the current Node in the slice of Nodes that
-// contains it, or a value < 0 if the current Node is not part of a slice.
-// The index of the current node changes if InsertBefore is called while
-// processing the current node.
-func (c *Cursor) Index() int {
-       if c.iter != nil {
-               return c.iter.index
-       }
-       return -1
-}
-
-// field returns the current node's parent field value.
-func (c *Cursor) field() reflect.Value {
-       return reflect.Indirect(reflect.ValueOf(c.parent)).FieldByName(c.name)
-}
-
-// Replace replaces the current Node with n.
-// The replacement node is not walked by Apply.
-func (c *Cursor) Replace(n ast.Node) {
-       if _, ok := c.node.(*ast.File); ok {
-               file, ok := n.(*ast.File)
-               if !ok {
-                       panic("attempt to replace *ast.File with non-*ast.File")
-               }
-               c.parent.(*ast.Package).Files[c.name] = file
-               return
-       }
-
-       v := c.field()
-       if i := c.Index(); i >= 0 {
-               v = v.Index(i)
-       }
-       v.Set(reflect.ValueOf(n))
-}
-
-// Delete deletes the current Node from its containing slice.
-// If the current Node is not part of a slice, Delete panics.
-// As a special case, if the current node is a package file,
-// Delete removes it from the package's Files map.
-func (c *Cursor) Delete() {
-       if _, ok := c.node.(*ast.File); ok {
-               delete(c.parent.(*ast.Package).Files, c.name)
-               return
-       }
-
-       i := c.Index()
-       if i < 0 {
-               panic("Delete node not contained in slice")
-       }
-       v := c.field()
-       l := v.Len()
-       reflect.Copy(v.Slice(i, l), v.Slice(i+1, l))
-       v.Index(l - 1).Set(reflect.Zero(v.Type().Elem()))
-       v.SetLen(l - 1)
-       c.iter.step--
-}
-
-// InsertAfter inserts n after the current Node in its containing slice.
-// If the current Node is not part of a slice, InsertAfter panics.
-// Apply does not walk n.
-func (c *Cursor) InsertAfter(n ast.Node) {
-       i := c.Index()
-       if i < 0 {
-               panic("InsertAfter node not contained in slice")
-       }
-       v := c.field()
-       v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem())))
-       l := v.Len()
-       reflect.Copy(v.Slice(i+2, l), v.Slice(i+1, l))
-       v.Index(i + 1).Set(reflect.ValueOf(n))
-       c.iter.step++
-}
-
-// InsertBefore inserts n before the current Node in its containing slice.
-// If the current Node is not part of a slice, InsertBefore panics.
-// Apply will not walk n.
-func (c *Cursor) InsertBefore(n ast.Node) {
-       i := c.Index()
-       if i < 0 {
-               panic("InsertBefore node not contained in slice")
-       }
-       v := c.field()
-       v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem())))
-       l := v.Len()
-       reflect.Copy(v.Slice(i+1, l), v.Slice(i, l))
-       v.Index(i).Set(reflect.ValueOf(n))
-       c.iter.index++
-}
-
-// application carries all the shared data so we can pass it around cheaply.
-type application struct {
-       pre, post ApplyFunc
-       cursor    Cursor
-       iter      iterator
-}
-
-func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.Node) {
-       // convert typed nil into untyped nil
-       if v := reflect.ValueOf(n); v.Kind() == reflect.Ptr && v.IsNil() {
-               n = nil
-       }
-
-       // avoid heap-allocating a new cursor for each apply call; reuse a.cursor instead
-       saved := a.cursor
-       a.cursor.parent = parent
-       a.cursor.name = name
-       a.cursor.iter = iter
-       a.cursor.node = n
-
-       if a.pre != nil && !a.pre(&a.cursor) {
-               a.cursor = saved
-               return
-       }
-
-       // walk children
-       // (the order of the cases matches the order of the corresponding node types in go/ast)
-       switch n := n.(type) {
-       case nil:
-               // nothing to do
-
-       // Comments and fields
-       case *ast.Comment:
-               // nothing to do
-
-       case *ast.CommentGroup:
-               if n != nil {
-                       a.applyList(n, "List")
-               }
-
-       case *ast.Field:
-               a.apply(n, "Doc", nil, n.Doc)
-               a.applyList(n, "Names")
-               a.apply(n, "Type", nil, n.Type)
-               a.apply(n, "Tag", nil, n.Tag)
-               a.apply(n, "Comment", nil, n.Comment)
-
-       case *ast.FieldList:
-               a.applyList(n, "List")
-
-       // Expressions
-       case *ast.BadExpr, *ast.Ident, *ast.BasicLit:
-               // nothing to do
-
-       case *ast.Ellipsis:
-               a.apply(n, "Elt", nil, n.Elt)
-
-       case *ast.FuncLit:
-               a.apply(n, "Type", nil, n.Type)
-               a.apply(n, "Body", nil, n.Body)
-
-       case *ast.CompositeLit:
-               a.apply(n, "Type", nil, n.Type)
-               a.applyList(n, "Elts")
-
-       case *ast.ParenExpr:
-               a.apply(n, "X", nil, n.X)
-
-       case *ast.SelectorExpr:
-               a.apply(n, "X", nil, n.X)
-               a.apply(n, "Sel", nil, n.Sel)
-
-       case *ast.IndexExpr:
-               a.apply(n, "X", nil, n.X)
-               a.apply(n, "Index", nil, n.Index)
-
-       case *ast.IndexListExpr:
-               a.apply(n, "X", nil, n.X)
-               a.applyList(n, "Indices")
-
-       case *ast.SliceExpr:
-               a.apply(n, "X", nil, n.X)
-               a.apply(n, "Low", nil, n.Low)
-               a.apply(n, "High", nil, n.High)
-               a.apply(n, "Max", nil, n.Max)
-
-       case *ast.TypeAssertExpr:
-               a.apply(n, "X", nil, n.X)
-               a.apply(n, "Type", nil, n.Type)
-
-       case *ast.CallExpr:
-               a.apply(n, "Fun", nil, n.Fun)
-               a.applyList(n, "Args")
-
-       case *ast.StarExpr:
-               a.apply(n, "X", nil, n.X)
-
-       case *ast.UnaryExpr:
-               a.apply(n, "X", nil, n.X)
-
-       case *ast.BinaryExpr:
-               a.apply(n, "X", nil, n.X)
-               a.apply(n, "Y", nil, n.Y)
-
-       case *ast.KeyValueExpr:
-               a.apply(n, "Key", nil, n.Key)
-               a.apply(n, "Value", nil, n.Value)
-
-       // Types
-       case *ast.ArrayType:
-               a.apply(n, "Len", nil, n.Len)
-               a.apply(n, "Elt", nil, n.Elt)
-
-       case *ast.StructType:
-               a.apply(n, "Fields", nil, n.Fields)
-
-       case *ast.FuncType:
-               if tparams := n.TypeParams; tparams != nil {
-                       a.apply(n, "TypeParams", nil, tparams)
-               }
-               a.apply(n, "Params", nil, n.Params)
-               a.apply(n, "Results", nil, n.Results)
-
-       case *ast.InterfaceType:
-               a.apply(n, "Methods", nil, n.Methods)
-
-       case *ast.MapType:
-               a.apply(n, "Key", nil, n.Key)
-               a.apply(n, "Value", nil, n.Value)
-
-       case *ast.ChanType:
-               a.apply(n, "Value", nil, n.Value)
-
-       // Statements
-       case *ast.BadStmt:
-               // nothing to do
-
-       case *ast.DeclStmt:
-               a.apply(n, "Decl", nil, n.Decl)
-
-       case *ast.EmptyStmt:
-               // nothing to do
-
-       case *ast.LabeledStmt:
-               a.apply(n, "Label", nil, n.Label)
-               a.apply(n, "Stmt", nil, n.Stmt)
-
-       case *ast.ExprStmt:
-               a.apply(n, "X", nil, n.X)
-
-       case *ast.SendStmt:
-               a.apply(n, "Chan", nil, n.Chan)
-               a.apply(n, "Value", nil, n.Value)
-
-       case *ast.IncDecStmt:
-               a.apply(n, "X", nil, n.X)
-
-       case *ast.AssignStmt:
-               a.applyList(n, "Lhs")
-               a.applyList(n, "Rhs")
-
-       case *ast.GoStmt:
-               a.apply(n, "Call", nil, n.Call)
-
-       case *ast.DeferStmt:
-               a.apply(n, "Call", nil, n.Call)
-
-       case *ast.ReturnStmt:
-               a.applyList(n, "Results")
-
-       case *ast.BranchStmt:
-               a.apply(n, "Label", nil, n.Label)
-
-       case *ast.BlockStmt:
-               a.applyList(n, "List")
-
-       case *ast.IfStmt:
-               a.apply(n, "Init", nil, n.Init)
-               a.apply(n, "Cond", nil, n.Cond)
-               a.apply(n, "Body", nil, n.Body)
-               a.apply(n, "Else", nil, n.Else)
-
-       case *ast.CaseClause:
-               a.applyList(n, "List")
-               a.applyList(n, "Body")
-
-       case *ast.SwitchStmt:
-               a.apply(n, "Init", nil, n.Init)
-               a.apply(n, "Tag", nil, n.Tag)
-               a.apply(n, "Body", nil, n.Body)
-
-       case *ast.TypeSwitchStmt:
-               a.apply(n, "Init", nil, n.Init)
-               a.apply(n, "Assign", nil, n.Assign)
-               a.apply(n, "Body", nil, n.Body)
-
-       case *ast.CommClause:
-               a.apply(n, "Comm", nil, n.Comm)
-               a.applyList(n, "Body")
-
-       case *ast.SelectStmt:
-               a.apply(n, "Body", nil, n.Body)
-
-       case *ast.ForStmt:
-               a.apply(n, "Init", nil, n.Init)
-               a.apply(n, "Cond", nil, n.Cond)
-               a.apply(n, "Post", nil, n.Post)
-               a.apply(n, "Body", nil, n.Body)
-
-       case *ast.RangeStmt:
-               a.apply(n, "Key", nil, n.Key)
-               a.apply(n, "Value", nil, n.Value)
-               a.apply(n, "X", nil, n.X)
-               a.apply(n, "Body", nil, n.Body)
-
-       // Declarations
-       case *ast.ImportSpec:
-               a.apply(n, "Doc", nil, n.Doc)
-               a.apply(n, "Name", nil, n.Name)
-               a.apply(n, "Path", nil, n.Path)
-               a.apply(n, "Comment", nil, n.Comment)
-
-       case *ast.ValueSpec:
-               a.apply(n, "Doc", nil, n.Doc)
-               a.applyList(n, "Names")
-               a.apply(n, "Type", nil, n.Type)
-               a.applyList(n, "Values")
-               a.apply(n, "Comment", nil, n.Comment)
-
-       case *ast.TypeSpec:
-               a.apply(n, "Doc", nil, n.Doc)
-               a.apply(n, "Name", nil, n.Name)
-               if tparams := n.TypeParams; tparams != nil {
-                       a.apply(n, "TypeParams", nil, tparams)
-               }
-               a.apply(n, "Type", nil, n.Type)
-               a.apply(n, "Comment", nil, n.Comment)
-
-       case *ast.BadDecl:
-               // nothing to do
-
-       case *ast.GenDecl:
-               a.apply(n, "Doc", nil, n.Doc)
-               a.applyList(n, "Specs")
-
-       case *ast.FuncDecl:
-               a.apply(n, "Doc", nil, n.Doc)
-               a.apply(n, "Recv", nil, n.Recv)
-               a.apply(n, "Name", nil, n.Name)
-               a.apply(n, "Type", nil, n.Type)
-               a.apply(n, "Body", nil, n.Body)
-
-       // Files and packages
-       case *ast.File:
-               a.apply(n, "Doc", nil, n.Doc)
-               a.apply(n, "Name", nil, n.Name)
-               a.applyList(n, "Decls")
-               // Don't walk n.Comments; they have either been walked already if
-               // they are Doc comments, or they can be easily walked explicitly.
-
-       case *ast.Package:
-               // collect and sort names for reproducible behavior
-               var names []string
-               for name := range n.Files {
-                       names = append(names, name)
-               }
-               sort.Strings(names)
-               for _, name := range names {
-                       a.apply(n, name, nil, n.Files[name])
-               }
-
-       default:
-               panic(fmt.Sprintf("Apply: unexpected node type %T", n))
-       }
-
-       if a.post != nil && !a.post(&a.cursor) {
-               panic(abort)
-       }
-
-       a.cursor = saved
-}
-
-// An iterator controls iteration over a slice of nodes.
-type iterator struct {
-       index, step int
-}
-
-func (a *application) applyList(parent ast.Node, name string) {
-       // avoid heap-allocating a new iterator for each applyList call; reuse a.iter instead
-       saved := a.iter
-       a.iter.index = 0
-       for {
-               // must reload parent.name each time, since cursor modifications might change it
-               v := reflect.Indirect(reflect.ValueOf(parent)).FieldByName(name)
-               if a.iter.index >= v.Len() {
-                       break
-               }
-
-               // element x may be nil in a bad AST - be cautious
-               var x ast.Node
-               if e := v.Index(a.iter.index); e.IsValid() {
-                       x = e.Interface().(ast.Node)
-               }
-
-               a.iter.step = 1
-               a.apply(parent, name, &a.iter, x)
-               a.iter.index += a.iter.step
-       }
-       a.iter = saved
-}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/ast/astutil/util.go b/src/cmd/vendor/golang.org/x/tools/go/ast/astutil/util.go
deleted file mode 100644 (file)
index 6bdcf70..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2015 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.
-
-package astutil
-
-import "go/ast"
-
-// Unparen returns e with any enclosing parentheses stripped.
-// TODO(adonovan): use go1.22's ast.Unparen.
-func Unparen(e ast.Expr) ast.Expr {
-       for {
-               p, ok := e.(*ast.ParenExpr)
-               if !ok {
-                       return e
-               }
-               e = p.X
-       }
-}
index 1fc1de0bd10a7d722e89587c3b4801d3d1b04b31..958cf38deb00a4c85d5659cad7f3efe34d6efc79 100644 (file)
@@ -73,6 +73,15 @@ func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) {
        // check, Preorder is almost twice as fast as Nodes. The two
        // features seem to contribute similar slowdowns (~1.4x each).
 
+       // This function is equivalent to the PreorderSeq call below,
+       // but to avoid the additional dynamic call (which adds 13-35%
+       // to the benchmarks), we expand it out.
+       //
+       // in.PreorderSeq(types...)(func(n ast.Node) bool {
+       //      f(n)
+       //      return true
+       // })
+
        mask := maskOf(types)
        for i := 0; i < len(in.events); {
                ev := in.events[i]
@@ -171,7 +180,9 @@ func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, s
 // traverse builds the table of events representing a traversal.
 func traverse(files []*ast.File) []event {
        // Preallocate approximate number of events
-       // based on source file extent.
+       // based on source file extent of the declarations.
+       // (We use End-Pos not FileStart-FileEnd to neglect
+       // the effect of long doc comments.)
        // This makes traverse faster by 4x (!).
        var extent int
        for _, f := range files {
diff --git a/src/cmd/vendor/golang.org/x/tools/go/ast/inspector/iter.go b/src/cmd/vendor/golang.org/x/tools/go/ast/inspector/iter.go
new file mode 100644 (file)
index 0000000..b7e9591
--- /dev/null
@@ -0,0 +1,85 @@
+// 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
+
+package inspector
+
+import (
+       "go/ast"
+       "iter"
+)
+
+// PreorderSeq returns an iterator that visits all the
+// nodes of the files supplied to New in depth-first order.
+// It visits each node n before n's children.
+// The complete traversal sequence is determined by ast.Inspect.
+//
+// The types argument, if non-empty, enables type-based
+// filtering of events: only nodes whose type matches an
+// element of the types slice are included in the sequence.
+func (in *Inspector) PreorderSeq(types ...ast.Node) iter.Seq[ast.Node] {
+
+       // This implementation is identical to Preorder,
+       // except that it supports breaking out of the loop.
+
+       return func(yield func(ast.Node) bool) {
+               mask := maskOf(types)
+               for i := 0; i < len(in.events); {
+                       ev := in.events[i]
+                       if ev.index > i {
+                               // push
+                               if ev.typ&mask != 0 {
+                                       if !yield(ev.node) {
+                                               break
+                                       }
+                               }
+                               pop := ev.index
+                               if in.events[pop].typ&mask == 0 {
+                                       // Subtrees do not contain types: skip them and pop.
+                                       i = pop + 1
+                                       continue
+                               }
+                       }
+                       i++
+               }
+       }
+}
+
+// All[N] returns an iterator over all the nodes of type N.
+// N must be a pointer-to-struct type that implements ast.Node.
+//
+// Example:
+//
+//     for call := range All[*ast.CallExpr](in) { ... }
+func All[N interface {
+       *S
+       ast.Node
+}, S any](in *Inspector) iter.Seq[N] {
+
+       // To avoid additional dynamic call overheads,
+       // we duplicate rather than call the logic of PreorderSeq.
+
+       mask := typeOf((N)(nil))
+       return func(yield func(N) bool) {
+               for i := 0; i < len(in.events); {
+                       ev := in.events[i]
+                       if ev.index > i {
+                               // push
+                               if ev.typ&mask != 0 {
+                                       if !yield(ev.node.(N)) {
+                                               break
+                                       }
+                               }
+                               pop := ev.index
+                               if in.events[pop].typ&mask == 0 {
+                                       // Subtrees do not contain types: skip them and pop.
+                                       i = pop + 1
+                                       continue
+                               }
+                       }
+                       i++
+               }
+       }
+}
index 9ada177758ff7308c171da582ff6a00af2a00d1a..16ed3c1780bad78d4a03354ad889a2888be169cc 100644 (file)
@@ -228,7 +228,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
        //    Reject obviously non-viable cases.
        switch obj := obj.(type) {
        case *types.TypeName:
-               if _, ok := aliases.Unalias(obj.Type()).(*types.TypeParam); !ok {
+               if _, ok := types.Unalias(obj.Type()).(*types.TypeParam); !ok {
                        // With the exception of type parameters, only package-level type names
                        // have a path.
                        return "", fmt.Errorf("no path for %v", obj)
@@ -280,26 +280,26 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
                path = append(path, opType)
 
                T := o.Type()
-               if alias, ok := T.(*aliases.Alias); ok {
-                       if r := findTypeParam(obj, aliases.TypeParams(alias), path, opTypeParam, nil); r != nil {
+               if alias, ok := T.(*types.Alias); ok {
+                       if r := findTypeParam(obj, aliases.TypeParams(alias), path, opTypeParam); r != nil {
                                return Path(r), nil
                        }
-                       if r := find(obj, aliases.Rhs(alias), append(path, opRhs), nil); r != nil {
+                       if r := find(obj, aliases.Rhs(alias), append(path, opRhs)); r != nil {
                                return Path(r), nil
                        }
 
                } else if tname.IsAlias() {
                        // legacy alias
-                       if r := find(obj, T, path, nil); r != nil {
+                       if r := find(obj, T, path); r != nil {
                                return Path(r), nil
                        }
 
                } else if named, ok := T.(*types.Named); ok {
                        // defined (named) type
-                       if r := findTypeParam(obj, named.TypeParams(), path, opTypeParam, nil); r != nil {
+                       if r := findTypeParam(obj, named.TypeParams(), path, opTypeParam); r != nil {
                                return Path(r), nil
                        }
-                       if r := find(obj, named.Underlying(), append(path, opUnderlying), nil); r != nil {
+                       if r := find(obj, named.Underlying(), append(path, opUnderlying)); r != nil {
                                return Path(r), nil
                        }
                }
@@ -312,7 +312,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
                if _, ok := o.(*types.TypeName); !ok {
                        if o.Exported() {
                                // exported non-type (const, var, func)
-                               if r := find(obj, o.Type(), append(path, opType), nil); r != nil {
+                               if r := find(obj, o.Type(), append(path, opType)); r != nil {
                                        return Path(r), nil
                                }
                        }
@@ -320,7 +320,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
                }
 
                // Inspect declared methods of defined types.
-               if T, ok := aliases.Unalias(o.Type()).(*types.Named); ok {
+               if T, ok := types.Unalias(o.Type()).(*types.Named); ok {
                        path = append(path, opType)
                        // The method index here is always with respect
                        // to the underlying go/types data structures,
@@ -332,7 +332,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
                                if m == obj {
                                        return Path(path2), nil // found declared method
                                }
-                               if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
+                               if r := find(obj, m.Type(), append(path2, opType)); r != nil {
                                        return Path(r), nil
                                }
                        }
@@ -447,46 +447,64 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
 //
 // The seen map is used to short circuit cycles through type parameters. If
 // nil, it will be allocated as necessary.
-func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]bool) []byte {
+//
+// The seenMethods map is used internally to short circuit cycles through
+// interface methods, such as occur in the following example:
+//
+//     type I interface { f() interface{I} }
+//
+// See golang/go#68046 for details.
+func find(obj types.Object, T types.Type, path []byte) []byte {
+       return (&finder{obj: obj}).find(T, path)
+}
+
+// finder closes over search state for a call to find.
+type finder struct {
+       obj             types.Object             // the sought object
+       seenTParamNames map[*types.TypeName]bool // for cycle breaking through type parameters
+       seenMethods     map[*types.Func]bool     // for cycle breaking through recursive interfaces
+}
+
+func (f *finder) find(T types.Type, path []byte) []byte {
        switch T := T.(type) {
-       case *aliases.Alias:
-               return find(obj, aliases.Unalias(T), path, seen)
+       case *types.Alias:
+               return f.find(types.Unalias(T), path)
        case *types.Basic, *types.Named:
                // Named types belonging to pkg were handled already,
                // so T must belong to another package. No path.
                return nil
        case *types.Pointer:
-               return find(obj, T.Elem(), append(path, opElem), seen)
+               return f.find(T.Elem(), append(path, opElem))
        case *types.Slice:
-               return find(obj, T.Elem(), append(path, opElem), seen)
+               return f.find(T.Elem(), append(path, opElem))
        case *types.Array:
-               return find(obj, T.Elem(), append(path, opElem), seen)
+               return f.find(T.Elem(), append(path, opElem))
        case *types.Chan:
-               return find(obj, T.Elem(), append(path, opElem), seen)
+               return f.find(T.Elem(), append(path, opElem))
        case *types.Map:
-               if r := find(obj, T.Key(), append(path, opKey), seen); r != nil {
+               if r := f.find(T.Key(), append(path, opKey)); r != nil {
                        return r
                }
-               return find(obj, T.Elem(), append(path, opElem), seen)
+               return f.find(T.Elem(), append(path, opElem))
        case *types.Signature:
-               if r := findTypeParam(obj, T.RecvTypeParams(), path, opRecvTypeParam, nil); r != nil {
+               if r := f.findTypeParam(T.RecvTypeParams(), path, opRecvTypeParam); r != nil {
                        return r
                }
-               if r := findTypeParam(obj, T.TypeParams(), path, opTypeParam, seen); r != nil {
+               if r := f.findTypeParam(T.TypeParams(), path, opTypeParam); r != nil {
                        return r
                }
-               if r := find(obj, T.Params(), append(path, opParams), seen); r != nil {
+               if r := f.find(T.Params(), append(path, opParams)); r != nil {
                        return r
                }
-               return find(obj, T.Results(), append(path, opResults), seen)
+               return f.find(T.Results(), append(path, opResults))
        case *types.Struct:
                for i := 0; i < T.NumFields(); i++ {
                        fld := T.Field(i)
                        path2 := appendOpArg(path, opField, i)
-                       if fld == obj {
+                       if fld == f.obj {
                                return path2 // found field var
                        }
-                       if r := find(obj, fld.Type(), append(path2, opType), seen); r != nil {
+                       if r := f.find(fld.Type(), append(path2, opType)); r != nil {
                                return r
                        }
                }
@@ -495,10 +513,10 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
                for i := 0; i < T.Len(); i++ {
                        v := T.At(i)
                        path2 := appendOpArg(path, opAt, i)
-                       if v == obj {
+                       if v == f.obj {
                                return path2 // found param/result var
                        }
-                       if r := find(obj, v.Type(), append(path2, opType), seen); r != nil {
+                       if r := f.find(v.Type(), append(path2, opType)); r != nil {
                                return r
                        }
                }
@@ -506,28 +524,35 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
        case *types.Interface:
                for i := 0; i < T.NumMethods(); i++ {
                        m := T.Method(i)
+                       if f.seenMethods[m] {
+                               return nil
+                       }
                        path2 := appendOpArg(path, opMethod, i)
-                       if m == obj {
+                       if m == f.obj {
                                return path2 // found interface method
                        }
-                       if r := find(obj, m.Type(), append(path2, opType), seen); r != nil {
+                       if f.seenMethods == nil {
+                               f.seenMethods = make(map[*types.Func]bool)
+                       }
+                       f.seenMethods[m] = true
+                       if r := f.find(m.Type(), append(path2, opType)); r != nil {
                                return r
                        }
                }
                return nil
        case *types.TypeParam:
                name := T.Obj()
-               if name == obj {
-                       return append(path, opObj)
-               }
-               if seen[name] {
+               if f.seenTParamNames[name] {
                        return nil
                }
-               if seen == nil {
-                       seen = make(map[*types.TypeName]bool)
+               if name == f.obj {
+                       return append(path, opObj)
                }
-               seen[name] = true
-               if r := find(obj, T.Constraint(), append(path, opConstraint), seen); r != nil {
+               if f.seenTParamNames == nil {
+                       f.seenTParamNames = make(map[*types.TypeName]bool)
+               }
+               f.seenTParamNames[name] = true
+               if r := f.find(T.Constraint(), append(path, opConstraint)); r != nil {
                        return r
                }
                return nil
@@ -535,11 +560,15 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
        panic(T)
 }
 
-func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, op byte, seen map[*types.TypeName]bool) []byte {
+func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, op byte) []byte {
+       return (&finder{obj: obj}).findTypeParam(list, path, op)
+}
+
+func (f *finder) findTypeParam(list *types.TypeParamList, path []byte, op byte) []byte {
        for i := 0; i < list.Len(); i++ {
                tparam := list.At(i)
                path2 := appendOpArg(path, op, i)
-               if r := find(obj, tparam, path2, seen); r != nil {
+               if r := f.find(tparam, path2); r != nil {
                        return r
                }
        }
@@ -626,7 +655,7 @@ func Object(pkg *types.Package, p Path) (types.Object, error) {
 
                // Inv: t != nil, obj == nil
 
-               t = aliases.Unalias(t)
+               t = types.Unalias(t)
                switch code {
                case opElem:
                        hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map
@@ -664,7 +693,7 @@ func Object(pkg *types.Package, p Path) (types.Object, error) {
                        t = named.Underlying()
 
                case opRhs:
-                       if alias, ok := t.(*aliases.Alias); ok {
+                       if alias, ok := t.(*types.Alias); ok {
                                t = aliases.Rhs(alias)
                        } else if false && aliases.Enabled() {
                                // The Enabled check is too expensive, so for now we
index 90dc541adfe3f40e13a3d0b84c87fa29617a6ef9..754380351e86500146206b501e94f90a5af8dedb 100644 (file)
@@ -8,7 +8,6 @@ import (
        "go/ast"
        "go/types"
 
-       "golang.org/x/tools/go/ast/astutil"
        "golang.org/x/tools/internal/typeparams"
 )
 
@@ -17,7 +16,7 @@ import (
 //
 // Functions and methods may potentially have type parameters.
 func Callee(info *types.Info, call *ast.CallExpr) types.Object {
-       fun := astutil.Unparen(call.Fun)
+       fun := ast.Unparen(call.Fun)
 
        // Look through type instantiation if necessary.
        isInstance := false
index a92f80dd2da99cb536b339bece9f43b5f031d1ac..8d824f7140f456ac27e5ad6affa2deb7f2f460e5 100644 (file)
@@ -12,7 +12,6 @@ import (
        "go/types"
        "reflect"
 
-       "golang.org/x/tools/internal/aliases"
        "golang.org/x/tools/internal/typeparams"
 )
 
@@ -260,8 +259,8 @@ func (h Hasher) hashFor(t types.Type) uint32 {
        case *types.Basic:
                return uint32(t.Kind())
 
-       case *aliases.Alias:
-               return h.Hash(aliases.Unalias(t))
+       case *types.Alias:
+               return h.Hash(types.Unalias(t))
 
        case *types.Array:
                return 9043 + 2*uint32(t.Len()) + 3*h.Hash(t.Elem())
@@ -461,8 +460,8 @@ func (h Hasher) shallowHash(t types.Type) uint32 {
        // elements (mostly Slice, Pointer, Basic, Named),
        // so there's no need to optimize anything else.
        switch t := t.(type) {
-       case *aliases.Alias:
-               return h.shallowHash(aliases.Unalias(t))
+       case *types.Alias:
+               return h.shallowHash(types.Unalias(t))
 
        case *types.Signature:
                var hash uint32 = 604171
index bd71aafaaa1885c1b4bcaa19b1df17deb3192fd7..f7666028fe5d38cdec8a7fc936db6613eafdd4db 100644 (file)
@@ -9,8 +9,6 @@ package typeutil
 import (
        "go/types"
        "sync"
-
-       "golang.org/x/tools/internal/aliases"
 )
 
 // A MethodSetCache records the method set of each type T for which
@@ -34,12 +32,12 @@ func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet {
        cache.mu.Lock()
        defer cache.mu.Unlock()
 
-       switch T := aliases.Unalias(T).(type) {
+       switch T := types.Unalias(T).(type) {
        case *types.Named:
                return cache.lookupNamed(T).value
 
        case *types.Pointer:
-               if N, ok := aliases.Unalias(T.Elem()).(*types.Named); ok {
+               if N, ok := types.Unalias(T.Elem()).(*types.Named); ok {
                        return cache.lookupNamed(N).pointer
                }
        }
index a0c1a60ac023d8fe792d436a5c73812d1a6f222d..9dda6a25df79e1147f0f3baf9bd81d8f1adc56cf 100644 (file)
@@ -8,8 +8,6 @@ package typeutil
 
 import (
        "go/types"
-
-       "golang.org/x/tools/internal/aliases"
 )
 
 // IntuitiveMethodSet returns the intuitive method set of a type T,
@@ -28,7 +26,7 @@ import (
 // The order of the result is as for types.MethodSet(T).
 func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection {
        isPointerToConcrete := func(T types.Type) bool {
-               ptr, ok := aliases.Unalias(T).(*types.Pointer)
+               ptr, ok := types.Unalias(T).(*types.Pointer)
                return ok && !types.IsInterface(ptr.Elem())
        }
 
index f7798e3354e485cc108abb46c6d5fd2ea7680396..b9425f5a20990fc534c08d5bcbb34502f0cee620 100644 (file)
@@ -28,7 +28,7 @@ import (
 func NewAlias(enabled bool, pos token.Pos, pkg *types.Package, name string, rhs types.Type, tparams []*types.TypeParam) *types.TypeName {
        if enabled {
                tname := types.NewTypeName(pos, pkg, name, nil)
-               newAlias(tname, rhs, tparams)
+               SetTypeParams(types.NewAlias(tname, rhs), tparams)
                return tname
        }
        if len(tparams) > 0 {
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go b/src/cmd/vendor/golang.org/x/tools/internal/aliases/aliases_go121.go
deleted file mode 100644 (file)
index a775fcc..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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.22
-// +build !go1.22
-
-package aliases
-
-import (
-       "go/types"
-)
-
-// Alias is a placeholder for a go/types.Alias for <=1.21.
-// It will never be created by go/types.
-type Alias struct{}
-
-func (*Alias) String() string                                { panic("unreachable") }
-func (*Alias) Underlying() types.Type                        { panic("unreachable") }
-func (*Alias) Obj() *types.TypeName                          { panic("unreachable") }
-func Rhs(alias *Alias) types.Type                            { panic("unreachable") }
-func TypeParams(alias *Alias) *types.TypeParamList           { panic("unreachable") }
-func SetTypeParams(alias *Alias, tparams []*types.TypeParam) { panic("unreachable") }
-func TypeArgs(alias *Alias) *types.TypeList                  { panic("unreachable") }
-func Origin(alias *Alias) *Alias                             { panic("unreachable") }
-
-// Unalias returns the type t for go <=1.21.
-func Unalias(t types.Type) types.Type { return t }
-
-func newAlias(name *types.TypeName, rhs types.Type, tparams []*types.TypeParam) *Alias {
-       panic("unreachable")
-}
-
-// Enabled reports whether [NewAlias] should create [types.Alias] types.
-//
-// Before go1.22, this function always returns false.
-func Enabled() bool { return false }
index 31c159e42e6c44e0b22b6bc2437008e149a91656..7716a3331db8afe1a07580f8f40d24087fd335ec 100644 (file)
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build go1.22
-// +build go1.22
-
 package aliases
 
 import (
@@ -14,22 +11,19 @@ import (
        "go/types"
 )
 
-// Alias is an alias of types.Alias.
-type Alias = types.Alias
-
 // Rhs returns the type on the right-hand side of the alias declaration.
-func Rhs(alias *Alias) types.Type {
+func Rhs(alias *types.Alias) types.Type {
        if alias, ok := any(alias).(interface{ Rhs() types.Type }); ok {
                return alias.Rhs() // go1.23+
        }
 
        // go1.22's Alias didn't have the Rhs method,
        // so Unalias is the best we can do.
-       return Unalias(alias)
+       return types.Unalias(alias)
 }
 
 // TypeParams returns the type parameter list of the alias.
-func TypeParams(alias *Alias) *types.TypeParamList {
+func TypeParams(alias *types.Alias) *types.TypeParamList {
        if alias, ok := any(alias).(interface{ TypeParams() *types.TypeParamList }); ok {
                return alias.TypeParams() // go1.23+
        }
@@ -37,7 +31,7 @@ func TypeParams(alias *Alias) *types.TypeParamList {
 }
 
 // SetTypeParams sets the type parameters of the alias type.
-func SetTypeParams(alias *Alias, tparams []*types.TypeParam) {
+func SetTypeParams(alias *types.Alias, tparams []*types.TypeParam) {
        if alias, ok := any(alias).(interface {
                SetTypeParams(tparams []*types.TypeParam)
        }); ok {
@@ -48,7 +42,7 @@ func SetTypeParams(alias *Alias, tparams []*types.TypeParam) {
 }
 
 // TypeArgs returns the type arguments used to instantiate the Alias type.
-func TypeArgs(alias *Alias) *types.TypeList {
+func TypeArgs(alias *types.Alias) *types.TypeList {
        if alias, ok := any(alias).(interface{ TypeArgs() *types.TypeList }); ok {
                return alias.TypeArgs() // go1.23+
        }
@@ -57,25 +51,13 @@ func TypeArgs(alias *Alias) *types.TypeList {
 
 // Origin returns the generic Alias type of which alias is an instance.
 // If alias is not an instance of a generic alias, Origin returns alias.
-func Origin(alias *Alias) *Alias {
+func Origin(alias *types.Alias) *types.Alias {
        if alias, ok := any(alias).(interface{ Origin() *types.Alias }); ok {
                return alias.Origin() // go1.23+
        }
        return alias // not an instance of a generic alias (go1.22)
 }
 
-// Unalias is a wrapper of types.Unalias.
-func Unalias(t types.Type) types.Type { return types.Unalias(t) }
-
-// newAlias is an internal alias around types.NewAlias.
-// Direct usage is discouraged as the moment.
-// Try to use NewAlias instead.
-func newAlias(tname *types.TypeName, rhs types.Type, tparams []*types.TypeParam) *Alias {
-       a := types.NewAlias(tname, rhs)
-       SetTypeParams(a, tparams)
-       return a
-}
-
 // Enabled reports whether [NewAlias] should create [types.Alias] types.
 //
 // This function is expensive! Call it sparingly.
@@ -91,7 +73,7 @@ func Enabled() bool {
        //     many tests. Therefore any attempt to cache the result
        //     is just incorrect.
        fset := token.NewFileSet()
-       f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", 0)
+       f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", parser.SkipObjectResolution)
        pkg, _ := new(types.Config).Check("p", fset, []*ast.File{f}, nil)
        _, enabled := pkg.Scope().Lookup("A").Type().(*types.Alias)
        return enabled
index e0b13e70a015671ae0a903148fc953709b34fd1e..4ccaa210af112a29c7095d8ceac4a06396f92cb1 100644 (file)
@@ -10,6 +10,7 @@ import (
        "bytes"
        "fmt"
        "go/ast"
+       "go/scanner"
        "go/token"
        "go/types"
        "os"
@@ -17,24 +18,57 @@ import (
        "strconv"
 
        "golang.org/x/tools/go/analysis"
-       "golang.org/x/tools/internal/aliases"
 )
 
 func TypeErrorEndPos(fset *token.FileSet, src []byte, start token.Pos) token.Pos {
        // Get the end position for the type error.
-       offset, end := fset.PositionFor(start, false).Offset, start
-       if offset >= len(src) {
-               return end
+       file := fset.File(start)
+       if file == nil {
+               return start
        }
-       if width := bytes.IndexAny(src[offset:], " \n,():;[]+-*"); width > 0 {
-               end = start + token.Pos(width)
+       if offset := file.PositionFor(start, false).Offset; offset > len(src) {
+               return start
+       } else {
+               src = src[offset:]
+       }
+
+       // Attempt to find a reasonable end position for the type error.
+       //
+       // TODO(rfindley): the heuristic implemented here is unclear. It looks like
+       // it seeks the end of the primary operand starting at start, but that is not
+       // quite implemented (for example, given a func literal this heuristic will
+       // return the range of the func keyword).
+       //
+       // We should formalize this heuristic, or deprecate it by finally proposing
+       // to add end position to all type checker errors.
+       //
+       // Nevertheless, ensure that the end position at least spans the current
+       // token at the cursor (this was golang/go#69505).
+       end := start
+       {
+               var s scanner.Scanner
+               fset := token.NewFileSet()
+               f := fset.AddFile("", fset.Base(), len(src))
+               s.Init(f, src, nil /* no error handler */, scanner.ScanComments)
+               pos, tok, lit := s.Scan()
+               if tok != token.SEMICOLON && token.Pos(f.Base()) <= pos && pos <= token.Pos(f.Base()+f.Size()) {
+                       off := file.Offset(pos) + len(lit)
+                       src = src[off:]
+                       end += token.Pos(off)
+               }
+       }
+
+       // Look for bytes that might terminate the current operand. See note above:
+       // this is imprecise.
+       if width := bytes.IndexAny(src, " \n,():;[]+-*/"); width > 0 {
+               end += token.Pos(width)
        }
        return end
 }
 
 func ZeroValue(f *ast.File, pkg *types.Package, typ types.Type) ast.Expr {
        // TODO(adonovan): think about generics, and also generic aliases.
-       under := aliases.Unalias(typ)
+       under := types.Unalias(typ)
        // Don't call Underlying unconditionally: although it removes
        // Named and Alias, it also removes TypeParam.
        if n, ok := under.(*types.Named); ok {
@@ -416,8 +450,7 @@ func CheckReadable(pass *analysis.Pass, filename string) error {
                return nil
        }
        for _, f := range pass.Files {
-               // TODO(adonovan): use go1.20 f.FileStart
-               if pass.Fset.File(f.Pos()).Name() == filename {
+               if pass.Fset.File(f.FileStart).Name() == filename {
                        return nil
                }
        }
index 9f706cd954fed46e2d13759a42354730f4d6ba77..c36f2a5af0c46eb147f0ac6d569680560746738d 100644 (file)
@@ -6,8 +6,6 @@ package facts
 
 import (
        "go/types"
-
-       "golang.org/x/tools/internal/aliases"
 )
 
 // importMap computes the import map for a package by traversing the
@@ -47,8 +45,8 @@ func importMap(imports []*types.Package) map[string]*types.Package {
 
        addType = func(T types.Type) {
                switch T := T.(type) {
-               case *aliases.Alias:
-                       addType(aliases.Unalias(T))
+               case *types.Alias:
+                       addType(types.Unalias(T))
                case *types.Basic:
                        // nop
                case *types.Named:
index 89bd256dc67b3351059347eff11822fdf8c63d9c..0b84acc5c7fa43e3d2e9199916194fb9e0d268e1 100644 (file)
@@ -16,8 +16,6 @@ import (
        "go/ast"
        "go/token"
        "go/types"
-
-       "golang.org/x/tools/internal/aliases"
 )
 
 // UnpackIndexExpr extracts data from AST nodes that represent index
@@ -65,7 +63,7 @@ func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack toke
 
 // IsTypeParam reports whether t is a type parameter (or an alias of one).
 func IsTypeParam(t types.Type) bool {
-       _, ok := aliases.Unalias(t).(*types.TypeParam)
+       _, ok := types.Unalias(t).(*types.TypeParam)
        return ok
 }
 
@@ -93,8 +91,8 @@ func IsTypeParam(t types.Type) bool {
 // In this case, GenericAssignableTo reports that instantiations of Container
 // are assignable to the corresponding instantiation of Interface.
 func GenericAssignableTo(ctxt *types.Context, V, T types.Type) bool {
-       V = aliases.Unalias(V)
-       T = aliases.Unalias(T)
+       V = types.Unalias(V)
+       T = types.Unalias(T)
 
        // If V and T are not both named, or do not have matching non-empty type
        // parameter lists, fall back on types.AssignableTo.
index a1d138226c98939f126a5a0c3fe2c42132353bbe..0ade5c2949edad351dbad01eb4e4ef4b7f55f88e 100644 (file)
@@ -37,8 +37,20 @@ func (w *Free) Has(typ types.Type) (res bool) {
        case nil, *types.Basic: // TODO(gri) should nil be handled here?
                break
 
-       case *aliases.Alias:
-               return w.Has(aliases.Unalias(t))
+       case *types.Alias:
+               if aliases.TypeParams(t).Len() > aliases.TypeArgs(t).Len() {
+                       return true // This is an uninstantiated Alias.
+               }
+               // The expansion of an alias can have free type parameters,
+               // whether or not the alias itself has type parameters:
+               //
+               //   func _[K comparable]() {
+               //     type Set      = map[K]bool // free(Set)      = {K}
+               //     type MapTo[V] = map[K]V    // free(Map[foo]) = {V}
+               //   }
+               //
+               // So, we must Unalias.
+               return w.Has(types.Unalias(t))
 
        case *types.Array:
                return w.Has(t.Elem())
@@ -98,9 +110,8 @@ func (w *Free) Has(typ types.Type) (res bool) {
 
        case *types.Named:
                args := t.TypeArgs()
-               // TODO(taking): this does not match go/types/infer.go. Check with rfindley.
                if params := t.TypeParams(); params.Len() > args.Len() {
-                       return true
+                       return true // this is an uninstantiated named type.
                }
                for i, n := 0, args.Len(); i < n; i++ {
                        if w.Has(args.At(i)) {
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/typesinternal/element.go b/src/cmd/vendor/golang.org/x/tools/internal/typesinternal/element.go
new file mode 100644 (file)
index 0000000..4957f02
--- /dev/null
@@ -0,0 +1,133 @@
+// 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.
+
+package typesinternal
+
+import (
+       "fmt"
+       "go/types"
+
+       "golang.org/x/tools/go/types/typeutil"
+)
+
+// ForEachElement calls f for type T and each type reachable from its
+// type through reflection. It does this by recursively stripping off
+// type constructors; in addition, for each named type N, the type *N
+// is added to the result as it may have additional methods.
+//
+// The caller must provide an initially empty set used to de-duplicate
+// identical types, potentially across multiple calls to ForEachElement.
+// (Its final value holds all the elements seen, matching the arguments
+// passed to f.)
+//
+// TODO(adonovan): share/harmonize with go/callgraph/rta.
+func ForEachElement(rtypes *typeutil.Map, msets *typeutil.MethodSetCache, T types.Type, f func(types.Type)) {
+       var visit func(T types.Type, skip bool)
+       visit = func(T types.Type, skip bool) {
+               if !skip {
+                       if seen, _ := rtypes.Set(T, true).(bool); seen {
+                               return // de-dup
+                       }
+
+                       f(T) // notify caller of new element type
+               }
+
+               // Recursion over signatures of each method.
+               tmset := msets.MethodSet(T)
+               for i := 0; i < tmset.Len(); i++ {
+                       sig := tmset.At(i).Type().(*types.Signature)
+                       // It is tempting to call visit(sig, false)
+                       // but, as noted in golang.org/cl/65450043,
+                       // the Signature.Recv field is ignored by
+                       // types.Identical and typeutil.Map, which
+                       // is confusing at best.
+                       //
+                       // More importantly, the true signature rtype
+                       // reachable from a method using reflection
+                       // has no receiver but an extra ordinary parameter.
+                       // For the Read method of io.Reader we want:
+                       //   func(Reader, []byte) (int, error)
+                       // but here sig is:
+                       //   func([]byte) (int, error)
+                       // with .Recv = Reader (though it is hard to
+                       // notice because it doesn't affect Signature.String
+                       // or types.Identical).
+                       //
+                       // TODO(adonovan): construct and visit the correct
+                       // non-method signature with an extra parameter
+                       // (though since unnamed func types have no methods
+                       // there is essentially no actual demand for this).
+                       //
+                       // TODO(adonovan): document whether or not it is
+                       // safe to skip non-exported methods (as RTA does).
+                       visit(sig.Params(), true)  // skip the Tuple
+                       visit(sig.Results(), true) // skip the Tuple
+               }
+
+               switch T := T.(type) {
+               case *types.Alias:
+                       visit(types.Unalias(T), skip) // emulates the pre-Alias behavior
+
+               case *types.Basic:
+                       // nop
+
+               case *types.Interface:
+                       // nop---handled by recursion over method set.
+
+               case *types.Pointer:
+                       visit(T.Elem(), false)
+
+               case *types.Slice:
+                       visit(T.Elem(), false)
+
+               case *types.Chan:
+                       visit(T.Elem(), false)
+
+               case *types.Map:
+                       visit(T.Key(), false)
+                       visit(T.Elem(), false)
+
+               case *types.Signature:
+                       if T.Recv() != nil {
+                               panic(fmt.Sprintf("Signature %s has Recv %s", T, T.Recv()))
+                       }
+                       visit(T.Params(), true)  // skip the Tuple
+                       visit(T.Results(), true) // skip the Tuple
+
+               case *types.Named:
+                       // A pointer-to-named type can be derived from a named
+                       // type via reflection.  It may have methods too.
+                       visit(types.NewPointer(T), false)
+
+                       // Consider 'type T struct{S}' where S has methods.
+                       // Reflection provides no way to get from T to struct{S},
+                       // only to S, so the method set of struct{S} is unwanted,
+                       // so set 'skip' flag during recursion.
+                       visit(T.Underlying(), true) // skip the unnamed type
+
+               case *types.Array:
+                       visit(T.Elem(), false)
+
+               case *types.Struct:
+                       for i, n := 0, T.NumFields(); i < n; i++ {
+                               // TODO(adonovan): document whether or not
+                               // it is safe to skip non-exported fields.
+                               visit(T.Field(i).Type(), false)
+                       }
+
+               case *types.Tuple:
+                       for i, n := 0, T.Len(); i < n; i++ {
+                               visit(T.At(i).Type(), false)
+                       }
+
+               case *types.TypeParam, *types.Union:
+                       // forEachReachable must not be called on parameterized types.
+                       panic(T)
+
+               default:
+                       panic(T)
+               }
+       }
+       visit(T, false)
+}
index fea7c8b75e8e832bc5145a636aff964880525c57..ba6f4f4ebd522f42c7f440838f9099479cd5d3db 100644 (file)
@@ -6,8 +6,6 @@ package typesinternal
 
 import (
        "go/types"
-
-       "golang.org/x/tools/internal/aliases"
 )
 
 // ReceiverNamed returns the named type (if any) associated with the
@@ -15,11 +13,11 @@ import (
 // It also reports whether a Pointer was present.
 func ReceiverNamed(recv *types.Var) (isPtr bool, named *types.Named) {
        t := recv.Type()
-       if ptr, ok := aliases.Unalias(t).(*types.Pointer); ok {
+       if ptr, ok := types.Unalias(t).(*types.Pointer); ok {
                isPtr = true
                t = ptr.Elem()
        }
-       named, _ = aliases.Unalias(t).(*types.Named)
+       named, _ = types.Unalias(t).(*types.Named)
        return
 }
 
@@ -36,7 +34,7 @@ func ReceiverNamed(recv *types.Var) (isPtr bool, named *types.Named) {
 // indirection from the type, regardless of named types (analogous to
 // a LOAD instruction).
 func Unpointer(t types.Type) types.Type {
-       if ptr, ok := aliases.Unalias(t).(*types.Pointer); ok {
+       if ptr, ok := types.Unalias(t).(*types.Pointer); ok {
                return ptr.Elem()
        }
        return t
index 83923286120d4f3f905e03c25a80daa6c666054f..df3ea52125439c929827ed7ffc553d89d22e5eb5 100644 (file)
@@ -11,6 +11,8 @@ import (
        "go/types"
        "reflect"
        "unsafe"
+
+       "golang.org/x/tools/internal/aliases"
 )
 
 func SetUsesCgo(conf *types.Config) bool {
@@ -63,3 +65,57 @@ func NameRelativeTo(pkg *types.Package) types.Qualifier {
                return other.Name()
        }
 }
+
+// A NamedOrAlias is a [types.Type] that is named (as
+// defined by the spec) and capable of bearing type parameters: it
+// abstracts aliases ([types.Alias]) and defined types
+// ([types.Named]).
+//
+// Every type declared by an explicit "type" declaration is a
+// NamedOrAlias. (Built-in type symbols may additionally
+// have type [types.Basic], which is not a NamedOrAlias,
+// though the spec regards them as "named".)
+//
+// NamedOrAlias cannot expose the Origin method, because
+// [types.Alias.Origin] and [types.Named.Origin] have different
+// (covariant) result types; use [Origin] instead.
+type NamedOrAlias interface {
+       types.Type
+       Obj() *types.TypeName
+}
+
+// TypeParams is a light shim around t.TypeParams().
+// (go/types.Alias).TypeParams requires >= 1.23.
+func TypeParams(t NamedOrAlias) *types.TypeParamList {
+       switch t := t.(type) {
+       case *types.Alias:
+               return aliases.TypeParams(t)
+       case *types.Named:
+               return t.TypeParams()
+       }
+       return nil
+}
+
+// TypeArgs is a light shim around t.TypeArgs().
+// (go/types.Alias).TypeArgs requires >= 1.23.
+func TypeArgs(t NamedOrAlias) *types.TypeList {
+       switch t := t.(type) {
+       case *types.Alias:
+               return aliases.TypeArgs(t)
+       case *types.Named:
+               return t.TypeArgs()
+       }
+       return nil
+}
+
+// Origin returns the generic type of the Named or Alias type t if it
+// is instantiated, otherwise it returns t.
+func Origin(t NamedOrAlias) NamedOrAlias {
+       switch t := t.(type) {
+       case *types.Alias:
+               return aliases.Origin(t)
+       case *types.Named:
+               return t.Origin()
+       }
+       return t
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/versions/toolchain.go b/src/cmd/vendor/golang.org/x/tools/internal/versions/toolchain.go
deleted file mode 100644 (file)
index 377bf7a..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.
-
-package versions
-
-// toolchain is maximum version (<1.22) that the go toolchain used
-// to build the current tool is known to support.
-//
-// When a tool is built with >=1.22, the value of toolchain is unused.
-//
-// x/tools does not support building with go <1.18. So we take this
-// as the minimum possible maximum.
-var toolchain string = Go1_18
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go b/src/cmd/vendor/golang.org/x/tools/internal/versions/toolchain_go119.go
deleted file mode 100644 (file)
index f65beed..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.19
-// +build go1.19
-
-package versions
-
-func init() {
-       if Compare(toolchain, Go1_19) < 0 {
-               toolchain = Go1_19
-       }
-}
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go b/src/cmd/vendor/golang.org/x/tools/internal/versions/toolchain_go120.go
deleted file mode 100644 (file)
index 1a9efa1..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.20
-// +build go1.20
-
-package versions
-
-func init() {
-       if Compare(toolchain, Go1_20) < 0 {
-               toolchain = Go1_20
-       }
-}
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go b/src/cmd/vendor/golang.org/x/tools/internal/versions/toolchain_go121.go
deleted file mode 100644 (file)
index b7ef216..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.21
-// +build go1.21
-
-package versions
-
-func init() {
-       if Compare(toolchain, Go1_21) < 0 {
-               toolchain = Go1_21
-       }
-}
index 562eef21fa20ee90b83d6f6c35496a59b6db9b54..0fc10ce4eb591ea9061a68463075f70181ad44dc 100644 (file)
@@ -5,15 +5,29 @@
 package versions
 
 import (
+       "go/ast"
        "go/types"
 )
 
-// GoVersion returns the Go version of the type package.
-// It returns zero if no version can be determined.
-func GoVersion(pkg *types.Package) string {
-       // TODO(taking): x/tools can call GoVersion() [from 1.21] after 1.25.
-       if pkg, ok := any(pkg).(interface{ GoVersion() string }); ok {
-               return pkg.GoVersion()
+// FileVersion returns a file's Go version.
+// The reported version is an unknown Future version if a
+// version cannot be determined.
+func FileVersion(info *types.Info, file *ast.File) string {
+       // In tools built with Go >= 1.22, the Go version of a file
+       // follow a cascades of sources:
+       // 1) types.Info.FileVersion, which follows the cascade:
+       //   1.a) file version (ast.File.GoVersion),
+       //   1.b) the package version (types.Config.GoVersion), or
+       // 2) is some unknown Future version.
+       //
+       // File versions require a valid package version to be provided to types
+       // in Config.GoVersion. Config.GoVersion is either from the package's module
+       // or the toolchain (go run). This value should be provided by go/packages
+       // or unitchecker.Config.GoVersion.
+       if v := info.FileVersions[file]; IsValid(v) {
+               return v
        }
-       return ""
+       // Note: we could instead return runtime.Version() [if valid].
+       // This would act as a max version on what a tool can support.
+       return Future
 }
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/versions/types_go121.go b/src/cmd/vendor/golang.org/x/tools/internal/versions/types_go121.go
deleted file mode 100644 (file)
index b4345d3..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2023 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.22
-// +build !go1.22
-
-package versions
-
-import (
-       "go/ast"
-       "go/types"
-)
-
-// FileVersion returns a language version (<=1.21) derived from runtime.Version()
-// or an unknown future version.
-func FileVersion(info *types.Info, file *ast.File) string {
-       // In x/tools built with Go <= 1.21, we do not have Info.FileVersions
-       // available. We use a go version derived from the toolchain used to
-       // compile the tool by default.
-       // This will be <= go1.21. We take this as the maximum version that
-       // this tool can support.
-       //
-       // There are no features currently in x/tools that need to tell fine grained
-       // differences for versions <1.22.
-       return toolchain
-}
-
-// InitFileVersions is a noop when compiled with this Go version.
-func InitFileVersions(*types.Info) {}
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/versions/types_go122.go b/src/cmd/vendor/golang.org/x/tools/internal/versions/types_go122.go
deleted file mode 100644 (file)
index aac5db6..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2023 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.22
-// +build go1.22
-
-package versions
-
-import (
-       "go/ast"
-       "go/types"
-)
-
-// FileVersion returns a file's Go version.
-// The reported version is an unknown Future version if a
-// version cannot be determined.
-func FileVersion(info *types.Info, file *ast.File) string {
-       // In tools built with Go >= 1.22, the Go version of a file
-       // follow a cascades of sources:
-       // 1) types.Info.FileVersion, which follows the cascade:
-       //   1.a) file version (ast.File.GoVersion),
-       //   1.b) the package version (types.Config.GoVersion), or
-       // 2) is some unknown Future version.
-       //
-       // File versions require a valid package version to be provided to types
-       // in Config.GoVersion. Config.GoVersion is either from the package's module
-       // or the toolchain (go run). This value should be provided by go/packages
-       // or unitchecker.Config.GoVersion.
-       if v := info.FileVersions[file]; IsValid(v) {
-               return v
-       }
-       // Note: we could instead return runtime.Version() [if valid].
-       // This would act as a max version on what a tool can support.
-       return Future
-}
-
-// InitFileVersions initializes info to record Go versions for Go files.
-func InitFileVersions(info *types.Info) {
-       info.FileVersions = make(map[*ast.File]string)
-}
index a645e6421ee90a61a197b47acf9cab93e58a2353..cc2ce3df7e7e70fa7f3367f63d2798110c954231 100644 (file)
@@ -28,8 +28,8 @@ golang.org/x/arch/x86/x86asm
 # golang.org/x/build v0.0.0-20240722200705-b9910f320300
 ## explicit; go 1.21
 golang.org/x/build/relnote
-# golang.org/x/mod v0.20.0
-## explicit; go 1.18
+# golang.org/x/mod v0.22.0
+## explicit; go 1.22.0
 golang.org/x/mod/internal/lazyregexp
 golang.org/x/mod/modfile
 golang.org/x/mod/module
@@ -39,7 +39,7 @@ golang.org/x/mod/sumdb/dirhash
 golang.org/x/mod/sumdb/note
 golang.org/x/mod/sumdb/tlog
 golang.org/x/mod/zip
-# golang.org/x/sync v0.8.0
+# golang.org/x/sync v0.9.0
 ## explicit; go 1.18
 golang.org/x/sync/errgroup
 golang.org/x/sync/semaphore
@@ -73,8 +73,8 @@ golang.org/x/text/internal/tag
 golang.org/x/text/language
 golang.org/x/text/transform
 golang.org/x/text/unicode/norm
-# golang.org/x/tools v0.24.1-0.20240904143311-70f56264139c
-## explicit; go 1.22.6
+# golang.org/x/tools v0.27.0
+## explicit; go 1.22.0
 golang.org/x/tools/cmd/bisect
 golang.org/x/tools/cover
 golang.org/x/tools/go/analysis
@@ -116,7 +116,6 @@ golang.org/x/tools/go/analysis/passes/unreachable
 golang.org/x/tools/go/analysis/passes/unsafeptr
 golang.org/x/tools/go/analysis/passes/unusedresult
 golang.org/x/tools/go/analysis/unitchecker
-golang.org/x/tools/go/ast/astutil
 golang.org/x/tools/go/ast/inspector
 golang.org/x/tools/go/cfg
 golang.org/x/tools/go/types/objectpath