mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-28 16:29:58 +00:00
TUN-9016: update go to 1.24
## Summary Update several moving parts of cloudflared build system: * use goboring 1.24.2 in cfsetup * update linter and fix lint issues * update packages namely **quic-go and net** * install script for macos * update docker files to use go 1.24.1 * remove usage of cloudflare-go * pin golang linter Closes TUN-9016
This commit is contained in:
63
vendor/golang.org/x/tools/internal/gcimporter/bimport.go
generated
vendored
63
vendor/golang.org/x/tools/internal/gcimporter/bimport.go
generated
vendored
@@ -14,7 +14,7 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
func errorf(format string, args ...interface{}) {
|
||||
func errorf(format string, args ...any) {
|
||||
panic(fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
@@ -87,64 +87,3 @@ func chanDir(d int) types.ChanDir {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
var predeclOnce sync.Once
|
||||
var predecl []types.Type // initialized lazily
|
||||
|
||||
func predeclared() []types.Type {
|
||||
predeclOnce.Do(func() {
|
||||
// initialize lazily to be sure that all
|
||||
// elements have been initialized before
|
||||
predecl = []types.Type{ // basic types
|
||||
types.Typ[types.Bool],
|
||||
types.Typ[types.Int],
|
||||
types.Typ[types.Int8],
|
||||
types.Typ[types.Int16],
|
||||
types.Typ[types.Int32],
|
||||
types.Typ[types.Int64],
|
||||
types.Typ[types.Uint],
|
||||
types.Typ[types.Uint8],
|
||||
types.Typ[types.Uint16],
|
||||
types.Typ[types.Uint32],
|
||||
types.Typ[types.Uint64],
|
||||
types.Typ[types.Uintptr],
|
||||
types.Typ[types.Float32],
|
||||
types.Typ[types.Float64],
|
||||
types.Typ[types.Complex64],
|
||||
types.Typ[types.Complex128],
|
||||
types.Typ[types.String],
|
||||
|
||||
// basic type aliases
|
||||
types.Universe.Lookup("byte").Type(),
|
||||
types.Universe.Lookup("rune").Type(),
|
||||
|
||||
// error
|
||||
types.Universe.Lookup("error").Type(),
|
||||
|
||||
// untyped types
|
||||
types.Typ[types.UntypedBool],
|
||||
types.Typ[types.UntypedInt],
|
||||
types.Typ[types.UntypedRune],
|
||||
types.Typ[types.UntypedFloat],
|
||||
types.Typ[types.UntypedComplex],
|
||||
types.Typ[types.UntypedString],
|
||||
types.Typ[types.UntypedNil],
|
||||
|
||||
// package unsafe
|
||||
types.Typ[types.UnsafePointer],
|
||||
|
||||
// invalid type
|
||||
types.Typ[types.Invalid], // only appears in packages with errors
|
||||
|
||||
// used internally by gc; never used by this package or in .a files
|
||||
anyType{},
|
||||
}
|
||||
predecl = append(predecl, additionalPredeclared()...)
|
||||
})
|
||||
return predecl
|
||||
}
|
||||
|
||||
type anyType struct{}
|
||||
|
||||
func (t anyType) Underlying() types.Type { return t }
|
||||
func (t anyType) String() string { return "any" }
|
||||
|
448
vendor/golang.org/x/tools/internal/gcimporter/exportdata.go
generated
vendored
448
vendor/golang.org/x/tools/internal/gcimporter/exportdata.go
generated
vendored
@@ -2,49 +2,183 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go.
|
||||
|
||||
// This file implements FindExportData.
|
||||
// This file should be kept in sync with $GOROOT/src/internal/exportdata/exportdata.go.
|
||||
// This file also additionally implements FindExportData for gcexportdata.NewReader.
|
||||
|
||||
package gcimporter
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"io"
|
||||
"strconv"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func readGopackHeader(r *bufio.Reader) (name string, size int64, err error) {
|
||||
// See $GOROOT/include/ar.h.
|
||||
hdr := make([]byte, 16+12+6+6+8+10+2)
|
||||
_, err = io.ReadFull(r, hdr)
|
||||
// FindExportData positions the reader r at the beginning of the
|
||||
// export data section of an underlying cmd/compile created archive
|
||||
// file by reading from it. The reader must be positioned at the
|
||||
// start of the file before calling this function.
|
||||
// This returns the length of the export data in bytes.
|
||||
//
|
||||
// This function is needed by [gcexportdata.Read], which must
|
||||
// accept inputs produced by the last two releases of cmd/compile,
|
||||
// plus tip.
|
||||
func FindExportData(r *bufio.Reader) (size int64, err error) {
|
||||
arsize, err := FindPackageDefinition(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// leave for debugging
|
||||
if false {
|
||||
fmt.Printf("header: %s", hdr)
|
||||
}
|
||||
s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
|
||||
length, err := strconv.Atoi(s)
|
||||
size = int64(length)
|
||||
if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
|
||||
err = fmt.Errorf("invalid archive header")
|
||||
size = int64(arsize)
|
||||
|
||||
objapi, headers, err := ReadObjectHeaders(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
name = strings.TrimSpace(string(hdr[:16]))
|
||||
size -= int64(len(objapi))
|
||||
for _, h := range headers {
|
||||
size -= int64(len(h))
|
||||
}
|
||||
|
||||
// Check for the binary export data section header "$$B\n".
|
||||
// TODO(taking): Unify with ReadExportDataHeader so that it stops at the 'u' instead of reading
|
||||
line, err := r.ReadSlice('\n')
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
hdr := string(line)
|
||||
if hdr != "$$B\n" {
|
||||
err = fmt.Errorf("unknown export data header: %q", hdr)
|
||||
return
|
||||
}
|
||||
size -= int64(len(hdr))
|
||||
|
||||
// For files with a binary export data header "$$B\n",
|
||||
// these are always terminated by an end-of-section marker "\n$$\n".
|
||||
// So the last bytes must always be this constant.
|
||||
//
|
||||
// The end-of-section marker is not a part of the export data itself.
|
||||
// Do not include these in size.
|
||||
//
|
||||
// It would be nice to have sanity check that the final bytes after
|
||||
// the export data are indeed the end-of-section marker. The split
|
||||
// of gcexportdata.NewReader and gcexportdata.Read make checking this
|
||||
// ugly so gcimporter gives up enforcing this. The compiler and go/types
|
||||
// importer do enforce this, which seems good enough.
|
||||
const endofsection = "\n$$\n"
|
||||
size -= int64(len(endofsection))
|
||||
|
||||
if size < 0 {
|
||||
err = fmt.Errorf("invalid size (%d) in the archive file: %d bytes remain without section headers (recompile package)", arsize, size)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FindExportData positions the reader r at the beginning of the
|
||||
// export data section of an underlying GC-created object/archive
|
||||
// file by reading from it. The reader must be positioned at the
|
||||
// start of the file before calling this function. The hdr result
|
||||
// is the string before the export data, either "$$" or "$$B".
|
||||
// The size result is the length of the export data in bytes, or -1 if not known.
|
||||
func FindExportData(r *bufio.Reader) (hdr string, size int64, err error) {
|
||||
// ReadUnified reads the contents of the unified export data from a reader r
|
||||
// that contains the contents of a GC-created archive file.
|
||||
//
|
||||
// On success, the reader will be positioned after the end-of-section marker "\n$$\n".
|
||||
//
|
||||
// Supported GC-created archive files have 4 layers of nesting:
|
||||
// - An archive file containing a package definition file.
|
||||
// - The package definition file contains headers followed by a data section.
|
||||
// Headers are lines (≤ 4kb) that do not start with "$$".
|
||||
// - The data section starts with "$$B\n" followed by export data followed
|
||||
// by an end of section marker "\n$$\n". (The section start "$$\n" is no
|
||||
// longer supported.)
|
||||
// - The export data starts with a format byte ('u') followed by the <data> in
|
||||
// the given format. (See ReadExportDataHeader for older formats.)
|
||||
//
|
||||
// Putting this together, the bytes in a GC-created archive files are expected
|
||||
// to look like the following.
|
||||
// See cmd/internal/archive for more details on ar file headers.
|
||||
//
|
||||
// | <!arch>\n | ar file signature
|
||||
// | __.PKGDEF...size...\n | ar header for __.PKGDEF including size.
|
||||
// | go object <...>\n | objabi header
|
||||
// | <optional headers>\n | other headers such as build id
|
||||
// | $$B\n | binary format marker
|
||||
// | u<data>\n | unified export <data>
|
||||
// | $$\n | end-of-section marker
|
||||
// | [optional padding] | padding byte (0x0A) if size is odd
|
||||
// | [ar file header] | other ar files
|
||||
// | [ar file data] |
|
||||
func ReadUnified(r *bufio.Reader) (data []byte, err error) {
|
||||
// We historically guaranteed headers at the default buffer size (4096) work.
|
||||
// This ensures we can use ReadSlice throughout.
|
||||
const minBufferSize = 4096
|
||||
r = bufio.NewReaderSize(r, minBufferSize)
|
||||
|
||||
size, err := FindPackageDefinition(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n := size
|
||||
|
||||
objapi, headers, err := ReadObjectHeaders(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n -= len(objapi)
|
||||
for _, h := range headers {
|
||||
n -= len(h)
|
||||
}
|
||||
|
||||
hdrlen, err := ReadExportDataHeader(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n -= hdrlen
|
||||
|
||||
// size also includes the end of section marker. Remove that many bytes from the end.
|
||||
const marker = "\n$$\n"
|
||||
n -= len(marker)
|
||||
|
||||
if n < 0 {
|
||||
err = fmt.Errorf("invalid size (%d) in the archive file: %d bytes remain without section headers (recompile package)", size, n)
|
||||
return
|
||||
}
|
||||
|
||||
// Read n bytes from buf.
|
||||
data = make([]byte, n)
|
||||
_, err = io.ReadFull(r, data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Check for marker at the end.
|
||||
var suffix [len(marker)]byte
|
||||
_, err = io.ReadFull(r, suffix[:])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if s := string(suffix[:]); s != marker {
|
||||
err = fmt.Errorf("read %q instead of end-of-section marker (%q)", s, marker)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FindPackageDefinition positions the reader r at the beginning of a package
|
||||
// definition file ("__.PKGDEF") within a GC-created archive by reading
|
||||
// from it, and returns the size of the package definition file in the archive.
|
||||
//
|
||||
// The reader must be positioned at the start of the archive file before calling
|
||||
// this function, and "__.PKGDEF" is assumed to be the first file in the archive.
|
||||
//
|
||||
// See cmd/internal/archive for details on the archive format.
|
||||
func FindPackageDefinition(r *bufio.Reader) (size int, err error) {
|
||||
// Uses ReadSlice to limit risk of malformed inputs.
|
||||
|
||||
// Read first line to make sure this is an object file.
|
||||
line, err := r.ReadSlice('\n')
|
||||
if err != nil {
|
||||
@@ -52,48 +186,236 @@ func FindExportData(r *bufio.Reader) (hdr string, size int64, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if string(line) == "!<arch>\n" {
|
||||
// Archive file. Scan to __.PKGDEF.
|
||||
var name string
|
||||
if name, size, err = readGopackHeader(r); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// First entry should be __.PKGDEF.
|
||||
if name != "__.PKGDEF" {
|
||||
err = fmt.Errorf("go archive is missing __.PKGDEF")
|
||||
return
|
||||
}
|
||||
|
||||
// Read first line of __.PKGDEF data, so that line
|
||||
// is once again the first line of the input.
|
||||
if line, err = r.ReadSlice('\n'); err != nil {
|
||||
err = fmt.Errorf("can't find export data (%v)", err)
|
||||
return
|
||||
}
|
||||
size -= int64(len(line))
|
||||
}
|
||||
|
||||
// Now at __.PKGDEF in archive or still at beginning of file.
|
||||
// Either way, line should begin with "go object ".
|
||||
if !strings.HasPrefix(string(line), "go object ") {
|
||||
err = fmt.Errorf("not a Go object file")
|
||||
// Is the first line an archive file signature?
|
||||
if string(line) != "!<arch>\n" {
|
||||
err = fmt.Errorf("not the start of an archive file (%q)", line)
|
||||
return
|
||||
}
|
||||
|
||||
// Skip over object header to export data.
|
||||
// Begins after first line starting with $$.
|
||||
for line[0] != '$' {
|
||||
if line, err = r.ReadSlice('\n'); err != nil {
|
||||
err = fmt.Errorf("can't find export data (%v)", err)
|
||||
return
|
||||
}
|
||||
size -= int64(len(line))
|
||||
}
|
||||
hdr = string(line)
|
||||
if size < 0 {
|
||||
size = -1
|
||||
// package export block should be first
|
||||
size = readArchiveHeader(r, "__.PKGDEF")
|
||||
if size <= 0 {
|
||||
err = fmt.Errorf("not a package file")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ReadObjectHeaders reads object headers from the reader. Object headers are
|
||||
// lines that do not start with an end-of-section marker "$$". The first header
|
||||
// is the objabi header. On success, the reader will be positioned at the beginning
|
||||
// of the end-of-section marker.
|
||||
//
|
||||
// It returns an error if any header does not fit in r.Size() bytes.
|
||||
func ReadObjectHeaders(r *bufio.Reader) (objapi string, headers []string, err error) {
|
||||
// line is a temporary buffer for headers.
|
||||
// Use bounded reads (ReadSlice, Peek) to limit risk of malformed inputs.
|
||||
var line []byte
|
||||
|
||||
// objapi header should be the first line
|
||||
if line, err = r.ReadSlice('\n'); err != nil {
|
||||
err = fmt.Errorf("can't find export data (%v)", err)
|
||||
return
|
||||
}
|
||||
objapi = string(line)
|
||||
|
||||
// objapi header begins with "go object ".
|
||||
if !strings.HasPrefix(objapi, "go object ") {
|
||||
err = fmt.Errorf("not a go object file: %s", objapi)
|
||||
return
|
||||
}
|
||||
|
||||
// process remaining object header lines
|
||||
for {
|
||||
// check for an end of section marker "$$"
|
||||
line, err = r.Peek(2)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if string(line) == "$$" {
|
||||
return // stop
|
||||
}
|
||||
|
||||
// read next header
|
||||
line, err = r.ReadSlice('\n')
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
headers = append(headers, string(line))
|
||||
}
|
||||
}
|
||||
|
||||
// ReadExportDataHeader reads the export data header and format from r.
|
||||
// It returns the number of bytes read, or an error if the format is no longer
|
||||
// supported or it failed to read.
|
||||
//
|
||||
// The only currently supported format is binary export data in the
|
||||
// unified export format.
|
||||
func ReadExportDataHeader(r *bufio.Reader) (n int, err error) {
|
||||
// Read export data header.
|
||||
line, err := r.ReadSlice('\n')
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
hdr := string(line)
|
||||
switch hdr {
|
||||
case "$$\n":
|
||||
err = fmt.Errorf("old textual export format no longer supported (recompile package)")
|
||||
return
|
||||
|
||||
case "$$B\n":
|
||||
var format byte
|
||||
format, err = r.ReadByte()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// The unified export format starts with a 'u'.
|
||||
switch format {
|
||||
case 'u':
|
||||
default:
|
||||
// Older no longer supported export formats include:
|
||||
// indexed export format which started with an 'i'; and
|
||||
// the older binary export format which started with a 'c',
|
||||
// 'd', or 'v' (from "version").
|
||||
err = fmt.Errorf("binary export format %q is no longer supported (recompile package)", format)
|
||||
return
|
||||
}
|
||||
|
||||
default:
|
||||
err = fmt.Errorf("unknown export data header: %q", hdr)
|
||||
return
|
||||
}
|
||||
|
||||
n = len(hdr) + 1 // + 1 is for 'u'
|
||||
return
|
||||
}
|
||||
|
||||
// FindPkg returns the filename and unique package id for an import
|
||||
// path based on package information provided by build.Import (using
|
||||
// the build.Default build.Context). A relative srcDir is interpreted
|
||||
// relative to the current working directory.
|
||||
//
|
||||
// FindPkg is only used in tests within x/tools.
|
||||
func FindPkg(path, srcDir string) (filename, id string, err error) {
|
||||
// TODO(taking): Move internal/exportdata.FindPkg into its own file,
|
||||
// and then this copy into a _test package.
|
||||
if path == "" {
|
||||
return "", "", errors.New("path is empty")
|
||||
}
|
||||
|
||||
var noext string
|
||||
switch {
|
||||
default:
|
||||
// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
|
||||
// Don't require the source files to be present.
|
||||
if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
|
||||
srcDir = abs
|
||||
}
|
||||
var bp *build.Package
|
||||
bp, err = build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
|
||||
if bp.PkgObj == "" {
|
||||
if bp.Goroot && bp.Dir != "" {
|
||||
filename, err = lookupGorootExport(bp.Dir)
|
||||
if err == nil {
|
||||
_, err = os.Stat(filename)
|
||||
}
|
||||
if err == nil {
|
||||
return filename, bp.ImportPath, nil
|
||||
}
|
||||
}
|
||||
goto notfound
|
||||
} else {
|
||||
noext = strings.TrimSuffix(bp.PkgObj, ".a")
|
||||
}
|
||||
id = bp.ImportPath
|
||||
|
||||
case build.IsLocalImport(path):
|
||||
// "./x" -> "/this/directory/x.ext", "/this/directory/x"
|
||||
noext = filepath.Join(srcDir, path)
|
||||
id = noext
|
||||
|
||||
case filepath.IsAbs(path):
|
||||
// for completeness only - go/build.Import
|
||||
// does not support absolute imports
|
||||
// "/x" -> "/x.ext", "/x"
|
||||
noext = path
|
||||
id = path
|
||||
}
|
||||
|
||||
if false { // for debugging
|
||||
if path != id {
|
||||
fmt.Printf("%s -> %s\n", path, id)
|
||||
}
|
||||
}
|
||||
|
||||
// try extensions
|
||||
for _, ext := range pkgExts {
|
||||
filename = noext + ext
|
||||
f, statErr := os.Stat(filename)
|
||||
if statErr == nil && !f.IsDir() {
|
||||
return filename, id, nil
|
||||
}
|
||||
if err == nil {
|
||||
err = statErr
|
||||
}
|
||||
}
|
||||
|
||||
notfound:
|
||||
if err == nil {
|
||||
return "", path, fmt.Errorf("can't find import: %q", path)
|
||||
}
|
||||
return "", path, fmt.Errorf("can't find import: %q: %w", path, err)
|
||||
}
|
||||
|
||||
var pkgExts = [...]string{".a", ".o"} // a file from the build cache will have no extension
|
||||
|
||||
var exportMap sync.Map // package dir → func() (string, error)
|
||||
|
||||
// lookupGorootExport returns the location of the export data
|
||||
// (normally found in the build cache, but located in GOROOT/pkg
|
||||
// in prior Go releases) for the package located in pkgDir.
|
||||
//
|
||||
// (We use the package's directory instead of its import path
|
||||
// mainly to simplify handling of the packages in src/vendor
|
||||
// and cmd/vendor.)
|
||||
//
|
||||
// lookupGorootExport is only used in tests within x/tools.
|
||||
func lookupGorootExport(pkgDir string) (string, error) {
|
||||
f, ok := exportMap.Load(pkgDir)
|
||||
if !ok {
|
||||
var (
|
||||
listOnce sync.Once
|
||||
exportPath string
|
||||
err error
|
||||
)
|
||||
f, _ = exportMap.LoadOrStore(pkgDir, func() (string, error) {
|
||||
listOnce.Do(func() {
|
||||
cmd := exec.Command(filepath.Join(build.Default.GOROOT, "bin", "go"), "list", "-export", "-f", "{{.Export}}", pkgDir)
|
||||
cmd.Dir = build.Default.GOROOT
|
||||
cmd.Env = append(os.Environ(), "PWD="+cmd.Dir, "GOROOT="+build.Default.GOROOT)
|
||||
var output []byte
|
||||
output, err = cmd.Output()
|
||||
if err != nil {
|
||||
if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 {
|
||||
err = errors.New(string(ee.Stderr))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
exports := strings.Split(string(bytes.TrimSpace(output)), "\n")
|
||||
if len(exports) != 1 {
|
||||
err = fmt.Errorf("go list reported %d exports; expected 1", len(exports))
|
||||
return
|
||||
}
|
||||
|
||||
exportPath = exports[0]
|
||||
})
|
||||
|
||||
return exportPath, err
|
||||
})
|
||||
}
|
||||
|
||||
return f.(func() (string, error))()
|
||||
}
|
||||
|
182
vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go
generated
vendored
182
vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go
generated
vendored
@@ -23,17 +23,11 @@ package gcimporter // import "golang.org/x/tools/internal/gcimporter"
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -45,125 +39,14 @@ const (
|
||||
trace = false
|
||||
)
|
||||
|
||||
var exportMap sync.Map // package dir → func() (string, bool)
|
||||
|
||||
// lookupGorootExport returns the location of the export data
|
||||
// (normally found in the build cache, but located in GOROOT/pkg
|
||||
// in prior Go releases) for the package located in pkgDir.
|
||||
//
|
||||
// (We use the package's directory instead of its import path
|
||||
// mainly to simplify handling of the packages in src/vendor
|
||||
// and cmd/vendor.)
|
||||
func lookupGorootExport(pkgDir string) (string, bool) {
|
||||
f, ok := exportMap.Load(pkgDir)
|
||||
if !ok {
|
||||
var (
|
||||
listOnce sync.Once
|
||||
exportPath string
|
||||
)
|
||||
f, _ = exportMap.LoadOrStore(pkgDir, func() (string, bool) {
|
||||
listOnce.Do(func() {
|
||||
cmd := exec.Command("go", "list", "-export", "-f", "{{.Export}}", pkgDir)
|
||||
cmd.Dir = build.Default.GOROOT
|
||||
var output []byte
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
exports := strings.Split(string(bytes.TrimSpace(output)), "\n")
|
||||
if len(exports) != 1 {
|
||||
return
|
||||
}
|
||||
|
||||
exportPath = exports[0]
|
||||
})
|
||||
|
||||
return exportPath, exportPath != ""
|
||||
})
|
||||
}
|
||||
|
||||
return f.(func() (string, bool))()
|
||||
}
|
||||
|
||||
var pkgExts = [...]string{".a", ".o"}
|
||||
|
||||
// FindPkg returns the filename and unique package id for an import
|
||||
// path based on package information provided by build.Import (using
|
||||
// the build.Default build.Context). A relative srcDir is interpreted
|
||||
// relative to the current working directory.
|
||||
// If no file was found, an empty filename is returned.
|
||||
func FindPkg(path, srcDir string) (filename, id string) {
|
||||
if path == "" {
|
||||
return
|
||||
}
|
||||
|
||||
var noext string
|
||||
switch {
|
||||
default:
|
||||
// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
|
||||
// Don't require the source files to be present.
|
||||
if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
|
||||
srcDir = abs
|
||||
}
|
||||
bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
|
||||
if bp.PkgObj == "" {
|
||||
var ok bool
|
||||
if bp.Goroot && bp.Dir != "" {
|
||||
filename, ok = lookupGorootExport(bp.Dir)
|
||||
}
|
||||
if !ok {
|
||||
id = path // make sure we have an id to print in error message
|
||||
return
|
||||
}
|
||||
} else {
|
||||
noext = strings.TrimSuffix(bp.PkgObj, ".a")
|
||||
id = bp.ImportPath
|
||||
}
|
||||
|
||||
case build.IsLocalImport(path):
|
||||
// "./x" -> "/this/directory/x.ext", "/this/directory/x"
|
||||
noext = filepath.Join(srcDir, path)
|
||||
id = noext
|
||||
|
||||
case filepath.IsAbs(path):
|
||||
// for completeness only - go/build.Import
|
||||
// does not support absolute imports
|
||||
// "/x" -> "/x.ext", "/x"
|
||||
noext = path
|
||||
id = path
|
||||
}
|
||||
|
||||
if false { // for debugging
|
||||
if path != id {
|
||||
fmt.Printf("%s -> %s\n", path, id)
|
||||
}
|
||||
}
|
||||
|
||||
if filename != "" {
|
||||
if f, err := os.Stat(filename); err == nil && !f.IsDir() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// try extensions
|
||||
for _, ext := range pkgExts {
|
||||
filename = noext + ext
|
||||
if f, err := os.Stat(filename); err == nil && !f.IsDir() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
filename = "" // not found
|
||||
return
|
||||
}
|
||||
|
||||
// Import imports a gc-generated package given its import path and srcDir, adds
|
||||
// the corresponding package object to the packages map, and returns the object.
|
||||
// The packages map must contain all packages already imported.
|
||||
func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
|
||||
//
|
||||
// Import is only used in tests.
|
||||
func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
|
||||
var rc io.ReadCloser
|
||||
var filename, id string
|
||||
var id string
|
||||
if lookup != nil {
|
||||
// With custom lookup specified, assume that caller has
|
||||
// converted path to a canonical import path for use in the map.
|
||||
@@ -182,12 +65,13 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func
|
||||
}
|
||||
rc = f
|
||||
} else {
|
||||
filename, id = FindPkg(path, srcDir)
|
||||
var filename string
|
||||
filename, id, err = FindPkg(path, srcDir)
|
||||
if filename == "" {
|
||||
if path == "unsafe" {
|
||||
return types.Unsafe, nil
|
||||
}
|
||||
return nil, fmt.Errorf("can't find import: %q", id)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// no need to re-import if the package was imported completely before
|
||||
@@ -210,57 +94,15 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
var hdr string
|
||||
var size int64
|
||||
buf := bufio.NewReader(rc)
|
||||
if hdr, size, err = FindExportData(buf); err != nil {
|
||||
data, err := ReadUnified(buf)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("import %q: %v", path, err)
|
||||
return
|
||||
}
|
||||
|
||||
switch hdr {
|
||||
case "$$B\n":
|
||||
var data []byte
|
||||
data, err = io.ReadAll(buf)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
// TODO(gri): allow clients of go/importer to provide a FileSet.
|
||||
// Or, define a new standard go/types/gcexportdata package.
|
||||
fset := token.NewFileSet()
|
||||
|
||||
// Select appropriate importer.
|
||||
if len(data) > 0 {
|
||||
switch data[0] {
|
||||
case 'v', 'c', 'd': // binary, till go1.10
|
||||
return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0])
|
||||
|
||||
case 'i': // indexed, till go1.19
|
||||
_, pkg, err := IImportData(fset, packages, data[1:], id)
|
||||
return pkg, err
|
||||
|
||||
case 'u': // unified, from go1.20
|
||||
_, pkg, err := UImportData(fset, packages, data[1:size], id)
|
||||
return pkg, err
|
||||
|
||||
default:
|
||||
l := len(data)
|
||||
if l > 10 {
|
||||
l = 10
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), id)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
err = fmt.Errorf("unknown export data header: %q", hdr)
|
||||
}
|
||||
// unified: emitted by cmd/compile since go1.20.
|
||||
_, pkg, err = UImportData(fset, packages, data, id)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type byPath []*types.Package
|
||||
|
||||
func (a byPath) Len() int { return len(a) }
|
||||
func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
|
||||
|
324
vendor/golang.org/x/tools/internal/gcimporter/iexport.go
generated
vendored
324
vendor/golang.org/x/tools/internal/gcimporter/iexport.go
generated
vendored
@@ -2,9 +2,227 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Indexed binary package export.
|
||||
// This file was derived from $GOROOT/src/cmd/compile/internal/gc/iexport.go;
|
||||
// see that file for specification of the format.
|
||||
// Indexed package export.
|
||||
//
|
||||
// The indexed export data format is an evolution of the previous
|
||||
// binary export data format. Its chief contribution is introducing an
|
||||
// index table, which allows efficient random access of individual
|
||||
// declarations and inline function bodies. In turn, this allows
|
||||
// avoiding unnecessary work for compilation units that import large
|
||||
// packages.
|
||||
//
|
||||
//
|
||||
// The top-level data format is structured as:
|
||||
//
|
||||
// Header struct {
|
||||
// Tag byte // 'i'
|
||||
// Version uvarint
|
||||
// StringSize uvarint
|
||||
// DataSize uvarint
|
||||
// }
|
||||
//
|
||||
// Strings [StringSize]byte
|
||||
// Data [DataSize]byte
|
||||
//
|
||||
// MainIndex []struct{
|
||||
// PkgPath stringOff
|
||||
// PkgName stringOff
|
||||
// PkgHeight uvarint
|
||||
//
|
||||
// Decls []struct{
|
||||
// Name stringOff
|
||||
// Offset declOff
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Fingerprint [8]byte
|
||||
//
|
||||
// uvarint means a uint64 written out using uvarint encoding.
|
||||
//
|
||||
// []T means a uvarint followed by that many T objects. In other
|
||||
// words:
|
||||
//
|
||||
// Len uvarint
|
||||
// Elems [Len]T
|
||||
//
|
||||
// stringOff means a uvarint that indicates an offset within the
|
||||
// Strings section. At that offset is another uvarint, followed by
|
||||
// that many bytes, which form the string value.
|
||||
//
|
||||
// declOff means a uvarint that indicates an offset within the Data
|
||||
// section where the associated declaration can be found.
|
||||
//
|
||||
//
|
||||
// There are five kinds of declarations, distinguished by their first
|
||||
// byte:
|
||||
//
|
||||
// type Var struct {
|
||||
// Tag byte // 'V'
|
||||
// Pos Pos
|
||||
// Type typeOff
|
||||
// }
|
||||
//
|
||||
// type Func struct {
|
||||
// Tag byte // 'F' or 'G'
|
||||
// Pos Pos
|
||||
// TypeParams []typeOff // only present if Tag == 'G'
|
||||
// Signature Signature
|
||||
// }
|
||||
//
|
||||
// type Const struct {
|
||||
// Tag byte // 'C'
|
||||
// Pos Pos
|
||||
// Value Value
|
||||
// }
|
||||
//
|
||||
// type Type struct {
|
||||
// Tag byte // 'T' or 'U'
|
||||
// Pos Pos
|
||||
// TypeParams []typeOff // only present if Tag == 'U'
|
||||
// Underlying typeOff
|
||||
//
|
||||
// Methods []struct{ // omitted if Underlying is an interface type
|
||||
// Pos Pos
|
||||
// Name stringOff
|
||||
// Recv Param
|
||||
// Signature Signature
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// type Alias struct {
|
||||
// Tag byte // 'A' or 'B'
|
||||
// Pos Pos
|
||||
// TypeParams []typeOff // only present if Tag == 'B'
|
||||
// Type typeOff
|
||||
// }
|
||||
//
|
||||
// // "Automatic" declaration of each typeparam
|
||||
// type TypeParam struct {
|
||||
// Tag byte // 'P'
|
||||
// Pos Pos
|
||||
// Implicit bool
|
||||
// Constraint typeOff
|
||||
// }
|
||||
//
|
||||
// typeOff means a uvarint that either indicates a predeclared type,
|
||||
// or an offset into the Data section. If the uvarint is less than
|
||||
// predeclReserved, then it indicates the index into the predeclared
|
||||
// types list (see predeclared in bexport.go for order). Otherwise,
|
||||
// subtracting predeclReserved yields the offset of a type descriptor.
|
||||
//
|
||||
// Value means a type, kind, and type-specific value. See
|
||||
// (*exportWriter).value for details.
|
||||
//
|
||||
//
|
||||
// There are twelve kinds of type descriptors, distinguished by an itag:
|
||||
//
|
||||
// type DefinedType struct {
|
||||
// Tag itag // definedType
|
||||
// Name stringOff
|
||||
// PkgPath stringOff
|
||||
// }
|
||||
//
|
||||
// type PointerType struct {
|
||||
// Tag itag // pointerType
|
||||
// Elem typeOff
|
||||
// }
|
||||
//
|
||||
// type SliceType struct {
|
||||
// Tag itag // sliceType
|
||||
// Elem typeOff
|
||||
// }
|
||||
//
|
||||
// type ArrayType struct {
|
||||
// Tag itag // arrayType
|
||||
// Len uint64
|
||||
// Elem typeOff
|
||||
// }
|
||||
//
|
||||
// type ChanType struct {
|
||||
// Tag itag // chanType
|
||||
// Dir uint64 // 1 RecvOnly; 2 SendOnly; 3 SendRecv
|
||||
// Elem typeOff
|
||||
// }
|
||||
//
|
||||
// type MapType struct {
|
||||
// Tag itag // mapType
|
||||
// Key typeOff
|
||||
// Elem typeOff
|
||||
// }
|
||||
//
|
||||
// type FuncType struct {
|
||||
// Tag itag // signatureType
|
||||
// PkgPath stringOff
|
||||
// Signature Signature
|
||||
// }
|
||||
//
|
||||
// type StructType struct {
|
||||
// Tag itag // structType
|
||||
// PkgPath stringOff
|
||||
// Fields []struct {
|
||||
// Pos Pos
|
||||
// Name stringOff
|
||||
// Type typeOff
|
||||
// Embedded bool
|
||||
// Note stringOff
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// type InterfaceType struct {
|
||||
// Tag itag // interfaceType
|
||||
// PkgPath stringOff
|
||||
// Embeddeds []struct {
|
||||
// Pos Pos
|
||||
// Type typeOff
|
||||
// }
|
||||
// Methods []struct {
|
||||
// Pos Pos
|
||||
// Name stringOff
|
||||
// Signature Signature
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Reference to a type param declaration
|
||||
// type TypeParamType struct {
|
||||
// Tag itag // typeParamType
|
||||
// Name stringOff
|
||||
// PkgPath stringOff
|
||||
// }
|
||||
//
|
||||
// // Instantiation of a generic type (like List[T2] or List[int])
|
||||
// type InstanceType struct {
|
||||
// Tag itag // instanceType
|
||||
// Pos pos
|
||||
// TypeArgs []typeOff
|
||||
// BaseType typeOff
|
||||
// }
|
||||
//
|
||||
// type UnionType struct {
|
||||
// Tag itag // interfaceType
|
||||
// Terms []struct {
|
||||
// tilde bool
|
||||
// Type typeOff
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// type Signature struct {
|
||||
// Params []Param
|
||||
// Results []Param
|
||||
// Variadic bool // omitted if Results is empty
|
||||
// }
|
||||
//
|
||||
// type Param struct {
|
||||
// Pos Pos
|
||||
// Name stringOff
|
||||
// Type typOff
|
||||
// }
|
||||
//
|
||||
//
|
||||
// Pos encodes a file:line:column triple, incorporating a simple delta
|
||||
// encoding scheme within a data object. See exportWriter.pos for
|
||||
// details.
|
||||
|
||||
package gcimporter
|
||||
|
||||
@@ -18,26 +236,46 @@ import (
|
||||
"io"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/types/objectpath"
|
||||
"golang.org/x/tools/internal/aliases"
|
||||
"golang.org/x/tools/internal/tokeninternal"
|
||||
)
|
||||
|
||||
// IExportShallow encodes "shallow" export data for the specified package.
|
||||
//
|
||||
// For types, we use "shallow" export data. Historically, the Go
|
||||
// compiler always produced a summary of the types for a given package
|
||||
// that included types from other packages that it indirectly
|
||||
// referenced: "deep" export data. This had the advantage that the
|
||||
// compiler (and analogous tools such as gopls) need only load one
|
||||
// file per direct import. However, it meant that the files tended to
|
||||
// get larger based on the level of the package in the import
|
||||
// graph. For example, higher-level packages in the kubernetes module
|
||||
// have over 1MB of "deep" export data, even when they have almost no
|
||||
// content of their own, merely because they mention a major type that
|
||||
// references many others. In pathological cases the export data was
|
||||
// 300x larger than the source for a package due to this quadratic
|
||||
// growth.
|
||||
//
|
||||
// "Shallow" export data means that the serialized types describe only
|
||||
// a single package. If those types mention types from other packages,
|
||||
// the type checker may need to request additional packages beyond
|
||||
// just the direct imports. Type information for the entire transitive
|
||||
// closure of imports is provided (lazily) by the DAG.
|
||||
//
|
||||
// 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.
|
||||
// If the provided reportf func is non-nil, it is used for reporting
|
||||
// bugs (e.g. recovered panics) encountered during export, enabling us
|
||||
// to obtain via telemetry the stack that would otherwise be lost by
|
||||
// merely returning an error.
|
||||
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
|
||||
@@ -46,13 +284,13 @@ func IExportShallow(fset *token.FileSet, pkg *types.Package, reportf ReportFunc)
|
||||
// TODO(adonovan): use byte slices throughout, avoiding copying.
|
||||
const bundle, shallow = false, true
|
||||
var out bytes.Buffer
|
||||
err := iexportCommon(&out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg})
|
||||
err := iexportCommon(&out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg}, reportf)
|
||||
return out.Bytes(), err
|
||||
}
|
||||
|
||||
// IImportShallow decodes "shallow" types.Package data encoded by
|
||||
// IExportShallow in the same executable. This function cannot import data from
|
||||
// cmd/compile or gcexportdata.Write.
|
||||
// [IExportShallow] in the same executable. This function cannot import data
|
||||
// from cmd/compile or gcexportdata.Write.
|
||||
//
|
||||
// The importer calls getPackages to obtain package symbols for all
|
||||
// packages mentioned in the export data, including the one being
|
||||
@@ -73,7 +311,7 @@ func IImportShallow(fset *token.FileSet, getPackages GetPackagesFunc, data []byt
|
||||
}
|
||||
|
||||
// ReportFunc is the type of a function used to report formatted bugs.
|
||||
type ReportFunc = func(string, ...interface{})
|
||||
type ReportFunc = func(string, ...any)
|
||||
|
||||
// Current bundled export format version. Increase with each format change.
|
||||
// 0: initial implementation
|
||||
@@ -86,20 +324,27 @@ const bundleVersion = 0
|
||||
// so that calls to IImportData can override with a provided package path.
|
||||
func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error {
|
||||
const bundle, shallow = false, false
|
||||
return iexportCommon(out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg})
|
||||
return iexportCommon(out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg}, nil)
|
||||
}
|
||||
|
||||
// IExportBundle writes an indexed export bundle for pkgs to out.
|
||||
func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error {
|
||||
const bundle, shallow = true, false
|
||||
return iexportCommon(out, fset, bundle, shallow, iexportVersion, pkgs)
|
||||
return iexportCommon(out, fset, bundle, shallow, iexportVersion, pkgs, nil)
|
||||
}
|
||||
|
||||
func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, version int, pkgs []*types.Package) (err error) {
|
||||
func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, version int, pkgs []*types.Package, reportf ReportFunc) (err error) {
|
||||
if !debug {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
// Report the stack via telemetry (see #71067).
|
||||
if reportf != nil {
|
||||
reportf("panic in exporter")
|
||||
}
|
||||
if ierr, ok := e.(internalError); ok {
|
||||
// internalError usually means we exported a
|
||||
// bad go/types data structure: a violation
|
||||
// of an implicit precondition of Export.
|
||||
err = ierr
|
||||
return
|
||||
}
|
||||
@@ -221,9 +466,9 @@ func (p *iexporter) encodeFile(w *intWriter, file *token.File, needed []uint64)
|
||||
w.uint64(size)
|
||||
|
||||
// Sort the set of needed offsets. Duplicates are harmless.
|
||||
sort.Slice(needed, func(i, j int) bool { return needed[i] < needed[j] })
|
||||
slices.Sort(needed)
|
||||
|
||||
lines := tokeninternal.GetLines(file) // byte offset of each line start
|
||||
lines := file.Lines() // byte offset of each line start
|
||||
w.uint64(uint64(len(lines)))
|
||||
|
||||
// Rather than record the entire array of line start offsets,
|
||||
@@ -360,7 +605,7 @@ type filePositions struct {
|
||||
needed []uint64 // unordered list of needed file offsets
|
||||
}
|
||||
|
||||
func (p *iexporter) trace(format string, args ...interface{}) {
|
||||
func (p *iexporter) trace(format string, args ...any) {
|
||||
if !trace {
|
||||
// Call sites should also be guarded, but having this check here allows
|
||||
// easily enabling/disabling debug trace statements.
|
||||
@@ -507,13 +752,13 @@ func (p *iexporter) doDecl(obj types.Object) {
|
||||
case *types.TypeName:
|
||||
t := obj.Type()
|
||||
|
||||
if tparam, ok := aliases.Unalias(t).(*types.TypeParam); ok {
|
||||
if tparam, ok := types.Unalias(t).(*types.TypeParam); ok {
|
||||
w.tag(typeParamTag)
|
||||
w.pos(obj.Pos())
|
||||
constraint := tparam.Constraint()
|
||||
if p.version >= iexportVersionGo1_18 {
|
||||
implicit := false
|
||||
if iface, _ := aliases.Unalias(constraint).(*types.Interface); iface != nil {
|
||||
if iface, _ := types.Unalias(constraint).(*types.Interface); iface != nil {
|
||||
implicit = iface.IsImplicit()
|
||||
}
|
||||
w.bool(implicit)
|
||||
@@ -523,9 +768,22 @@ func (p *iexporter) doDecl(obj types.Object) {
|
||||
}
|
||||
|
||||
if obj.IsAlias() {
|
||||
w.tag(aliasTag)
|
||||
alias, materialized := t.(*types.Alias) // may fail when aliases are not enabled
|
||||
|
||||
var tparams *types.TypeParamList
|
||||
if materialized {
|
||||
tparams = aliases.TypeParams(alias)
|
||||
}
|
||||
if tparams.Len() == 0 {
|
||||
w.tag(aliasTag)
|
||||
} else {
|
||||
w.tag(genericAliasTag)
|
||||
}
|
||||
w.pos(obj.Pos())
|
||||
if alias, ok := t.(*aliases.Alias); ok {
|
||||
if tparams.Len() > 0 {
|
||||
w.tparamList(obj.Name(), tparams, obj.Pkg())
|
||||
}
|
||||
if materialized {
|
||||
// Preserve materialized aliases,
|
||||
// even of non-exported types.
|
||||
t = aliases.Rhs(alias)
|
||||
@@ -562,7 +820,7 @@ func (p *iexporter) doDecl(obj types.Object) {
|
||||
|
||||
n := named.NumMethods()
|
||||
w.uint64(uint64(n))
|
||||
for i := 0; i < n; i++ {
|
||||
for i := range n {
|
||||
m := named.Method(i)
|
||||
w.pos(m.Pos())
|
||||
w.string(m.Name())
|
||||
@@ -744,8 +1002,14 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
|
||||
}()
|
||||
}
|
||||
switch t := t.(type) {
|
||||
case *aliases.Alias:
|
||||
// TODO(adonovan): support parameterized aliases, following *types.Named.
|
||||
case *types.Alias:
|
||||
if targs := aliases.TypeArgs(t); targs.Len() > 0 {
|
||||
w.startType(instanceType)
|
||||
w.pos(t.Obj().Pos())
|
||||
w.typeList(targs, pkg)
|
||||
w.typ(aliases.Origin(t), pkg)
|
||||
return
|
||||
}
|
||||
w.startType(aliasType)
|
||||
w.qualifiedType(t.Obj())
|
||||
|
||||
@@ -833,7 +1097,7 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
|
||||
w.pkg(fieldPkg)
|
||||
w.uint64(uint64(n))
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
for i := range n {
|
||||
f := t.Field(i)
|
||||
if w.p.shallow {
|
||||
w.objectPath(f)
|
||||
@@ -854,7 +1118,7 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
|
||||
for i := 0; i < n; i++ {
|
||||
ft := t.EmbeddedType(i)
|
||||
tPkg := pkg
|
||||
if named, _ := aliases.Unalias(ft).(*types.Named); named != nil {
|
||||
if named, _ := types.Unalias(ft).(*types.Named); named != nil {
|
||||
w.pos(named.Obj().Pos())
|
||||
} else {
|
||||
w.pos(token.NoPos)
|
||||
@@ -882,7 +1146,7 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
|
||||
w.startType(unionType)
|
||||
nt := t.Len()
|
||||
w.uint64(uint64(nt))
|
||||
for i := 0; i < nt; i++ {
|
||||
for i := range nt {
|
||||
term := t.Term(i)
|
||||
w.bool(term.Tilde())
|
||||
w.typ(term.Type(), pkg)
|
||||
@@ -1011,7 +1275,7 @@ func tparamName(exportName string) string {
|
||||
func (w *exportWriter) paramList(tup *types.Tuple) {
|
||||
n := tup.Len()
|
||||
w.uint64(uint64(n))
|
||||
for i := 0; i < n; i++ {
|
||||
for i := range n {
|
||||
w.param(tup.At(i))
|
||||
}
|
||||
}
|
||||
@@ -1327,6 +1591,6 @@ func (e internalError) Error() string { return "gcimporter: " + string(e) }
|
||||
// "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 {
|
||||
func internalErrorf(format string, args ...any) error {
|
||||
return internalError(fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
60
vendor/golang.org/x/tools/internal/gcimporter/iimport.go
generated
vendored
60
vendor/golang.org/x/tools/internal/gcimporter/iimport.go
generated
vendored
@@ -3,9 +3,7 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Indexed package import.
|
||||
// See cmd/compile/internal/gc/iexport.go for the export data format.
|
||||
|
||||
// This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go.
|
||||
// See iexport.go for the export data format.
|
||||
|
||||
package gcimporter
|
||||
|
||||
@@ -18,6 +16,7 @@ import (
|
||||
"go/types"
|
||||
"io"
|
||||
"math/big"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@@ -53,6 +52,7 @@ const (
|
||||
iexportVersionPosCol = 1
|
||||
iexportVersionGo1_18 = 2
|
||||
iexportVersionGenerics = 2
|
||||
iexportVersion = iexportVersionGenerics
|
||||
|
||||
iexportVersionCurrent = 2
|
||||
)
|
||||
@@ -315,7 +315,7 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte
|
||||
pkgs = pkgList[:1]
|
||||
|
||||
// record all referenced packages as imports
|
||||
list := append(([]*types.Package)(nil), pkgList[1:]...)
|
||||
list := slices.Clone(pkgList[1:])
|
||||
sort.Sort(byPath(list))
|
||||
pkgs[0].SetImports(list)
|
||||
}
|
||||
@@ -401,7 +401,7 @@ type iimporter struct {
|
||||
indent int // for tracing support
|
||||
}
|
||||
|
||||
func (p *iimporter) trace(format string, args ...interface{}) {
|
||||
func (p *iimporter) trace(format string, args ...any) {
|
||||
if !trace {
|
||||
// Call sites should also be guarded, but having this check here allows
|
||||
// easily enabling/disabling debug trace statements.
|
||||
@@ -540,7 +540,7 @@ func canReuse(def *types.Named, rhs types.Type) bool {
|
||||
if def == nil {
|
||||
return true
|
||||
}
|
||||
iface, _ := aliases.Unalias(rhs).(*types.Interface)
|
||||
iface, _ := types.Unalias(rhs).(*types.Interface)
|
||||
if iface == nil {
|
||||
return true
|
||||
}
|
||||
@@ -557,19 +557,28 @@ type importReader struct {
|
||||
prevColumn int64
|
||||
}
|
||||
|
||||
// markBlack is redefined in iimport_go123.go, to work around golang/go#69912.
|
||||
//
|
||||
// If TypeNames are not marked black (in the sense of go/types cycle
|
||||
// detection), they may be mutated when dot-imported. Fix this by punching a
|
||||
// hole through the type, when compiling with Go 1.23. (The bug has been fixed
|
||||
// for 1.24, but the fix was not worth back-porting).
|
||||
var markBlack = func(name *types.TypeName) {}
|
||||
|
||||
func (r *importReader) obj(name string) {
|
||||
tag := r.byte()
|
||||
pos := r.pos()
|
||||
|
||||
switch tag {
|
||||
case aliasTag:
|
||||
case aliasTag, genericAliasTag:
|
||||
var tparams []*types.TypeParam
|
||||
if tag == genericAliasTag {
|
||||
tparams = r.tparamList()
|
||||
}
|
||||
typ := r.typ()
|
||||
// TODO(adonovan): support generic aliases:
|
||||
// if tag == genericAliasTag {
|
||||
// tparams := r.tparamList()
|
||||
// alias.SetTypeParams(tparams)
|
||||
// }
|
||||
r.declare(aliases.NewAlias(r.p.aliases, pos, r.currPkg, name, typ))
|
||||
obj := aliases.NewAlias(r.p.aliases, pos, r.currPkg, name, typ, tparams)
|
||||
markBlack(obj) // workaround for golang/go#69912
|
||||
r.declare(obj)
|
||||
|
||||
case constTag:
|
||||
typ, val := r.value()
|
||||
@@ -589,6 +598,9 @@ func (r *importReader) obj(name string) {
|
||||
// declaration before recursing.
|
||||
obj := types.NewTypeName(pos, r.currPkg, name, nil)
|
||||
named := types.NewNamed(obj, nil, nil)
|
||||
|
||||
markBlack(obj) // workaround for golang/go#69912
|
||||
|
||||
// Declare obj before calling r.tparamList, so the new type name is recognized
|
||||
// if used in the constraint of one of its own typeparams (see #48280).
|
||||
r.declare(obj)
|
||||
@@ -615,7 +627,7 @@ func (r *importReader) obj(name string) {
|
||||
if targs.Len() > 0 {
|
||||
rparams = make([]*types.TypeParam, targs.Len())
|
||||
for i := range rparams {
|
||||
rparams[i] = aliases.Unalias(targs.At(i)).(*types.TypeParam)
|
||||
rparams[i] = types.Unalias(targs.At(i)).(*types.TypeParam)
|
||||
}
|
||||
}
|
||||
msig := r.signature(recv, rparams, nil)
|
||||
@@ -645,7 +657,7 @@ func (r *importReader) obj(name string) {
|
||||
}
|
||||
constraint := r.typ()
|
||||
if implicit {
|
||||
iface, _ := aliases.Unalias(constraint).(*types.Interface)
|
||||
iface, _ := types.Unalias(constraint).(*types.Interface)
|
||||
if iface == nil {
|
||||
errorf("non-interface constraint marked implicit")
|
||||
}
|
||||
@@ -660,7 +672,9 @@ func (r *importReader) obj(name string) {
|
||||
case varTag:
|
||||
typ := r.typ()
|
||||
|
||||
r.declare(types.NewVar(pos, r.currPkg, name, typ))
|
||||
v := types.NewVar(pos, r.currPkg, name, typ)
|
||||
typesinternal.SetVarKind(v, typesinternal.PackageVar)
|
||||
r.declare(v)
|
||||
|
||||
default:
|
||||
errorf("unexpected tag: %v", tag)
|
||||
@@ -852,7 +866,7 @@ func (r *importReader) typ() types.Type {
|
||||
}
|
||||
|
||||
func isInterface(t types.Type) bool {
|
||||
_, ok := aliases.Unalias(t).(*types.Interface)
|
||||
_, ok := types.Unalias(t).(*types.Interface)
|
||||
return ok
|
||||
}
|
||||
|
||||
@@ -862,7 +876,7 @@ func (r *importReader) string() string { return r.p.stringAt(r.uint64()) }
|
||||
func (r *importReader) doType(base *types.Named) (res types.Type) {
|
||||
k := r.kind()
|
||||
if debug {
|
||||
r.p.trace("importing type %d (base: %s)", k, base)
|
||||
r.p.trace("importing type %d (base: %v)", k, base)
|
||||
r.p.indent++
|
||||
defer func() {
|
||||
r.p.indent--
|
||||
@@ -959,7 +973,7 @@ func (r *importReader) doType(base *types.Named) (res types.Type) {
|
||||
methods[i] = method
|
||||
}
|
||||
|
||||
typ := newInterface(methods, embeddeds)
|
||||
typ := types.NewInterfaceType(methods, embeddeds)
|
||||
r.p.interfaceList = append(r.p.interfaceList, typ)
|
||||
return typ
|
||||
|
||||
@@ -1051,7 +1065,7 @@ func (r *importReader) tparamList() []*types.TypeParam {
|
||||
for i := range xs {
|
||||
// Note: the standard library importer is tolerant of nil types here,
|
||||
// though would panic in SetTypeParams.
|
||||
xs[i] = aliases.Unalias(r.typ()).(*types.TypeParam)
|
||||
xs[i] = types.Unalias(r.typ()).(*types.TypeParam)
|
||||
}
|
||||
return xs
|
||||
}
|
||||
@@ -1098,3 +1112,9 @@ func (r *importReader) byte() byte {
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
type byPath []*types.Package
|
||||
|
||||
func (a byPath) Len() int { return len(a) }
|
||||
func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
|
||||
|
53
vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go
generated
vendored
Normal file
53
vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.22 && !go1.24
|
||||
|
||||
package gcimporter
|
||||
|
||||
import (
|
||||
"go/token"
|
||||
"go/types"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// TODO(rfindley): delete this workaround once go1.24 is assured.
|
||||
|
||||
func init() {
|
||||
// Update markBlack so that it correctly sets the color
|
||||
// of imported TypeNames.
|
||||
//
|
||||
// See the doc comment for markBlack for details.
|
||||
|
||||
type color uint32
|
||||
const (
|
||||
white color = iota
|
||||
black
|
||||
grey
|
||||
)
|
||||
type object struct {
|
||||
_ *types.Scope
|
||||
_ token.Pos
|
||||
_ *types.Package
|
||||
_ string
|
||||
_ types.Type
|
||||
_ uint32
|
||||
color_ color
|
||||
_ token.Pos
|
||||
}
|
||||
type typeName struct {
|
||||
object
|
||||
}
|
||||
|
||||
// If the size of types.TypeName changes, this will fail to compile.
|
||||
const delta = int64(unsafe.Sizeof(typeName{})) - int64(unsafe.Sizeof(types.TypeName{}))
|
||||
var _ [-delta * delta]int
|
||||
|
||||
markBlack = func(obj *types.TypeName) {
|
||||
type uP = unsafe.Pointer
|
||||
var ptr *typeName
|
||||
*(*uP)(uP(&ptr)) = uP(obj)
|
||||
ptr.color_ = black
|
||||
}
|
||||
}
|
22
vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go
generated
vendored
22
vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go
generated
vendored
@@ -1,22 +0,0 @@
|
||||
// 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.
|
||||
|
||||
//go:build !go1.11
|
||||
// +build !go1.11
|
||||
|
||||
package gcimporter
|
||||
|
||||
import "go/types"
|
||||
|
||||
func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
|
||||
named := make([]*types.Named, len(embeddeds))
|
||||
for i, e := range embeddeds {
|
||||
var ok bool
|
||||
named[i], ok = e.(*types.Named)
|
||||
if !ok {
|
||||
panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11")
|
||||
}
|
||||
}
|
||||
return types.NewInterface(methods, named)
|
||||
}
|
14
vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go
generated
vendored
14
vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go
generated
vendored
@@ -1,14 +0,0 @@
|
||||
// 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.
|
||||
|
||||
//go:build go1.11
|
||||
// +build go1.11
|
||||
|
||||
package gcimporter
|
||||
|
||||
import "go/types"
|
||||
|
||||
func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
|
||||
return types.NewInterfaceType(methods, embeddeds)
|
||||
}
|
91
vendor/golang.org/x/tools/internal/gcimporter/predeclared.go
generated
vendored
Normal file
91
vendor/golang.org/x/tools/internal/gcimporter/predeclared.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gcimporter
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// predecl is a cache for the predeclared types in types.Universe.
|
||||
//
|
||||
// Cache a distinct result based on the runtime value of any.
|
||||
// The pointer value of the any type varies based on GODEBUG settings.
|
||||
var predeclMu sync.Mutex
|
||||
var predecl map[types.Type][]types.Type
|
||||
|
||||
func predeclared() []types.Type {
|
||||
anyt := types.Universe.Lookup("any").Type()
|
||||
|
||||
predeclMu.Lock()
|
||||
defer predeclMu.Unlock()
|
||||
|
||||
if pre, ok := predecl[anyt]; ok {
|
||||
return pre
|
||||
}
|
||||
|
||||
if predecl == nil {
|
||||
predecl = make(map[types.Type][]types.Type)
|
||||
}
|
||||
|
||||
decls := []types.Type{ // basic types
|
||||
types.Typ[types.Bool],
|
||||
types.Typ[types.Int],
|
||||
types.Typ[types.Int8],
|
||||
types.Typ[types.Int16],
|
||||
types.Typ[types.Int32],
|
||||
types.Typ[types.Int64],
|
||||
types.Typ[types.Uint],
|
||||
types.Typ[types.Uint8],
|
||||
types.Typ[types.Uint16],
|
||||
types.Typ[types.Uint32],
|
||||
types.Typ[types.Uint64],
|
||||
types.Typ[types.Uintptr],
|
||||
types.Typ[types.Float32],
|
||||
types.Typ[types.Float64],
|
||||
types.Typ[types.Complex64],
|
||||
types.Typ[types.Complex128],
|
||||
types.Typ[types.String],
|
||||
|
||||
// basic type aliases
|
||||
types.Universe.Lookup("byte").Type(),
|
||||
types.Universe.Lookup("rune").Type(),
|
||||
|
||||
// error
|
||||
types.Universe.Lookup("error").Type(),
|
||||
|
||||
// untyped types
|
||||
types.Typ[types.UntypedBool],
|
||||
types.Typ[types.UntypedInt],
|
||||
types.Typ[types.UntypedRune],
|
||||
types.Typ[types.UntypedFloat],
|
||||
types.Typ[types.UntypedComplex],
|
||||
types.Typ[types.UntypedString],
|
||||
types.Typ[types.UntypedNil],
|
||||
|
||||
// package unsafe
|
||||
types.Typ[types.UnsafePointer],
|
||||
|
||||
// invalid type
|
||||
types.Typ[types.Invalid], // only appears in packages with errors
|
||||
|
||||
// used internally by gc; never used by this package or in .a files
|
||||
anyType{},
|
||||
|
||||
// comparable
|
||||
types.Universe.Lookup("comparable").Type(),
|
||||
|
||||
// any
|
||||
anyt,
|
||||
}
|
||||
|
||||
predecl[anyt] = decls
|
||||
return decls
|
||||
}
|
||||
|
||||
type anyType struct{}
|
||||
|
||||
func (t anyType) Underlying() types.Type { return t }
|
||||
func (t anyType) String() string { return "any" }
|
30
vendor/golang.org/x/tools/internal/gcimporter/support.go
generated
vendored
Normal file
30
vendor/golang.org/x/tools/internal/gcimporter/support.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gcimporter
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Copy of $GOROOT/src/cmd/internal/archive.ReadHeader.
|
||||
func readArchiveHeader(b *bufio.Reader, name string) int {
|
||||
// architecture-independent object file output
|
||||
const HeaderSize = 60
|
||||
|
||||
var buf [HeaderSize]byte
|
||||
if _, err := io.ReadFull(b, buf[:]); err != nil {
|
||||
return -1
|
||||
}
|
||||
aname := strings.Trim(string(buf[0:16]), " ")
|
||||
if !strings.HasPrefix(aname, name) {
|
||||
return -1
|
||||
}
|
||||
asize := strings.Trim(string(buf[48:58]), " ")
|
||||
i, _ := strconv.Atoi(asize)
|
||||
return i
|
||||
}
|
34
vendor/golang.org/x/tools/internal/gcimporter/support_go118.go
generated
vendored
34
vendor/golang.org/x/tools/internal/gcimporter/support_go118.go
generated
vendored
@@ -1,34 +0,0 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gcimporter
|
||||
|
||||
import "go/types"
|
||||
|
||||
const iexportVersion = iexportVersionGenerics
|
||||
|
||||
// additionalPredeclared returns additional predeclared types in go.1.18.
|
||||
func additionalPredeclared() []types.Type {
|
||||
return []types.Type{
|
||||
// comparable
|
||||
types.Universe.Lookup("comparable").Type(),
|
||||
|
||||
// any
|
||||
types.Universe.Lookup("any").Type(),
|
||||
}
|
||||
}
|
||||
|
||||
// See cmd/compile/internal/types.SplitVargenSuffix.
|
||||
func splitVargenSuffix(name string) (base, suffix string) {
|
||||
i := len(name)
|
||||
for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' {
|
||||
i--
|
||||
}
|
||||
const dot = "·"
|
||||
if i >= len(dot) && name[i-len(dot):i] == dot {
|
||||
i -= len(dot)
|
||||
return name[:i], name[i:]
|
||||
}
|
||||
return name, ""
|
||||
}
|
10
vendor/golang.org/x/tools/internal/gcimporter/unified_no.go
generated
vendored
10
vendor/golang.org/x/tools/internal/gcimporter/unified_no.go
generated
vendored
@@ -1,10 +0,0 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !goexperiment.unified
|
||||
// +build !goexperiment.unified
|
||||
|
||||
package gcimporter
|
||||
|
||||
const unifiedIR = false
|
10
vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go
generated
vendored
10
vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go
generated
vendored
@@ -1,10 +0,0 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build goexperiment.unified
|
||||
// +build goexperiment.unified
|
||||
|
||||
package gcimporter
|
||||
|
||||
const unifiedIR = true
|
61
vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go
generated
vendored
61
vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go
generated
vendored
@@ -11,10 +11,10 @@ import (
|
||||
"go/token"
|
||||
"go/types"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/internal/aliases"
|
||||
"golang.org/x/tools/internal/pkgbits"
|
||||
"golang.org/x/tools/internal/typesinternal"
|
||||
)
|
||||
|
||||
// A pkgReader holds the shared state for reading a unified IR package
|
||||
@@ -52,8 +52,7 @@ func (pr *pkgReader) later(fn func()) {
|
||||
|
||||
// See cmd/compile/internal/noder.derivedInfo.
|
||||
type derivedInfo struct {
|
||||
idx pkgbits.Index
|
||||
needed bool
|
||||
idx pkgbits.Index
|
||||
}
|
||||
|
||||
// See cmd/compile/internal/noder.typeInfo.
|
||||
@@ -72,7 +71,6 @@ func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []
|
||||
}
|
||||
|
||||
s := string(data)
|
||||
s = s[:strings.LastIndex(s, "\n$$\n")]
|
||||
input := pkgbits.NewPkgDecoder(path, s)
|
||||
pkg = readUnifiedPackage(fset, nil, imports, input)
|
||||
return
|
||||
@@ -110,13 +108,17 @@ func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[st
|
||||
|
||||
r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
|
||||
pkg := r.pkg()
|
||||
r.Bool() // has init
|
||||
if r.Version().Has(pkgbits.HasInit) {
|
||||
r.Bool()
|
||||
}
|
||||
|
||||
for i, n := 0, r.Len(); i < n; i++ {
|
||||
// As if r.obj(), but avoiding the Scope.Lookup call,
|
||||
// to avoid eager loading of imports.
|
||||
r.Sync(pkgbits.SyncObject)
|
||||
assert(!r.Bool())
|
||||
if r.Version().Has(pkgbits.DerivedFuncInstance) {
|
||||
assert(!r.Bool())
|
||||
}
|
||||
r.p.objIdx(r.Reloc(pkgbits.RelocObj))
|
||||
assert(r.Len() == 0)
|
||||
}
|
||||
@@ -165,7 +167,7 @@ type readerDict struct {
|
||||
// tparams is a slice of the constructed TypeParams for the element.
|
||||
tparams []*types.TypeParam
|
||||
|
||||
// devived is a slice of types derived from tparams, which may be
|
||||
// derived is a slice of types derived from tparams, which may be
|
||||
// instantiated while reading the current element.
|
||||
derived []derivedInfo
|
||||
derivedTypes []types.Type // lazily instantiated from derived
|
||||
@@ -263,7 +265,12 @@ func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package {
|
||||
func (r *reader) doPkg() *types.Package {
|
||||
path := r.String()
|
||||
switch path {
|
||||
case "":
|
||||
// cmd/compile emits path="main" for main packages because
|
||||
// that's the linker symbol prefix it used; but we need
|
||||
// the package's path as it would be reported by go list,
|
||||
// hence "main" below.
|
||||
// See test at go/packages.TestMainPackagePathInModeTypes.
|
||||
case "", "main":
|
||||
path = r.p.PkgPath()
|
||||
case "builtin":
|
||||
return nil // universe
|
||||
@@ -471,7 +478,9 @@ func (r *reader) param() *types.Var {
|
||||
func (r *reader) obj() (types.Object, []types.Type) {
|
||||
r.Sync(pkgbits.SyncObject)
|
||||
|
||||
assert(!r.Bool())
|
||||
if r.Version().Has(pkgbits.DerivedFuncInstance) {
|
||||
assert(!r.Bool())
|
||||
}
|
||||
|
||||
pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj))
|
||||
obj := pkgScope(pkg).Lookup(name)
|
||||
@@ -525,8 +534,12 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
|
||||
|
||||
case pkgbits.ObjAlias:
|
||||
pos := r.pos()
|
||||
var tparams []*types.TypeParam
|
||||
if r.Version().Has(pkgbits.AliasTypeParamNames) {
|
||||
tparams = r.typeParamNames()
|
||||
}
|
||||
typ := r.typ()
|
||||
declare(aliases.NewAlias(r.p.aliases, pos, objPkg, objName, typ))
|
||||
declare(aliases.NewAlias(r.p.aliases, pos, objPkg, objName, typ, tparams))
|
||||
|
||||
case pkgbits.ObjConst:
|
||||
pos := r.pos()
|
||||
@@ -553,14 +566,15 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
|
||||
// If the underlying type is an interface, we need to
|
||||
// duplicate its methods so we can replace the receiver
|
||||
// parameter's type (#49906).
|
||||
if iface, ok := aliases.Unalias(underlying).(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
|
||||
if iface, ok := types.Unalias(underlying).(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
|
||||
methods := make([]*types.Func, iface.NumExplicitMethods())
|
||||
for i := range methods {
|
||||
fn := iface.ExplicitMethod(i)
|
||||
sig := fn.Type().(*types.Signature)
|
||||
|
||||
recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named)
|
||||
methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic()))
|
||||
typesinternal.SetVarKind(recv, typesinternal.RecvVar)
|
||||
methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignatureType(recv, nil, nil, sig.Params(), sig.Results(), sig.Variadic()))
|
||||
}
|
||||
|
||||
embeds := make([]types.Type, iface.NumEmbeddeds())
|
||||
@@ -607,7 +621,9 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
|
||||
case pkgbits.ObjVar:
|
||||
pos := r.pos()
|
||||
typ := r.typ()
|
||||
declare(types.NewVar(pos, objPkg, objName, typ))
|
||||
v := types.NewVar(pos, objPkg, objName, typ)
|
||||
typesinternal.SetVarKind(v, typesinternal.PackageVar)
|
||||
declare(v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -632,7 +648,10 @@ func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
|
||||
dict.derived = make([]derivedInfo, r.Len())
|
||||
dict.derivedTypes = make([]types.Type, len(dict.derived))
|
||||
for i := range dict.derived {
|
||||
dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
|
||||
dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.RelocType)}
|
||||
if r.Version().Has(pkgbits.DerivedInfoNeeded) {
|
||||
assert(!r.Bool())
|
||||
}
|
||||
}
|
||||
|
||||
pr.retireReader(r)
|
||||
@@ -726,3 +745,17 @@ func pkgScope(pkg *types.Package) *types.Scope {
|
||||
}
|
||||
return types.Universe
|
||||
}
|
||||
|
||||
// See cmd/compile/internal/types.SplitVargenSuffix.
|
||||
func splitVargenSuffix(name string) (base, suffix string) {
|
||||
i := len(name)
|
||||
for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' {
|
||||
i--
|
||||
}
|
||||
const dot = "·"
|
||||
if i >= len(dot) && name[i-len(dot):i] == dot {
|
||||
i -= len(dot)
|
||||
return name[:i], name[i:]
|
||||
}
|
||||
return name, ""
|
||||
}
|
||||
|
Reference in New Issue
Block a user