Update module github.com/onsi/ginkgo/v2 to v2.14.0

Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This commit is contained in:
renovate[bot] 2024-01-17 20:22:02 +00:00 committed by GitHub
parent d38ee1364d
commit e757f7631e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
73 changed files with 1182 additions and 1460 deletions

6
go.mod
View File

@ -45,7 +45,7 @@ require (
github.com/mdlayher/vsock v1.2.1
github.com/moby/term v0.5.0
github.com/nxadm/tail v1.4.11
github.com/onsi/ginkgo/v2 v2.13.2
github.com/onsi/ginkgo/v2 v2.14.0
github.com/onsi/gomega v1.30.0
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.0-rc5
@ -205,9 +205,9 @@ require (
go.opentelemetry.io/otel/trace v1.19.0 // indirect
golang.org/x/arch v0.5.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/mod v0.13.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/oauth2 v0.15.0 // indirect
golang.org/x/tools v0.14.0 // indirect
golang.org/x/tools v0.16.1 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect
google.golang.org/grpc v1.58.3 // indirect

12
go.sum
View File

@ -834,8 +834,8 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs=
github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM=
github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY=
github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw=
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@ -1215,8 +1215,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1467,8 +1467,8 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA=
golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -4,7 +4,7 @@ go 1.20
require (
github.com/cpuguy83/go-md2man/v2 v2.0.3
github.com/onsi/ginkgo/v2 v2.13.2
github.com/onsi/ginkgo/v2 v2.14.0
github.com/vbatts/git-validation v1.2.1
golang.org/x/tools v0.16.1
)
@ -20,5 +20,5 @@ require (
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/sys v0.15.0 // indirect
)

View File

@ -25,9 +25,9 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs=
github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM=
github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY=
github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw=
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
@ -47,9 +47,9 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA=
golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=

View File

@ -505,6 +505,15 @@ func (g ginkgoErrors) IncorrectVariadicParameterTypeToTableFunction(expected, ac
}
}
func (g ginkgoErrors) ContextsCannotBeUsedInSubtreeTables(cl CodeLocation) error {
return GinkgoError{
Heading: "Contexts cannot be used in subtree tables",
Message: "You''ve defined a subtree body function that accepts a context but did not provide one in the table entry. Ginkgo SpecContexts can only be passed in to subject and setup nodes - so if you are trying to implement a spec timeout you should request a context in the It function within your subtree body function, not in the subtree body function itself.",
CodeLocation: cl,
DocLink: "table-specs",
}
}
/* Parallel Synchronization errors */
func (g ginkgoErrors) AggregatedReportUnavailableDueToNodeDisappearing() error {

View File

@ -1,3 +1,3 @@
package types
const VERSION = "2.13.2"
const VERSION = "2.14.0"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build dragonfly || freebsd || linux || netbsd || openbsd
//go:build dragonfly || freebsd || linux || netbsd
package unix

View File

@ -231,3 +231,8 @@ func IoctlLoopGetStatus64(fd int) (*LoopInfo64, error) {
func IoctlLoopSetStatus64(fd int, value *LoopInfo64) error {
return ioctlPtr(fd, LOOP_SET_STATUS64, unsafe.Pointer(value))
}
// IoctlLoopConfigure configures all loop device parameters in a single step
func IoctlLoopConfigure(fd int, value *LoopConfig) error {
return ioctlPtr(fd, LOOP_CONFIGURE, unsafe.Pointer(value))
}

View File

@ -519,6 +519,7 @@ ccflags="$@"
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
$2 == "LOOP_CONFIGURE" ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
$2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
@ -560,7 +561,7 @@ ccflags="$@"
$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ ||
$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
$2 ~ /^CLONE_[A-Z_]+/ ||
$2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ &&
$2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+|BPF_F_LINK)$/ &&
$2 ~ /^(BPF|DLT)_/ ||
$2 ~ /^AUDIT_/ ||
$2 ~ /^(CLOCK|TIMER)_/ ||

View File

@ -316,7 +316,7 @@ func GetsockoptString(fd, level, opt int) (string, error) {
if err != nil {
return "", err
}
return string(buf[:vallen-1]), nil
return ByteSliceToString(buf[:vallen]), nil
}
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)

View File

@ -61,15 +61,23 @@ func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (
}
//sys fchmodat(dirfd int, path string, mode uint32) (err error)
//sys fchmodat2(dirfd int, path string, mode uint32, flags int) (err error)
func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
// Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior
// and check the flags. Otherwise the mode would be applied to the symlink
// destination which is not what the user expects.
if flags&^AT_SYMLINK_NOFOLLOW != 0 {
return EINVAL
} else if flags&AT_SYMLINK_NOFOLLOW != 0 {
return EOPNOTSUPP
func Fchmodat(dirfd int, path string, mode uint32, flags int) error {
// Linux fchmodat doesn't support the flags parameter, but fchmodat2 does.
// Try fchmodat2 if flags are specified.
if flags != 0 {
err := fchmodat2(dirfd, path, mode, flags)
if err == ENOSYS {
// fchmodat2 isn't available. If the flags are known to be valid,
// return EOPNOTSUPP to indicate that fchmodat doesn't support them.
if flags&^(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 {
return EINVAL
} else if flags&(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 {
return EOPNOTSUPP
}
}
return err
}
return fchmodat(dirfd, path, mode)
}
@ -1302,7 +1310,7 @@ func GetsockoptString(fd, level, opt int) (string, error) {
return "", err
}
}
return string(buf[:vallen-1]), nil
return ByteSliceToString(buf[:vallen]), nil
}
func GetsockoptTpacketStats(fd, level, opt int) (*TpacketStats, error) {

View File

@ -166,6 +166,20 @@ func Getresgid() (rgid, egid, sgid int) {
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
//sys fcntl(fd int, cmd int, arg int) (n int, err error)
//sys fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) = SYS_FCNTL
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
return fcntl(int(fd), cmd, arg)
}
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
_, err := fcntlPtr(int(fd), cmd, unsafe.Pointer(lk))
return err
}
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {

View File

@ -158,7 +158,7 @@ func GetsockoptString(fd, level, opt int) (string, error) {
if err != nil {
return "", err
}
return string(buf[:vallen-1]), nil
return ByteSliceToString(buf[:vallen]), nil
}
const ImplementsGetwd = true

View File

@ -1104,7 +1104,7 @@ func GetsockoptString(fd, level, opt int) (string, error) {
return "", err
}
return string(buf[:vallen-1]), nil
return ByteSliceToString(buf[:vallen]), nil
}
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {

View File

@ -486,7 +486,6 @@ const (
BPF_F_ANY_ALIGNMENT = 0x2
BPF_F_BEFORE = 0x8
BPF_F_ID = 0x20
BPF_F_LINK = 0x2000
BPF_F_NETFILTER_IP_DEFRAG = 0x1
BPF_F_QUERY_EFFECTIVE = 0x1
BPF_F_REPLACE = 0x4
@ -1802,6 +1801,7 @@ const (
LOCK_SH = 0x1
LOCK_UN = 0x8
LOOP_CLR_FD = 0x4c01
LOOP_CONFIGURE = 0x4c0a
LOOP_CTL_ADD = 0x4c80
LOOP_CTL_GET_FREE = 0x4c82
LOOP_CTL_REMOVE = 0x4c81

View File

@ -37,6 +37,21 @@ func fchmodat(dirfd int, path string, mode uint32) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fchmodat2(dirfd int, path string, mode uint32, flags int) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
return
}
_, _, e1 := Syscall6(SYS_FCHMODAT2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ioctl(fd int, req uint, arg uintptr) (err error) {
_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
if e1 != 0 {

View File

@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntl(fd int, cmd int, arg int) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_fcntl_trampoline_addr uintptr
//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)

View File

@ -178,6 +178,11 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $4
DATA ·libc_sysctl_trampoline_addr(SB)/4, $libc_sysctl_trampoline<>(SB)
TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_fcntl(SB)
GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $4
DATA ·libc_fcntl_trampoline_addr(SB)/4, $libc_fcntl_trampoline<>(SB)
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_ppoll(SB)
GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $4

View File

@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntl(fd int, cmd int, arg int) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_fcntl_trampoline_addr uintptr
//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)

View File

@ -178,6 +178,11 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_fcntl(SB)
GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8
DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_ppoll(SB)
GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8

View File

@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntl(fd int, cmd int, arg int) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_fcntl_trampoline_addr uintptr
//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)

View File

@ -178,6 +178,11 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $4
DATA ·libc_sysctl_trampoline_addr(SB)/4, $libc_sysctl_trampoline<>(SB)
TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_fcntl(SB)
GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $4
DATA ·libc_fcntl_trampoline_addr(SB)/4, $libc_fcntl_trampoline<>(SB)
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_ppoll(SB)
GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $4

View File

@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntl(fd int, cmd int, arg int) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_fcntl_trampoline_addr uintptr
//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)

View File

@ -178,6 +178,11 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_fcntl(SB)
GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8
DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_ppoll(SB)
GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8

View File

@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntl(fd int, cmd int, arg int) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_fcntl_trampoline_addr uintptr
//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)

View File

@ -178,6 +178,11 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_fcntl(SB)
GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8
DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_ppoll(SB)
GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8

View File

@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntl(fd int, cmd int, arg int) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_fcntl_trampoline_addr uintptr
//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)

View File

@ -213,6 +213,12 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
CALL libc_fcntl(SB)
RET
GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8
DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
CALL libc_ppoll(SB)
RET

View File

@ -584,6 +584,32 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntl(fd int, cmd int, arg int) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_fcntl_trampoline_addr uintptr
//go:cgo_import_dynamic libc_fcntl fcntl "libc.so"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) {
r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
n = int(r0)

View File

@ -178,6 +178,11 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_fcntl(SB)
GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8
DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB)
TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_ppoll(SB)
GLOBL ·libc_ppoll_trampoline_addr(SB), RODATA, $8

View File

@ -2671,6 +2671,7 @@ const (
BPF_PROG_TYPE_LSM = 0x1d
BPF_PROG_TYPE_SK_LOOKUP = 0x1e
BPF_PROG_TYPE_SYSCALL = 0x1f
BPF_PROG_TYPE_NETFILTER = 0x20
BPF_CGROUP_INET_INGRESS = 0x0
BPF_CGROUP_INET_EGRESS = 0x1
BPF_CGROUP_INET_SOCK_CREATE = 0x2
@ -2715,6 +2716,11 @@ const (
BPF_PERF_EVENT = 0x29
BPF_TRACE_KPROBE_MULTI = 0x2a
BPF_LSM_CGROUP = 0x2b
BPF_STRUCT_OPS = 0x2c
BPF_NETFILTER = 0x2d
BPF_TCX_INGRESS = 0x2e
BPF_TCX_EGRESS = 0x2f
BPF_TRACE_UPROBE_MULTI = 0x30
BPF_LINK_TYPE_UNSPEC = 0x0
BPF_LINK_TYPE_RAW_TRACEPOINT = 0x1
BPF_LINK_TYPE_TRACING = 0x2
@ -2725,6 +2731,18 @@ const (
BPF_LINK_TYPE_PERF_EVENT = 0x7
BPF_LINK_TYPE_KPROBE_MULTI = 0x8
BPF_LINK_TYPE_STRUCT_OPS = 0x9
BPF_LINK_TYPE_NETFILTER = 0xa
BPF_LINK_TYPE_TCX = 0xb
BPF_LINK_TYPE_UPROBE_MULTI = 0xc
BPF_PERF_EVENT_UNSPEC = 0x0
BPF_PERF_EVENT_UPROBE = 0x1
BPF_PERF_EVENT_URETPROBE = 0x2
BPF_PERF_EVENT_KPROBE = 0x3
BPF_PERF_EVENT_KRETPROBE = 0x4
BPF_PERF_EVENT_TRACEPOINT = 0x5
BPF_PERF_EVENT_EVENT = 0x6
BPF_F_KPROBE_MULTI_RETURN = 0x1
BPF_F_UPROBE_MULTI_RETURN = 0x1
BPF_ANY = 0x0
BPF_NOEXIST = 0x1
BPF_EXIST = 0x2
@ -2742,6 +2760,8 @@ const (
BPF_F_MMAPABLE = 0x400
BPF_F_PRESERVE_ELEMS = 0x800
BPF_F_INNER_MAP = 0x1000
BPF_F_LINK = 0x2000
BPF_F_PATH_FD = 0x4000
BPF_STATS_RUN_TIME = 0x0
BPF_STACK_BUILD_ID_EMPTY = 0x0
BPF_STACK_BUILD_ID_VALID = 0x1
@ -2762,6 +2782,7 @@ const (
BPF_F_ZERO_CSUM_TX = 0x2
BPF_F_DONT_FRAGMENT = 0x4
BPF_F_SEQ_NUMBER = 0x8
BPF_F_NO_TUNNEL_KEY = 0x10
BPF_F_TUNINFO_FLAGS = 0x10
BPF_F_INDEX_MASK = 0xffffffff
BPF_F_CURRENT_CPU = 0xffffffff
@ -2778,6 +2799,8 @@ const (
BPF_F_ADJ_ROOM_ENCAP_L4_UDP = 0x10
BPF_F_ADJ_ROOM_NO_CSUM_RESET = 0x20
BPF_F_ADJ_ROOM_ENCAP_L2_ETH = 0x40
BPF_F_ADJ_ROOM_DECAP_L3_IPV4 = 0x80
BPF_F_ADJ_ROOM_DECAP_L3_IPV6 = 0x100
BPF_ADJ_ROOM_ENCAP_L2_MASK = 0xff
BPF_ADJ_ROOM_ENCAP_L2_SHIFT = 0x38
BPF_F_SYSCTL_BASE_NAME = 0x1
@ -2866,6 +2889,8 @@ const (
BPF_DEVCG_DEV_CHAR = 0x2
BPF_FIB_LOOKUP_DIRECT = 0x1
BPF_FIB_LOOKUP_OUTPUT = 0x2
BPF_FIB_LOOKUP_SKIP_NEIGH = 0x4
BPF_FIB_LOOKUP_TBID = 0x8
BPF_FIB_LKUP_RET_SUCCESS = 0x0
BPF_FIB_LKUP_RET_BLACKHOLE = 0x1
BPF_FIB_LKUP_RET_UNREACHABLE = 0x2
@ -2901,6 +2926,7 @@ const (
BPF_CORE_ENUMVAL_EXISTS = 0xa
BPF_CORE_ENUMVAL_VALUE = 0xb
BPF_CORE_TYPE_MATCHES = 0xc
BPF_F_TIMER_ABS = 0x1
)
const (
@ -2979,6 +3005,12 @@ type LoopInfo64 struct {
Encrypt_key [32]uint8
Init [2]uint64
}
type LoopConfig struct {
Fd uint32
Size uint32
Info LoopInfo64
_ [8]uint64
}
type TIPCSocketAddr struct {
Ref uint32

View File

@ -155,6 +155,8 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
//sys GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) = kernel32.GetModuleHandleExW
//sys SetDefaultDllDirectories(directoryFlags uint32) (err error)
//sys AddDllDirectory(path *uint16) (cookie uintptr, err error) = kernel32.AddDllDirectory
//sys RemoveDllDirectory(cookie uintptr) (err error) = kernel32.RemoveDllDirectory
//sys SetDllDirectory(path string) (err error) = kernel32.SetDllDirectoryW
//sys GetVersion() (ver uint32, err error)
//sys FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW

View File

@ -184,6 +184,7 @@ var (
procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo")
procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx")
procGetIfEntry = modiphlpapi.NewProc("GetIfEntry")
procAddDllDirectory = modkernel32.NewProc("AddDllDirectory")
procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject")
procCancelIo = modkernel32.NewProc("CancelIo")
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
@ -330,6 +331,7 @@ var (
procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory")
procReleaseMutex = modkernel32.NewProc("ReleaseMutex")
procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW")
procRemoveDllDirectory = modkernel32.NewProc("RemoveDllDirectory")
procResetEvent = modkernel32.NewProc("ResetEvent")
procResizePseudoConsole = modkernel32.NewProc("ResizePseudoConsole")
procResumeThread = modkernel32.NewProc("ResumeThread")
@ -1605,6 +1607,15 @@ func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
return
}
func AddDllDirectory(path *uint16) (cookie uintptr, err error) {
r0, _, e1 := syscall.Syscall(procAddDllDirectory.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
cookie = uintptr(r0)
if cookie == 0 {
err = errnoErr(e1)
}
return
}
func AssignProcessToJobObject(job Handle, process Handle) (err error) {
r1, _, e1 := syscall.Syscall(procAssignProcessToJobObject.Addr(), 2, uintptr(job), uintptr(process), 0)
if r1 == 0 {
@ -2879,6 +2890,14 @@ func RemoveDirectory(path *uint16) (err error) {
return
}
func RemoveDllDirectory(cookie uintptr) (err error) {
r1, _, e1 := syscall.Syscall(procRemoveDllDirectory.Addr(), 1, uintptr(cookie), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func ResetEvent(event Handle) (err error) {
r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0)
if r1 == 0 {

View File

@ -23,7 +23,7 @@ github.com/mattn/go-colorable
# github.com/mattn/go-isatty v0.0.17
## explicit; go 1.15
github.com/mattn/go-isatty
# github.com/onsi/ginkgo/v2 v2.13.2
# github.com/onsi/ginkgo/v2 v2.14.0
## explicit; go 1.18
github.com/onsi/ginkgo/v2/config
github.com/onsi/ginkgo/v2/formatter
@ -61,7 +61,7 @@ github.com/vbatts/git-validation/validate
golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/module
golang.org/x/mod/semver
# golang.org/x/sys v0.14.0
# golang.org/x/sys v0.15.0
## explicit; go 1.18
golang.org/x/sys/unix
golang.org/x/sys/windows

View File

@ -1,3 +1,28 @@
## 2.14.0
### Features
You can now use `GinkgoTB()` when you need an instance of `testing.TB` to pass to a library.
Prior to this release table testing only supported generating individual `It`s for each test entry. `DescribeTableSubtree` extends table testing support to entire testing subtrees - under the hood `DescrieTableSubtree` generates a new container for each entry and invokes your function to fill our the container. See the [docs](https://onsi.github.io/ginkgo/#generating-subtree-tables) to learn more.
- Introduce DescribeTableSubtree [65ec56d]
- add GinkgoTB() to docs [4a2c832]
- Add GinkgoTB() function (#1333) [92b6744]
### Fixes
- Fix typo in internal/suite.go (#1332) [beb9507]
- Fix typo in docs/index.md (#1319) [4ac3a13]
- allow wasm to compile with ginkgo present (#1311) [b2e5bc5]
### Maintenance
- Bump golang.org/x/tools from 0.16.0 to 0.16.1 (#1316) [465a8ec]
- Bump actions/setup-go from 4 to 5 (#1313) [eab0e40]
- Bump github/codeql-action from 2 to 3 (#1317) [fbf9724]
- Bump golang.org/x/crypto (#1318) [3ee80ee]
- Bump golang.org/x/tools from 0.14.0 to 0.16.0 (#1306) [123e1d5]
- Bump github.com/onsi/gomega from 1.29.0 to 1.30.0 (#1297) [558f6e0]
- Bump golang.org/x/net from 0.17.0 to 0.19.0 (#1307) [84ff7f3]
## 2.13.2
### Fixes

View File

@ -1,7 +1,10 @@
package ginkgo
import (
"testing"
"github.com/onsi/ginkgo/v2/internal/testingtproxy"
"github.com/onsi/ginkgo/v2/types"
)
/*
@ -15,7 +18,7 @@ correct line number associated with the failure - though you do not need to use
You can learn more here: https://onsi.github.io/ginkgo/#using-third-party-libraries
*/
func GinkgoT(optionalOffset ...int) FullGinkgoTInterface {
offset := 3
offset := 1
if len(optionalOffset) > 0 {
offset = optionalOffset[0]
}
@ -41,21 +44,21 @@ The portion of the interface returned by GinkgoT() that maps onto methods in the
type GinkgoTInterface interface {
Cleanup(func())
Setenv(kev, value string)
Error(args ...interface{})
Errorf(format string, args ...interface{})
Error(args ...any)
Errorf(format string, args ...any)
Fail()
FailNow()
Failed() bool
Fatal(args ...interface{})
Fatalf(format string, args ...interface{})
Fatal(args ...any)
Fatalf(format string, args ...any)
Helper()
Log(args ...interface{})
Logf(format string, args ...interface{})
Log(args ...any)
Logf(format string, args ...any)
Name() string
Parallel()
Skip(args ...interface{})
Skip(args ...any)
SkipNow()
Skipf(format string, args ...interface{})
Skipf(format string, args ...any)
Skipped() bool
TempDir() string
}
@ -71,9 +74,9 @@ type FullGinkgoTInterface interface {
AddReportEntryVisibilityNever(name string, args ...any)
//Prints to the GinkgoWriter
Print(a ...interface{})
Printf(format string, a ...interface{})
Println(a ...interface{})
Print(a ...any)
Printf(format string, a ...any)
Println(a ...any)
//Provides access to Ginkgo's color formatting, correctly configured to match the color settings specified in the invocation of ginkgo
F(format string, args ...any) string
@ -92,3 +95,81 @@ type FullGinkgoTInterface interface {
AttachProgressReporter(func() string) func()
}
/*
GinkgoTB() implements a wrapper that exactly matches the testing.TB interface.
In go 1.18 a new private() function was added to the testing.TB interface. Any function which accepts testing.TB as input needs to be passed in something that directly implements testing.TB.
This wrapper satisfies the testing.TB interface and intended to be used as a drop-in replacement with third party libraries that accept testing.TB.
Similar to GinkgoT(), GinkgoTB() takes an optional offset argument that can be used to get the
correct line number associated with the failure - though you do not need to use this if you call GinkgoHelper() or GinkgoT().Helper() appropriately
*/
func GinkgoTB(optionalOffset ...int) *GinkgoTBWrapper {
offset := 2
if len(optionalOffset) > 0 {
offset = optionalOffset[0]
}
return &GinkgoTBWrapper{GinkgoT: GinkgoT(offset)}
}
type GinkgoTBWrapper struct {
testing.TB
GinkgoT FullGinkgoTInterface
}
func (g *GinkgoTBWrapper) Cleanup(f func()) {
g.GinkgoT.Cleanup(f)
}
func (g *GinkgoTBWrapper) Error(args ...any) {
g.GinkgoT.Error(args...)
}
func (g *GinkgoTBWrapper) Errorf(format string, args ...any) {
g.GinkgoT.Errorf(format, args...)
}
func (g *GinkgoTBWrapper) Fail() {
g.GinkgoT.Fail()
}
func (g *GinkgoTBWrapper) FailNow() {
g.GinkgoT.FailNow()
}
func (g *GinkgoTBWrapper) Failed() bool {
return g.GinkgoT.Failed()
}
func (g *GinkgoTBWrapper) Fatal(args ...any) {
g.GinkgoT.Fatal(args...)
}
func (g *GinkgoTBWrapper) Fatalf(format string, args ...any) {
g.GinkgoT.Fatalf(format, args...)
}
func (g *GinkgoTBWrapper) Helper() {
types.MarkAsHelper(1)
}
func (g *GinkgoTBWrapper) Log(args ...any) {
g.GinkgoT.Log(args...)
}
func (g *GinkgoTBWrapper) Logf(format string, args ...any) {
g.GinkgoT.Logf(format, args...)
}
func (g *GinkgoTBWrapper) Name() string {
return g.GinkgoT.Name()
}
func (g *GinkgoTBWrapper) Setenv(key, value string) {
g.GinkgoT.Setenv(key, value)
}
func (g *GinkgoTBWrapper) Skip(args ...any) {
g.GinkgoT.Skip(args...)
}
func (g *GinkgoTBWrapper) SkipNow() {
g.GinkgoT.SkipNow()
}
func (g *GinkgoTBWrapper) Skipf(format string, args ...any) {
g.GinkgoT.Skipf(format, args...)
}
func (g *GinkgoTBWrapper) Skipped() bool {
return g.GinkgoT.Skipped()
}
func (g *GinkgoTBWrapper) TempDir() string {
return g.GinkgoT.TempDir()
}

View File

@ -0,0 +1,7 @@
//go:build wasm
package internal
func NewOutputInterceptor() OutputInterceptor {
return &NoopOutputInterceptor{}
}

View File

@ -0,0 +1,10 @@
//go:build wasm
package internal
import (
"os"
"syscall"
)
var PROGRESS_SIGNALS = []os.Signal{syscall.SIGUSR1}

View File

@ -79,7 +79,7 @@ func NewSuite() *Suite {
func (suite *Suite) Clone() (*Suite, error) {
if suite.phase != PhaseBuildTopLevel {
return nil, fmt.Errorf("cnanot clone suite after tree has been built")
return nil, fmt.Errorf("cannot clone suite after tree has been built")
}
return &Suite{
tree: &TreeNode{},

View File

@ -46,7 +46,7 @@ And can explore some Table patterns here: https://onsi.github.io/ginkgo/#table-s
*/
func DescribeTable(description string, args ...interface{}) bool {
GinkgoHelper()
generateTable(description, args...)
generateTable(description, false, args...)
return true
}
@ -56,7 +56,7 @@ You can focus a table with `FDescribeTable`. This is equivalent to `FDescribe`.
func FDescribeTable(description string, args ...interface{}) bool {
GinkgoHelper()
args = append(args, internal.Focus)
generateTable(description, args...)
generateTable(description, false, args...)
return true
}
@ -66,7 +66,7 @@ You can mark a table as pending with `PDescribeTable`. This is equivalent to `P
func PDescribeTable(description string, args ...interface{}) bool {
GinkgoHelper()
args = append(args, internal.Pending)
generateTable(description, args...)
generateTable(description, false, args...)
return true
}
@ -75,6 +75,71 @@ You can mark a table as pending with `XDescribeTable`. This is equivalent to `X
*/
var XDescribeTable = PDescribeTable
/*
DescribeTableSubtree describes a table-driven spec that generates a set of tests for each entry.
For example:
DescribeTableSubtree("a subtree table",
func(url string, code int, message string) {
var resp *http.Response
BeforeEach(func() {
var err error
resp, err = http.Get(url)
Expect(err).NotTo(HaveOccurred())
DeferCleanup(resp.Body.Close)
})
It("should return the expected status code", func() {
Expect(resp.StatusCode).To(Equal(code))
})
It("should return the expected message", func() {
body, err := ioutil.ReadAll(resp.Body)
Expect(err).NotTo(HaveOccurred())
Expect(string(body)).To(Equal(message))
})
},
Entry("default response", "example.com/response", http.StatusOK, "hello world"),
Entry("missing response", "example.com/missing", http.StatusNotFound, "wat?"),
)
Note that you **must** place define an It inside the body function.
You can learn more about DescribeTableSubtree here: https://onsi.github.io/ginkgo/#table-specs
And can explore some Table patterns here: https://onsi.github.io/ginkgo/#table-specs-patterns
*/
func DescribeTableSubtree(description string, args ...interface{}) bool {
GinkgoHelper()
generateTable(description, true, args...)
return true
}
/*
You can focus a table with `FDescribeTableSubtree`. This is equivalent to `FDescribe`.
*/
func FDescribeTableSubtree(description string, args ...interface{}) bool {
GinkgoHelper()
args = append(args, internal.Focus)
generateTable(description, true, args...)
return true
}
/*
You can mark a table as pending with `PDescribeTableSubtree`. This is equivalent to `PDescribe`.
*/
func PDescribeTableSubtree(description string, args ...interface{}) bool {
GinkgoHelper()
args = append(args, internal.Pending)
generateTable(description, true, args...)
return true
}
/*
You can mark a table as pending with `XDescribeTableSubtree`. This is equivalent to `XDescribe`.
*/
var XDescribeTableSubtree = PDescribeTableSubtree
/*
TableEntry represents an entry in a table test. You generally use the `Entry` constructor.
*/
@ -131,14 +196,14 @@ var XEntry = PEntry
var contextType = reflect.TypeOf(new(context.Context)).Elem()
var specContextType = reflect.TypeOf(new(SpecContext)).Elem()
func generateTable(description string, args ...interface{}) {
func generateTable(description string, isSubtree bool, args ...interface{}) {
GinkgoHelper()
cl := types.NewCodeLocation(0)
containerNodeArgs := []interface{}{cl}
entries := []TableEntry{}
var itBody interface{}
var itBodyType reflect.Type
var internalBody interface{}
var internalBodyType reflect.Type
var tableLevelEntryDescription interface{}
tableLevelEntryDescription = func(args ...interface{}) string {
@ -166,11 +231,11 @@ func generateTable(description string, args ...interface{}) {
case t.Kind() == reflect.Func && t.NumOut() == 1 && t.Out(0) == reflect.TypeOf(""):
tableLevelEntryDescription = arg
case t.Kind() == reflect.Func:
if itBody != nil {
if internalBody != nil {
exitIfErr(types.GinkgoErrors.MultipleEntryBodyFunctionsForTable(cl))
}
itBody = arg
itBodyType = reflect.TypeOf(itBody)
internalBody = arg
internalBodyType = reflect.TypeOf(internalBody)
default:
containerNodeArgs = append(containerNodeArgs, arg)
}
@ -200,39 +265,47 @@ func generateTable(description string, args ...interface{}) {
err = types.GinkgoErrors.InvalidEntryDescription(entry.codeLocation)
}
itNodeArgs := []interface{}{entry.codeLocation}
itNodeArgs = append(itNodeArgs, entry.decorations...)
internalNodeArgs := []interface{}{entry.codeLocation}
internalNodeArgs = append(internalNodeArgs, entry.decorations...)
hasContext := false
if itBodyType.NumIn() > 0. {
if itBodyType.In(0).Implements(specContextType) {
if internalBodyType.NumIn() > 0. {
if internalBodyType.In(0).Implements(specContextType) {
hasContext = true
} else if itBodyType.In(0).Implements(contextType) && (len(entry.parameters) == 0 || !reflect.TypeOf(entry.parameters[0]).Implements(contextType)) {
} else if internalBodyType.In(0).Implements(contextType) && (len(entry.parameters) == 0 || !reflect.TypeOf(entry.parameters[0]).Implements(contextType)) {
hasContext = true
}
}
if err == nil {
err = validateParameters(itBody, entry.parameters, "Table Body function", entry.codeLocation, hasContext)
err = validateParameters(internalBody, entry.parameters, "Table Body function", entry.codeLocation, hasContext)
}
if hasContext {
itNodeArgs = append(itNodeArgs, func(c SpecContext) {
internalNodeArgs = append(internalNodeArgs, func(c SpecContext) {
if err != nil {
panic(err)
}
invokeFunction(itBody, append([]interface{}{c}, entry.parameters...))
invokeFunction(internalBody, append([]interface{}{c}, entry.parameters...))
})
if isSubtree {
exitIfErr(types.GinkgoErrors.ContextsCannotBeUsedInSubtreeTables(cl))
}
} else {
itNodeArgs = append(itNodeArgs, func() {
internalNodeArgs = append(internalNodeArgs, func() {
if err != nil {
panic(err)
}
invokeFunction(itBody, entry.parameters)
invokeFunction(internalBody, entry.parameters)
})
}
pushNode(internal.NewNode(deprecationTracker, types.NodeTypeIt, description, itNodeArgs...))
internalNodeType := types.NodeTypeIt
if isSubtree {
internalNodeType = types.NodeTypeContainer
}
pushNode(internal.NewNode(deprecationTracker, internalNodeType, description, internalNodeArgs...))
}
})

View File

@ -505,6 +505,15 @@ func (g ginkgoErrors) IncorrectVariadicParameterTypeToTableFunction(expected, ac
}
}
func (g ginkgoErrors) ContextsCannotBeUsedInSubtreeTables(cl CodeLocation) error {
return GinkgoError{
Heading: "Contexts cannot be used in subtree tables",
Message: "You''ve defined a subtree body function that accepts a context but did not provide one in the table entry. Ginkgo SpecContexts can only be passed in to subject and setup nodes - so if you are trying to implement a spec timeout you should request a context in the It function within your subtree body function, not in the subtree body function itself.",
CodeLocation: cl,
DocLink: "table-specs",
}
}
/* Parallel Synchronization errors */
func (g ginkgoErrors) AggregatedReportUnavailableDueToNodeDisappearing() error {

View File

@ -1,3 +1,3 @@
package types
const VERSION = "2.13.2"
const VERSION = "2.14.0"

View File

@ -1,102 +0,0 @@
// Copyright 2020 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 execabs is a drop-in replacement for os/exec
// that requires PATH lookups to find absolute paths.
// That is, execabs.Command("cmd") runs the same PATH lookup
// as exec.Command("cmd"), but if the result is a path
// which is relative, the Run and Start methods will report
// an error instead of running the executable.
//
// See https://blog.golang.org/path-security for more information
// about when it may be necessary or appropriate to use this package.
package execabs
import (
"context"
"fmt"
"os/exec"
"path/filepath"
"reflect"
"unsafe"
)
// ErrNotFound is the error resulting if a path search failed to find an executable file.
// It is an alias for exec.ErrNotFound.
var ErrNotFound = exec.ErrNotFound
// Cmd represents an external command being prepared or run.
// It is an alias for exec.Cmd.
type Cmd = exec.Cmd
// Error is returned by LookPath when it fails to classify a file as an executable.
// It is an alias for exec.Error.
type Error = exec.Error
// An ExitError reports an unsuccessful exit by a command.
// It is an alias for exec.ExitError.
type ExitError = exec.ExitError
func relError(file, path string) error {
return fmt.Errorf("%s resolves to executable in current directory (.%c%s)", file, filepath.Separator, path)
}
// LookPath searches for an executable named file in the directories
// named by the PATH environment variable. If file contains a slash,
// it is tried directly and the PATH is not consulted. The result will be
// an absolute path.
//
// LookPath differs from exec.LookPath in its handling of PATH lookups,
// which are used for file names without slashes. If exec.LookPath's
// PATH lookup would have returned an executable from the current directory,
// LookPath instead returns an error.
func LookPath(file string) (string, error) {
path, err := exec.LookPath(file)
if err != nil && !isGo119ErrDot(err) {
return "", err
}
if filepath.Base(file) == file && !filepath.IsAbs(path) {
return "", relError(file, path)
}
return path, nil
}
func fixCmd(name string, cmd *exec.Cmd) {
if filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) && !isGo119ErrFieldSet(cmd) {
// exec.Command was called with a bare binary name and
// exec.LookPath returned a path which is not absolute.
// Set cmd.lookPathErr and clear cmd.Path so that it
// cannot be run.
lookPathErr := (*error)(unsafe.Pointer(reflect.ValueOf(cmd).Elem().FieldByName("lookPathErr").Addr().Pointer()))
if *lookPathErr == nil {
*lookPathErr = relError(name, cmd.Path)
}
cmd.Path = ""
}
}
// CommandContext is like Command but includes a context.
//
// The provided context is used to kill the process (by calling os.Process.Kill)
// if the context becomes done before the command completes on its own.
func CommandContext(ctx context.Context, name string, arg ...string) *exec.Cmd {
cmd := exec.CommandContext(ctx, name, arg...)
fixCmd(name, cmd)
return cmd
}
// Command returns the Cmd struct to execute the named program with the given arguments.
// See exec.Command for most details.
//
// Command differs from exec.Command in its handling of PATH lookups,
// which are used when the program name contains no slashes.
// If exec.Command would have returned an exec.Cmd configured to run an
// executable from the current directory, Command instead
// returns an exec.Cmd that will return an error from Start or Run.
func Command(name string, arg ...string) *exec.Cmd {
cmd := exec.Command(name, arg...)
fixCmd(name, cmd)
return cmd
}

View File

@ -1,17 +0,0 @@
// Copyright 2022 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
package execabs
import "os/exec"
func isGo119ErrDot(err error) bool {
return false
}
func isGo119ErrFieldSet(cmd *exec.Cmd) bool {
return false
}

View File

@ -1,20 +0,0 @@
// Copyright 2022 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
package execabs
import (
"errors"
"os/exec"
)
func isGo119ErrDot(err error) bool {
return errors.Is(err, exec.ErrDot)
}
func isGo119ErrFieldSet(cmd *exec.Cmd) bool {
return cmd.Err != nil
}

View File

@ -12,8 +12,6 @@ package inspector
import (
"go/ast"
"math"
"golang.org/x/tools/internal/typeparams"
)
const (
@ -171,7 +169,7 @@ func typeOf(n ast.Node) uint64 {
return 1 << nIncDecStmt
case *ast.IndexExpr:
return 1 << nIndexExpr
case *typeparams.IndexListExpr:
case *ast.IndexListExpr:
return 1 << nIndexListExpr
case *ast.InterfaceType:
return 1 << nInterfaceType

View File

@ -13,16 +13,17 @@ import (
"golang.org/x/tools/internal/gocommand"
)
var debug = false
func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) {
inv.Verb = "list"
inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}
stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv)
var goarch, compiler string
if rawErr != nil {
if rawErrMsg := rawErr.Error(); strings.Contains(rawErrMsg, "cannot find main module") || strings.Contains(rawErrMsg, "go.mod file not found") {
// User's running outside of a module. All bets are off. Get GOARCH and guess compiler is gc.
rawErrMsg := rawErr.Error()
if strings.Contains(rawErrMsg, "cannot find main module") ||
strings.Contains(rawErrMsg, "go.mod file not found") {
// User's running outside of a module.
// All bets are off. Get GOARCH and guess compiler is gc.
// TODO(matloob): Is this a problem in practice?
inv.Verb = "env"
inv.Args = []string{"GOARCH"}
@ -32,8 +33,12 @@ func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdR
}
goarch = strings.TrimSpace(envout.String())
compiler = "gc"
} else {
} else if friendlyErr != nil {
return "", "", friendlyErr
} else {
// This should be unreachable, but be defensive
// in case RunRaw's error results are inconsistent.
return "", "", rawErr
}
} else {
fields := strings.Fields(stdout.String())

View File

@ -5,12 +5,32 @@
/*
Package packages loads Go packages for inspection and analysis.
The Load function takes as input a list of patterns and return a list of Package
structs describing individual packages matched by those patterns.
The LoadMode controls the amount of detail in the loaded packages.
The [Load] function takes as input a list of patterns and returns a
list of [Package] values describing individual packages matched by those
patterns.
A [Config] specifies configuration options, the most important of which is
the [LoadMode], which controls the amount of detail in the loaded packages.
Load passes most patterns directly to the underlying build tool,
but all patterns with the prefix "query=", where query is a
Load passes most patterns directly to the underlying build tool.
The default build tool is the go command.
Its supported patterns are described at
https://pkg.go.dev/cmd/go#hdr-Package_lists_and_patterns.
Load may be used in Go projects that use alternative build systems, by
installing an appropriate "driver" program for the build system and
specifying its location in the GOPACKAGESDRIVER environment variable.
For example,
https://github.com/bazelbuild/rules_go/wiki/Editor-and-tool-integration
explains how to use the driver for Bazel.
The driver program is responsible for interpreting patterns in its
preferred notation and reporting information about the packages that
they identify.
(See driverRequest and driverResponse types for the JSON
schema used by the protocol.
Though the protocol is supported, these types are currently unexported;
see #64608 for a proposal to publish them.)
Regardless of driver, all patterns with the prefix "query=", where query is a
non-empty string of letters from [a-z], are reserved and may be
interpreted as query operators.
@ -64,7 +84,7 @@ reported about the loaded packages. See the documentation for type LoadMode
for details.
Most tools should pass their command-line arguments (after any flags)
uninterpreted to the loader, so that the loader can interpret them
uninterpreted to [Load], so that it can interpret them
according to the conventions of the underlying build system.
See the Example function for typical usage.
*/

View File

@ -12,8 +12,8 @@ import (
"bytes"
"encoding/json"
"fmt"
exec "golang.org/x/sys/execabs"
"os"
"os/exec"
"strings"
)

View File

@ -11,6 +11,7 @@ import (
"fmt"
"log"
"os"
"os/exec"
"path"
"path/filepath"
"reflect"
@ -20,7 +21,6 @@ import (
"sync"
"unicode"
exec "golang.org/x/sys/execabs"
"golang.org/x/tools/go/internal/packagesdriver"
"golang.org/x/tools/internal/gocommand"
"golang.org/x/tools/internal/packagesinternal"
@ -208,62 +208,6 @@ extractQueries:
}
}
// Only use go/packages' overlay processing if we're using a Go version
// below 1.16. Otherwise, go list handles it.
if goVersion, err := state.getGoVersion(); err == nil && goVersion < 16 {
modifiedPkgs, needPkgs, err := state.processGolistOverlay(response)
if err != nil {
return nil, err
}
var containsCandidates []string
if len(containFiles) > 0 {
containsCandidates = append(containsCandidates, modifiedPkgs...)
containsCandidates = append(containsCandidates, needPkgs...)
}
if err := state.addNeededOverlayPackages(response, needPkgs); err != nil {
return nil, err
}
// Check candidate packages for containFiles.
if len(containFiles) > 0 {
for _, id := range containsCandidates {
pkg, ok := response.seenPackages[id]
if !ok {
response.addPackage(&Package{
ID: id,
Errors: []Error{{
Kind: ListError,
Msg: fmt.Sprintf("package %s expected but not seen", id),
}},
})
continue
}
for _, f := range containFiles {
for _, g := range pkg.GoFiles {
if sameFile(f, g) {
response.addRoot(id)
}
}
}
}
}
// Add root for any package that matches a pattern. This applies only to
// packages that are modified by overlays, since they are not added as
// roots automatically.
for _, pattern := range restPatterns {
match := matchPattern(pattern)
for _, pkgID := range modifiedPkgs {
pkg, ok := response.seenPackages[pkgID]
if !ok {
continue
}
if match(pkg.PkgPath) {
response.addRoot(pkg.ID)
}
}
}
}
sizeswg.Wait()
if sizeserr != nil {
return nil, sizeserr
@ -271,24 +215,6 @@ extractQueries:
return response.dr, nil
}
func (state *golistState) addNeededOverlayPackages(response *responseDeduper, pkgs []string) error {
if len(pkgs) == 0 {
return nil
}
dr, err := state.createDriverResponse(pkgs...)
if err != nil {
return err
}
for _, pkg := range dr.Packages {
response.addPackage(pkg)
}
_, needPkgs, err := state.processGolistOverlay(response)
if err != nil {
return err
}
return state.addNeededOverlayPackages(response, needPkgs)
}
func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error {
for _, query := range queries {
// TODO(matloob): Do only one query per directory.

View File

@ -6,314 +6,11 @@ package packages
import (
"encoding/json"
"fmt"
"go/parser"
"go/token"
"os"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
"golang.org/x/tools/internal/gocommand"
)
// processGolistOverlay provides rudimentary support for adding
// files that don't exist on disk to an overlay. The results can be
// sometimes incorrect.
// TODO(matloob): Handle unsupported cases, including the following:
// - determining the correct package to add given a new import path
func (state *golistState) processGolistOverlay(response *responseDeduper) (modifiedPkgs, needPkgs []string, err error) {
havePkgs := make(map[string]string) // importPath -> non-test package ID
needPkgsSet := make(map[string]bool)
modifiedPkgsSet := make(map[string]bool)
pkgOfDir := make(map[string][]*Package)
for _, pkg := range response.dr.Packages {
// This is an approximation of import path to id. This can be
// wrong for tests, vendored packages, and a number of other cases.
havePkgs[pkg.PkgPath] = pkg.ID
dir, err := commonDir(pkg.GoFiles)
if err != nil {
return nil, nil, err
}
if dir != "" {
pkgOfDir[dir] = append(pkgOfDir[dir], pkg)
}
}
// If no new imports are added, it is safe to avoid loading any needPkgs.
// Otherwise, it's hard to tell which package is actually being loaded
// (due to vendoring) and whether any modified package will show up
// in the transitive set of dependencies (because new imports are added,
// potentially modifying the transitive set of dependencies).
var overlayAddsImports bool
// If both a package and its test package are created by the overlay, we
// need the real package first. Process all non-test files before test
// files, and make the whole process deterministic while we're at it.
var overlayFiles []string
for opath := range state.cfg.Overlay {
overlayFiles = append(overlayFiles, opath)
}
sort.Slice(overlayFiles, func(i, j int) bool {
iTest := strings.HasSuffix(overlayFiles[i], "_test.go")
jTest := strings.HasSuffix(overlayFiles[j], "_test.go")
if iTest != jTest {
return !iTest // non-tests are before tests.
}
return overlayFiles[i] < overlayFiles[j]
})
for _, opath := range overlayFiles {
contents := state.cfg.Overlay[opath]
base := filepath.Base(opath)
dir := filepath.Dir(opath)
var pkg *Package // if opath belongs to both a package and its test variant, this will be the test variant
var testVariantOf *Package // if opath is a test file, this is the package it is testing
var fileExists bool
isTestFile := strings.HasSuffix(opath, "_test.go")
pkgName, ok := extractPackageName(opath, contents)
if !ok {
// Don't bother adding a file that doesn't even have a parsable package statement
// to the overlay.
continue
}
// If all the overlay files belong to a different package, change the
// package name to that package.
maybeFixPackageName(pkgName, isTestFile, pkgOfDir[dir])
nextPackage:
for _, p := range response.dr.Packages {
if pkgName != p.Name && p.ID != "command-line-arguments" {
continue
}
for _, f := range p.GoFiles {
if !sameFile(filepath.Dir(f), dir) {
continue
}
// Make sure to capture information on the package's test variant, if needed.
if isTestFile && !hasTestFiles(p) {
// TODO(matloob): Are there packages other than the 'production' variant
// of a package that this can match? This shouldn't match the test main package
// because the file is generated in another directory.
testVariantOf = p
continue nextPackage
} else if !isTestFile && hasTestFiles(p) {
// We're examining a test variant, but the overlaid file is
// a non-test file. Because the overlay implementation
// (currently) only adds a file to one package, skip this
// package, so that we can add the file to the production
// variant of the package. (https://golang.org/issue/36857
// tracks handling overlays on both the production and test
// variant of a package).
continue nextPackage
}
if pkg != nil && p != pkg && pkg.PkgPath == p.PkgPath {
// We have already seen the production version of the
// for which p is a test variant.
if hasTestFiles(p) {
testVariantOf = pkg
}
}
pkg = p
if filepath.Base(f) == base {
fileExists = true
}
}
}
// The overlay could have included an entirely new package or an
// ad-hoc package. An ad-hoc package is one that we have manually
// constructed from inadequate `go list` results for a file= query.
// It will have the ID command-line-arguments.
if pkg == nil || pkg.ID == "command-line-arguments" {
// Try to find the module or gopath dir the file is contained in.
// Then for modules, add the module opath to the beginning.
pkgPath, ok, err := state.getPkgPath(dir)
if err != nil {
return nil, nil, err
}
if !ok {
break
}
var forTest string // only set for x tests
isXTest := strings.HasSuffix(pkgName, "_test")
if isXTest {
forTest = pkgPath
pkgPath += "_test"
}
id := pkgPath
if isTestFile {
if isXTest {
id = fmt.Sprintf("%s [%s.test]", pkgPath, forTest)
} else {
id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath)
}
}
if pkg != nil {
// TODO(rstambler): We should change the package's path and ID
// here. The only issue is that this messes with the roots.
} else {
// Try to reclaim a package with the same ID, if it exists in the response.
for _, p := range response.dr.Packages {
if reclaimPackage(p, id, opath, contents) {
pkg = p
break
}
}
// Otherwise, create a new package.
if pkg == nil {
pkg = &Package{
PkgPath: pkgPath,
ID: id,
Name: pkgName,
Imports: make(map[string]*Package),
}
response.addPackage(pkg)
havePkgs[pkg.PkgPath] = id
// Add the production package's sources for a test variant.
if isTestFile && !isXTest && testVariantOf != nil {
pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...)
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...)
// Add the package under test and its imports to the test variant.
pkg.forTest = testVariantOf.PkgPath
for k, v := range testVariantOf.Imports {
pkg.Imports[k] = &Package{ID: v.ID}
}
}
if isXTest {
pkg.forTest = forTest
}
}
}
}
if !fileExists {
pkg.GoFiles = append(pkg.GoFiles, opath)
// TODO(matloob): Adding the file to CompiledGoFiles can exhibit the wrong behavior
// if the file will be ignored due to its build tags.
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, opath)
modifiedPkgsSet[pkg.ID] = true
}
imports, err := extractImports(opath, contents)
if err != nil {
// Let the parser or type checker report errors later.
continue
}
for _, imp := range imports {
// TODO(rstambler): If the package is an x test and the import has
// a test variant, make sure to replace it.
if _, found := pkg.Imports[imp]; found {
continue
}
overlayAddsImports = true
id, ok := havePkgs[imp]
if !ok {
var err error
id, err = state.resolveImport(dir, imp)
if err != nil {
return nil, nil, err
}
}
pkg.Imports[imp] = &Package{ID: id}
// Add dependencies to the non-test variant version of this package as well.
if testVariantOf != nil {
testVariantOf.Imports[imp] = &Package{ID: id}
}
}
}
// toPkgPath guesses the package path given the id.
toPkgPath := func(sourceDir, id string) (string, error) {
if i := strings.IndexByte(id, ' '); i >= 0 {
return state.resolveImport(sourceDir, id[:i])
}
return state.resolveImport(sourceDir, id)
}
// Now that new packages have been created, do another pass to determine
// the new set of missing packages.
for _, pkg := range response.dr.Packages {
for _, imp := range pkg.Imports {
if len(pkg.GoFiles) == 0 {
return nil, nil, fmt.Errorf("cannot resolve imports for package %q with no Go files", pkg.PkgPath)
}
pkgPath, err := toPkgPath(filepath.Dir(pkg.GoFiles[0]), imp.ID)
if err != nil {
return nil, nil, err
}
if _, ok := havePkgs[pkgPath]; !ok {
needPkgsSet[pkgPath] = true
}
}
}
if overlayAddsImports {
needPkgs = make([]string, 0, len(needPkgsSet))
for pkg := range needPkgsSet {
needPkgs = append(needPkgs, pkg)
}
}
modifiedPkgs = make([]string, 0, len(modifiedPkgsSet))
for pkg := range modifiedPkgsSet {
modifiedPkgs = append(modifiedPkgs, pkg)
}
return modifiedPkgs, needPkgs, err
}
// resolveImport finds the ID of a package given its import path.
// In particular, it will find the right vendored copy when in GOPATH mode.
func (state *golistState) resolveImport(sourceDir, importPath string) (string, error) {
env, err := state.getEnv()
if err != nil {
return "", err
}
if env["GOMOD"] != "" {
return importPath, nil
}
searchDir := sourceDir
for {
vendorDir := filepath.Join(searchDir, "vendor")
exists, ok := state.vendorDirs[vendorDir]
if !ok {
info, err := os.Stat(vendorDir)
exists = err == nil && info.IsDir()
state.vendorDirs[vendorDir] = exists
}
if exists {
vendoredPath := filepath.Join(vendorDir, importPath)
if info, err := os.Stat(vendoredPath); err == nil && info.IsDir() {
// We should probably check for .go files here, but shame on anyone who fools us.
path, ok, err := state.getPkgPath(vendoredPath)
if err != nil {
return "", err
}
if ok {
return path, nil
}
}
}
// We know we've hit the top of the filesystem when we Dir / and get /,
// or C:\ and get C:\, etc.
next := filepath.Dir(searchDir)
if next == searchDir {
break
}
searchDir = next
}
return importPath, nil
}
func hasTestFiles(p *Package) bool {
for _, f := range p.GoFiles {
if strings.HasSuffix(f, "_test.go") {
return true
}
}
return false
}
// determineRootDirs returns a mapping from absolute directories that could
// contain code to their corresponding import path prefixes.
func (state *golistState) determineRootDirs() (map[string]string, error) {
@ -384,192 +81,3 @@ func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) {
}
return m, nil
}
func extractImports(filename string, contents []byte) ([]string, error) {
f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.ImportsOnly) // TODO(matloob): reuse fileset?
if err != nil {
return nil, err
}
var res []string
for _, imp := range f.Imports {
quotedPath := imp.Path.Value
path, err := strconv.Unquote(quotedPath)
if err != nil {
return nil, err
}
res = append(res, path)
}
return res, nil
}
// reclaimPackage attempts to reuse a package that failed to load in an overlay.
//
// If the package has errors and has no Name, GoFiles, or Imports,
// then it's possible that it doesn't yet exist on disk.
func reclaimPackage(pkg *Package, id string, filename string, contents []byte) bool {
// TODO(rstambler): Check the message of the actual error?
// It differs between $GOPATH and module mode.
if pkg.ID != id {
return false
}
if len(pkg.Errors) != 1 {
return false
}
if pkg.Name != "" || pkg.ExportFile != "" {
return false
}
if len(pkg.GoFiles) > 0 || len(pkg.CompiledGoFiles) > 0 || len(pkg.OtherFiles) > 0 {
return false
}
if len(pkg.Imports) > 0 {
return false
}
pkgName, ok := extractPackageName(filename, contents)
if !ok {
return false
}
pkg.Name = pkgName
pkg.Errors = nil
return true
}
func extractPackageName(filename string, contents []byte) (string, bool) {
// TODO(rstambler): Check the message of the actual error?
// It differs between $GOPATH and module mode.
f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.PackageClauseOnly) // TODO(matloob): reuse fileset?
if err != nil {
return "", false
}
return f.Name.Name, true
}
// commonDir returns the directory that all files are in, "" if files is empty,
// or an error if they aren't in the same directory.
func commonDir(files []string) (string, error) {
seen := make(map[string]bool)
for _, f := range files {
seen[filepath.Dir(f)] = true
}
if len(seen) > 1 {
return "", fmt.Errorf("files (%v) are in more than one directory: %v", files, seen)
}
for k := range seen {
// seen has only one element; return it.
return k, nil
}
return "", nil // no files
}
// It is possible that the files in the disk directory dir have a different package
// name from newName, which is deduced from the overlays. If they all have a different
// package name, and they all have the same package name, then that name becomes
// the package name.
// It returns true if it changes the package name, false otherwise.
func maybeFixPackageName(newName string, isTestFile bool, pkgsOfDir []*Package) {
names := make(map[string]int)
for _, p := range pkgsOfDir {
names[p.Name]++
}
if len(names) != 1 {
// some files are in different packages
return
}
var oldName string
for k := range names {
oldName = k
}
if newName == oldName {
return
}
// We might have a case where all of the package names in the directory are
// the same, but the overlay file is for an x test, which belongs to its
// own package. If the x test does not yet exist on disk, we may not yet
// have its package name on disk, but we should not rename the packages.
//
// We use a heuristic to determine if this file belongs to an x test:
// The test file should have a package name whose package name has a _test
// suffix or looks like "newName_test".
maybeXTest := strings.HasPrefix(oldName+"_test", newName) || strings.HasSuffix(newName, "_test")
if isTestFile && maybeXTest {
return
}
for _, p := range pkgsOfDir {
p.Name = newName
}
}
// This function is copy-pasted from
// https://github.com/golang/go/blob/9706f510a5e2754595d716bd64be8375997311fb/src/cmd/go/internal/search/search.go#L360.
// It should be deleted when we remove support for overlays from go/packages.
//
// NOTE: This does not handle any ./... or ./ style queries, as this function
// doesn't know the working directory.
//
// matchPattern(pattern)(name) reports whether
// name matches pattern. Pattern is a limited glob
// pattern in which '...' means 'any string' and there
// is no other special syntax.
// Unfortunately, there are two special cases. Quoting "go help packages":
//
// First, /... at the end of the pattern can match an empty string,
// so that net/... matches both net and packages in its subdirectories, like net/http.
// Second, any slash-separated pattern element containing a wildcard never
// participates in a match of the "vendor" element in the path of a vendored
// package, so that ./... does not match packages in subdirectories of
// ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
// Note, however, that a directory named vendor that itself contains code
// is not a vendored package: cmd/vendor would be a command named vendor,
// and the pattern cmd/... matches it.
func matchPattern(pattern string) func(name string) bool {
// Convert pattern to regular expression.
// The strategy for the trailing /... is to nest it in an explicit ? expression.
// The strategy for the vendor exclusion is to change the unmatchable
// vendor strings to a disallowed code point (vendorChar) and to use
// "(anything but that codepoint)*" as the implementation of the ... wildcard.
// This is a bit complicated but the obvious alternative,
// namely a hand-written search like in most shell glob matchers,
// is too easy to make accidentally exponential.
// Using package regexp guarantees linear-time matching.
const vendorChar = "\x00"
if strings.Contains(pattern, vendorChar) {
return func(name string) bool { return false }
}
re := regexp.QuoteMeta(pattern)
re = replaceVendor(re, vendorChar)
switch {
case strings.HasSuffix(re, `/`+vendorChar+`/\.\.\.`):
re = strings.TrimSuffix(re, `/`+vendorChar+`/\.\.\.`) + `(/vendor|/` + vendorChar + `/\.\.\.)`
case re == vendorChar+`/\.\.\.`:
re = `(/vendor|/` + vendorChar + `/\.\.\.)`
case strings.HasSuffix(re, `/\.\.\.`):
re = strings.TrimSuffix(re, `/\.\.\.`) + `(/\.\.\.)?`
}
re = strings.ReplaceAll(re, `\.\.\.`, `[^`+vendorChar+`]*`)
reg := regexp.MustCompile(`^` + re + `$`)
return func(name string) bool {
if strings.Contains(name, vendorChar) {
return false
}
return reg.MatchString(replaceVendor(name, vendorChar))
}
}
// replaceVendor returns the result of replacing
// non-trailing vendor path elements in x with repl.
func replaceVendor(x, repl string) string {
if !strings.Contains(x, "vendor") {
return x
}
elem := strings.Split(x, "/")
for i := 0; i < len(elem)-1; i++ {
if elem[i] == "vendor" {
elem[i] = repl
}
}
return strings.Join(elem, "/")
}

View File

@ -27,8 +27,8 @@ import (
"golang.org/x/tools/go/gcexportdata"
"golang.org/x/tools/internal/gocommand"
"golang.org/x/tools/internal/packagesinternal"
"golang.org/x/tools/internal/typeparams"
"golang.org/x/tools/internal/typesinternal"
"golang.org/x/tools/internal/versions"
)
// A LoadMode controls the amount of detail to return when loading.
@ -258,31 +258,52 @@ type driverResponse struct {
// proceeding with further analysis. The PrintErrors function is
// provided for convenient display of all errors.
func Load(cfg *Config, patterns ...string) ([]*Package, error) {
l := newLoader(cfg)
response, err := defaultDriver(&l.Config, patterns...)
ld := newLoader(cfg)
response, external, err := defaultDriver(&ld.Config, patterns...)
if err != nil {
return nil, err
}
l.sizes = types.SizesFor(response.Compiler, response.Arch)
return l.refine(response)
ld.sizes = types.SizesFor(response.Compiler, response.Arch)
if ld.sizes == nil && ld.Config.Mode&(NeedTypes|NeedTypesSizes|NeedTypesInfo) != 0 {
// Type size information is needed but unavailable.
if external {
// An external driver may fail to populate the Compiler/GOARCH fields,
// especially since they are relatively new (see #63700).
// Provide a sensible fallback in this case.
ld.sizes = types.SizesFor("gc", runtime.GOARCH)
if ld.sizes == nil { // gccgo-only arch
ld.sizes = types.SizesFor("gc", "amd64")
}
} else {
// Go list should never fail to deliver accurate size information.
// Reject the whole Load since the error is the same for every package.
return nil, fmt.Errorf("can't determine type sizes for compiler %q on GOARCH %q",
response.Compiler, response.Arch)
}
}
return ld.refine(response)
}
// defaultDriver is a driver that implements go/packages' fallback behavior.
// It will try to request to an external driver, if one exists. If there's
// no external driver, or the driver returns a response with NotHandled set,
// defaultDriver will fall back to the go list driver.
func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
driver := findExternalDriver(cfg)
if driver == nil {
driver = goListDriver
// The boolean result indicates that an external driver handled the request.
func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, bool, error) {
if driver := findExternalDriver(cfg); driver != nil {
response, err := driver(cfg, patterns...)
if err != nil {
return nil, false, err
} else if !response.NotHandled {
return response, true, nil
}
// (fall through)
}
response, err := driver(cfg, patterns...)
if err != nil {
return response, err
} else if response.NotHandled {
return goListDriver(cfg, patterns...)
}
return response, nil
response, err := goListDriver(cfg, patterns...)
return response, false, err
}
// A Package describes a loaded Go package.
@ -411,12 +432,6 @@ func init() {
packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError {
return p.(*Package).depsErrors
}
packagesinternal.GetGoCmdRunner = func(config interface{}) *gocommand.Runner {
return config.(*Config).gocmdRunner
}
packagesinternal.SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {
config.(*Config).gocmdRunner = runner
}
packagesinternal.SetModFile = func(config interface{}, value string) {
config.(*Config).modFile = value
}
@ -553,7 +568,7 @@ type loaderPackage struct {
type loader struct {
pkgs map[string]*loaderPackage
Config
sizes types.Sizes
sizes types.Sizes // non-nil if needed by mode
parseCache map[string]*parseValue
parseCacheMu sync.Mutex
exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
@ -678,39 +693,38 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
}
}
// Materialize the import graph.
if ld.Mode&NeedImports != 0 {
// Materialize the import graph.
const (
white = 0 // new
grey = 1 // in progress
black = 2 // complete
)
const (
white = 0 // new
grey = 1 // in progress
black = 2 // complete
)
// visit traverses the import graph, depth-first,
// and materializes the graph as Packages.Imports.
//
// Valid imports are saved in the Packages.Import map.
// Invalid imports (cycles and missing nodes) are saved in the importErrors map.
// Thus, even in the presence of both kinds of errors, the Import graph remains a DAG.
//
// visit returns whether the package needs src or has a transitive
// dependency on a package that does. These are the only packages
// for which we load source code.
var stack []*loaderPackage
var visit func(lpkg *loaderPackage) bool
var srcPkgs []*loaderPackage
visit = func(lpkg *loaderPackage) bool {
switch lpkg.color {
case black:
return lpkg.needsrc
case grey:
panic("internal error: grey node")
}
lpkg.color = grey
stack = append(stack, lpkg) // push
stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
// If NeedImports isn't set, the imports fields will all be zeroed out.
if ld.Mode&NeedImports != 0 {
// visit traverses the import graph, depth-first,
// and materializes the graph as Packages.Imports.
//
// Valid imports are saved in the Packages.Import map.
// Invalid imports (cycles and missing nodes) are saved in the importErrors map.
// Thus, even in the presence of both kinds of errors,
// the Import graph remains a DAG.
//
// visit returns whether the package needs src or has a transitive
// dependency on a package that does. These are the only packages
// for which we load source code.
var stack []*loaderPackage
var visit func(lpkg *loaderPackage) bool
visit = func(lpkg *loaderPackage) bool {
switch lpkg.color {
case black:
return lpkg.needsrc
case grey:
panic("internal error: grey node")
}
lpkg.color = grey
stack = append(stack, lpkg) // push
stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
lpkg.Imports = make(map[string]*Package, len(stubs))
for importPath, ipkg := range stubs {
var importErr error
@ -734,40 +748,39 @@ func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
}
lpkg.Imports[importPath] = imp.Package
}
}
if lpkg.needsrc {
srcPkgs = append(srcPkgs, lpkg)
}
if ld.Mode&NeedTypesSizes != 0 {
lpkg.TypesSizes = ld.sizes
}
stack = stack[:len(stack)-1] // pop
lpkg.color = black
return lpkg.needsrc
}
// Complete type information is required for the
// immediate dependencies of each source package.
if lpkg.needsrc && ld.Mode&NeedTypes != 0 {
for _, ipkg := range lpkg.Imports {
ld.pkgs[ipkg.ID].needtypes = true
}
}
if ld.Mode&NeedImports == 0 {
// We do this to drop the stub import packages that we are not even going to try to resolve.
for _, lpkg := range initial {
lpkg.Imports = nil
// NeedTypeSizes causes TypeSizes to be set even
// on packages for which types aren't needed.
if ld.Mode&NeedTypesSizes != 0 {
lpkg.TypesSizes = ld.sizes
}
stack = stack[:len(stack)-1] // pop
lpkg.color = black
return lpkg.needsrc
}
} else {
// For each initial package, create its import DAG.
for _, lpkg := range initial {
visit(lpkg)
}
}
if ld.Mode&NeedImports != 0 && ld.Mode&NeedTypes != 0 {
for _, lpkg := range srcPkgs {
// Complete type information is required for the
// immediate dependencies of each source package.
for _, ipkg := range lpkg.Imports {
imp := ld.pkgs[ipkg.ID]
imp.needtypes = true
}
} else {
// !NeedImports: drop the stub (ID-only) import packages
// that we are not even going to try to resolve.
for _, lpkg := range initial {
lpkg.Imports = nil
}
}
// Load type data and syntax if needed, starting at
// the initial packages (roots of the import DAG).
if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
@ -1001,10 +1014,11 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
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),
}
typeparams.InitInstanceInfo(lpkg.TypesInfo)
versions.InitFileVersions(lpkg.TypesInfo)
lpkg.TypesSizes = ld.sizes
importer := importerFunc(func(path string) (*types.Package, error) {
@ -1042,7 +1056,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial,
Error: appendError,
Sizes: ld.sizes,
Sizes: ld.sizes, // may be nil
}
if lpkg.Module != nil && lpkg.Module.GoVersion != "" {
typesinternal.SetGoVersion(tc, "go"+lpkg.Module.GoVersion)

View File

@ -26,13 +26,10 @@ package objectpath
import (
"fmt"
"go/types"
"sort"
"strconv"
"strings"
_ "unsafe"
"golang.org/x/tools/internal/typeparams"
"golang.org/x/tools/internal/typesinternal"
)
// A Path is an opaque name that identifies a types.Object
@ -123,20 +120,7 @@ func For(obj types.Object) (Path, error) {
// An Encoder amortizes the cost of encoding the paths of multiple objects.
// The zero value of an Encoder is ready to use.
type Encoder struct {
scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects
namedMethodsMemo map[*types.Named][]*types.Func // memoization of namedMethods()
skipMethodSorting bool
}
// Expose back doors so that gopls can avoid method sorting, which can dominate
// analysis on certain repositories.
//
// TODO(golang/go#61443): remove this.
func init() {
typesinternal.SkipEncoderMethodSorting = func(enc interface{}) {
enc.(*Encoder).skipMethodSorting = true
}
typesinternal.ObjectpathObject = object
scopeMemo map[*types.Scope][]types.Object // memoization of scopeObjects
}
// For returns the path to an object relative to its package,
@ -239,7 +223,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
// Reject obviously non-viable cases.
switch obj := obj.(type) {
case *types.TypeName:
if _, ok := obj.Type().(*typeparams.TypeParam); !ok {
if _, ok := 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)
@ -299,7 +283,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
}
} else {
if named, _ := T.(*types.Named); named != nil {
if r := findTypeParam(obj, typeparams.ForNamed(named), path, nil); r != nil {
if r := findTypeParam(obj, named.TypeParams(), path, nil); r != nil {
// generic named type
return Path(r), nil
}
@ -328,31 +312,18 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
// Inspect declared methods of defined types.
if T, ok := o.Type().(*types.Named); ok {
path = append(path, opType)
if !enc.skipMethodSorting {
// Note that method index here is always with respect
// to canonical ordering of methods, regardless of how
// they appear in the underlying type.
for i, m := range enc.namedMethods(T) {
path2 := appendOpArg(path, opMethod, i)
if m == obj {
return Path(path2), nil // found declared method
}
if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
return Path(r), nil
}
// The method index here is always with respect
// to the underlying go/types data structures,
// which ultimately derives from source order
// and must be preserved by export data.
for i := 0; i < T.NumMethods(); i++ {
m := T.Method(i)
path2 := appendOpArg(path, opMethod, i)
if m == obj {
return Path(path2), nil // found declared method
}
} else {
// This branch must match the logic in the branch above, using go/types
// APIs without sorting.
for i := 0; i < T.NumMethods(); i++ {
m := T.Method(i)
path2 := appendOpArg(path, opMethod, i)
if m == obj {
return Path(path2), nil // found declared method
}
if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
return Path(r), nil
}
if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
return Path(r), nil
}
}
}
@ -448,22 +419,13 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
path = append(path, name...)
path = append(path, opType)
if !enc.skipMethodSorting {
for i, m := range enc.namedMethods(named) {
if m == meth {
path = appendOpArg(path, opMethod, i)
return Path(path), true
}
}
} else {
// This branch must match the logic of the branch above, using go/types
// APIs without sorting.
for i := 0; i < named.NumMethods(); i++ {
m := named.Method(i)
if m == meth {
path = appendOpArg(path, opMethod, i)
return Path(path), true
}
// Method indices are w.r.t. the go/types data structures,
// ultimately deriving from source order,
// which is preserved by export data.
for i := 0; i < named.NumMethods(); i++ {
if named.Method(i) == meth {
path = appendOpArg(path, opMethod, i)
return Path(path), true
}
}
@ -500,7 +462,7 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
}
return find(obj, T.Elem(), append(path, opElem), seen)
case *types.Signature:
if r := findTypeParam(obj, typeparams.ForSignature(T), path, seen); r != nil {
if r := findTypeParam(obj, T.TypeParams(), path, seen); r != nil {
return r
}
if r := find(obj, T.Params(), append(path, opParams), seen); r != nil {
@ -543,7 +505,7 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
}
}
return nil
case *typeparams.TypeParam:
case *types.TypeParam:
name := T.Obj()
if name == obj {
return append(path, opObj)
@ -563,7 +525,7 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
panic(T)
}
func findTypeParam(obj types.Object, list *typeparams.TypeParamList, path []byte, seen map[*types.TypeName]bool) []byte {
func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, seen map[*types.TypeName]bool) []byte {
for i := 0; i < list.Len(); i++ {
tparam := list.At(i)
path2 := appendOpArg(path, opTypeParam, i)
@ -576,12 +538,7 @@ func findTypeParam(obj types.Object, list *typeparams.TypeParamList, path []byte
// Object returns the object denoted by path p within the package pkg.
func Object(pkg *types.Package, p Path) (types.Object, error) {
return object(pkg, string(p), false)
}
// Note: the skipMethodSorting parameter must match the value of
// Encoder.skipMethodSorting used during encoding.
func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.Object, error) {
pathstr := string(p)
if pathstr == "" {
return nil, fmt.Errorf("empty path")
}
@ -605,7 +562,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
}
// abstraction of *types.{Named,Signature}
type hasTypeParams interface {
TypeParams() *typeparams.TypeParamList
TypeParams() *types.TypeParamList
}
// abstraction of *types.{Named,TypeParam}
type hasObj interface {
@ -707,7 +664,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
t = tparams.At(index)
case opConstraint:
tparam, ok := t.(*typeparams.TypeParam)
tparam, ok := t.(*types.TypeParam)
if !ok {
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t)
}
@ -747,12 +704,7 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
if index >= t.NumMethods() {
return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods())
}
if skipMethodSorting {
obj = t.Method(index)
} else {
methods := namedMethods(t) // (unmemoized)
obj = methods[index] // Id-ordered
}
obj = t.Method(index)
default:
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t)
@ -779,33 +731,6 @@ func object(pkg *types.Package, pathstr string, skipMethodSorting bool) (types.O
return obj, nil // success
}
// namedMethods returns the methods of a Named type in ascending Id order.
func namedMethods(named *types.Named) []*types.Func {
methods := make([]*types.Func, named.NumMethods())
for i := range methods {
methods[i] = named.Method(i)
}
sort.Slice(methods, func(i, j int) bool {
return methods[i].Id() < methods[j].Id()
})
return methods
}
// namedMethods is a memoization of the namedMethods function. Callers must not modify the result.
func (enc *Encoder) namedMethods(named *types.Named) []*types.Func {
m := enc.namedMethodsMemo
if m == nil {
m = make(map[*types.Named][]*types.Func)
enc.namedMethodsMemo = m
}
methods, ok := m[named]
if !ok {
methods = namedMethods(named) // allocates and sorts
m[named] = methods
}
return methods
}
// scopeObjects is a memoization of scope objects.
// Callers must not modify the result.
func (enc *Encoder) scopeObjects(scope *types.Scope) []types.Object {

21
vendor/golang.org/x/tools/internal/event/keys/util.go generated vendored Normal file
View File

@ -0,0 +1,21 @@
// 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.
package keys
import (
"sort"
"strings"
)
// Join returns a canonical join of the keys in S:
// a sorted comma-separated string list.
func Join[S ~[]T, T ~string](s S) string {
strs := make([]string, 0, len(s))
for _, v := range s {
strs = append(strs, string(v))
}
sort.Strings(strs)
return strings.Join(strs, ",")
}

View File

@ -24,7 +24,6 @@ import (
"golang.org/x/tools/go/types/objectpath"
"golang.org/x/tools/internal/tokeninternal"
"golang.org/x/tools/internal/typeparams"
)
// IExportShallow encodes "shallow" export data for the specified package.
@ -481,7 +480,7 @@ func (p *iexporter) doDecl(obj types.Object) {
}
// Function.
if typeparams.ForSignature(sig).Len() == 0 {
if sig.TypeParams().Len() == 0 {
w.tag('F')
} else {
w.tag('G')
@ -494,7 +493,7 @@ func (p *iexporter) doDecl(obj types.Object) {
//
// While importing the type parameters, tparamList computes and records
// their export name, so that it can be later used when writing the index.
if tparams := typeparams.ForSignature(sig); tparams.Len() > 0 {
if tparams := sig.TypeParams(); tparams.Len() > 0 {
w.tparamList(obj.Name(), tparams, obj.Pkg())
}
w.signature(sig)
@ -507,14 +506,14 @@ func (p *iexporter) doDecl(obj types.Object) {
case *types.TypeName:
t := obj.Type()
if tparam, ok := t.(*typeparams.TypeParam); ok {
if tparam, ok := t.(*types.TypeParam); ok {
w.tag('P')
w.pos(obj.Pos())
constraint := tparam.Constraint()
if p.version >= iexportVersionGo1_18 {
implicit := false
if iface, _ := constraint.(*types.Interface); iface != nil {
implicit = typeparams.IsImplicit(iface)
implicit = iface.IsImplicit()
}
w.bool(implicit)
}
@ -535,17 +534,17 @@ func (p *iexporter) doDecl(obj types.Object) {
panic(internalErrorf("%s is not a defined type", t))
}
if typeparams.ForNamed(named).Len() == 0 {
if named.TypeParams().Len() == 0 {
w.tag('T')
} else {
w.tag('U')
}
w.pos(obj.Pos())
if typeparams.ForNamed(named).Len() > 0 {
if named.TypeParams().Len() > 0 {
// While importing the type parameters, tparamList computes and records
// their export name, so that it can be later used when writing the index.
w.tparamList(obj.Name(), typeparams.ForNamed(named), obj.Pkg())
w.tparamList(obj.Name(), named.TypeParams(), obj.Pkg())
}
underlying := obj.Type().Underlying()
@ -565,7 +564,7 @@ func (p *iexporter) doDecl(obj types.Object) {
// Receiver type parameters are type arguments of the receiver type, so
// their name must be qualified before exporting recv.
if rparams := typeparams.RecvTypeParams(sig); rparams.Len() > 0 {
if rparams := sig.RecvTypeParams(); rparams.Len() > 0 {
prefix := obj.Name() + "." + m.Name()
for i := 0; i < rparams.Len(); i++ {
rparam := rparams.At(i)
@ -740,19 +739,19 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
}
switch t := t.(type) {
case *types.Named:
if targs := typeparams.NamedTypeArgs(t); targs.Len() > 0 {
if targs := t.TypeArgs(); targs.Len() > 0 {
w.startType(instanceType)
// TODO(rfindley): investigate if this position is correct, and if it
// matters.
w.pos(t.Obj().Pos())
w.typeList(targs, pkg)
w.typ(typeparams.NamedTypeOrigin(t), pkg)
w.typ(t.Origin(), pkg)
return
}
w.startType(definedType)
w.qualifiedType(t.Obj())
case *typeparams.TypeParam:
case *types.TypeParam:
w.startType(typeParamType)
w.qualifiedType(t.Obj())
@ -868,7 +867,7 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
w.signature(sig)
}
case *typeparams.Union:
case *types.Union:
w.startType(unionType)
nt := t.Len()
w.uint64(uint64(nt))
@ -948,14 +947,14 @@ func (w *exportWriter) signature(sig *types.Signature) {
}
}
func (w *exportWriter) typeList(ts *typeparams.TypeList, pkg *types.Package) {
func (w *exportWriter) typeList(ts *types.TypeList, pkg *types.Package) {
w.uint64(uint64(ts.Len()))
for i := 0; i < ts.Len(); i++ {
w.typ(ts.At(i), pkg)
}
}
func (w *exportWriter) tparamList(prefix string, list *typeparams.TypeParamList, pkg *types.Package) {
func (w *exportWriter) tparamList(prefix string, list *types.TypeParamList, pkg *types.Package) {
ll := uint64(list.Len())
w.uint64(ll)
for i := 0; i < list.Len(); i++ {
@ -973,7 +972,7 @@ const blankMarker = "$"
// differs from its actual object name: it is prefixed with a qualifier, and
// blank type parameter names are disambiguated by their index in the type
// parameter list.
func tparamExportName(prefix string, tparam *typeparams.TypeParam) string {
func tparamExportName(prefix string, tparam *types.TypeParam) string {
assert(prefix != "")
name := tparam.Obj().Name()
if name == "_" {

View File

@ -22,7 +22,6 @@ import (
"strings"
"golang.org/x/tools/go/types/objectpath"
"golang.org/x/tools/internal/typeparams"
)
type intReader struct {
@ -321,7 +320,7 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte
// Therefore, we defer calling SetConstraint there, and call it here instead
// after all types are complete.
for _, d := range p.later {
typeparams.SetTypeParamConstraint(d.t, d.constraint)
d.t.SetConstraint(d.constraint)
}
for _, typ := range p.interfaceList {
@ -339,7 +338,7 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte
}
type setConstraintArgs struct {
t *typeparams.TypeParam
t *types.TypeParam
constraint types.Type
}
@ -549,7 +548,7 @@ func (r *importReader) obj(name string) {
r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
case 'F', 'G':
var tparams []*typeparams.TypeParam
var tparams []*types.TypeParam
if tag == 'G' {
tparams = r.tparamList()
}
@ -566,7 +565,7 @@ func (r *importReader) obj(name string) {
r.declare(obj)
if tag == 'U' {
tparams := r.tparamList()
typeparams.SetForNamed(named, tparams)
named.SetTypeParams(tparams)
}
underlying := r.p.typAt(r.uint64(), named).Underlying()
@ -583,12 +582,12 @@ func (r *importReader) obj(name string) {
// typeparams being used in the method sig/body).
base := baseType(recv.Type())
assert(base != nil)
targs := typeparams.NamedTypeArgs(base)
var rparams []*typeparams.TypeParam
targs := base.TypeArgs()
var rparams []*types.TypeParam
if targs.Len() > 0 {
rparams = make([]*typeparams.TypeParam, targs.Len())
rparams = make([]*types.TypeParam, targs.Len())
for i := range rparams {
rparams[i] = targs.At(i).(*typeparams.TypeParam)
rparams[i] = targs.At(i).(*types.TypeParam)
}
}
msig := r.signature(recv, rparams, nil)
@ -606,7 +605,7 @@ func (r *importReader) obj(name string) {
}
name0 := tparamName(name)
tn := types.NewTypeName(pos, r.currPkg, name0, nil)
t := typeparams.NewTypeParam(tn, nil)
t := types.NewTypeParam(tn, nil)
// To handle recursive references to the typeparam within its
// bound, save the partial type in tparamIndex before reading the bounds.
@ -622,7 +621,7 @@ func (r *importReader) obj(name string) {
if iface == nil {
errorf("non-interface constraint marked implicit")
}
typeparams.MarkImplicit(iface)
iface.MarkImplicit()
}
// The constraint type may not be complete, if we
// are in the middle of a type recursion involving type
@ -966,7 +965,7 @@ func (r *importReader) doType(base *types.Named) (res types.Type) {
// The imported instantiated type doesn't include any methods, so
// we must always use the methods of the base (orig) type.
// TODO provide a non-nil *Environment
t, _ := typeparams.Instantiate(nil, baseType, targs, false)
t, _ := types.Instantiate(nil, baseType, targs, false)
// Workaround for golang/go#61561. See the doc for instanceList for details.
r.p.instanceList = append(r.p.instanceList, t)
@ -976,11 +975,11 @@ func (r *importReader) doType(base *types.Named) (res types.Type) {
if r.p.version < iexportVersionGenerics {
errorf("unexpected instantiation type")
}
terms := make([]*typeparams.Term, r.uint64())
terms := make([]*types.Term, r.uint64())
for i := range terms {
terms[i] = typeparams.NewTerm(r.bool(), r.typ())
terms[i] = types.NewTerm(r.bool(), r.typ())
}
return typeparams.NewUnion(terms)
return types.NewUnion(terms)
}
}
@ -1008,23 +1007,23 @@ func (r *importReader) objectPathObject() types.Object {
return obj
}
func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature {
func (r *importReader) signature(recv *types.Var, rparams []*types.TypeParam, tparams []*types.TypeParam) *types.Signature {
params := r.paramList()
results := r.paramList()
variadic := params.Len() > 0 && r.bool()
return typeparams.NewSignatureType(recv, rparams, tparams, params, results, variadic)
return types.NewSignatureType(recv, rparams, tparams, params, results, variadic)
}
func (r *importReader) tparamList() []*typeparams.TypeParam {
func (r *importReader) tparamList() []*types.TypeParam {
n := r.uint64()
if n == 0 {
return nil
}
xs := make([]*typeparams.TypeParam, n)
xs := make([]*types.TypeParam, n)
for i := range xs {
// Note: the standard library importer is tolerant of nil types here,
// though would panic in SetTypeParams.
xs[i] = r.typ().(*typeparams.TypeParam)
xs[i] = r.typ().(*types.TypeParam)
}
return xs
}

View File

@ -13,6 +13,7 @@ import (
"io"
"log"
"os"
"os/exec"
"reflect"
"regexp"
"runtime"
@ -21,8 +22,6 @@ import (
"sync"
"time"
exec "golang.org/x/sys/execabs"
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/event/keys"
"golang.org/x/tools/internal/event/label"
@ -85,6 +84,7 @@ func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stde
// RunRaw runs the invocation, serializing requests only if they fight over
// go.mod changes.
// Postcondition: both error results have same nilness.
func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
ctx, done := event.Start(ctx, "gocommand.Runner.RunRaw", invLabels(inv)...)
defer done()
@ -95,23 +95,24 @@ func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer
stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv)
// If we encounter a load concurrency error, we need to retry serially.
if friendlyErr == nil || !modConcurrencyError.MatchString(friendlyErr.Error()) {
return stdout, stderr, friendlyErr, err
}
event.Error(ctx, "Load concurrency error, will retry serially", err)
if friendlyErr != nil && modConcurrencyError.MatchString(friendlyErr.Error()) {
event.Error(ctx, "Load concurrency error, will retry serially", err)
// Run serially by calling runPiped.
stdout.Reset()
stderr.Reset()
friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr)
}
// Run serially by calling runPiped.
stdout.Reset()
stderr.Reset()
friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr)
return stdout, stderr, friendlyErr, err
}
// Postcondition: both error results have same nilness.
func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
// Wait for 1 worker to become available.
select {
case <-ctx.Done():
return nil, nil, nil, ctx.Err()
return nil, nil, ctx.Err(), ctx.Err()
case runner.inFlight <- struct{}{}:
defer func() { <-runner.inFlight }()
}
@ -121,6 +122,7 @@ func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes
return stdout, stderr, friendlyErr, err
}
// Postcondition: both error results have same nilness.
func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) {
// Make sure the runner is always initialized.
runner.initialize()
@ -129,7 +131,7 @@ func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stde
// runPiped commands.
select {
case <-ctx.Done():
return nil, ctx.Err()
return ctx.Err(), ctx.Err()
case runner.serialized <- struct{}{}:
defer func() { <-runner.serialized }()
}
@ -139,7 +141,7 @@ func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stde
for i := 0; i < maxInFlight; i++ {
select {
case <-ctx.Done():
return nil, ctx.Err()
return ctx.Err(), ctx.Err()
case runner.inFlight <- struct{}{}:
// Make sure we always "return" any workers we took.
defer func() { <-runner.inFlight }()
@ -172,6 +174,7 @@ type Invocation struct {
Logf func(format string, args ...interface{})
}
// Postcondition: both error results have same nilness.
func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) {
rawError = i.run(ctx, stdout, stderr)
if rawError != nil {

View File

@ -5,10 +5,6 @@
// Package packagesinternal exposes internal-only fields from go/packages.
package packagesinternal
import (
"golang.org/x/tools/internal/gocommand"
)
var GetForTest = func(p interface{}) string { return "" }
var GetDepsErrors = func(p interface{}) []*PackageError { return nil }
@ -18,10 +14,6 @@ type PackageError struct {
Err string // the error itself
}
var GetGoCmdRunner = func(config interface{}) *gocommand.Runner { return nil }
var SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {}
var TypecheckCgo int
var DepsErrors int // must be set as a LoadMode to call GetDepsErrors
var ForTest int // must be set as a LoadMode to call GetForTest

View File

@ -42,7 +42,7 @@ func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Ex
switch e := n.(type) {
case *ast.IndexExpr:
return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack
case *IndexListExpr:
case *ast.IndexListExpr:
return e.X, e.Lbrack, e.Indices, e.Rbrack
}
return nil, token.NoPos, nil, token.NoPos
@ -63,7 +63,7 @@ func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack toke
Rbrack: rbrack,
}
default:
return &IndexListExpr{
return &ast.IndexListExpr{
X: x,
Lbrack: lbrack,
Indices: indices,
@ -74,7 +74,7 @@ func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack toke
// IsTypeParam reports whether t is a type parameter.
func IsTypeParam(t types.Type) bool {
_, ok := t.(*TypeParam)
_, ok := t.(*types.TypeParam)
return ok
}
@ -100,11 +100,11 @@ func OriginMethod(fn *types.Func) *types.Func {
// Receiver is a *types.Interface.
return fn
}
if ForNamed(named).Len() == 0 {
if named.TypeParams().Len() == 0 {
// Receiver base has no type parameters, so we can avoid the lookup below.
return fn
}
orig := NamedTypeOrigin(named)
orig := named.Origin()
gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name())
// This is a fix for a gopls crash (#60628) due to a go/types bug (#60634). In:
@ -157,7 +157,7 @@ func OriginMethod(fn *types.Func) *types.Func {
//
// In this case, GenericAssignableTo reports that instantiations of Container
// are assignable to the corresponding instantiation of Interface.
func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
func GenericAssignableTo(ctxt *types.Context, V, T types.Type) bool {
// If V and T are not both named, or do not have matching non-empty type
// parameter lists, fall back on types.AssignableTo.
@ -167,9 +167,9 @@ func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
return types.AssignableTo(V, T)
}
vtparams := ForNamed(VN)
ttparams := ForNamed(TN)
if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || NamedTypeArgs(VN).Len() != 0 || NamedTypeArgs(TN).Len() != 0 {
vtparams := VN.TypeParams()
ttparams := TN.TypeParams()
if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || VN.TypeArgs().Len() != 0 || TN.TypeArgs().Len() != 0 {
return types.AssignableTo(V, T)
}
@ -182,7 +182,7 @@ func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
// Minor optimization: ensure we share a context across the two
// instantiations below.
if ctxt == nil {
ctxt = NewContext()
ctxt = types.NewContext()
}
var targs []types.Type
@ -190,12 +190,12 @@ func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
targs = append(targs, vtparams.At(i))
}
vinst, err := Instantiate(ctxt, V, targs, true)
vinst, err := types.Instantiate(ctxt, V, targs, true)
if err != nil {
panic("type parameters should satisfy their own constraints")
}
tinst, err := Instantiate(ctxt, T, targs, true)
tinst, err := types.Instantiate(ctxt, T, targs, true)
if err != nil {
return false
}

View File

@ -108,15 +108,15 @@ func CoreType(T types.Type) types.Type {
//
// _NormalTerms makes no guarantees about the order of terms, except that it
// is deterministic.
func _NormalTerms(typ types.Type) ([]*Term, error) {
func _NormalTerms(typ types.Type) ([]*types.Term, error) {
switch typ := typ.(type) {
case *TypeParam:
case *types.TypeParam:
return StructuralTerms(typ)
case *Union:
case *types.Union:
return UnionTermSet(typ)
case *types.Interface:
return InterfaceTermSet(typ)
default:
return []*Term{NewTerm(false, typ)}, nil
return []*types.Term{types.NewTerm(false, typ)}, nil
}
}

View File

@ -1,12 +0,0 @@
// Copyright 2021 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.18
// +build !go1.18
package typeparams
// Enabled reports whether type parameters are enabled in the current build
// environment.
const Enabled = false

View File

@ -1,15 +0,0 @@
// Copyright 2021 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.18
// +build go1.18
package typeparams
// Note: this constant is in a separate file as this is the only acceptable
// diff between the <1.18 API of this package and the 1.18 API.
// Enabled reports whether type parameters are enabled in the current build
// environment.
const Enabled = true

View File

@ -60,7 +60,7 @@ var ErrEmptyTypeSet = errors.New("empty type set")
//
// StructuralTerms makes no guarantees about the order of terms, except that it
// is deterministic.
func StructuralTerms(tparam *TypeParam) ([]*Term, error) {
func StructuralTerms(tparam *types.TypeParam) ([]*types.Term, error) {
constraint := tparam.Constraint()
if constraint == nil {
return nil, fmt.Errorf("%s has nil constraint", tparam)
@ -78,7 +78,7 @@ func StructuralTerms(tparam *TypeParam) ([]*Term, error) {
//
// See the documentation of StructuralTerms for more information on
// normalization.
func InterfaceTermSet(iface *types.Interface) ([]*Term, error) {
func InterfaceTermSet(iface *types.Interface) ([]*types.Term, error) {
return computeTermSet(iface)
}
@ -88,11 +88,11 @@ func InterfaceTermSet(iface *types.Interface) ([]*Term, error) {
//
// See the documentation of StructuralTerms for more information on
// normalization.
func UnionTermSet(union *Union) ([]*Term, error) {
func UnionTermSet(union *types.Union) ([]*types.Term, error) {
return computeTermSet(union)
}
func computeTermSet(typ types.Type) ([]*Term, error) {
func computeTermSet(typ types.Type) ([]*types.Term, error) {
tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0)
if err != nil {
return nil, err
@ -103,9 +103,9 @@ func computeTermSet(typ types.Type) ([]*Term, error) {
if tset.terms.isAll() {
return nil, nil
}
var terms []*Term
var terms []*types.Term
for _, term := range tset.terms {
terms = append(terms, NewTerm(term.tilde, term.typ))
terms = append(terms, types.NewTerm(term.tilde, term.typ))
}
return terms, nil
}
@ -162,7 +162,7 @@ func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth in
tset.terms = allTermlist
for i := 0; i < u.NumEmbeddeds(); i++ {
embedded := u.EmbeddedType(i)
if _, ok := embedded.Underlying().(*TypeParam); ok {
if _, ok := embedded.Underlying().(*types.TypeParam); ok {
return nil, fmt.Errorf("invalid embedded type %T", embedded)
}
tset2, err := computeTermSetInternal(embedded, seen, depth+1)
@ -171,7 +171,7 @@ func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth in
}
tset.terms = tset.terms.intersect(tset2.terms)
}
case *Union:
case *types.Union:
// The term set of a union is the union of term sets of its terms.
tset.terms = nil
for i := 0; i < u.Len(); i++ {
@ -184,7 +184,7 @@ func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth in
return nil, err
}
terms = tset2.terms
case *TypeParam, *Union:
case *types.TypeParam, *types.Union:
// A stand-alone type parameter or union is not permitted as union
// term.
return nil, fmt.Errorf("invalid union term %T", t)
@ -199,7 +199,7 @@ func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth in
return nil, fmt.Errorf("exceeded max term count %d", maxTermCount)
}
}
case *TypeParam:
case *types.TypeParam:
panic("unreachable")
default:
// For all other types, the term set is just a single non-tilde term

View File

@ -1,197 +0,0 @@
// Copyright 2021 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.18
// +build !go1.18
package typeparams
import (
"go/ast"
"go/token"
"go/types"
)
func unsupported() {
panic("type parameters are unsupported at this go version")
}
// IndexListExpr is a placeholder type, as type parameters are not supported at
// this Go version. Its methods panic on use.
type IndexListExpr struct {
ast.Expr
X ast.Expr // expression
Lbrack token.Pos // position of "["
Indices []ast.Expr // index expressions
Rbrack token.Pos // position of "]"
}
// ForTypeSpec returns an empty field list, as type parameters on not supported
// at this Go version.
func ForTypeSpec(*ast.TypeSpec) *ast.FieldList {
return nil
}
// ForFuncType returns an empty field list, as type parameters are not
// supported at this Go version.
func ForFuncType(*ast.FuncType) *ast.FieldList {
return nil
}
// TypeParam is a placeholder type, as type parameters are not supported at
// this Go version. Its methods panic on use.
type TypeParam struct{ types.Type }
func (*TypeParam) Index() int { unsupported(); return 0 }
func (*TypeParam) Constraint() types.Type { unsupported(); return nil }
func (*TypeParam) Obj() *types.TypeName { unsupported(); return nil }
// TypeParamList is a placeholder for an empty type parameter list.
type TypeParamList struct{}
func (*TypeParamList) Len() int { return 0 }
func (*TypeParamList) At(int) *TypeParam { unsupported(); return nil }
// TypeList is a placeholder for an empty type list.
type TypeList struct{}
func (*TypeList) Len() int { return 0 }
func (*TypeList) At(int) types.Type { unsupported(); return nil }
// NewTypeParam is unsupported at this Go version, and panics.
func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam {
unsupported()
return nil
}
// SetTypeParamConstraint is unsupported at this Go version, and panics.
func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) {
unsupported()
}
// NewSignatureType calls types.NewSignature, panicking if recvTypeParams or
// typeParams is non-empty.
func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature {
if len(recvTypeParams) != 0 || len(typeParams) != 0 {
panic("signatures cannot have type parameters at this Go version")
}
return types.NewSignature(recv, params, results, variadic)
}
// ForSignature returns an empty slice.
func ForSignature(*types.Signature) *TypeParamList {
return nil
}
// RecvTypeParams returns a nil slice.
func RecvTypeParams(sig *types.Signature) *TypeParamList {
return nil
}
// IsComparable returns false, as no interfaces are type-restricted at this Go
// version.
func IsComparable(*types.Interface) bool {
return false
}
// IsMethodSet returns true, as no interfaces are type-restricted at this Go
// version.
func IsMethodSet(*types.Interface) bool {
return true
}
// IsImplicit returns false, as no interfaces are implicit at this Go version.
func IsImplicit(*types.Interface) bool {
return false
}
// MarkImplicit does nothing, because this Go version does not have implicit
// interfaces.
func MarkImplicit(*types.Interface) {}
// ForNamed returns an empty type parameter list, as type parameters are not
// supported at this Go version.
func ForNamed(*types.Named) *TypeParamList {
return nil
}
// SetForNamed panics if tparams is non-empty.
func SetForNamed(_ *types.Named, tparams []*TypeParam) {
if len(tparams) > 0 {
unsupported()
}
}
// NamedTypeArgs returns nil.
func NamedTypeArgs(*types.Named) *TypeList {
return nil
}
// NamedTypeOrigin is the identity method at this Go version.
func NamedTypeOrigin(named *types.Named) *types.Named {
return named
}
// Term holds information about a structural type restriction.
type Term struct {
tilde bool
typ types.Type
}
func (m *Term) Tilde() bool { return m.tilde }
func (m *Term) Type() types.Type { return m.typ }
func (m *Term) String() string {
pre := ""
if m.tilde {
pre = "~"
}
return pre + m.typ.String()
}
// NewTerm is unsupported at this Go version, and panics.
func NewTerm(tilde bool, typ types.Type) *Term {
return &Term{tilde, typ}
}
// Union is a placeholder type, as type parameters are not supported at this Go
// version. Its methods panic on use.
type Union struct{ types.Type }
func (*Union) Len() int { return 0 }
func (*Union) Term(i int) *Term { unsupported(); return nil }
// NewUnion is unsupported at this Go version, and panics.
func NewUnion(terms []*Term) *Union {
unsupported()
return nil
}
// InitInstanceInfo is a noop at this Go version.
func InitInstanceInfo(*types.Info) {}
// Instance is a placeholder type, as type parameters are not supported at this
// Go version.
type Instance struct {
TypeArgs *TypeList
Type types.Type
}
// GetInstances returns a nil map, as type parameters are not supported at this
// Go version.
func GetInstances(info *types.Info) map[*ast.Ident]Instance { return nil }
// Context is a placeholder type, as type parameters are not supported at
// this Go version.
type Context struct{}
// NewContext returns a placeholder Context instance.
func NewContext() *Context {
return &Context{}
}
// Instantiate is unsupported on this Go version, and panics.
func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) {
unsupported()
return nil, nil
}

View File

@ -1,151 +0,0 @@
// Copyright 2021 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.18
// +build go1.18
package typeparams
import (
"go/ast"
"go/types"
)
// IndexListExpr is an alias for ast.IndexListExpr.
type IndexListExpr = ast.IndexListExpr
// ForTypeSpec returns n.TypeParams.
func ForTypeSpec(n *ast.TypeSpec) *ast.FieldList {
if n == nil {
return nil
}
return n.TypeParams
}
// ForFuncType returns n.TypeParams.
func ForFuncType(n *ast.FuncType) *ast.FieldList {
if n == nil {
return nil
}
return n.TypeParams
}
// TypeParam is an alias for types.TypeParam
type TypeParam = types.TypeParam
// TypeParamList is an alias for types.TypeParamList
type TypeParamList = types.TypeParamList
// TypeList is an alias for types.TypeList
type TypeList = types.TypeList
// NewTypeParam calls types.NewTypeParam.
func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam {
return types.NewTypeParam(name, constraint)
}
// SetTypeParamConstraint calls tparam.SetConstraint(constraint).
func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) {
tparam.SetConstraint(constraint)
}
// NewSignatureType calls types.NewSignatureType.
func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature {
return types.NewSignatureType(recv, recvTypeParams, typeParams, params, results, variadic)
}
// ForSignature returns sig.TypeParams()
func ForSignature(sig *types.Signature) *TypeParamList {
return sig.TypeParams()
}
// RecvTypeParams returns sig.RecvTypeParams().
func RecvTypeParams(sig *types.Signature) *TypeParamList {
return sig.RecvTypeParams()
}
// IsComparable calls iface.IsComparable().
func IsComparable(iface *types.Interface) bool {
return iface.IsComparable()
}
// IsMethodSet calls iface.IsMethodSet().
func IsMethodSet(iface *types.Interface) bool {
return iface.IsMethodSet()
}
// IsImplicit calls iface.IsImplicit().
func IsImplicit(iface *types.Interface) bool {
return iface.IsImplicit()
}
// MarkImplicit calls iface.MarkImplicit().
func MarkImplicit(iface *types.Interface) {
iface.MarkImplicit()
}
// ForNamed extracts the (possibly empty) type parameter object list from
// named.
func ForNamed(named *types.Named) *TypeParamList {
return named.TypeParams()
}
// SetForNamed sets the type params tparams on n. Each tparam must be of
// dynamic type *types.TypeParam.
func SetForNamed(n *types.Named, tparams []*TypeParam) {
n.SetTypeParams(tparams)
}
// NamedTypeArgs returns named.TypeArgs().
func NamedTypeArgs(named *types.Named) *TypeList {
return named.TypeArgs()
}
// NamedTypeOrigin returns named.Orig().
func NamedTypeOrigin(named *types.Named) *types.Named {
return named.Origin()
}
// Term is an alias for types.Term.
type Term = types.Term
// NewTerm calls types.NewTerm.
func NewTerm(tilde bool, typ types.Type) *Term {
return types.NewTerm(tilde, typ)
}
// Union is an alias for types.Union
type Union = types.Union
// NewUnion calls types.NewUnion.
func NewUnion(terms []*Term) *Union {
return types.NewUnion(terms)
}
// InitInstanceInfo initializes info to record information about type and
// function instances.
func InitInstanceInfo(info *types.Info) {
info.Instances = make(map[*ast.Ident]types.Instance)
}
// Instance is an alias for types.Instance.
type Instance = types.Instance
// GetInstances returns info.Instances.
func GetInstances(info *types.Info) map[*ast.Ident]Instance {
return info.Instances
}
// Context is an alias for types.Context.
type Context = types.Context
// NewContext calls types.NewContext.
func NewContext() *Context {
return types.NewContext()
}
// Instantiate calls types.Instantiate.
func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) {
return types.Instantiate(ctxt, typ, targs, validate)
}

View File

@ -1,24 +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.
package typesinternal
import "go/types"
// This file contains back doors that allow gopls to avoid method sorting when
// using the objectpath package.
//
// This is performance-critical in certain repositories, but changing the
// behavior of the objectpath package is still being discussed in
// golang/go#61443. If we decide to remove the sorting in objectpath we can
// simply delete these back doors. Otherwise, we should add a new API to
// objectpath that allows controlling the sorting.
// SkipEncoderMethodSorting marks enc (which must be an *objectpath.Encoder) as
// not requiring sorted methods.
var SkipEncoderMethodSorting func(enc interface{})
// ObjectpathObject is like objectpath.Object, but allows suppressing method
// sorting.
var ObjectpathObject func(pkg *types.Package, p string, skipMethodSorting bool) (types.Object, error)

172
vendor/golang.org/x/tools/internal/versions/gover.go generated vendored Normal file
View File

@ -0,0 +1,172 @@
// 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.
// This is a fork of internal/gover for use by x/tools until
// go1.21 and earlier are no longer supported by x/tools.
package versions
import "strings"
// A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]]
// The numbers are the original decimal strings to avoid integer overflows
// and since there is very little actual math. (Probably overflow doesn't matter in practice,
// but at the time this code was written, there was an existing test that used
// go1.99999999999, which does not fit in an int on 32-bit platforms.
// The "big decimal" representation avoids the problem entirely.)
type gover struct {
major string // decimal
minor string // decimal or ""
patch string // decimal or ""
kind string // "", "alpha", "beta", "rc"
pre string // decimal or ""
}
// compare returns -1, 0, or +1 depending on whether
// x < y, x == y, or x > y, interpreted as toolchain versions.
// The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21".
// Malformed versions compare less than well-formed versions and equal to each other.
// The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0".
func compare(x, y string) int {
vx := parse(x)
vy := parse(y)
if c := cmpInt(vx.major, vy.major); c != 0 {
return c
}
if c := cmpInt(vx.minor, vy.minor); c != 0 {
return c
}
if c := cmpInt(vx.patch, vy.patch); c != 0 {
return c
}
if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc
return c
}
if c := cmpInt(vx.pre, vy.pre); c != 0 {
return c
}
return 0
}
// lang returns the Go language version. For example, lang("1.2.3") == "1.2".
func lang(x string) string {
v := parse(x)
if v.minor == "" || v.major == "1" && v.minor == "0" {
return v.major
}
return v.major + "." + v.minor
}
// isValid reports whether the version x is valid.
func isValid(x string) bool {
return parse(x) != gover{}
}
// parse parses the Go version string x into a version.
// It returns the zero version if x is malformed.
func parse(x string) gover {
var v gover
// Parse major version.
var ok bool
v.major, x, ok = cutInt(x)
if !ok {
return gover{}
}
if x == "" {
// Interpret "1" as "1.0.0".
v.minor = "0"
v.patch = "0"
return v
}
// Parse . before minor version.
if x[0] != '.' {
return gover{}
}
// Parse minor version.
v.minor, x, ok = cutInt(x[1:])
if !ok {
return gover{}
}
if x == "" {
// Patch missing is same as "0" for older versions.
// Starting in Go 1.21, patch missing is different from explicit .0.
if cmpInt(v.minor, "21") < 0 {
v.patch = "0"
}
return v
}
// Parse patch if present.
if x[0] == '.' {
v.patch, x, ok = cutInt(x[1:])
if !ok || x != "" {
// Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != "").
// Allowing them would be a bit confusing because we already have:
// 1.21 < 1.21rc1
// But a prerelease of a patch would have the opposite effect:
// 1.21.3rc1 < 1.21.3
// We've never needed them before, so let's not start now.
return gover{}
}
return v
}
// Parse prerelease.
i := 0
for i < len(x) && (x[i] < '0' || '9' < x[i]) {
if x[i] < 'a' || 'z' < x[i] {
return gover{}
}
i++
}
if i == 0 {
return gover{}
}
v.kind, x = x[:i], x[i:]
if x == "" {
return v
}
v.pre, x, ok = cutInt(x)
if !ok || x != "" {
return gover{}
}
return v
}
// cutInt scans the leading decimal number at the start of x to an integer
// and returns that value and the rest of the string.
func cutInt(x string) (n, rest string, ok bool) {
i := 0
for i < len(x) && '0' <= x[i] && x[i] <= '9' {
i++
}
if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero
return "", "", false
}
return x[:i], x[i:], true
}
// cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers.
// (Copied from golang.org/x/mod/semver's compareInt.)
func cmpInt(x, y string) int {
if x == y {
return 0
}
if len(x) < len(y) {
return -1
}
if len(x) > len(y) {
return +1
}
if x < y {
return -1
} else {
return +1
}
}

19
vendor/golang.org/x/tools/internal/versions/types.go generated vendored Normal file
View File

@ -0,0 +1,19 @@
// 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.
package versions
import (
"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()
}
return ""
}

View File

@ -0,0 +1,20 @@
// 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"
)
// FileVersions always reports the a file's Go version as the
// zero version at this Go version.
func FileVersions(info *types.Info, file *ast.File) string { return "" }
// InitFileVersions is a noop at this Go version.
func InitFileVersions(*types.Info) {}

View File

@ -0,0 +1,24 @@
// 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"
)
// FileVersions maps a file to the file's semantic Go version.
// The reported version is the zero version if a version cannot be determined.
func FileVersions(info *types.Info, file *ast.File) string {
return info.FileVersions[file]
}
// InitFileVersions initializes info to record Go versions for Go files.
func InitFileVersions(info *types.Info) {
info.FileVersions = make(map[*ast.File]string)
}

View File

@ -0,0 +1,49 @@
// 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
// Lang returns the Go language version for version x.
// If x is not a valid version, Lang returns the empty string.
// For example:
//
// Lang("go1.21rc2") = "go1.21"
// Lang("go1.21.2") = "go1.21"
// Lang("go1.21") = "go1.21"
// Lang("go1") = "go1"
// Lang("bad") = ""
// Lang("1.21") = ""
func Lang(x string) string {
v := lang(stripGo(x))
if v == "" {
return ""
}
return x[:2+len(v)] // "go"+v without allocation
}
// Compare returns -1, 0, or +1 depending on whether
// x < y, x == y, or x > y, interpreted as Go versions.
// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21".
// Invalid versions, including the empty string, compare less than
// valid versions and equal to each other.
// The language version "go1.21" compares less than the
// release candidate and eventual releases "go1.21rc1" and "go1.21.0".
// Custom toolchain suffixes are ignored during comparison:
// "go1.21.0" and "go1.21.0-bigcorp" are equal.
func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) }
// IsValid reports whether the version x is valid.
func IsValid(x string) bool { return isValid(stripGo(x)) }
// stripGo converts from a "go1.21" version to a "1.21" version.
// If v does not start with "go", stripGo returns the empty string (a known invalid version).
func stripGo(v string) string {
if len(v) < 2 || v[:2] != "go" {
return ""
}
return v[2:]
}

View File

@ -0,0 +1,38 @@
// 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/version"
)
// Lang returns the Go language version for version x.
// If x is not a valid version, Lang returns the empty string.
// For example:
//
// Lang("go1.21rc2") = "go1.21"
// Lang("go1.21.2") = "go1.21"
// Lang("go1.21") = "go1.21"
// Lang("go1") = "go1"
// Lang("bad") = ""
// Lang("1.21") = ""
func Lang(x string) string { return version.Lang(x) }
// Compare returns -1, 0, or +1 depending on whether
// x < y, x == y, or x > y, interpreted as Go versions.
// The versions x and y must begin with a "go" prefix: "go1.21" not "1.21".
// Invalid versions, including the empty string, compare less than
// valid versions and equal to each other.
// The language version "go1.21" compares less than the
// release candidate and eventual releases "go1.21rc1" and "go1.21.0".
// Custom toolchain suffixes are ignored during comparison:
// "go1.21.0" and "go1.21.0-bigcorp" are equal.
func Compare(x, y string) int { return version.Compare(x, y) }
// IsValid reports whether the version x is valid.
func IsValid(x string) bool { return version.IsValid(x) }

8
vendor/modules.txt vendored
View File

@ -814,7 +814,7 @@ github.com/nxadm/tail/winfile
# github.com/oklog/ulid v1.3.1
## explicit
github.com/oklog/ulid
# github.com/onsi/ginkgo/v2 v2.13.2
# github.com/onsi/ginkgo/v2 v2.14.0
## explicit; go 1.18
github.com/onsi/ginkgo/v2
github.com/onsi/ginkgo/v2/config
@ -1155,7 +1155,7 @@ golang.org/x/crypto/xts
golang.org/x/exp/constraints
golang.org/x/exp/maps
golang.org/x/exp/slices
# golang.org/x/mod v0.13.0
# golang.org/x/mod v0.14.0
## explicit; go 1.18
golang.org/x/mod/semver
golang.org/x/mod/sumdb/note
@ -1186,7 +1186,6 @@ golang.org/x/sync/semaphore
# golang.org/x/sys v0.16.0
## explicit; go 1.18
golang.org/x/sys/cpu
golang.org/x/sys/execabs
golang.org/x/sys/plan9
golang.org/x/sys/unix
golang.org/x/sys/windows
@ -1217,7 +1216,7 @@ golang.org/x/text/secure/bidirule
golang.org/x/text/transform
golang.org/x/text/unicode/bidi
golang.org/x/text/unicode/norm
# golang.org/x/tools v0.14.0
# golang.org/x/tools v0.16.1
## explicit; go 1.18
golang.org/x/tools/cmd/stringer
golang.org/x/tools/go/ast/inspector
@ -1237,6 +1236,7 @@ golang.org/x/tools/internal/pkgbits
golang.org/x/tools/internal/tokeninternal
golang.org/x/tools/internal/typeparams
golang.org/x/tools/internal/typesinternal
golang.org/x/tools/internal/versions
# google.golang.org/appengine v1.6.8
## explicit; go 1.11
google.golang.org/appengine/internal