mirror of
https://github.com/containers/podman.git
synced 2026-10-23 02:15:11 -04:00
Merge pull request #19725 from containers/renovate/github.com-onsi-ginkgo-v2-2.x
Update module github.com/onsi/ginkgo/v2 to v2.12.0
This commit is contained in:
81 files changed
+1640
-285
No files matched your search
@@ -43,7 +43,7 @@ require (
|
||||
github.com/mattn/go-sqlite3 v1.14.17
|
||||
github.com/moby/term v0.5.0
|
||||
github.com/nxadm/tail v1.4.8
|
||||
github.com/onsi/ginkgo/v2 v2.11.0
|
||||
github.com/onsi/ginkgo/v2 v2.12.0
|
||||
github.com/onsi/gomega v1.27.10
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.1.0-rc4
|
||||
@@ -185,9 +185,9 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.16.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.12.0 // indirect
|
||||
golang.org/x/mod v0.11.0 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/oauth2 v0.11.0 // indirect
|
||||
golang.org/x/tools v0.9.3 // indirect
|
||||
golang.org/x/tools v0.12.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||
google.golang.org/grpc v1.56.2 // indirect
|
||||
|
||||
@@ -787,8 +787,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.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
|
||||
github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
|
||||
github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ=
|
||||
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=
|
||||
@@ -1142,8 +1142,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
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.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
||||
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
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=
|
||||
@@ -1376,8 +1376,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
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.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM=
|
||||
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||
golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=
|
||||
golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
||||
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=
|
||||
|
||||
+3
-3
@@ -4,9 +4,9 @@ go 1.18
|
||||
|
||||
require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2
|
||||
github.com/onsi/ginkgo/v2 v2.11.0
|
||||
github.com/onsi/ginkgo/v2 v2.12.0
|
||||
github.com/vbatts/git-validation v1.2.0
|
||||
golang.org/x/tools v0.11.0
|
||||
golang.org/x/tools v0.12.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -16,5 +16,5 @@ require (
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/sys v0.10.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
)
|
||||
+9
-9
@@ -17,9 +17,9 @@ github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04
|
||||
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
|
||||
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
|
||||
github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
|
||||
github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
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=
|
||||
@@ -35,15 +35,15 @@ github.com/vbatts/git-validation v1.2.0 h1:IrPrZ8NRvI3kN6XfFVA6tqsByS6yImqmMiv0j
|
||||
github.com/vbatts/git-validation v1.2.0/go.mod h1:3TVljc5dpnsCnENsoayGa30TRhvxHnHdFmMgfeV6ee0=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
|
||||
golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=
|
||||
golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
+1
-3
@@ -244,9 +244,7 @@ func labelFromCallExpr(ce *ast.CallExpr) []string {
|
||||
}
|
||||
if id.Name == "Label" {
|
||||
ls := extractLabels(expr)
|
||||
for _, label := range ls {
|
||||
labels = append(labels, label)
|
||||
}
|
||||
labels = append(labels, ls...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -27,6 +27,7 @@ type SuiteConfig struct {
|
||||
FailOnPending bool
|
||||
FailFast bool
|
||||
FlakeAttempts int
|
||||
MustPassRepeatedly int
|
||||
DryRun bool
|
||||
PollProgressAfter time.Duration
|
||||
PollProgressInterval time.Duration
|
||||
|
||||
+2
-2
@@ -453,8 +453,8 @@ func (g ginkgoErrors) InvalidEntryDescription(cl CodeLocation) error {
|
||||
|
||||
func (g ginkgoErrors) MissingParametersForTableFunction(cl CodeLocation) error {
|
||||
return GinkgoError{
|
||||
Heading: fmt.Sprintf("No parameters have been passed to the Table Function"),
|
||||
Message: fmt.Sprintf("The Table Function expected at least 1 parameter"),
|
||||
Heading: "No parameters have been passed to the Table Function",
|
||||
Message: "The Table Function expected at least 1 parameter",
|
||||
CodeLocation: cl,
|
||||
DocLink: "table-specs",
|
||||
}
|
||||
|
||||
+1
-3
@@ -97,9 +97,7 @@ func (report Report) Add(other Report) Report {
|
||||
report.RunTime = report.EndTime.Sub(report.StartTime)
|
||||
|
||||
reports := make(SpecReports, len(report.SpecReports)+len(other.SpecReports))
|
||||
for i := range report.SpecReports {
|
||||
reports[i] = report.SpecReports[i]
|
||||
}
|
||||
copy(reports, report.SpecReports)
|
||||
offset := len(report.SpecReports)
|
||||
for i := range other.SpecReports {
|
||||
reports[i+offset] = other.SpecReports[i]
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
package types
|
||||
|
||||
const VERSION = "2.11.0"
|
||||
const VERSION = "2.12.0"
|
||||
+1
-1
@@ -624,7 +624,7 @@ ccflags="$@"
|
||||
$2 ~ /^MEM/ ||
|
||||
$2 ~ /^WG/ ||
|
||||
$2 ~ /^FIB_RULE_/ ||
|
||||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
|
||||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE|IOMIN$|IOOPT$|ALIGNOFF$|DISCARD|ROTATIONAL$|ZEROOUT$|GETDISKSEQ$)/ {printf("\t%s = C.%s\n", $2, $2)}
|
||||
$2 ~ /^__WCOREFLAG$/ {next}
|
||||
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
|
||||
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// 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 aix || darwin || dragonfly || freebsd || openbsd || solaris
|
||||
// +build aix darwin dragonfly freebsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
var mapper = &mmapper{
|
||||
active: make(map[*byte][]byte),
|
||||
mmap: mmap,
|
||||
munmap: munmap,
|
||||
}
|
||||
+17
-4
@@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux
|
||||
// +build linux
|
||||
//go:build linux || netbsd
|
||||
// +build linux netbsd
|
||||
|
||||
package unix
|
||||
|
||||
@@ -14,8 +14,17 @@ type mremapMmapper struct {
|
||||
mremap func(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
|
||||
}
|
||||
|
||||
var mapper = &mremapMmapper{
|
||||
mmapper: mmapper{
|
||||
active: make(map[*byte][]byte),
|
||||
mmap: mmap,
|
||||
munmap: munmap,
|
||||
},
|
||||
mremap: mremap,
|
||||
}
|
||||
|
||||
func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
|
||||
if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&MREMAP_FIXED != 0 {
|
||||
if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&mremapFixed != 0 {
|
||||
return nil, EINVAL
|
||||
}
|
||||
|
||||
@@ -32,9 +41,13 @@ func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data [
|
||||
}
|
||||
bNew := unsafe.Slice((*byte)(unsafe.Pointer(newAddr)), newLength)
|
||||
pNew := &bNew[cap(bNew)-1]
|
||||
if flags&MREMAP_DONTUNMAP == 0 {
|
||||
if flags&mremapDontunmap == 0 {
|
||||
delete(m.active, pOld)
|
||||
}
|
||||
m.active[pNew] = bNew
|
||||
return bNew, nil
|
||||
}
|
||||
|
||||
func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
|
||||
return mapper.Mremap(oldData, newLength, flags)
|
||||
}
|
||||
-15
@@ -535,21 +535,6 @@ func Fsync(fd int) error {
|
||||
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg
|
||||
|
||||
//sys munmap(addr uintptr, length uintptr) (err error)
|
||||
|
||||
var mapper = &mmapper{
|
||||
active: make(map[*byte][]byte),
|
||||
mmap: mmap,
|
||||
munmap: munmap,
|
||||
}
|
||||
|
||||
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
|
||||
return mapper.Mmap(fd, offset, length, prot, flags)
|
||||
}
|
||||
|
||||
func Munmap(b []byte) (err error) {
|
||||
return mapper.Munmap(b)
|
||||
}
|
||||
|
||||
//sys Madvise(b []byte, advice int) (err error)
|
||||
//sys Mprotect(b []byte, prot int) (err error)
|
||||
//sys Mlock(b []byte) (err error)
|
||||
|
||||
-14
@@ -601,20 +601,6 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||
// Gethostuuid(uuid *byte, timeout *Timespec) (err error)
|
||||
// Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error)
|
||||
|
||||
var mapper = &mmapper{
|
||||
active: make(map[*byte][]byte),
|
||||
mmap: mmap,
|
||||
munmap: munmap,
|
||||
}
|
||||
|
||||
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
|
||||
return mapper.Mmap(fd, offset, length, prot, flags)
|
||||
}
|
||||
|
||||
func Munmap(b []byte) (err error) {
|
||||
return mapper.Munmap(b)
|
||||
}
|
||||
|
||||
//sys Madvise(b []byte, behav int) (err error)
|
||||
//sys Mlock(b []byte) (err error)
|
||||
//sys Mlockall(flags int) (err error)
|
||||
|
||||
+28
-22
@@ -510,30 +510,36 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Find size.
|
||||
n := uintptr(0)
|
||||
if err := sysctl(mib, nil, &n, nil, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if n%SizeofKinfoProc != 0 {
|
||||
return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
|
||||
}
|
||||
for {
|
||||
// Find size.
|
||||
n := uintptr(0)
|
||||
if err := sysctl(mib, nil, &n, nil, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if n%SizeofKinfoProc != 0 {
|
||||
return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
|
||||
}
|
||||
|
||||
// Read into buffer of that size.
|
||||
buf := make([]KinfoProc, n/SizeofKinfoProc)
|
||||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n%SizeofKinfoProc != 0 {
|
||||
return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
|
||||
}
|
||||
// Read into buffer of that size.
|
||||
buf := make([]KinfoProc, n/SizeofKinfoProc)
|
||||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {
|
||||
if err == ENOMEM {
|
||||
// Process table grew. Try again.
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if n%SizeofKinfoProc != 0 {
|
||||
return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
|
||||
}
|
||||
|
||||
// The actual call may return less than the original reported required
|
||||
// size so ensure we deal with that.
|
||||
return buf[:n/SizeofKinfoProc], nil
|
||||
// The actual call may return less than the original reported required
|
||||
// size so ensure we deal with that.
|
||||
return buf[:n/SizeofKinfoProc], nil
|
||||
}
|
||||
}
|
||||
|
||||
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
|
||||
|
||||
+40
-23
@@ -1885,7 +1885,7 @@ func Getpgrp() (pid int) {
|
||||
//sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)
|
||||
//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
|
||||
//sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
|
||||
//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6
|
||||
//sys pselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_argpack) (n int, err error)
|
||||
//sys read(fd int, p []byte) (n int, err error)
|
||||
//sys Removexattr(path string, attr string) (err error)
|
||||
//sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error)
|
||||
@@ -2125,28 +2125,6 @@ func writevRacedetect(iovecs []Iovec, n int) {
|
||||
// mmap varies by architecture; see syscall_linux_*.go.
|
||||
//sys munmap(addr uintptr, length uintptr) (err error)
|
||||
//sys mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
|
||||
|
||||
var mapper = &mremapMmapper{
|
||||
mmapper: mmapper{
|
||||
active: make(map[*byte][]byte),
|
||||
mmap: mmap,
|
||||
munmap: munmap,
|
||||
},
|
||||
mremap: mremap,
|
||||
}
|
||||
|
||||
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
|
||||
return mapper.Mmap(fd, offset, length, prot, flags)
|
||||
}
|
||||
|
||||
func Munmap(b []byte) (err error) {
|
||||
return mapper.Munmap(b)
|
||||
}
|
||||
|
||||
func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
|
||||
return mapper.Mremap(oldData, newLength, flags)
|
||||
}
|
||||
|
||||
//sys Madvise(b []byte, advice int) (err error)
|
||||
//sys Mprotect(b []byte, prot int) (err error)
|
||||
//sys Mlock(b []byte) (err error)
|
||||
@@ -2155,6 +2133,12 @@ func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
|
||||
//sys Munlock(b []byte) (err error)
|
||||
//sys Munlockall() (err error)
|
||||
|
||||
const (
|
||||
mremapFixed = MREMAP_FIXED
|
||||
mremapDontunmap = MREMAP_DONTUNMAP
|
||||
mremapMaymove = MREMAP_MAYMOVE
|
||||
)
|
||||
|
||||
// Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd,
|
||||
// using the specified flags.
|
||||
func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
|
||||
@@ -2454,6 +2438,39 @@ func Getresgid() (rgid, egid, sgid int) {
|
||||
return int(r), int(e), int(s)
|
||||
}
|
||||
|
||||
// Pselect is a wrapper around the Linux pselect6 system call.
|
||||
// This version does not modify the timeout argument.
|
||||
func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
|
||||
// Per https://man7.org/linux/man-pages/man2/select.2.html#NOTES,
|
||||
// The Linux pselect6() system call modifies its timeout argument.
|
||||
// [Not modifying the argument] is the behavior required by POSIX.1-2001.
|
||||
var mutableTimeout *Timespec
|
||||
if timeout != nil {
|
||||
mutableTimeout = new(Timespec)
|
||||
*mutableTimeout = *timeout
|
||||
}
|
||||
|
||||
// The final argument of the pselect6() system call is not a
|
||||
// sigset_t * pointer, but is instead a structure
|
||||
var kernelMask *sigset_argpack
|
||||
if sigmask != nil {
|
||||
wordBits := 32 << (^uintptr(0) >> 63) // see math.intSize
|
||||
|
||||
// A sigset stores one bit per signal,
|
||||
// offset by 1 (because signal 0 does not exist).
|
||||
// So the number of words needed is ⌈__C_NSIG - 1 / wordBits⌉.
|
||||
sigsetWords := (_C__NSIG - 1 + wordBits - 1) / (wordBits)
|
||||
|
||||
sigsetBytes := uintptr(sigsetWords * (wordBits / 8))
|
||||
kernelMask = &sigset_argpack{
|
||||
ss: sigmask,
|
||||
ssLen: sigsetBytes,
|
||||
}
|
||||
}
|
||||
|
||||
return pselect6(nfd, r, w, e, mutableTimeout, kernelMask)
|
||||
}
|
||||
|
||||
/*
|
||||
* Unimplemented
|
||||
*/
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||
if timeout != nil {
|
||||
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
|
||||
}
|
||||
return Pselect(nfd, r, w, e, ts, nil)
|
||||
return pselect6(nfd, r, w, e, ts, nil)
|
||||
}
|
||||
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||
if timeout != nil {
|
||||
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
|
||||
}
|
||||
return Pselect(nfd, r, w, e, ts, nil)
|
||||
return pselect6(nfd, r, w, e, ts, nil)
|
||||
}
|
||||
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||
if timeout != nil {
|
||||
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
|
||||
}
|
||||
return Pselect(nfd, r, w, e, ts, nil)
|
||||
return pselect6(nfd, r, w, e, ts, nil)
|
||||
}
|
||||
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||
if timeout != nil {
|
||||
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
|
||||
}
|
||||
return Pselect(nfd, r, w, e, ts, nil)
|
||||
return pselect6(nfd, r, w, e, ts, nil)
|
||||
}
|
||||
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
|
||||
+12
-1
@@ -32,7 +32,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
|
||||
if timeout != nil {
|
||||
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
|
||||
}
|
||||
return Pselect(nfd, r, w, e, ts, nil)
|
||||
return pselect6(nfd, r, w, e, ts, nil)
|
||||
}
|
||||
|
||||
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||
@@ -177,3 +177,14 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error
|
||||
}
|
||||
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
|
||||
}
|
||||
|
||||
//sys riscvHWProbe(pairs []RISCVHWProbePairs, cpuCount uintptr, cpus *CPUSet, flags uint) (err error)
|
||||
|
||||
func RISCVHWProbe(pairs []RISCVHWProbePairs, set *CPUSet, flags uint) (err error) {
|
||||
var setSize uintptr
|
||||
|
||||
if set != nil {
|
||||
setSize = uintptr(unsafe.Sizeof(*set))
|
||||
}
|
||||
return riscvHWProbe(pairs, setSize, set, flags)
|
||||
}
|
||||
+12
-1
@@ -360,6 +360,18 @@ func Statvfs(path string, buf *Statvfs_t) (err error) {
|
||||
//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
|
||||
//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
|
||||
|
||||
const (
|
||||
mremapFixed = MAP_FIXED
|
||||
mremapDontunmap = 0
|
||||
mremapMaymove = 0
|
||||
)
|
||||
|
||||
//sys mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) = SYS_MREMAP
|
||||
|
||||
func mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (uintptr, error) {
|
||||
return mremapNetBSD(oldaddr, oldlength, newaddr, newlength, flags)
|
||||
}
|
||||
|
||||
/*
|
||||
* Unimplemented
|
||||
*/
|
||||
@@ -564,7 +576,6 @@ func Statvfs(path string, buf *Statvfs_t) (err error) {
|
||||
// mq_timedreceive
|
||||
// mq_timedsend
|
||||
// mq_unlink
|
||||
// mremap
|
||||
// msgget
|
||||
// msgrcv
|
||||
// msgsnd
|
||||
|
||||
-14
@@ -716,20 +716,6 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
var mapper = &mmapper{
|
||||
active: make(map[*byte][]byte),
|
||||
mmap: mmap,
|
||||
munmap: munmap,
|
||||
}
|
||||
|
||||
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
|
||||
return mapper.Mmap(fd, offset, length, prot, flags)
|
||||
}
|
||||
|
||||
func Munmap(b []byte) (err error) {
|
||||
return mapper.Munmap(b)
|
||||
}
|
||||
|
||||
// Event Ports
|
||||
|
||||
type fileObjCookie struct {
|
||||
|
||||
+8
@@ -147,6 +147,14 @@ func (m *mmapper) Munmap(data []byte) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
|
||||
return mapper.Mmap(fd, offset, length, prot, flags)
|
||||
}
|
||||
|
||||
func Munmap(b []byte) (err error) {
|
||||
return mapper.Munmap(b)
|
||||
}
|
||||
|
||||
func Read(fd int, p []byte) (n int, err error) {
|
||||
n, err = read(fd, p)
|
||||
if raceenabled {
|
||||
|
||||
-14
@@ -285,25 +285,11 @@ func Close(fd int) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
var mapper = &mmapper{
|
||||
active: make(map[*byte][]byte),
|
||||
mmap: mmap,
|
||||
munmap: munmap,
|
||||
}
|
||||
|
||||
// Dummy function: there are no semantics for Madvise on z/OS
|
||||
func Madvise(b []byte, advice int) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
|
||||
return mapper.Mmap(fd, offset, length, prot, flags)
|
||||
}
|
||||
|
||||
func Munmap(b []byte) (err error) {
|
||||
return mapper.Munmap(b)
|
||||
}
|
||||
|
||||
//sys Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A
|
||||
//sysnb Getegid() (egid int)
|
||||
//sysnb Geteuid() (uid int)
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x1001
|
||||
B576000 = 0x1006
|
||||
B921600 = 0x1007
|
||||
BLKALIGNOFF = 0x127a
|
||||
BLKBSZGET = 0x80041270
|
||||
BLKBSZSET = 0x40041271
|
||||
BLKDISCARD = 0x1277
|
||||
BLKDISCARDZEROES = 0x127c
|
||||
BLKFLSBUF = 0x1261
|
||||
BLKFRAGET = 0x1265
|
||||
BLKFRASET = 0x1264
|
||||
BLKGETDISKSEQ = 0x80081280
|
||||
BLKGETSIZE = 0x1260
|
||||
BLKGETSIZE64 = 0x80041272
|
||||
BLKIOMIN = 0x1278
|
||||
BLKIOOPT = 0x1279
|
||||
BLKPBSZGET = 0x127b
|
||||
BLKRAGET = 0x1263
|
||||
BLKRASET = 0x1262
|
||||
BLKROGET = 0x125e
|
||||
BLKROSET = 0x125d
|
||||
BLKROTATIONAL = 0x127e
|
||||
BLKRRPART = 0x125f
|
||||
BLKSECDISCARD = 0x127d
|
||||
BLKSECTGET = 0x1267
|
||||
BLKSECTSET = 0x1266
|
||||
BLKSSZGET = 0x1268
|
||||
BLKZEROOUT = 0x127f
|
||||
BOTHER = 0x1000
|
||||
BS1 = 0x2000
|
||||
BSDLY = 0x2000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x1001
|
||||
B576000 = 0x1006
|
||||
B921600 = 0x1007
|
||||
BLKALIGNOFF = 0x127a
|
||||
BLKBSZGET = 0x80081270
|
||||
BLKBSZSET = 0x40081271
|
||||
BLKDISCARD = 0x1277
|
||||
BLKDISCARDZEROES = 0x127c
|
||||
BLKFLSBUF = 0x1261
|
||||
BLKFRAGET = 0x1265
|
||||
BLKFRASET = 0x1264
|
||||
BLKGETDISKSEQ = 0x80081280
|
||||
BLKGETSIZE = 0x1260
|
||||
BLKGETSIZE64 = 0x80081272
|
||||
BLKIOMIN = 0x1278
|
||||
BLKIOOPT = 0x1279
|
||||
BLKPBSZGET = 0x127b
|
||||
BLKRAGET = 0x1263
|
||||
BLKRASET = 0x1262
|
||||
BLKROGET = 0x125e
|
||||
BLKROSET = 0x125d
|
||||
BLKROTATIONAL = 0x127e
|
||||
BLKRRPART = 0x125f
|
||||
BLKSECDISCARD = 0x127d
|
||||
BLKSECTGET = 0x1267
|
||||
BLKSECTSET = 0x1266
|
||||
BLKSSZGET = 0x1268
|
||||
BLKZEROOUT = 0x127f
|
||||
BOTHER = 0x1000
|
||||
BS1 = 0x2000
|
||||
BSDLY = 0x2000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x1001
|
||||
B576000 = 0x1006
|
||||
B921600 = 0x1007
|
||||
BLKALIGNOFF = 0x127a
|
||||
BLKBSZGET = 0x80041270
|
||||
BLKBSZSET = 0x40041271
|
||||
BLKDISCARD = 0x1277
|
||||
BLKDISCARDZEROES = 0x127c
|
||||
BLKFLSBUF = 0x1261
|
||||
BLKFRAGET = 0x1265
|
||||
BLKFRASET = 0x1264
|
||||
BLKGETDISKSEQ = 0x80081280
|
||||
BLKGETSIZE = 0x1260
|
||||
BLKGETSIZE64 = 0x80041272
|
||||
BLKIOMIN = 0x1278
|
||||
BLKIOOPT = 0x1279
|
||||
BLKPBSZGET = 0x127b
|
||||
BLKRAGET = 0x1263
|
||||
BLKRASET = 0x1262
|
||||
BLKROGET = 0x125e
|
||||
BLKROSET = 0x125d
|
||||
BLKROTATIONAL = 0x127e
|
||||
BLKRRPART = 0x125f
|
||||
BLKSECDISCARD = 0x127d
|
||||
BLKSECTGET = 0x1267
|
||||
BLKSECTSET = 0x1266
|
||||
BLKSSZGET = 0x1268
|
||||
BLKZEROOUT = 0x127f
|
||||
BOTHER = 0x1000
|
||||
BS1 = 0x2000
|
||||
BSDLY = 0x2000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x1001
|
||||
B576000 = 0x1006
|
||||
B921600 = 0x1007
|
||||
BLKALIGNOFF = 0x127a
|
||||
BLKBSZGET = 0x80081270
|
||||
BLKBSZSET = 0x40081271
|
||||
BLKDISCARD = 0x1277
|
||||
BLKDISCARDZEROES = 0x127c
|
||||
BLKFLSBUF = 0x1261
|
||||
BLKFRAGET = 0x1265
|
||||
BLKFRASET = 0x1264
|
||||
BLKGETDISKSEQ = 0x80081280
|
||||
BLKGETSIZE = 0x1260
|
||||
BLKGETSIZE64 = 0x80081272
|
||||
BLKIOMIN = 0x1278
|
||||
BLKIOOPT = 0x1279
|
||||
BLKPBSZGET = 0x127b
|
||||
BLKRAGET = 0x1263
|
||||
BLKRASET = 0x1262
|
||||
BLKROGET = 0x125e
|
||||
BLKROSET = 0x125d
|
||||
BLKROTATIONAL = 0x127e
|
||||
BLKRRPART = 0x125f
|
||||
BLKSECDISCARD = 0x127d
|
||||
BLKSECTGET = 0x1267
|
||||
BLKSECTSET = 0x1266
|
||||
BLKSSZGET = 0x1268
|
||||
BLKZEROOUT = 0x127f
|
||||
BOTHER = 0x1000
|
||||
BS1 = 0x2000
|
||||
BSDLY = 0x2000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x1001
|
||||
B576000 = 0x1006
|
||||
B921600 = 0x1007
|
||||
BLKALIGNOFF = 0x127a
|
||||
BLKBSZGET = 0x80081270
|
||||
BLKBSZSET = 0x40081271
|
||||
BLKDISCARD = 0x1277
|
||||
BLKDISCARDZEROES = 0x127c
|
||||
BLKFLSBUF = 0x1261
|
||||
BLKFRAGET = 0x1265
|
||||
BLKFRASET = 0x1264
|
||||
BLKGETDISKSEQ = 0x80081280
|
||||
BLKGETSIZE = 0x1260
|
||||
BLKGETSIZE64 = 0x80081272
|
||||
BLKIOMIN = 0x1278
|
||||
BLKIOOPT = 0x1279
|
||||
BLKPBSZGET = 0x127b
|
||||
BLKRAGET = 0x1263
|
||||
BLKRASET = 0x1262
|
||||
BLKROGET = 0x125e
|
||||
BLKROSET = 0x125d
|
||||
BLKROTATIONAL = 0x127e
|
||||
BLKRRPART = 0x125f
|
||||
BLKSECDISCARD = 0x127d
|
||||
BLKSECTGET = 0x1267
|
||||
BLKSECTSET = 0x1266
|
||||
BLKSSZGET = 0x1268
|
||||
BLKZEROOUT = 0x127f
|
||||
BOTHER = 0x1000
|
||||
BS1 = 0x2000
|
||||
BSDLY = 0x2000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x1001
|
||||
B576000 = 0x1006
|
||||
B921600 = 0x1007
|
||||
BLKALIGNOFF = 0x2000127a
|
||||
BLKBSZGET = 0x40041270
|
||||
BLKBSZSET = 0x80041271
|
||||
BLKDISCARD = 0x20001277
|
||||
BLKDISCARDZEROES = 0x2000127c
|
||||
BLKFLSBUF = 0x20001261
|
||||
BLKFRAGET = 0x20001265
|
||||
BLKFRASET = 0x20001264
|
||||
BLKGETDISKSEQ = 0x40081280
|
||||
BLKGETSIZE = 0x20001260
|
||||
BLKGETSIZE64 = 0x40041272
|
||||
BLKIOMIN = 0x20001278
|
||||
BLKIOOPT = 0x20001279
|
||||
BLKPBSZGET = 0x2000127b
|
||||
BLKRAGET = 0x20001263
|
||||
BLKRASET = 0x20001262
|
||||
BLKROGET = 0x2000125e
|
||||
BLKROSET = 0x2000125d
|
||||
BLKROTATIONAL = 0x2000127e
|
||||
BLKRRPART = 0x2000125f
|
||||
BLKSECDISCARD = 0x2000127d
|
||||
BLKSECTGET = 0x20001267
|
||||
BLKSECTSET = 0x20001266
|
||||
BLKSSZGET = 0x20001268
|
||||
BLKZEROOUT = 0x2000127f
|
||||
BOTHER = 0x1000
|
||||
BS1 = 0x2000
|
||||
BSDLY = 0x2000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x1001
|
||||
B576000 = 0x1006
|
||||
B921600 = 0x1007
|
||||
BLKALIGNOFF = 0x2000127a
|
||||
BLKBSZGET = 0x40081270
|
||||
BLKBSZSET = 0x80081271
|
||||
BLKDISCARD = 0x20001277
|
||||
BLKDISCARDZEROES = 0x2000127c
|
||||
BLKFLSBUF = 0x20001261
|
||||
BLKFRAGET = 0x20001265
|
||||
BLKFRASET = 0x20001264
|
||||
BLKGETDISKSEQ = 0x40081280
|
||||
BLKGETSIZE = 0x20001260
|
||||
BLKGETSIZE64 = 0x40081272
|
||||
BLKIOMIN = 0x20001278
|
||||
BLKIOOPT = 0x20001279
|
||||
BLKPBSZGET = 0x2000127b
|
||||
BLKRAGET = 0x20001263
|
||||
BLKRASET = 0x20001262
|
||||
BLKROGET = 0x2000125e
|
||||
BLKROSET = 0x2000125d
|
||||
BLKROTATIONAL = 0x2000127e
|
||||
BLKRRPART = 0x2000125f
|
||||
BLKSECDISCARD = 0x2000127d
|
||||
BLKSECTGET = 0x20001267
|
||||
BLKSECTSET = 0x20001266
|
||||
BLKSSZGET = 0x20001268
|
||||
BLKZEROOUT = 0x2000127f
|
||||
BOTHER = 0x1000
|
||||
BS1 = 0x2000
|
||||
BSDLY = 0x2000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x1001
|
||||
B576000 = 0x1006
|
||||
B921600 = 0x1007
|
||||
BLKALIGNOFF = 0x2000127a
|
||||
BLKBSZGET = 0x40081270
|
||||
BLKBSZSET = 0x80081271
|
||||
BLKDISCARD = 0x20001277
|
||||
BLKDISCARDZEROES = 0x2000127c
|
||||
BLKFLSBUF = 0x20001261
|
||||
BLKFRAGET = 0x20001265
|
||||
BLKFRASET = 0x20001264
|
||||
BLKGETDISKSEQ = 0x40081280
|
||||
BLKGETSIZE = 0x20001260
|
||||
BLKGETSIZE64 = 0x40081272
|
||||
BLKIOMIN = 0x20001278
|
||||
BLKIOOPT = 0x20001279
|
||||
BLKPBSZGET = 0x2000127b
|
||||
BLKRAGET = 0x20001263
|
||||
BLKRASET = 0x20001262
|
||||
BLKROGET = 0x2000125e
|
||||
BLKROSET = 0x2000125d
|
||||
BLKROTATIONAL = 0x2000127e
|
||||
BLKRRPART = 0x2000125f
|
||||
BLKSECDISCARD = 0x2000127d
|
||||
BLKSECTGET = 0x20001267
|
||||
BLKSECTSET = 0x20001266
|
||||
BLKSSZGET = 0x20001268
|
||||
BLKZEROOUT = 0x2000127f
|
||||
BOTHER = 0x1000
|
||||
BS1 = 0x2000
|
||||
BSDLY = 0x2000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x1001
|
||||
B576000 = 0x1006
|
||||
B921600 = 0x1007
|
||||
BLKALIGNOFF = 0x2000127a
|
||||
BLKBSZGET = 0x40041270
|
||||
BLKBSZSET = 0x80041271
|
||||
BLKDISCARD = 0x20001277
|
||||
BLKDISCARDZEROES = 0x2000127c
|
||||
BLKFLSBUF = 0x20001261
|
||||
BLKFRAGET = 0x20001265
|
||||
BLKFRASET = 0x20001264
|
||||
BLKGETDISKSEQ = 0x40081280
|
||||
BLKGETSIZE = 0x20001260
|
||||
BLKGETSIZE64 = 0x40041272
|
||||
BLKIOMIN = 0x20001278
|
||||
BLKIOOPT = 0x20001279
|
||||
BLKPBSZGET = 0x2000127b
|
||||
BLKRAGET = 0x20001263
|
||||
BLKRASET = 0x20001262
|
||||
BLKROGET = 0x2000125e
|
||||
BLKROSET = 0x2000125d
|
||||
BLKROTATIONAL = 0x2000127e
|
||||
BLKRRPART = 0x2000125f
|
||||
BLKSECDISCARD = 0x2000127d
|
||||
BLKSECTGET = 0x20001267
|
||||
BLKSECTSET = 0x20001266
|
||||
BLKSSZGET = 0x20001268
|
||||
BLKZEROOUT = 0x2000127f
|
||||
BOTHER = 0x1000
|
||||
BS1 = 0x2000
|
||||
BSDLY = 0x2000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x10
|
||||
B576000 = 0x15
|
||||
B921600 = 0x16
|
||||
BLKALIGNOFF = 0x2000127a
|
||||
BLKBSZGET = 0x40041270
|
||||
BLKBSZSET = 0x80041271
|
||||
BLKDISCARD = 0x20001277
|
||||
BLKDISCARDZEROES = 0x2000127c
|
||||
BLKFLSBUF = 0x20001261
|
||||
BLKFRAGET = 0x20001265
|
||||
BLKFRASET = 0x20001264
|
||||
BLKGETDISKSEQ = 0x40081280
|
||||
BLKGETSIZE = 0x20001260
|
||||
BLKGETSIZE64 = 0x40041272
|
||||
BLKIOMIN = 0x20001278
|
||||
BLKIOOPT = 0x20001279
|
||||
BLKPBSZGET = 0x2000127b
|
||||
BLKRAGET = 0x20001263
|
||||
BLKRASET = 0x20001262
|
||||
BLKROGET = 0x2000125e
|
||||
BLKROSET = 0x2000125d
|
||||
BLKROTATIONAL = 0x2000127e
|
||||
BLKRRPART = 0x2000125f
|
||||
BLKSECDISCARD = 0x2000127d
|
||||
BLKSECTGET = 0x20001267
|
||||
BLKSECTSET = 0x20001266
|
||||
BLKSSZGET = 0x20001268
|
||||
BLKZEROOUT = 0x2000127f
|
||||
BOTHER = 0x1f
|
||||
BS1 = 0x8000
|
||||
BSDLY = 0x8000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x10
|
||||
B576000 = 0x15
|
||||
B921600 = 0x16
|
||||
BLKALIGNOFF = 0x2000127a
|
||||
BLKBSZGET = 0x40081270
|
||||
BLKBSZSET = 0x80081271
|
||||
BLKDISCARD = 0x20001277
|
||||
BLKDISCARDZEROES = 0x2000127c
|
||||
BLKFLSBUF = 0x20001261
|
||||
BLKFRAGET = 0x20001265
|
||||
BLKFRASET = 0x20001264
|
||||
BLKGETDISKSEQ = 0x40081280
|
||||
BLKGETSIZE = 0x20001260
|
||||
BLKGETSIZE64 = 0x40081272
|
||||
BLKIOMIN = 0x20001278
|
||||
BLKIOOPT = 0x20001279
|
||||
BLKPBSZGET = 0x2000127b
|
||||
BLKRAGET = 0x20001263
|
||||
BLKRASET = 0x20001262
|
||||
BLKROGET = 0x2000125e
|
||||
BLKROSET = 0x2000125d
|
||||
BLKROTATIONAL = 0x2000127e
|
||||
BLKRRPART = 0x2000125f
|
||||
BLKSECDISCARD = 0x2000127d
|
||||
BLKSECTGET = 0x20001267
|
||||
BLKSECTSET = 0x20001266
|
||||
BLKSSZGET = 0x20001268
|
||||
BLKZEROOUT = 0x2000127f
|
||||
BOTHER = 0x1f
|
||||
BS1 = 0x8000
|
||||
BSDLY = 0x8000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x10
|
||||
B576000 = 0x15
|
||||
B921600 = 0x16
|
||||
BLKALIGNOFF = 0x2000127a
|
||||
BLKBSZGET = 0x40081270
|
||||
BLKBSZSET = 0x80081271
|
||||
BLKDISCARD = 0x20001277
|
||||
BLKDISCARDZEROES = 0x2000127c
|
||||
BLKFLSBUF = 0x20001261
|
||||
BLKFRAGET = 0x20001265
|
||||
BLKFRASET = 0x20001264
|
||||
BLKGETDISKSEQ = 0x40081280
|
||||
BLKGETSIZE = 0x20001260
|
||||
BLKGETSIZE64 = 0x40081272
|
||||
BLKIOMIN = 0x20001278
|
||||
BLKIOOPT = 0x20001279
|
||||
BLKPBSZGET = 0x2000127b
|
||||
BLKRAGET = 0x20001263
|
||||
BLKRASET = 0x20001262
|
||||
BLKROGET = 0x2000125e
|
||||
BLKROSET = 0x2000125d
|
||||
BLKROTATIONAL = 0x2000127e
|
||||
BLKRRPART = 0x2000125f
|
||||
BLKSECDISCARD = 0x2000127d
|
||||
BLKSECTGET = 0x20001267
|
||||
BLKSECTSET = 0x20001266
|
||||
BLKSSZGET = 0x20001268
|
||||
BLKZEROOUT = 0x2000127f
|
||||
BOTHER = 0x1f
|
||||
BS1 = 0x8000
|
||||
BSDLY = 0x8000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x1001
|
||||
B576000 = 0x1006
|
||||
B921600 = 0x1007
|
||||
BLKALIGNOFF = 0x127a
|
||||
BLKBSZGET = 0x80081270
|
||||
BLKBSZSET = 0x40081271
|
||||
BLKDISCARD = 0x1277
|
||||
BLKDISCARDZEROES = 0x127c
|
||||
BLKFLSBUF = 0x1261
|
||||
BLKFRAGET = 0x1265
|
||||
BLKFRASET = 0x1264
|
||||
BLKGETDISKSEQ = 0x80081280
|
||||
BLKGETSIZE = 0x1260
|
||||
BLKGETSIZE64 = 0x80081272
|
||||
BLKIOMIN = 0x1278
|
||||
BLKIOOPT = 0x1279
|
||||
BLKPBSZGET = 0x127b
|
||||
BLKRAGET = 0x1263
|
||||
BLKRASET = 0x1262
|
||||
BLKROGET = 0x125e
|
||||
BLKROSET = 0x125d
|
||||
BLKROTATIONAL = 0x127e
|
||||
BLKRRPART = 0x125f
|
||||
BLKSECDISCARD = 0x127d
|
||||
BLKSECTGET = 0x1267
|
||||
BLKSECTSET = 0x1266
|
||||
BLKSSZGET = 0x1268
|
||||
BLKZEROOUT = 0x127f
|
||||
BOTHER = 0x1000
|
||||
BS1 = 0x2000
|
||||
BSDLY = 0x2000
|
||||
|
||||
+9
@@ -27,22 +27,31 @@ const (
|
||||
B57600 = 0x1001
|
||||
B576000 = 0x1006
|
||||
B921600 = 0x1007
|
||||
BLKALIGNOFF = 0x127a
|
||||
BLKBSZGET = 0x80081270
|
||||
BLKBSZSET = 0x40081271
|
||||
BLKDISCARD = 0x1277
|
||||
BLKDISCARDZEROES = 0x127c
|
||||
BLKFLSBUF = 0x1261
|
||||
BLKFRAGET = 0x1265
|
||||
BLKFRASET = 0x1264
|
||||
BLKGETDISKSEQ = 0x80081280
|
||||
BLKGETSIZE = 0x1260
|
||||
BLKGETSIZE64 = 0x80081272
|
||||
BLKIOMIN = 0x1278
|
||||
BLKIOOPT = 0x1279
|
||||
BLKPBSZGET = 0x127b
|
||||
BLKRAGET = 0x1263
|
||||
BLKRASET = 0x1262
|
||||
BLKROGET = 0x125e
|
||||
BLKROSET = 0x125d
|
||||
BLKROTATIONAL = 0x127e
|
||||
BLKRRPART = 0x125f
|
||||
BLKSECDISCARD = 0x127d
|
||||
BLKSECTGET = 0x1267
|
||||
BLKSECTSET = 0x1266
|
||||
BLKSSZGET = 0x1268
|
||||
BLKZEROOUT = 0x127f
|
||||
BOTHER = 0x1000
|
||||
BS1 = 0x2000
|
||||
BSDLY = 0x2000
|
||||
|
||||
+9
@@ -30,22 +30,31 @@ const (
|
||||
B57600 = 0x1001
|
||||
B576000 = 0x1006
|
||||
B921600 = 0x1007
|
||||
BLKALIGNOFF = 0x2000127a
|
||||
BLKBSZGET = 0x40081270
|
||||
BLKBSZSET = 0x80081271
|
||||
BLKDISCARD = 0x20001277
|
||||
BLKDISCARDZEROES = 0x2000127c
|
||||
BLKFLSBUF = 0x20001261
|
||||
BLKFRAGET = 0x20001265
|
||||
BLKFRASET = 0x20001264
|
||||
BLKGETDISKSEQ = 0x40081280
|
||||
BLKGETSIZE = 0x20001260
|
||||
BLKGETSIZE64 = 0x40081272
|
||||
BLKIOMIN = 0x20001278
|
||||
BLKIOOPT = 0x20001279
|
||||
BLKPBSZGET = 0x2000127b
|
||||
BLKRAGET = 0x20001263
|
||||
BLKRASET = 0x20001262
|
||||
BLKROGET = 0x2000125e
|
||||
BLKROSET = 0x2000125d
|
||||
BLKROTATIONAL = 0x2000127e
|
||||
BLKRRPART = 0x2000125f
|
||||
BLKSECDISCARD = 0x2000127d
|
||||
BLKSECTGET = 0x20001267
|
||||
BLKSECTSET = 0x20001266
|
||||
BLKSSZGET = 0x20001268
|
||||
BLKZEROOUT = 0x2000127f
|
||||
BOTHER = 0x1000
|
||||
BS1 = 0x2000
|
||||
BSDLY = 0x2000
|
||||
|
||||
+1
-1
@@ -1356,7 +1356,7 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
|
||||
func pselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_argpack) (n int, err error) {
|
||||
r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
|
||||
+16
@@ -531,3 +531,19 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func riscvHWProbe(pairs []RISCVHWProbePairs, cpuCount uintptr, cpus *CPUSet, flags uint) (err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(pairs) > 0 {
|
||||
_p0 = unsafe.Pointer(&pairs[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
_, _, e1 := Syscall6(SYS_RISCV_HWPROBE, uintptr(_p0), uintptr(len(pairs)), uintptr(cpuCount), uintptr(unsafe.Pointer(cpus)), uintptr(flags), 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
+11
@@ -1858,3 +1858,14 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) {
|
||||
r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldp), uintptr(oldsize), uintptr(newp), uintptr(newsize), uintptr(flags), 0)
|
||||
xaddr = uintptr(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
+11
@@ -1858,3 +1858,14 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) {
|
||||
r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldp), uintptr(oldsize), uintptr(newp), uintptr(newsize), uintptr(flags), 0)
|
||||
xaddr = uintptr(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
+11
@@ -1858,3 +1858,14 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) {
|
||||
r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldp), uintptr(oldsize), uintptr(newp), uintptr(newsize), uintptr(flags), 0)
|
||||
xaddr = uintptr(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
+11
@@ -1858,3 +1858,14 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) {
|
||||
r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldp), uintptr(oldsize), uintptr(newp), uintptr(newsize), uintptr(flags), 0)
|
||||
xaddr = uintptr(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
+2
@@ -251,6 +251,8 @@ const (
|
||||
SYS_ACCEPT4 = 242
|
||||
SYS_RECVMMSG = 243
|
||||
SYS_ARCH_SPECIFIC_SYSCALL = 244
|
||||
SYS_RISCV_HWPROBE = 258
|
||||
SYS_RISCV_FLUSH_ICACHE = 259
|
||||
SYS_WAIT4 = 260
|
||||
SYS_PRLIMIT64 = 261
|
||||
SYS_FANOTIFY_INIT = 262
|
||||
|
||||
+5
@@ -866,6 +866,11 @@ const (
|
||||
POLLNVAL = 0x20
|
||||
)
|
||||
|
||||
type sigset_argpack struct {
|
||||
ss *Sigset_t
|
||||
ssLen uintptr
|
||||
}
|
||||
|
||||
type SignalfdSiginfo struct {
|
||||
Signo uint32
|
||||
Errno int32
|
||||
|
||||
+23
@@ -718,3 +718,26 @@ type SysvShmDesc struct {
|
||||
_ uint64
|
||||
_ uint64
|
||||
}
|
||||
|
||||
type RISCVHWProbePairs struct {
|
||||
Key int64
|
||||
Value uint64
|
||||
}
|
||||
|
||||
const (
|
||||
RISCV_HWPROBE_KEY_MVENDORID = 0x0
|
||||
RISCV_HWPROBE_KEY_MARCHID = 0x1
|
||||
RISCV_HWPROBE_KEY_MIMPID = 0x2
|
||||
RISCV_HWPROBE_KEY_BASE_BEHAVIOR = 0x3
|
||||
RISCV_HWPROBE_BASE_BEHAVIOR_IMA = 0x1
|
||||
RISCV_HWPROBE_KEY_IMA_EXT_0 = 0x4
|
||||
RISCV_HWPROBE_IMA_FD = 0x1
|
||||
RISCV_HWPROBE_IMA_C = 0x2
|
||||
RISCV_HWPROBE_KEY_CPUPERF_0 = 0x5
|
||||
RISCV_HWPROBE_MISALIGNED_UNKNOWN = 0x0
|
||||
RISCV_HWPROBE_MISALIGNED_EMULATED = 0x1
|
||||
RISCV_HWPROBE_MISALIGNED_SLOW = 0x2
|
||||
RISCV_HWPROBE_MISALIGNED_FAST = 0x3
|
||||
RISCV_HWPROBE_MISALIGNED_UNSUPPORTED = 0x4
|
||||
RISCV_HWPROBE_MISALIGNED_MASK = 0x7
|
||||
)
|
||||
+2
-2
@@ -135,14 +135,14 @@ func Getpagesize() int { return 4096 }
|
||||
|
||||
// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention.
|
||||
// This is useful when interoperating with Windows code requiring callbacks.
|
||||
// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
|
||||
// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
|
||||
func NewCallback(fn interface{}) uintptr {
|
||||
return syscall.NewCallback(fn)
|
||||
}
|
||||
|
||||
// NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention.
|
||||
// This is useful when interoperating with Windows code requiring callbacks.
|
||||
// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
|
||||
// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
|
||||
func NewCallbackCDecl(fn interface{}) uintptr {
|
||||
return syscall.NewCallbackCDecl(fn)
|
||||
}
|
||||
|
||||
+2
-2
@@ -319,7 +319,7 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) {
|
||||
// Per https://pkg.go.dev/os#File.Close, the call to stdoutR.Close
|
||||
// should cause the Read call in io.Copy to unblock and return
|
||||
// immediately, but we still need to receive from stdoutErr to confirm
|
||||
// that that has happened.
|
||||
// that it has happened.
|
||||
<-stdoutErr
|
||||
err2 = ctx.Err()
|
||||
}
|
||||
@@ -333,7 +333,7 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) {
|
||||
// one goroutine at a time will call Write.”
|
||||
//
|
||||
// Since we're starting a goroutine that writes to cmd.Stdout, we must
|
||||
// also update cmd.Stderr so that that still holds.
|
||||
// also update cmd.Stderr so that it still holds.
|
||||
func() {
|
||||
defer func() { recover() }()
|
||||
if cmd.Stderr == prevStdout {
|
||||
|
||||
+13
-7
@@ -9,8 +9,6 @@ package gopathwalk
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -78,7 +76,7 @@ func walkDir(root Root, add func(Root, string), skip func(root Root, dir string)
|
||||
}
|
||||
start := time.Now()
|
||||
if opts.Logf != nil {
|
||||
opts.Logf("gopathwalk: scanning %s", root.Path)
|
||||
opts.Logf("scanning %s", root.Path)
|
||||
}
|
||||
w := &walker{
|
||||
root: root,
|
||||
@@ -88,11 +86,15 @@ func walkDir(root Root, add func(Root, string), skip func(root Root, dir string)
|
||||
}
|
||||
w.init()
|
||||
if err := fastwalk.Walk(root.Path, w.walk); err != nil {
|
||||
log.Printf("gopathwalk: scanning directory %v: %v", root.Path, err)
|
||||
logf := opts.Logf
|
||||
if logf == nil {
|
||||
logf = log.Printf
|
||||
}
|
||||
logf("scanning directory %v: %v", root.Path, err)
|
||||
}
|
||||
|
||||
if opts.Logf != nil {
|
||||
opts.Logf("gopathwalk: scanned %s in %v", root.Path, time.Since(start))
|
||||
opts.Logf("scanned %s in %v", root.Path, time.Since(start))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +137,7 @@ func (w *walker) init() {
|
||||
// The provided path is one of the $GOPATH entries with "src" appended.
|
||||
func (w *walker) getIgnoredDirs(path string) []string {
|
||||
file := filepath.Join(path, ".goimportsignore")
|
||||
slurp, err := ioutil.ReadFile(file)
|
||||
slurp, err := os.ReadFile(file)
|
||||
if w.opts.Logf != nil {
|
||||
if err != nil {
|
||||
w.opts.Logf("%v", err)
|
||||
@@ -222,7 +224,11 @@ func (w *walker) walk(path string, typ os.FileMode) error {
|
||||
func (w *walker) shouldTraverse(path string) bool {
|
||||
ts, err := os.Stat(path)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
logf := w.opts.Logf
|
||||
if logf == nil {
|
||||
logf = log.Printf
|
||||
}
|
||||
logf("%v", err)
|
||||
return false
|
||||
}
|
||||
if !ts.IsDir() {
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import (
|
||||
"golang.org/x/tools/internal/gopathwalk"
|
||||
)
|
||||
|
||||
// To find packages to import, the resolver needs to know about all of the
|
||||
// To find packages to import, the resolver needs to know about all of
|
||||
// the packages that could be imported. This includes packages that are
|
||||
// already in modules that are in (1) the current module, (2) replace targets,
|
||||
// and (3) packages in the module cache. Packages in (1) and (2) may change over
|
||||
|
||||
+6
@@ -23,6 +23,7 @@
|
||||
package typeparams
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
@@ -125,6 +126,11 @@ func OriginMethod(fn *types.Func) *types.Func {
|
||||
}
|
||||
}
|
||||
|
||||
// In golang/go#61196, we observe another crash, this time inexplicable.
|
||||
if gfn == nil {
|
||||
panic(fmt.Sprintf("missing origin method for %s.%s; named == origin: %t, named.NumMethods(): %d, origin.NumMethods(): %d", named, fn, named == orig, named.NumMethods(), orig.NumMethods()))
|
||||
}
|
||||
|
||||
return gfn.(*types.Func)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ func NamedTypeArgs(*types.Named) *TypeList {
|
||||
}
|
||||
|
||||
// NamedTypeOrigin is the identity method at this Go version.
|
||||
func NamedTypeOrigin(named *types.Named) types.Type {
|
||||
func NamedTypeOrigin(named *types.Named) *types.Named {
|
||||
return named
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ func NamedTypeArgs(named *types.Named) *TypeList {
|
||||
}
|
||||
|
||||
// NamedTypeOrigin returns named.Orig().
|
||||
func NamedTypeOrigin(named *types.Named) types.Type {
|
||||
func NamedTypeOrigin(named *types.Named) *types.Named {
|
||||
return named.Origin()
|
||||
}
|
||||
|
||||
|
||||
Vendored
+3
-3
@@ -11,7 +11,7 @@ github.com/google/pprof/profile
|
||||
# github.com/hashicorp/go-version v1.3.0
|
||||
## explicit
|
||||
github.com/hashicorp/go-version
|
||||
# github.com/onsi/ginkgo/v2 v2.11.0
|
||||
# github.com/onsi/ginkgo/v2 v2.12.0
|
||||
## explicit; go 1.18
|
||||
github.com/onsi/ginkgo/v2/config
|
||||
github.com/onsi/ginkgo/v2/formatter
|
||||
@@ -49,13 +49,13 @@ 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.10.0
|
||||
# golang.org/x/sys v0.11.0
|
||||
## explicit; go 1.17
|
||||
golang.org/x/sys/execabs
|
||||
golang.org/x/sys/internal/unsafeheader
|
||||
golang.org/x/sys/unix
|
||||
golang.org/x/sys/windows
|
||||
# golang.org/x/tools v0.11.0
|
||||
# golang.org/x/tools v0.12.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/tools/cmd/goimports
|
||||
golang.org/x/tools/go/ast/astutil
|
||||
|
||||
+14
@@ -1,3 +1,17 @@
|
||||
## 2.12.0
|
||||
|
||||
### Features
|
||||
|
||||
- feat: allow MustPassRepeatedly decorator to be set at suite level (#1266) [05de518]
|
||||
|
||||
### Fixes
|
||||
|
||||
- fix-errors-in-readme (#1244) [27c2f5d]
|
||||
|
||||
### Maintenance
|
||||
|
||||
Various chores/dependency bumps.
|
||||
|
||||
## 2.11.0
|
||||
|
||||
In prior versions of Ginkgo specs the CLI filter flags (e.g. `--focus`, `--label-filter`) would _override_ any programmatic focus. This behavior has proved surprising and confusing in at least the following ways:
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@ import (
|
||||
...
|
||||
)
|
||||
|
||||
Describe("Checking books out of the library", Label("library"), func() {
|
||||
var _ = Describe("Checking books out of the library", Label("library"), func() {
|
||||
var library *libraries.Library
|
||||
var book *books.Book
|
||||
var valjean *users.User
|
||||
@@ -50,7 +50,7 @@ Describe("Checking books out of the library", Label("library"), func() {
|
||||
|
||||
It("tells the user", func(ctx SpecContext) {
|
||||
err := valjean.Checkout(ctx, library, "Les Miserables")
|
||||
Expect(error).To(MatchError("Les Miserables is currently checked out"))
|
||||
Expect(err).To(MatchError("Les Miserables is currently checked out"))
|
||||
}, SpecTimeout(time.Second * 5))
|
||||
|
||||
It("lets the user place a hold and get notified later", func(ctx SpecContext) {
|
||||
@@ -74,7 +74,7 @@ Describe("Checking books out of the library", Label("library"), func() {
|
||||
When("the library does not have the book in question", func() {
|
||||
It("tells the reader the book is unavailable", func(ctx SpecContext) {
|
||||
err := valjean.Checkout(ctx, library, "Les Miserables")
|
||||
Expect(error).To(MatchError("Les Miserables is not in the library catalog"))
|
||||
Expect(err).To(MatchError("Les Miserables is not in the library catalog"))
|
||||
}, SpecTimeout(time.Second * 5))
|
||||
})
|
||||
})
|
||||
|
||||
+1
-3
@@ -244,9 +244,7 @@ func labelFromCallExpr(ce *ast.CallExpr) []string {
|
||||
}
|
||||
if id.Name == "Label" {
|
||||
ls := extractLabels(expr)
|
||||
for _, label := range ls {
|
||||
labels = append(labels, label)
|
||||
}
|
||||
labels = append(labels, ls...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -321,7 +321,10 @@ func (g *group) run(specs Specs) {
|
||||
if !skip {
|
||||
var maxAttempts = 1
|
||||
|
||||
if g.suite.currentSpecReport.MaxMustPassRepeatedly > 0 {
|
||||
if g.suite.config.MustPassRepeatedly > 0 {
|
||||
maxAttempts = g.suite.config.MustPassRepeatedly
|
||||
g.suite.currentSpecReport.MaxMustPassRepeatedly = maxAttempts
|
||||
} else if g.suite.currentSpecReport.MaxMustPassRepeatedly > 0 {
|
||||
maxAttempts = max(1, spec.MustPassRepeatedly())
|
||||
} else if g.suite.config.FlakeAttempts > 0 {
|
||||
maxAttempts = g.suite.config.FlakeAttempts
|
||||
|
||||
+1
-3
@@ -600,9 +600,7 @@ type Nodes []Node
|
||||
func (n Nodes) CopyAppend(nodes ...Node) Nodes {
|
||||
numN := len(n)
|
||||
out := make(Nodes, numN+len(nodes))
|
||||
for i, node := range n {
|
||||
out[i] = node
|
||||
}
|
||||
copy(out, n)
|
||||
for j, node := range nodes {
|
||||
out[numN+j] = node
|
||||
}
|
||||
|
||||
+1
@@ -27,6 +27,7 @@ type SuiteConfig struct {
|
||||
FailOnPending bool
|
||||
FailFast bool
|
||||
FlakeAttempts int
|
||||
MustPassRepeatedly int
|
||||
DryRun bool
|
||||
PollProgressAfter time.Duration
|
||||
PollProgressInterval time.Duration
|
||||
|
||||
+2
-2
@@ -453,8 +453,8 @@ func (g ginkgoErrors) InvalidEntryDescription(cl CodeLocation) error {
|
||||
|
||||
func (g ginkgoErrors) MissingParametersForTableFunction(cl CodeLocation) error {
|
||||
return GinkgoError{
|
||||
Heading: fmt.Sprintf("No parameters have been passed to the Table Function"),
|
||||
Message: fmt.Sprintf("The Table Function expected at least 1 parameter"),
|
||||
Heading: "No parameters have been passed to the Table Function",
|
||||
Message: "The Table Function expected at least 1 parameter",
|
||||
CodeLocation: cl,
|
||||
DocLink: "table-specs",
|
||||
}
|
||||
|
||||
+1
-3
@@ -97,9 +97,7 @@ func (report Report) Add(other Report) Report {
|
||||
report.RunTime = report.EndTime.Sub(report.StartTime)
|
||||
|
||||
reports := make(SpecReports, len(report.SpecReports)+len(other.SpecReports))
|
||||
for i := range report.SpecReports {
|
||||
reports[i] = report.SpecReports[i]
|
||||
}
|
||||
copy(reports, report.SpecReports)
|
||||
offset := len(report.SpecReports)
|
||||
for i := range other.SpecReports {
|
||||
reports[i+offset] = other.SpecReports[i]
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
package types
|
||||
|
||||
const VERSION = "2.11.0"
|
||||
const VERSION = "2.12.0"
|
||||
+3
-3
@@ -140,7 +140,7 @@ func Compare(v, w string) int {
|
||||
// Max canonicalizes its arguments and then returns the version string
|
||||
// that compares greater.
|
||||
//
|
||||
// Deprecated: use Compare instead. In most cases, returning a canonicalized
|
||||
// Deprecated: use [Compare] instead. In most cases, returning a canonicalized
|
||||
// version is not expected or desired.
|
||||
func Max(v, w string) string {
|
||||
v = Canonical(v)
|
||||
@@ -151,7 +151,7 @@ func Max(v, w string) string {
|
||||
return w
|
||||
}
|
||||
|
||||
// ByVersion implements sort.Interface for sorting semantic version strings.
|
||||
// ByVersion implements [sort.Interface] for sorting semantic version strings.
|
||||
type ByVersion []string
|
||||
|
||||
func (vs ByVersion) Len() int { return len(vs) }
|
||||
@@ -164,7 +164,7 @@ func (vs ByVersion) Less(i, j int) bool {
|
||||
return vs[i] < vs[j]
|
||||
}
|
||||
|
||||
// Sort sorts a list of semantic version strings using ByVersion.
|
||||
// Sort sorts a list of semantic version strings using [ByVersion].
|
||||
func Sort(list []string) {
|
||||
sort.Sort(ByVersion(list))
|
||||
}
|
||||
|
||||
+19
-19
@@ -20,45 +20,45 @@
|
||||
//
|
||||
// # Verifying Notes
|
||||
//
|
||||
// A Verifier allows verification of signatures by one server public key.
|
||||
// A [Verifier] allows verification of signatures by one server public key.
|
||||
// It can report the name of the server and the uint32 hash of the key,
|
||||
// and it can verify a purported signature by that key.
|
||||
//
|
||||
// The standard implementation of a Verifier is constructed
|
||||
// by NewVerifier starting from a verifier key, which is a
|
||||
// by [NewVerifier] starting from a verifier key, which is a
|
||||
// plain text string of the form "<name>+<hash>+<keydata>".
|
||||
//
|
||||
// A Verifiers allows looking up a Verifier by the combination
|
||||
// A [Verifiers] allows looking up a Verifier by the combination
|
||||
// of server name and key hash.
|
||||
//
|
||||
// The standard implementation of a Verifiers is constructed
|
||||
// by VerifierList from a list of known verifiers.
|
||||
//
|
||||
// A Note represents a text with one or more signatures.
|
||||
// A [Note] represents a text with one or more signatures.
|
||||
// An implementation can reject a note with too many signatures
|
||||
// (for example, more than 100 signatures).
|
||||
//
|
||||
// A Signature represents a signature on a note, verified or not.
|
||||
// A [Signature] represents a signature on a note, verified or not.
|
||||
//
|
||||
// The Open function takes as input a signed message
|
||||
// The [Open] function takes as input a signed message
|
||||
// and a set of known verifiers. It decodes and verifies
|
||||
// the message signatures and returns a Note structure
|
||||
// the message signatures and returns a [Note] structure
|
||||
// containing the message text and (verified or unverified) signatures.
|
||||
//
|
||||
// # Signing Notes
|
||||
//
|
||||
// A Signer allows signing a text with a given key.
|
||||
// A [Signer] allows signing a text with a given key.
|
||||
// It can report the name of the server and the hash of the key
|
||||
// and can sign a raw text using that key.
|
||||
//
|
||||
// The standard implementation of a Signer is constructed
|
||||
// by NewSigner starting from an encoded signer key, which is a
|
||||
// by [NewSigner] starting from an encoded signer key, which is a
|
||||
// plain text string of the form "PRIVATE+KEY+<name>+<hash>+<keydata>".
|
||||
// Anyone with an encoded signer key can sign messages using that key,
|
||||
// so it must be kept secret. The encoding begins with the literal text
|
||||
// "PRIVATE+KEY" to avoid confusion with the public server key.
|
||||
//
|
||||
// The Sign function takes as input a Note and a list of Signers
|
||||
// The [Sign] function takes as input a Note and a list of Signers
|
||||
// and returns an encoded, signed message.
|
||||
//
|
||||
// # Signed Note Format
|
||||
@@ -88,7 +88,7 @@
|
||||
// although doing so will require deploying the new algorithms to all clients
|
||||
// before starting to depend on them for signatures.
|
||||
//
|
||||
// The GenerateKey function generates and returns a new signer
|
||||
// The [GenerateKey] function generates and returns a new signer
|
||||
// and corresponding verifier.
|
||||
//
|
||||
// # Example
|
||||
@@ -123,9 +123,9 @@
|
||||
// base URLs, the only syntactic requirement is that they
|
||||
// not contain spaces or newlines).
|
||||
//
|
||||
// If Open is given access to a Verifiers including the
|
||||
// Verifier for this key, then it will succeed at verifying
|
||||
// the encoded message and returning the parsed Note:
|
||||
// If [Open] is given access to a [Verifiers] including the
|
||||
// [Verifier] for this key, then it will succeed at verifying
|
||||
// the encoded message and returning the parsed [Note]:
|
||||
//
|
||||
// vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
|
||||
// msg := []byte("If you think cryptography is the answer to your problem,\n" +
|
||||
@@ -238,7 +238,7 @@ func isValidName(name string) bool {
|
||||
return name != "" && utf8.ValidString(name) && strings.IndexFunc(name, unicode.IsSpace) < 0 && !strings.Contains(name, "+")
|
||||
}
|
||||
|
||||
// NewVerifier construct a new Verifier from an encoded verifier key.
|
||||
// NewVerifier construct a new [Verifier] from an encoded verifier key.
|
||||
func NewVerifier(vkey string) (Verifier, error) {
|
||||
name, vkey := chop(vkey, "+")
|
||||
hash16, key64 := chop(vkey, "+")
|
||||
@@ -295,7 +295,7 @@ func (v *verifier) Name() string { return v.name }
|
||||
func (v *verifier) KeyHash() uint32 { return v.hash }
|
||||
func (v *verifier) Verify(msg, sig []byte) bool { return v.verify(msg, sig) }
|
||||
|
||||
// NewSigner constructs a new Signer from an encoded signer key.
|
||||
// NewSigner constructs a new [Signer] from an encoded signer key.
|
||||
func NewSigner(skey string) (Signer, error) {
|
||||
priv1, skey := chop(skey, "+")
|
||||
priv2, skey := chop(skey, "+")
|
||||
@@ -409,7 +409,7 @@ func (e *UnknownVerifierError) Error() string {
|
||||
}
|
||||
|
||||
// An ambiguousVerifierError indicates that the given name and hash
|
||||
// match multiple keys passed to VerifierList.
|
||||
// match multiple keys passed to [VerifierList].
|
||||
// (If this happens, some malicious actor has taken control of the
|
||||
// verifier list, at which point we may as well give up entirely,
|
||||
// but we diagnose the problem instead.)
|
||||
@@ -422,7 +422,7 @@ func (e *ambiguousVerifierError) Error() string {
|
||||
return fmt.Sprintf("ambiguous key %s+%08x", e.name, e.hash)
|
||||
}
|
||||
|
||||
// VerifierList returns a Verifiers implementation that uses the given list of verifiers.
|
||||
// VerifierList returns a [Verifiers] implementation that uses the given list of verifiers.
|
||||
func VerifierList(list ...Verifier) Verifiers {
|
||||
m := make(verifierMap)
|
||||
for _, v := range list {
|
||||
@@ -510,7 +510,7 @@ var (
|
||||
// If known.Verifier returns any other error, Open returns that error.
|
||||
//
|
||||
// If no known verifier has signed an otherwise valid note,
|
||||
// Open returns an UnverifiedNoteError.
|
||||
// Open returns an [UnverifiedNoteError].
|
||||
// In this case, the unverified note can be fetched from inside the error.
|
||||
func Open(msg []byte, known Verifiers) (*Note, error) {
|
||||
if known == nil {
|
||||
|
||||
+3
-1
@@ -64,8 +64,9 @@ type event struct {
|
||||
// depth-first order. It calls f(n) for each node n before it visits
|
||||
// n's children.
|
||||
//
|
||||
// The complete traversal sequence is determined by ast.Inspect.
|
||||
// The types argument, if non-empty, enables type-based filtering of
|
||||
// events. The function f if is called only for nodes whose type
|
||||
// events. The function f is called only for nodes whose type
|
||||
// matches an element of the types slice.
|
||||
func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) {
|
||||
// Because it avoids postorder calls to f, and the pruning
|
||||
@@ -97,6 +98,7 @@ func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) {
|
||||
// of the non-nil children of the node, followed by a call of
|
||||
// f(n, false).
|
||||
//
|
||||
// The complete traversal sequence is determined by ast.Inspect.
|
||||
// The types argument, if non-empty, enables type-based filtering of
|
||||
// events. The function f if is called only for nodes whose type
|
||||
// matches an element of the types slice.
|
||||
|
||||
+3
@@ -671,6 +671,9 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse
|
||||
// Temporary work-around for golang/go#39986. Parse filenames out of
|
||||
// error messages. This happens if there are unrecoverable syntax
|
||||
// errors in the source, so we can't match on a specific error message.
|
||||
//
|
||||
// TODO(rfindley): remove this heuristic, in favor of considering
|
||||
// InvalidGoFiles from the list driver.
|
||||
if err := p.Error; err != nil && state.shouldAddFilenameFromError(p) {
|
||||
addFilenameFromPos := func(pos string) bool {
|
||||
split := strings.Split(pos, ":")
|
||||
|
||||
+4
-1
@@ -630,7 +630,7 @@ func newLoader(cfg *Config) *loader {
|
||||
return ld
|
||||
}
|
||||
|
||||
// refine connects the supplied packages into a graph and then adds type and
|
||||
// refine connects the supplied packages into a graph and then adds type
|
||||
// and syntax information as requested by the LoadMode.
|
||||
func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
|
||||
roots := response.Roots
|
||||
@@ -1043,6 +1043,9 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||
Error: appendError,
|
||||
Sizes: ld.sizes,
|
||||
}
|
||||
if lpkg.Module != nil && lpkg.Module.GoVersion != "" {
|
||||
typesinternal.SetGoVersion(tc, "go"+lpkg.Module.GoVersion)
|
||||
}
|
||||
if (ld.Mode & typecheckCgo) != 0 {
|
||||
if !typesinternal.SetUsesCgo(tc) {
|
||||
appendError(Error{
|
||||
|
||||
+824
@@ -0,0 +1,824 @@
|
||||
// Copyright 2018 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 objectpath defines a naming scheme for types.Objects
|
||||
// (that is, named entities in Go programs) relative to their enclosing
|
||||
// package.
|
||||
//
|
||||
// Type-checker objects are canonical, so they are usually identified by
|
||||
// their address in memory (a pointer), but a pointer has meaning only
|
||||
// within one address space. By contrast, objectpath names allow the
|
||||
// identity of an object to be sent from one program to another,
|
||||
// establishing a correspondence between types.Object variables that are
|
||||
// distinct but logically equivalent.
|
||||
//
|
||||
// A single object may have multiple paths. In this example,
|
||||
//
|
||||
// type A struct{ X int }
|
||||
// type B A
|
||||
//
|
||||
// the field X has two paths due to its membership of both A and B.
|
||||
// The For(obj) function always returns one of these paths, arbitrarily
|
||||
// but consistently.
|
||||
package objectpath
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/types"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
_ "unsafe"
|
||||
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
// A Path is an opaque name that identifies a types.Object
|
||||
// relative to its package. Conceptually, the name consists of a
|
||||
// sequence of destructuring operations applied to the package scope
|
||||
// to obtain the original object.
|
||||
// The name does not include the package itself.
|
||||
type Path string
|
||||
|
||||
// Encoding
|
||||
//
|
||||
// An object path is a textual and (with training) human-readable encoding
|
||||
// of a sequence of destructuring operators, starting from a types.Package.
|
||||
// The sequences represent a path through the package/object/type graph.
|
||||
// We classify these operators by their type:
|
||||
//
|
||||
// PO package->object Package.Scope.Lookup
|
||||
// OT object->type Object.Type
|
||||
// TT type->type Type.{Elem,Key,Params,Results,Underlying} [EKPRU]
|
||||
// TO type->object Type.{At,Field,Method,Obj} [AFMO]
|
||||
//
|
||||
// All valid paths start with a package and end at an object
|
||||
// and thus may be defined by the regular language:
|
||||
//
|
||||
// objectpath = PO (OT TT* TO)*
|
||||
//
|
||||
// The concrete encoding follows directly:
|
||||
// - The only PO operator is Package.Scope.Lookup, which requires an identifier.
|
||||
// - The only OT operator is Object.Type,
|
||||
// which we encode as '.' because dot cannot appear in an identifier.
|
||||
// - The TT operators are encoded as [EKPRUTC];
|
||||
// one of these (TypeParam) requires an integer operand,
|
||||
// which is encoded as a string of decimal digits.
|
||||
// - The TO operators are encoded as [AFMO];
|
||||
// three of these (At,Field,Method) require an integer operand,
|
||||
// which is encoded as a string of decimal digits.
|
||||
// These indices are stable across different representations
|
||||
// of the same package, even source and export data.
|
||||
// The indices used are implementation specific and may not correspond to
|
||||
// the argument to the go/types function.
|
||||
//
|
||||
// In the example below,
|
||||
//
|
||||
// package p
|
||||
//
|
||||
// type T interface {
|
||||
// f() (a string, b struct{ X int })
|
||||
// }
|
||||
//
|
||||
// field X has the path "T.UM0.RA1.F0",
|
||||
// representing the following sequence of operations:
|
||||
//
|
||||
// p.Lookup("T") T
|
||||
// .Type().Underlying().Method(0). f
|
||||
// .Type().Results().At(1) b
|
||||
// .Type().Field(0) X
|
||||
//
|
||||
// The encoding is not maximally compact---every R or P is
|
||||
// followed by an A, for example---but this simplifies the
|
||||
// encoder and decoder.
|
||||
const (
|
||||
// object->type operators
|
||||
opType = '.' // .Type() (Object)
|
||||
|
||||
// type->type operators
|
||||
opElem = 'E' // .Elem() (Pointer, Slice, Array, Chan, Map)
|
||||
opKey = 'K' // .Key() (Map)
|
||||
opParams = 'P' // .Params() (Signature)
|
||||
opResults = 'R' // .Results() (Signature)
|
||||
opUnderlying = 'U' // .Underlying() (Named)
|
||||
opTypeParam = 'T' // .TypeParams.At(i) (Named, Signature)
|
||||
opConstraint = 'C' // .Constraint() (TypeParam)
|
||||
|
||||
// type->object operators
|
||||
opAt = 'A' // .At(i) (Tuple)
|
||||
opField = 'F' // .Field(i) (Struct)
|
||||
opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored)
|
||||
opObj = 'O' // .Obj() (Named, TypeParam)
|
||||
)
|
||||
|
||||
// For is equivalent to new(Encoder).For(obj).
|
||||
//
|
||||
// It may be more efficient to reuse a single Encoder across several calls.
|
||||
func For(obj types.Object) (Path, error) {
|
||||
return new(Encoder).For(obj)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// Exposed to gopls via golang.org/x/tools/internal/typesinternal
|
||||
// TODO(golang/go#61443): eliminate this parameter one way or the other.
|
||||
//
|
||||
//go:linkname skipMethodSorting
|
||||
func skipMethodSorting(enc *Encoder) {
|
||||
enc.skipMethodSorting = true
|
||||
}
|
||||
|
||||
// For returns the path to an object relative to its package,
|
||||
// or an error if the object is not accessible from the package's Scope.
|
||||
//
|
||||
// The For function guarantees to return a path only for the following objects:
|
||||
// - package-level types
|
||||
// - exported package-level non-types
|
||||
// - methods
|
||||
// - parameter and result variables
|
||||
// - struct fields
|
||||
// These objects are sufficient to define the API of their package.
|
||||
// The objects described by a package's export data are drawn from this set.
|
||||
//
|
||||
// The set of objects accessible from a package's Scope depends on
|
||||
// whether the package was produced by type-checking syntax, or
|
||||
// reading export data; the latter may have a smaller Scope since
|
||||
// export data trims objects that are not reachable from an exported
|
||||
// declaration. For example, the For function will return a path for
|
||||
// an exported method of an unexported type that is not reachable
|
||||
// from any public declaration; this path will cause the Object
|
||||
// function to fail if called on a package loaded from export data.
|
||||
// TODO(adonovan): is this a bug or feature? Should this package
|
||||
// compute accessibility in the same way?
|
||||
//
|
||||
// For does not return a path for predeclared names, imported package
|
||||
// names, local names, and unexported package-level names (except
|
||||
// types).
|
||||
//
|
||||
// Example: given this definition,
|
||||
//
|
||||
// package p
|
||||
//
|
||||
// type T interface {
|
||||
// f() (a string, b struct{ X int })
|
||||
// }
|
||||
//
|
||||
// For(X) would return a path that denotes the following sequence of operations:
|
||||
//
|
||||
// p.Scope().Lookup("T") (TypeName T)
|
||||
// .Type().Underlying().Method(0). (method Func f)
|
||||
// .Type().Results().At(1) (field Var b)
|
||||
// .Type().Field(0) (field Var X)
|
||||
//
|
||||
// where p is the package (*types.Package) to which X belongs.
|
||||
func (enc *Encoder) For(obj types.Object) (Path, error) {
|
||||
pkg := obj.Pkg()
|
||||
|
||||
// This table lists the cases of interest.
|
||||
//
|
||||
// Object Action
|
||||
// ------ ------
|
||||
// nil reject
|
||||
// builtin reject
|
||||
// pkgname reject
|
||||
// label reject
|
||||
// var
|
||||
// package-level accept
|
||||
// func param/result accept
|
||||
// local reject
|
||||
// struct field accept
|
||||
// const
|
||||
// package-level accept
|
||||
// local reject
|
||||
// func
|
||||
// package-level accept
|
||||
// init functions reject
|
||||
// concrete method accept
|
||||
// interface method accept
|
||||
// type
|
||||
// package-level accept
|
||||
// local reject
|
||||
//
|
||||
// The only accessible package-level objects are members of pkg itself.
|
||||
//
|
||||
// The cases are handled in four steps:
|
||||
//
|
||||
// 1. reject nil and builtin
|
||||
// 2. accept package-level objects
|
||||
// 3. reject obviously invalid objects
|
||||
// 4. search the API for the path to the param/result/field/method.
|
||||
|
||||
// 1. reference to nil or builtin?
|
||||
if pkg == nil {
|
||||
return "", fmt.Errorf("predeclared %s has no path", obj)
|
||||
}
|
||||
scope := pkg.Scope()
|
||||
|
||||
// 2. package-level object?
|
||||
if scope.Lookup(obj.Name()) == obj {
|
||||
// Only exported objects (and non-exported types) have a path.
|
||||
// Non-exported types may be referenced by other objects.
|
||||
if _, ok := obj.(*types.TypeName); !ok && !obj.Exported() {
|
||||
return "", fmt.Errorf("no path for non-exported %v", obj)
|
||||
}
|
||||
return Path(obj.Name()), nil
|
||||
}
|
||||
|
||||
// 3. Not a package-level object.
|
||||
// Reject obviously non-viable cases.
|
||||
switch obj := obj.(type) {
|
||||
case *types.TypeName:
|
||||
if _, ok := obj.Type().(*typeparams.TypeParam); !ok {
|
||||
// With the exception of type parameters, only package-level type names
|
||||
// have a path.
|
||||
return "", fmt.Errorf("no path for %v", obj)
|
||||
}
|
||||
case *types.Const, // Only package-level constants have a path.
|
||||
*types.Label, // Labels are function-local.
|
||||
*types.PkgName: // PkgNames are file-local.
|
||||
return "", fmt.Errorf("no path for %v", obj)
|
||||
|
||||
case *types.Var:
|
||||
// Could be:
|
||||
// - a field (obj.IsField())
|
||||
// - a func parameter or result
|
||||
// - a local var.
|
||||
// Sadly there is no way to distinguish
|
||||
// a param/result from a local
|
||||
// so we must proceed to the find.
|
||||
|
||||
case *types.Func:
|
||||
// A func, if not package-level, must be a method.
|
||||
if recv := obj.Type().(*types.Signature).Recv(); recv == nil {
|
||||
return "", fmt.Errorf("func is not a method: %v", obj)
|
||||
}
|
||||
|
||||
if path, ok := enc.concreteMethod(obj); ok {
|
||||
// Fast path for concrete methods that avoids looping over scope.
|
||||
return path, nil
|
||||
}
|
||||
|
||||
default:
|
||||
panic(obj)
|
||||
}
|
||||
|
||||
// 4. Search the API for the path to the var (field/param/result) or method.
|
||||
|
||||
// First inspect package-level named types.
|
||||
// In the presence of path aliases, these give
|
||||
// the best paths because non-types may
|
||||
// refer to types, but not the reverse.
|
||||
empty := make([]byte, 0, 48) // initial space
|
||||
objs := enc.scopeObjects(scope)
|
||||
for _, o := range objs {
|
||||
tname, ok := o.(*types.TypeName)
|
||||
if !ok {
|
||||
continue // handle non-types in second pass
|
||||
}
|
||||
|
||||
path := append(empty, o.Name()...)
|
||||
path = append(path, opType)
|
||||
|
||||
T := o.Type()
|
||||
|
||||
if tname.IsAlias() {
|
||||
// type alias
|
||||
if r := find(obj, T, path, nil); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
} else {
|
||||
if named, _ := T.(*types.Named); named != nil {
|
||||
if r := findTypeParam(obj, typeparams.ForNamed(named), path, nil); r != nil {
|
||||
// generic named type
|
||||
return Path(r), nil
|
||||
}
|
||||
}
|
||||
// defined (named) type
|
||||
if r := find(obj, T.Underlying(), append(path, opUnderlying), nil); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Then inspect everything else:
|
||||
// non-types, and declared methods of defined types.
|
||||
for _, o := range objs {
|
||||
path := append(empty, o.Name()...)
|
||||
if _, ok := o.(*types.TypeName); !ok {
|
||||
if o.Exported() {
|
||||
// exported non-type (const, var, func)
|
||||
if r := find(obj, o.Type(), append(path, opType), nil); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
} 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("can't find path for %v in %s", obj, pkg.Path())
|
||||
}
|
||||
|
||||
func appendOpArg(path []byte, op byte, arg int) []byte {
|
||||
path = append(path, op)
|
||||
path = strconv.AppendInt(path, int64(arg), 10)
|
||||
return path
|
||||
}
|
||||
|
||||
// concreteMethod returns the path for meth, which must have a non-nil receiver.
|
||||
// The second return value indicates success and may be false if the method is
|
||||
// an interface method or if it is an instantiated method.
|
||||
//
|
||||
// This function is just an optimization that avoids the general scope walking
|
||||
// approach. You are expected to fall back to the general approach if this
|
||||
// function fails.
|
||||
func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
|
||||
// Concrete methods can only be declared on package-scoped named types. For
|
||||
// that reason we can skip the expensive walk over the package scope: the
|
||||
// path will always be package -> named type -> method. We can trivially get
|
||||
// the type name from the receiver, and only have to look over the type's
|
||||
// methods to find the method index.
|
||||
//
|
||||
// Methods on generic types require special consideration, however. Consider
|
||||
// the following package:
|
||||
//
|
||||
// L1: type S[T any] struct{}
|
||||
// L2: func (recv S[A]) Foo() { recv.Bar() }
|
||||
// L3: func (recv S[B]) Bar() { }
|
||||
// L4: type Alias = S[int]
|
||||
// L5: func _[T any]() { var s S[int]; s.Foo() }
|
||||
//
|
||||
// The receivers of methods on generic types are instantiations. L2 and L3
|
||||
// instantiate S with the type-parameters A and B, which are scoped to the
|
||||
// respective methods. L4 and L5 each instantiate S with int. Each of these
|
||||
// instantiations has its own method set, full of methods (and thus objects)
|
||||
// with receivers whose types are the respective instantiations. In other
|
||||
// words, we have
|
||||
//
|
||||
// S[A].Foo, S[A].Bar
|
||||
// S[B].Foo, S[B].Bar
|
||||
// S[int].Foo, S[int].Bar
|
||||
//
|
||||
// We may thus be trying to produce object paths for any of these objects.
|
||||
//
|
||||
// S[A].Foo and S[B].Bar are the origin methods, and their paths are S.Foo
|
||||
// and S.Bar, which are the paths that this function naturally produces.
|
||||
//
|
||||
// S[A].Bar, S[B].Foo, and both methods on S[int] are instantiations that
|
||||
// don't correspond to the origin methods. For S[int], this is significant.
|
||||
// The most precise object path for S[int].Foo, for example, is Alias.Foo,
|
||||
// not S.Foo. Our function, however, would produce S.Foo, which would
|
||||
// resolve to a different object.
|
||||
//
|
||||
// For S[A].Bar and S[B].Foo it could be argued that S.Bar and S.Foo are
|
||||
// still the correct paths, since only the origin methods have meaningful
|
||||
// paths. But this is likely only true for trivial cases and has edge cases.
|
||||
// Since this function is only an optimization, we err on the side of giving
|
||||
// up, deferring to the slower but definitely correct algorithm. Most users
|
||||
// of objectpath will only be giving us origin methods, anyway, as referring
|
||||
// to instantiated methods is usually not useful.
|
||||
|
||||
if typeparams.OriginMethod(meth) != meth {
|
||||
return "", false
|
||||
}
|
||||
|
||||
recvT := meth.Type().(*types.Signature).Recv().Type()
|
||||
if ptr, ok := recvT.(*types.Pointer); ok {
|
||||
recvT = ptr.Elem()
|
||||
}
|
||||
|
||||
named, ok := recvT.(*types.Named)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
|
||||
if types.IsInterface(named) {
|
||||
// Named interfaces don't have to be package-scoped
|
||||
//
|
||||
// TODO(dominikh): opt: if scope.Lookup(name) == named, then we can apply this optimization to interface
|
||||
// methods, too, I think.
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Preallocate space for the name, opType, opMethod, and some digits.
|
||||
name := named.Obj().Name()
|
||||
path := make([]byte, 0, len(name)+8)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Due to golang/go#59944, go/types fails to associate the receiver with
|
||||
// certain methods on cgo types.
|
||||
//
|
||||
// TODO(rfindley): replace this panic once golang/go#59944 is fixed in all Go
|
||||
// versions gopls supports.
|
||||
return "", false
|
||||
// panic(fmt.Sprintf("couldn't find method %s on type %s; methods: %#v", meth, named, enc.namedMethods(named)))
|
||||
}
|
||||
|
||||
// find finds obj within type T, returning the path to it, or nil if not found.
|
||||
//
|
||||
// The seen map is used to short circuit cycles through type parameters. If
|
||||
// nil, it will be allocated as necessary.
|
||||
func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]bool) []byte {
|
||||
switch T := T.(type) {
|
||||
case *types.Basic, *types.Named:
|
||||
// Named types belonging to pkg were handled already,
|
||||
// so T must belong to another package. No path.
|
||||
return nil
|
||||
case *types.Pointer:
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
case *types.Slice:
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
case *types.Array:
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
case *types.Chan:
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
case *types.Map:
|
||||
if r := find(obj, T.Key(), append(path, opKey), seen); r != nil {
|
||||
return r
|
||||
}
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
case *types.Signature:
|
||||
if r := findTypeParam(obj, typeparams.ForSignature(T), path, seen); r != nil {
|
||||
return r
|
||||
}
|
||||
if r := find(obj, T.Params(), append(path, opParams), seen); r != nil {
|
||||
return r
|
||||
}
|
||||
return find(obj, T.Results(), append(path, opResults), seen)
|
||||
case *types.Struct:
|
||||
for i := 0; i < T.NumFields(); i++ {
|
||||
fld := T.Field(i)
|
||||
path2 := appendOpArg(path, opField, i)
|
||||
if fld == obj {
|
||||
return path2 // found field var
|
||||
}
|
||||
if r := find(obj, fld.Type(), append(path2, opType), seen); r != nil {
|
||||
return r
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case *types.Tuple:
|
||||
for i := 0; i < T.Len(); i++ {
|
||||
v := T.At(i)
|
||||
path2 := appendOpArg(path, opAt, i)
|
||||
if v == obj {
|
||||
return path2 // found param/result var
|
||||
}
|
||||
if r := find(obj, v.Type(), append(path2, opType), seen); r != nil {
|
||||
return r
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case *types.Interface:
|
||||
for i := 0; i < T.NumMethods(); i++ {
|
||||
m := T.Method(i)
|
||||
path2 := appendOpArg(path, opMethod, i)
|
||||
if m == obj {
|
||||
return path2 // found interface method
|
||||
}
|
||||
if r := find(obj, m.Type(), append(path2, opType), seen); r != nil {
|
||||
return r
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case *typeparams.TypeParam:
|
||||
name := T.Obj()
|
||||
if name == obj {
|
||||
return append(path, opObj)
|
||||
}
|
||||
if seen[name] {
|
||||
return nil
|
||||
}
|
||||
if seen == nil {
|
||||
seen = make(map[*types.TypeName]bool)
|
||||
}
|
||||
seen[name] = true
|
||||
if r := find(obj, T.Constraint(), append(path, opConstraint), seen); r != nil {
|
||||
return r
|
||||
}
|
||||
return nil
|
||||
}
|
||||
panic(T)
|
||||
}
|
||||
|
||||
func findTypeParam(obj types.Object, list *typeparams.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)
|
||||
if r := find(obj, tparam, path2, seen); r != nil {
|
||||
return r
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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, p, false)
|
||||
}
|
||||
|
||||
// Note: the skipMethodSorting parameter must match the value of
|
||||
// Encoder.skipMethodSorting used during encoding.
|
||||
func object(pkg *types.Package, p Path, skipMethodSorting bool) (types.Object, error) {
|
||||
if p == "" {
|
||||
return nil, fmt.Errorf("empty path")
|
||||
}
|
||||
|
||||
pathstr := string(p)
|
||||
var pkgobj, suffix string
|
||||
if dot := strings.IndexByte(pathstr, opType); dot < 0 {
|
||||
pkgobj = pathstr
|
||||
} else {
|
||||
pkgobj = pathstr[:dot]
|
||||
suffix = pathstr[dot:] // suffix starts with "."
|
||||
}
|
||||
|
||||
obj := pkg.Scope().Lookup(pkgobj)
|
||||
if obj == nil {
|
||||
return nil, fmt.Errorf("package %s does not contain %q", pkg.Path(), pkgobj)
|
||||
}
|
||||
|
||||
// abstraction of *types.{Pointer,Slice,Array,Chan,Map}
|
||||
type hasElem interface {
|
||||
Elem() types.Type
|
||||
}
|
||||
// abstraction of *types.{Named,Signature}
|
||||
type hasTypeParams interface {
|
||||
TypeParams() *typeparams.TypeParamList
|
||||
}
|
||||
// abstraction of *types.{Named,TypeParam}
|
||||
type hasObj interface {
|
||||
Obj() *types.TypeName
|
||||
}
|
||||
|
||||
// The loop state is the pair (t, obj),
|
||||
// exactly one of which is non-nil, initially obj.
|
||||
// All suffixes start with '.' (the only object->type operation),
|
||||
// followed by optional type->type operations,
|
||||
// then a type->object operation.
|
||||
// The cycle then repeats.
|
||||
var t types.Type
|
||||
for suffix != "" {
|
||||
code := suffix[0]
|
||||
suffix = suffix[1:]
|
||||
|
||||
// Codes [AFM] have an integer operand.
|
||||
var index int
|
||||
switch code {
|
||||
case opAt, opField, opMethod, opTypeParam:
|
||||
rest := strings.TrimLeft(suffix, "0123456789")
|
||||
numerals := suffix[:len(suffix)-len(rest)]
|
||||
suffix = rest
|
||||
i, err := strconv.Atoi(numerals)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid path: bad numeric operand %q for code %q", numerals, code)
|
||||
}
|
||||
index = int(i)
|
||||
case opObj:
|
||||
// no operand
|
||||
default:
|
||||
// The suffix must end with a type->object operation.
|
||||
if suffix == "" {
|
||||
return nil, fmt.Errorf("invalid path: ends with %q, want [AFMO]", code)
|
||||
}
|
||||
}
|
||||
|
||||
if code == opType {
|
||||
if t != nil {
|
||||
return nil, fmt.Errorf("invalid path: unexpected %q in type context", opType)
|
||||
}
|
||||
t = obj.Type()
|
||||
obj = nil
|
||||
continue
|
||||
}
|
||||
|
||||
if t == nil {
|
||||
return nil, fmt.Errorf("invalid path: code %q in object context", code)
|
||||
}
|
||||
|
||||
// Inv: t != nil, obj == nil
|
||||
|
||||
switch code {
|
||||
case opElem:
|
||||
hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want pointer, slice, array, chan or map)", code, t, t)
|
||||
}
|
||||
t = hasElem.Elem()
|
||||
|
||||
case opKey:
|
||||
mapType, ok := t.(*types.Map)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want map)", code, t, t)
|
||||
}
|
||||
t = mapType.Key()
|
||||
|
||||
case opParams:
|
||||
sig, ok := t.(*types.Signature)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t)
|
||||
}
|
||||
t = sig.Params()
|
||||
|
||||
case opResults:
|
||||
sig, ok := t.(*types.Signature)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t)
|
||||
}
|
||||
t = sig.Results()
|
||||
|
||||
case opUnderlying:
|
||||
named, ok := t.(*types.Named)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named)", code, t, t)
|
||||
}
|
||||
t = named.Underlying()
|
||||
|
||||
case opTypeParam:
|
||||
hasTypeParams, ok := t.(hasTypeParams) // Named, Signature
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or signature)", code, t, t)
|
||||
}
|
||||
tparams := hasTypeParams.TypeParams()
|
||||
if n := tparams.Len(); index >= n {
|
||||
return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n)
|
||||
}
|
||||
t = tparams.At(index)
|
||||
|
||||
case opConstraint:
|
||||
tparam, ok := t.(*typeparams.TypeParam)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t)
|
||||
}
|
||||
t = tparam.Constraint()
|
||||
|
||||
case opAt:
|
||||
tuple, ok := t.(*types.Tuple)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want tuple)", code, t, t)
|
||||
}
|
||||
if n := tuple.Len(); index >= n {
|
||||
return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n)
|
||||
}
|
||||
obj = tuple.At(index)
|
||||
t = nil
|
||||
|
||||
case opField:
|
||||
structType, ok := t.(*types.Struct)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want struct)", code, t, t)
|
||||
}
|
||||
if n := structType.NumFields(); index >= n {
|
||||
return nil, fmt.Errorf("field index %d out of range [0-%d)", index, n)
|
||||
}
|
||||
obj = structType.Field(index)
|
||||
t = nil
|
||||
|
||||
case opMethod:
|
||||
switch t := t.(type) {
|
||||
case *types.Interface:
|
||||
if index >= t.NumMethods() {
|
||||
return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods())
|
||||
}
|
||||
obj = t.Method(index) // Id-ordered
|
||||
|
||||
case *types.Named:
|
||||
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
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t)
|
||||
}
|
||||
t = nil
|
||||
|
||||
case opObj:
|
||||
hasObj, ok := t.(hasObj)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or type param)", code, t, t)
|
||||
}
|
||||
obj = hasObj.Obj()
|
||||
t = nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid path: unknown code %q", code)
|
||||
}
|
||||
}
|
||||
|
||||
if obj.Pkg() != pkg {
|
||||
return nil, fmt.Errorf("path denotes %s, which belongs to a different package", obj)
|
||||
}
|
||||
|
||||
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 {
|
||||
m := enc.scopeMemo
|
||||
if m == nil {
|
||||
m = make(map[*types.Scope][]types.Object)
|
||||
enc.scopeMemo = m
|
||||
}
|
||||
objs, ok := m[scope]
|
||||
if !ok {
|
||||
names := scope.Names() // allocates and sorts
|
||||
objs = make([]types.Object, len(names))
|
||||
for i, name := range names {
|
||||
objs[i] = scope.Lookup(name)
|
||||
}
|
||||
m[scope] = objs
|
||||
}
|
||||
return objs
|
||||
}
|
||||
+1
-1
@@ -19,7 +19,7 @@ var (
|
||||
File = keys.NewString("file", "")
|
||||
Directory = keys.New("directory", "")
|
||||
URI = keys.New("URI", "")
|
||||
Package = keys.NewString("package", "") // Package ID
|
||||
Package = keys.NewString("package", "") // sorted comma-separated list of Package IDs
|
||||
PackagePath = keys.NewString("package_path", "")
|
||||
Query = keys.New("query", "")
|
||||
Snapshot = keys.NewUInt64("snapshot", "")
|
||||
|
||||
+149
-26
@@ -22,17 +22,23 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"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.
|
||||
//
|
||||
// No promises are made about the encoding other than that it can be
|
||||
// decoded by the same version of IIExportShallow. If you plan to save
|
||||
// export data in the file system, be sure to include a cryptographic
|
||||
// digest of the executable in the key to avoid version skew.
|
||||
func IExportShallow(fset *token.FileSet, pkg *types.Package) ([]byte, error) {
|
||||
// No promises are made about the encoding other than that it can be decoded by
|
||||
// the same version of IIExportShallow. If you plan to save export data in the
|
||||
// file system, be sure to include a cryptographic digest of the executable in
|
||||
// the key to avoid version skew.
|
||||
//
|
||||
// If the provided reportf func is non-nil, it will be used for reporting bugs
|
||||
// encountered during export.
|
||||
// TODO(rfindley): remove reportf when we are confident enough in the new
|
||||
// objectpath encoding.
|
||||
func IExportShallow(fset *token.FileSet, pkg *types.Package, reportf ReportFunc) ([]byte, error) {
|
||||
// In principle this operation can only fail if out.Write fails,
|
||||
// but that's impossible for bytes.Buffer---and as a matter of
|
||||
// fact iexportCommon doesn't even check for I/O errors.
|
||||
@@ -47,19 +53,27 @@ func IExportShallow(fset *token.FileSet, pkg *types.Package) ([]byte, error) {
|
||||
// IImportShallow decodes "shallow" types.Package data encoded by
|
||||
// IExportShallow in the same executable. This function cannot import data from
|
||||
// cmd/compile or gcexportdata.Write.
|
||||
func IImportShallow(fset *token.FileSet, getPackage GetPackageFunc, data []byte, path string, insert InsertType) (*types.Package, error) {
|
||||
//
|
||||
// The importer calls getPackages to obtain package symbols for all
|
||||
// packages mentioned in the export data, including the one being
|
||||
// decoded.
|
||||
//
|
||||
// If the provided reportf func is non-nil, it will be used for reporting bugs
|
||||
// encountered during import.
|
||||
// TODO(rfindley): remove reportf when we are confident enough in the new
|
||||
// objectpath encoding.
|
||||
func IImportShallow(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, path string, reportf ReportFunc) (*types.Package, error) {
|
||||
const bundle = false
|
||||
pkgs, err := iimportCommon(fset, getPackage, data, bundle, path, insert)
|
||||
const shallow = true
|
||||
pkgs, err := iimportCommon(fset, getPackages, data, bundle, path, shallow, reportf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pkgs[0], nil
|
||||
}
|
||||
|
||||
// InsertType is the type of a function that creates a types.TypeName
|
||||
// object for a named type and inserts it into the scope of the
|
||||
// specified Package.
|
||||
type InsertType = func(pkg *types.Package, name string)
|
||||
// ReportFunc is the type of a function used to report formatted bugs.
|
||||
type ReportFunc = func(string, ...interface{})
|
||||
|
||||
// Current bundled export format version. Increase with each format change.
|
||||
// 0: initial implementation
|
||||
@@ -313,8 +327,9 @@ type iexporter struct {
|
||||
out *bytes.Buffer
|
||||
version int
|
||||
|
||||
shallow bool // don't put types from other packages in the index
|
||||
localpkg *types.Package // (nil in bundle mode)
|
||||
shallow bool // don't put types from other packages in the index
|
||||
objEncoder *objectpath.Encoder // encodes objects from other packages in shallow mode; lazily allocated
|
||||
localpkg *types.Package // (nil in bundle mode)
|
||||
|
||||
// allPkgs tracks all packages that have been referenced by
|
||||
// the export data, so we can ensure to include them in the
|
||||
@@ -354,6 +369,17 @@ func (p *iexporter) trace(format string, args ...interface{}) {
|
||||
fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
|
||||
}
|
||||
|
||||
// objectpathEncoder returns the lazily allocated objectpath.Encoder to use
|
||||
// when encoding objects in other packages during shallow export.
|
||||
//
|
||||
// Using a shared Encoder amortizes some of cost of objectpath search.
|
||||
func (p *iexporter) objectpathEncoder() *objectpath.Encoder {
|
||||
if p.objEncoder == nil {
|
||||
p.objEncoder = new(objectpath.Encoder)
|
||||
}
|
||||
return p.objEncoder
|
||||
}
|
||||
|
||||
// stringOff returns the offset of s within the string section.
|
||||
// If not already present, it's added to the end.
|
||||
func (p *iexporter) stringOff(s string) uint64 {
|
||||
@@ -413,7 +439,6 @@ type exportWriter struct {
|
||||
p *iexporter
|
||||
|
||||
data intWriter
|
||||
currPkg *types.Package
|
||||
prevFile string
|
||||
prevLine int64
|
||||
prevColumn int64
|
||||
@@ -436,7 +461,6 @@ func (p *iexporter) doDecl(obj types.Object) {
|
||||
}()
|
||||
}
|
||||
w := p.newWriter()
|
||||
w.setPkg(obj.Pkg(), false)
|
||||
|
||||
switch obj := obj.(type) {
|
||||
case *types.Var:
|
||||
@@ -673,6 +697,9 @@ func (w *exportWriter) qualifiedType(obj *types.TypeName) {
|
||||
w.pkg(obj.Pkg())
|
||||
}
|
||||
|
||||
// TODO(rfindley): what does 'pkg' even mean here? It would be better to pass
|
||||
// it in explicitly into signatures and structs that may use it for
|
||||
// constructing fields.
|
||||
func (w *exportWriter) typ(t types.Type, pkg *types.Package) {
|
||||
w.data.uint64(w.p.typOff(t, pkg))
|
||||
}
|
||||
@@ -764,30 +791,53 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
|
||||
|
||||
case *types.Signature:
|
||||
w.startType(signatureType)
|
||||
w.setPkg(pkg, true)
|
||||
w.pkg(pkg)
|
||||
w.signature(t)
|
||||
|
||||
case *types.Struct:
|
||||
w.startType(structType)
|
||||
n := t.NumFields()
|
||||
// Even for struct{} we must emit some qualifying package, because that's
|
||||
// what the compiler does, and thus that's what the importer expects.
|
||||
fieldPkg := pkg
|
||||
if n > 0 {
|
||||
w.setPkg(t.Field(0).Pkg(), true) // qualifying package for field objects
|
||||
} else {
|
||||
w.setPkg(pkg, true)
|
||||
fieldPkg = t.Field(0).Pkg()
|
||||
}
|
||||
if fieldPkg == nil {
|
||||
// TODO(rfindley): improve this very hacky logic.
|
||||
//
|
||||
// The importer expects a package to be set for all struct types, even
|
||||
// those with no fields. A better encoding might be to set NumFields
|
||||
// before pkg. setPkg panics with a nil package, which may be possible
|
||||
// to reach with invalid packages (and perhaps valid packages, too?), so
|
||||
// (arbitrarily) set the localpkg if available.
|
||||
//
|
||||
// Alternatively, we may be able to simply guarantee that pkg != nil, by
|
||||
// reconsidering the encoding of constant values.
|
||||
if w.p.shallow {
|
||||
fieldPkg = w.p.localpkg
|
||||
} else {
|
||||
panic(internalErrorf("no package to set for empty struct"))
|
||||
}
|
||||
}
|
||||
w.pkg(fieldPkg)
|
||||
w.uint64(uint64(n))
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
f := t.Field(i)
|
||||
if w.p.shallow {
|
||||
w.objectPath(f)
|
||||
}
|
||||
w.pos(f.Pos())
|
||||
w.string(f.Name()) // unexported fields implicitly qualified by prior setPkg
|
||||
w.typ(f.Type(), pkg)
|
||||
w.typ(f.Type(), fieldPkg)
|
||||
w.bool(f.Anonymous())
|
||||
w.string(t.Tag(i)) // note (or tag)
|
||||
}
|
||||
|
||||
case *types.Interface:
|
||||
w.startType(interfaceType)
|
||||
w.setPkg(pkg, true)
|
||||
w.pkg(pkg)
|
||||
|
||||
n := t.NumEmbeddeds()
|
||||
w.uint64(uint64(n))
|
||||
@@ -802,10 +852,16 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
|
||||
w.typ(ft, tPkg)
|
||||
}
|
||||
|
||||
// See comment for struct fields. In shallow mode we change the encoding
|
||||
// for interface methods that are promoted from other packages.
|
||||
|
||||
n = t.NumExplicitMethods()
|
||||
w.uint64(uint64(n))
|
||||
for i := 0; i < n; i++ {
|
||||
m := t.ExplicitMethod(i)
|
||||
if w.p.shallow {
|
||||
w.objectPath(m)
|
||||
}
|
||||
w.pos(m.Pos())
|
||||
w.string(m.Name())
|
||||
sig, _ := m.Type().(*types.Signature)
|
||||
@@ -827,12 +883,61 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
|
||||
}
|
||||
}
|
||||
|
||||
func (w *exportWriter) setPkg(pkg *types.Package, write bool) {
|
||||
if write {
|
||||
w.pkg(pkg)
|
||||
// objectPath writes the package and objectPath to use to look up obj in a
|
||||
// different package, when encoding in "shallow" mode.
|
||||
//
|
||||
// When doing a shallow import, the importer creates only the local package,
|
||||
// and requests package symbols for dependencies from the client.
|
||||
// However, certain types defined in the local package may hold objects defined
|
||||
// (perhaps deeply) within another package.
|
||||
//
|
||||
// For example, consider the following:
|
||||
//
|
||||
// package a
|
||||
// func F() chan * map[string] struct { X int }
|
||||
//
|
||||
// package b
|
||||
// import "a"
|
||||
// var B = a.F()
|
||||
//
|
||||
// In this example, the type of b.B holds fields defined in package a.
|
||||
// In order to have the correct canonical objects for the field defined in the
|
||||
// type of B, they are encoded as objectPaths and later looked up in the
|
||||
// importer. The same problem applies to interface methods.
|
||||
func (w *exportWriter) objectPath(obj types.Object) {
|
||||
if obj.Pkg() == nil || obj.Pkg() == w.p.localpkg {
|
||||
// obj.Pkg() may be nil for the builtin error.Error.
|
||||
// In this case, or if obj is declared in the local package, no need to
|
||||
// encode.
|
||||
w.string("")
|
||||
return
|
||||
}
|
||||
|
||||
w.currPkg = pkg
|
||||
objectPath, err := w.p.objectpathEncoder().For(obj)
|
||||
if err != nil {
|
||||
// Fall back to the empty string, which will cause the importer to create a
|
||||
// new object, which matches earlier behavior. Creating a new object is
|
||||
// sufficient for many purposes (such as type checking), but causes certain
|
||||
// references algorithms to fail (golang/go#60819). However, we didn't
|
||||
// notice this problem during months of gopls@v0.12.0 testing.
|
||||
//
|
||||
// TODO(golang/go#61674): this workaround is insufficient, as in the case
|
||||
// where the field forwarded from an instantiated type that may not appear
|
||||
// in the export data of the original package:
|
||||
//
|
||||
// // package a
|
||||
// type A[P any] struct{ F P }
|
||||
//
|
||||
// // package b
|
||||
// type B a.A[int]
|
||||
//
|
||||
// We need to update references algorithms not to depend on this
|
||||
// de-duplication, at which point we may want to simply remove the
|
||||
// workaround here.
|
||||
w.string("")
|
||||
return
|
||||
}
|
||||
w.string(string(objectPath))
|
||||
w.pkg(obj.Pkg())
|
||||
}
|
||||
|
||||
func (w *exportWriter) signature(sig *types.Signature) {
|
||||
@@ -913,6 +1018,17 @@ func (w *exportWriter) value(typ types.Type, v constant.Value) {
|
||||
w.int64(int64(v.Kind()))
|
||||
}
|
||||
|
||||
if v.Kind() == constant.Unknown {
|
||||
// golang/go#60605: treat unknown constant values as if they have invalid type
|
||||
//
|
||||
// This loses some fidelity over the package type-checked from source, but that
|
||||
// is acceptable.
|
||||
//
|
||||
// TODO(rfindley): we should switch on the recorded constant kind rather
|
||||
// than the constant type
|
||||
return
|
||||
}
|
||||
|
||||
switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
|
||||
case types.IsBoolean:
|
||||
w.bool(constant.BoolVal(v))
|
||||
@@ -1194,6 +1310,13 @@ type internalError string
|
||||
|
||||
func (e internalError) Error() string { return "gcimporter: " + string(e) }
|
||||
|
||||
// TODO(adonovan): make this call panic, so that it's symmetric with errorf.
|
||||
// Otherwise it's easy to forget to do anything with the error.
|
||||
//
|
||||
// TODO(adonovan): also, consider switching the names "errorf" and
|
||||
// "internalErrorf" as the former is used for bugs, whose cause is
|
||||
// internal inconsistency, whereas the latter is used for ordinary
|
||||
// situations like bad input, whose cause is external.
|
||||
func internalErrorf(format string, args ...interface{}) error {
|
||||
return internalError(fmt.Sprintf(format, args...))
|
||||
}
|
||||
+138
-50
@@ -21,6 +21,7 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/types/objectpath"
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
@@ -85,7 +86,7 @@ const (
|
||||
// If the export data version is not recognized or the format is otherwise
|
||||
// compromised, an error is returned.
|
||||
func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) {
|
||||
pkgs, err := iimportCommon(fset, GetPackageFromMap(imports), data, false, path, nil)
|
||||
pkgs, err := iimportCommon(fset, GetPackagesFromMap(imports), data, false, path, false, nil)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
@@ -94,33 +95,49 @@ func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []
|
||||
|
||||
// IImportBundle imports a set of packages from the serialized package bundle.
|
||||
func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) {
|
||||
return iimportCommon(fset, GetPackageFromMap(imports), data, true, "", nil)
|
||||
return iimportCommon(fset, GetPackagesFromMap(imports), data, true, "", false, nil)
|
||||
}
|
||||
|
||||
// A GetPackageFunc is a function that gets the package with the given path
|
||||
// from the importer state, creating it (with the specified name) if necessary.
|
||||
// It is an abstraction of the map historically used to memoize package creation.
|
||||
// A GetPackagesFunc function obtains the non-nil symbols for a set of
|
||||
// packages, creating and recursively importing them as needed. An
|
||||
// implementation should store each package symbol is in the Pkg
|
||||
// field of the items array.
|
||||
//
|
||||
// Two calls with the same path must return the same package.
|
||||
//
|
||||
// If the given getPackage func returns nil, the import will fail.
|
||||
type GetPackageFunc = func(path, name string) *types.Package
|
||||
// Any error causes importing to fail. This can be used to quickly read
|
||||
// the import manifest of an export data file without fully decoding it.
|
||||
type GetPackagesFunc = func(items []GetPackagesItem) error
|
||||
|
||||
// GetPackageFromMap returns a GetPackageFunc that retrieves packages from the
|
||||
// given map of package path -> package.
|
||||
// A GetPackagesItem is a request from the importer for the package
|
||||
// symbol of the specified name and path.
|
||||
type GetPackagesItem struct {
|
||||
Name, Path string
|
||||
Pkg *types.Package // to be filled in by GetPackagesFunc call
|
||||
|
||||
// private importer state
|
||||
pathOffset uint64
|
||||
nameIndex map[string]uint64
|
||||
}
|
||||
|
||||
// GetPackagesFromMap returns a GetPackagesFunc that retrieves
|
||||
// packages from the given map of package path to package.
|
||||
//
|
||||
// The resulting func may mutate m: if a requested package is not found, a new
|
||||
// package will be inserted into m.
|
||||
func GetPackageFromMap(m map[string]*types.Package) GetPackageFunc {
|
||||
return func(path, name string) *types.Package {
|
||||
if _, ok := m[path]; !ok {
|
||||
m[path] = types.NewPackage(path, name)
|
||||
// The returned function may mutate m: each requested package that is not
|
||||
// found is created with types.NewPackage and inserted into m.
|
||||
func GetPackagesFromMap(m map[string]*types.Package) GetPackagesFunc {
|
||||
return func(items []GetPackagesItem) error {
|
||||
for i, item := range items {
|
||||
pkg, ok := m[item.Path]
|
||||
if !ok {
|
||||
pkg = types.NewPackage(item.Path, item.Name)
|
||||
m[item.Path] = pkg
|
||||
}
|
||||
items[i].Pkg = pkg
|
||||
}
|
||||
return m[path]
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func iimportCommon(fset *token.FileSet, getPackage GetPackageFunc, data []byte, bundle bool, path string, insert InsertType) (pkgs []*types.Package, err error) {
|
||||
func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte, bundle bool, path string, shallow bool, reportf ReportFunc) (pkgs []*types.Package, err error) {
|
||||
const currentVersion = iexportVersionCurrent
|
||||
version := int64(-1)
|
||||
if !debug {
|
||||
@@ -159,7 +176,7 @@ func iimportCommon(fset *token.FileSet, getPackage GetPackageFunc, data []byte,
|
||||
sLen := int64(r.uint64())
|
||||
var fLen int64
|
||||
var fileOffset []uint64
|
||||
if insert != nil {
|
||||
if shallow {
|
||||
// Shallow mode uses a different position encoding.
|
||||
fLen = int64(r.uint64())
|
||||
fileOffset = make([]uint64, r.uint64())
|
||||
@@ -178,7 +195,8 @@ func iimportCommon(fset *token.FileSet, getPackage GetPackageFunc, data []byte,
|
||||
p := iimporter{
|
||||
version: int(version),
|
||||
ipath: path,
|
||||
insert: insert,
|
||||
shallow: shallow,
|
||||
reportf: reportf,
|
||||
|
||||
stringData: stringData,
|
||||
stringCache: make(map[uint64]string),
|
||||
@@ -205,8 +223,9 @@ func iimportCommon(fset *token.FileSet, getPackage GetPackageFunc, data []byte,
|
||||
p.typCache[uint64(i)] = pt
|
||||
}
|
||||
|
||||
pkgList := make([]*types.Package, r.uint64())
|
||||
for i := range pkgList {
|
||||
// Gather the relevant packages from the manifest.
|
||||
items := make([]GetPackagesItem, r.uint64())
|
||||
for i := range items {
|
||||
pkgPathOff := r.uint64()
|
||||
pkgPath := p.stringAt(pkgPathOff)
|
||||
pkgName := p.stringAt(r.uint64())
|
||||
@@ -215,29 +234,42 @@ func iimportCommon(fset *token.FileSet, getPackage GetPackageFunc, data []byte,
|
||||
if pkgPath == "" {
|
||||
pkgPath = path
|
||||
}
|
||||
pkg := getPackage(pkgPath, pkgName)
|
||||
if pkg == nil {
|
||||
errorf("internal error: getPackage returned nil package for %s", pkgPath)
|
||||
} else if pkg.Name() != pkgName {
|
||||
errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
|
||||
}
|
||||
if i == 0 && !bundle {
|
||||
p.localpkg = pkg
|
||||
}
|
||||
|
||||
p.pkgCache[pkgPathOff] = pkg
|
||||
items[i].Name = pkgName
|
||||
items[i].Path = pkgPath
|
||||
items[i].pathOffset = pkgPathOff
|
||||
|
||||
// Read index for package.
|
||||
nameIndex := make(map[string]uint64)
|
||||
nSyms := r.uint64()
|
||||
// In shallow mode we don't expect an index for other packages.
|
||||
assert(nSyms == 0 || p.localpkg == pkg || p.insert == nil)
|
||||
// In shallow mode, only the current package (i=0) has an index.
|
||||
assert(!(shallow && i > 0 && nSyms != 0))
|
||||
for ; nSyms > 0; nSyms-- {
|
||||
name := p.stringAt(r.uint64())
|
||||
nameIndex[name] = r.uint64()
|
||||
}
|
||||
|
||||
p.pkgIndex[pkg] = nameIndex
|
||||
items[i].nameIndex = nameIndex
|
||||
}
|
||||
|
||||
// Request packages all at once from the client,
|
||||
// enabling a parallel implementation.
|
||||
if err := getPackages(items); err != nil {
|
||||
return nil, err // don't wrap this error
|
||||
}
|
||||
|
||||
// Check the results and complete the index.
|
||||
pkgList := make([]*types.Package, len(items))
|
||||
for i, item := range items {
|
||||
pkg := item.Pkg
|
||||
if pkg == nil {
|
||||
errorf("internal error: getPackages returned nil package for %q", item.Path)
|
||||
} else if pkg.Path() != item.Path {
|
||||
errorf("internal error: getPackages returned wrong path %q, want %q", pkg.Path(), item.Path)
|
||||
} else if pkg.Name() != item.Name {
|
||||
errorf("internal error: getPackages returned wrong name %s for package %q, want %s", pkg.Name(), item.Path, item.Name)
|
||||
}
|
||||
p.pkgCache[item.pathOffset] = pkg
|
||||
p.pkgIndex[pkg] = item.nameIndex
|
||||
pkgList[i] = pkg
|
||||
}
|
||||
|
||||
@@ -296,6 +328,13 @@ func iimportCommon(fset *token.FileSet, getPackage GetPackageFunc, data []byte,
|
||||
typ.Complete()
|
||||
}
|
||||
|
||||
// Workaround for golang/go#61561. See the doc for instanceList for details.
|
||||
for _, typ := range p.instanceList {
|
||||
if iface, _ := typ.Underlying().(*types.Interface); iface != nil {
|
||||
iface.Complete()
|
||||
}
|
||||
}
|
||||
|
||||
return pkgs, nil
|
||||
}
|
||||
|
||||
@@ -308,8 +347,8 @@ type iimporter struct {
|
||||
version int
|
||||
ipath string
|
||||
|
||||
localpkg *types.Package
|
||||
insert func(pkg *types.Package, name string) // "shallow" mode only
|
||||
shallow bool
|
||||
reportf ReportFunc // if non-nil, used to report bugs
|
||||
|
||||
stringData []byte
|
||||
stringCache map[uint64]string
|
||||
@@ -326,6 +365,12 @@ type iimporter struct {
|
||||
fake fakeFileSet
|
||||
interfaceList []*types.Interface
|
||||
|
||||
// Workaround for the go/types bug golang/go#61561: instances produced during
|
||||
// instantiation may contain incomplete interfaces. Here we only complete the
|
||||
// underlying type of the instance, which is the most common case but doesn't
|
||||
// handle parameterized interface literals defined deeper in the type.
|
||||
instanceList []types.Type // instances for later completion (see golang/go#61561)
|
||||
|
||||
// Arguments for calls to SetConstraint that are deferred due to recursive types
|
||||
later []setConstraintArgs
|
||||
|
||||
@@ -357,13 +402,9 @@ func (p *iimporter) doDecl(pkg *types.Package, name string) {
|
||||
|
||||
off, ok := p.pkgIndex[pkg][name]
|
||||
if !ok {
|
||||
// In "shallow" mode, call back to the application to
|
||||
// find the object and insert it into the package scope.
|
||||
if p.insert != nil {
|
||||
assert(pkg != p.localpkg)
|
||||
p.insert(pkg, name) // "can't fail"
|
||||
return
|
||||
}
|
||||
// In deep mode, the index should be complete. In shallow
|
||||
// mode, we should have already recursively loaded necessary
|
||||
// dependencies so the above Lookup succeeds.
|
||||
errorf("%v.%v not in index", pkg, name)
|
||||
}
|
||||
|
||||
@@ -730,7 +771,8 @@ func (r *importReader) qualifiedIdent() (*types.Package, string) {
|
||||
}
|
||||
|
||||
func (r *importReader) pos() token.Pos {
|
||||
if r.p.insert != nil { // shallow mode
|
||||
if r.p.shallow {
|
||||
// precise offsets are encoded only in shallow mode
|
||||
return r.posv2()
|
||||
}
|
||||
if r.p.version >= iexportVersionPosCol {
|
||||
@@ -831,13 +873,28 @@ func (r *importReader) doType(base *types.Named) (res types.Type) {
|
||||
fields := make([]*types.Var, r.uint64())
|
||||
tags := make([]string, len(fields))
|
||||
for i := range fields {
|
||||
var field *types.Var
|
||||
if r.p.shallow {
|
||||
field, _ = r.objectPathObject().(*types.Var)
|
||||
}
|
||||
|
||||
fpos := r.pos()
|
||||
fname := r.ident()
|
||||
ftyp := r.typ()
|
||||
emb := r.bool()
|
||||
tag := r.string()
|
||||
|
||||
fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb)
|
||||
// Either this is not a shallow import, the field is local, or the
|
||||
// encoded objectPath failed to produce an object (a bug).
|
||||
//
|
||||
// Even in this last, buggy case, fall back on creating a new field. As
|
||||
// discussed in iexport.go, this is not correct, but mostly works and is
|
||||
// preferable to failing (for now at least).
|
||||
if field == nil {
|
||||
field = types.NewField(fpos, r.currPkg, fname, ftyp, emb)
|
||||
}
|
||||
|
||||
fields[i] = field
|
||||
tags[i] = tag
|
||||
}
|
||||
return types.NewStruct(fields, tags)
|
||||
@@ -853,6 +910,11 @@ func (r *importReader) doType(base *types.Named) (res types.Type) {
|
||||
|
||||
methods := make([]*types.Func, r.uint64())
|
||||
for i := range methods {
|
||||
var method *types.Func
|
||||
if r.p.shallow {
|
||||
method, _ = r.objectPathObject().(*types.Func)
|
||||
}
|
||||
|
||||
mpos := r.pos()
|
||||
mname := r.ident()
|
||||
|
||||
@@ -862,9 +924,12 @@ func (r *importReader) doType(base *types.Named) (res types.Type) {
|
||||
if base != nil {
|
||||
recv = types.NewVar(token.NoPos, r.currPkg, "", base)
|
||||
}
|
||||
|
||||
msig := r.signature(recv, nil, nil)
|
||||
methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig)
|
||||
|
||||
if method == nil {
|
||||
method = types.NewFunc(mpos, r.currPkg, mname, msig)
|
||||
}
|
||||
methods[i] = method
|
||||
}
|
||||
|
||||
typ := newInterface(methods, embeddeds)
|
||||
@@ -902,6 +967,9 @@ func (r *importReader) doType(base *types.Named) (res types.Type) {
|
||||
// we must always use the methods of the base (orig) type.
|
||||
// TODO provide a non-nil *Environment
|
||||
t, _ := typeparams.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)
|
||||
return t
|
||||
|
||||
case unionType:
|
||||
@@ -920,6 +988,26 @@ func (r *importReader) kind() itag {
|
||||
return itag(r.uint64())
|
||||
}
|
||||
|
||||
// objectPathObject is the inverse of exportWriter.objectPath.
|
||||
//
|
||||
// In shallow mode, certain fields and methods may need to be looked up in an
|
||||
// imported package. See the doc for exportWriter.objectPath for a full
|
||||
// explanation.
|
||||
func (r *importReader) objectPathObject() types.Object {
|
||||
objPath := objectpath.Path(r.string())
|
||||
if objPath == "" {
|
||||
return nil
|
||||
}
|
||||
pkg := r.pkg()
|
||||
obj, err := objectpath.Object(pkg, objPath)
|
||||
if err != nil {
|
||||
if r.p.reportf != nil {
|
||||
r.p.reportf("failed to find object for objectPath %q: %v", objPath, err)
|
||||
}
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature {
|
||||
params := r.paramList()
|
||||
results := r.paramList()
|
||||
|
||||
+2
-2
@@ -319,7 +319,7 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) {
|
||||
// Per https://pkg.go.dev/os#File.Close, the call to stdoutR.Close
|
||||
// should cause the Read call in io.Copy to unblock and return
|
||||
// immediately, but we still need to receive from stdoutErr to confirm
|
||||
// that that has happened.
|
||||
// that it has happened.
|
||||
<-stdoutErr
|
||||
err2 = ctx.Err()
|
||||
}
|
||||
@@ -333,7 +333,7 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) {
|
||||
// one goroutine at a time will call Write.”
|
||||
//
|
||||
// Since we're starting a goroutine that writes to cmd.Stdout, we must
|
||||
// also update cmd.Stderr so that that still holds.
|
||||
// also update cmd.Stderr so that it still holds.
|
||||
func() {
|
||||
defer func() { recover() }()
|
||||
if cmd.Stderr == prevStdout {
|
||||
|
||||
+26
@@ -23,6 +23,7 @@
|
||||
package typeparams
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
@@ -105,6 +106,31 @@ func OriginMethod(fn *types.Func) *types.Func {
|
||||
}
|
||||
orig := NamedTypeOrigin(named)
|
||||
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:
|
||||
// package p
|
||||
// type T *int
|
||||
// func (*T) f() {}
|
||||
// LookupFieldOrMethod(T, true, p, f)=nil, but NewMethodSet(*T)={(*T).f}.
|
||||
// Here we make them consistent by force.
|
||||
// (The go/types bug is general, but this workaround is reached only
|
||||
// for generic T thanks to the early return above.)
|
||||
if gfn == nil {
|
||||
mset := types.NewMethodSet(types.NewPointer(orig))
|
||||
for i := 0; i < mset.Len(); i++ {
|
||||
m := mset.At(i)
|
||||
if m.Obj().Id() == fn.Id() {
|
||||
gfn = m.Obj()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In golang/go#61196, we observe another crash, this time inexplicable.
|
||||
if gfn == nil {
|
||||
panic(fmt.Sprintf("missing origin method for %s.%s; named == origin: %t, named.NumMethods(): %d, origin.NumMethods(): %d", named, fn, named == orig, named.NumMethods(), orig.NumMethods()))
|
||||
}
|
||||
|
||||
return gfn.(*types.Func)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ func NamedTypeArgs(*types.Named) *TypeList {
|
||||
}
|
||||
|
||||
// NamedTypeOrigin is the identity method at this Go version.
|
||||
func NamedTypeOrigin(named *types.Named) types.Type {
|
||||
func NamedTypeOrigin(named *types.Named) *types.Named {
|
||||
return named
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ func NamedTypeArgs(named *types.Named) *TypeList {
|
||||
}
|
||||
|
||||
// NamedTypeOrigin returns named.Orig().
|
||||
func NamedTypeOrigin(named *types.Named) types.Type {
|
||||
func NamedTypeOrigin(named *types.Named) *types.Named {
|
||||
return named.Origin()
|
||||
}
|
||||
|
||||
|
||||
+16
@@ -11,6 +11,8 @@ import (
|
||||
"go/types"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/tools/go/types/objectpath"
|
||||
)
|
||||
|
||||
func SetUsesCgo(conf *types.Config) bool {
|
||||
@@ -50,3 +52,17 @@ func ReadGo116ErrorData(err types.Error) (code ErrorCode, start, end token.Pos,
|
||||
}
|
||||
|
||||
var SetGoVersion = func(conf *types.Config, version string) bool { return false }
|
||||
|
||||
// SkipEncoderMethodSorting marks the encoder as not requiring sorted methods,
|
||||
// as an optimization for gopls (which guarantees the order of parsed source files).
|
||||
//
|
||||
// TODO(golang/go#61443): eliminate this parameter one way or the other.
|
||||
//
|
||||
//go:linkname SkipEncoderMethodSorting golang.org/x/tools/go/types/objectpath.skipMethodSorting
|
||||
func SkipEncoderMethodSorting(enc *objectpath.Encoder)
|
||||
|
||||
// ObjectpathObject is like objectpath.Object, but allows suppressing method
|
||||
// sorting (which is not necessary for gopls).
|
||||
//
|
||||
//go:linkname ObjectpathObject golang.org/x/tools/go/types/objectpath.object
|
||||
func ObjectpathObject(pkg *types.Package, p objectpath.Path, skipMethodSorting bool) (types.Object, error)
|
||||
Vendored
+4
-3
@@ -755,7 +755,7 @@ github.com/nxadm/tail/winfile
|
||||
# github.com/oklog/ulid v1.3.1
|
||||
## explicit
|
||||
github.com/oklog/ulid
|
||||
# github.com/onsi/ginkgo/v2 v2.11.0
|
||||
# github.com/onsi/ginkgo/v2 v2.12.0
|
||||
## explicit; go 1.18
|
||||
github.com/onsi/ginkgo/v2
|
||||
github.com/onsi/ginkgo/v2/config
|
||||
@@ -1064,7 +1064,7 @@ golang.org/x/crypto/ssh/knownhosts
|
||||
golang.org/x/exp/constraints
|
||||
golang.org/x/exp/maps
|
||||
golang.org/x/exp/slices
|
||||
# golang.org/x/mod v0.11.0
|
||||
# golang.org/x/mod v0.12.0
|
||||
## explicit; go 1.17
|
||||
golang.org/x/mod/semver
|
||||
golang.org/x/mod/sumdb/note
|
||||
@@ -1126,13 +1126,14 @@ 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.9.3
|
||||
# golang.org/x/tools v0.12.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/tools/cmd/stringer
|
||||
golang.org/x/tools/go/ast/inspector
|
||||
golang.org/x/tools/go/gcexportdata
|
||||
golang.org/x/tools/go/internal/packagesdriver
|
||||
golang.org/x/tools/go/packages
|
||||
golang.org/x/tools/go/types/objectpath
|
||||
golang.org/x/tools/internal/event
|
||||
golang.org/x/tools/internal/event/core
|
||||
golang.org/x/tools/internal/event/keys
|
||||
|
||||
Reference in new issue
Block a user