4
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2025-07-12 02:56:28 +00:00

Update dependencies (#1784)

This commit is contained in:
Wim
2022-04-01 00:23:19 +02:00
committed by GitHub
parent 4ab72acec6
commit c6716e030c
255 changed files with 69606 additions and 58489 deletions

View File

@ -50,11 +50,24 @@ func Find(importPath, srcDir string) (filename, path string) {
// additional trailing data beyond the end of the export data.
func NewReader(r io.Reader) (io.Reader, error) {
buf := bufio.NewReader(r)
_, err := gcimporter.FindExportData(buf)
// If we ever switch to a zip-like archive format with the ToC
// at the end, we can return the correct portion of export data,
// but for now we must return the entire rest of the file.
return buf, err
_, size, err := gcimporter.FindExportData(buf)
if err != nil {
return nil, err
}
if size >= 0 {
// We were given an archive and found the __.PKGDEF in it.
// This tells us the size of the export data, and we don't
// need to return the entire file.
return &io.LimitedReader{
R: buf,
N: size,
}, nil
} else {
// We were given an object file. As such, we don't know how large
// the export data is and must return the entire file.
return buf, nil
}
}
// Read reads export data from in, decodes it, and returns type

View File

@ -34,9 +34,6 @@ import (
// (suspected) format errors, and whenever a change is made to the format.
const debugFormat = false // default: false
// If trace is set, debugging output is printed to std out.
const trace = false // default: false
// Current export format version. Increase with each format change.
// Note: The latest binary (non-indexed) export format is at version 6.
// This exporter is still at level 4, but it doesn't matter since

View File

@ -74,9 +74,10 @@ func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []
pathList: []string{""}, // empty string is mapped to 0
fake: fakeFileSet{
fset: fset,
files: make(map[string]*token.File),
files: make(map[string]*fileInfo),
},
}
defer p.fake.setLines() // set lines for files in fset
// read version info
var versionstr string
@ -338,37 +339,49 @@ func (p *importer) pos() token.Pos {
// Synthesize a token.Pos
type fakeFileSet struct {
fset *token.FileSet
files map[string]*token.File
files map[string]*fileInfo
}
type fileInfo struct {
file *token.File
lastline int
}
const maxlines = 64 * 1024
func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
// TODO(mdempsky): Make use of column.
// Since we don't know the set of needed file positions, we
// reserve maxlines positions per file.
const maxlines = 64 * 1024
// Since we don't know the set of needed file positions, we reserve maxlines
// positions per file. We delay calling token.File.SetLines until all
// positions have been calculated (by way of fakeFileSet.setLines), so that
// we can avoid setting unnecessary lines. See also golang/go#46586.
f := s.files[file]
if f == nil {
f = s.fset.AddFile(file, -1, maxlines)
f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)}
s.files[file] = f
// Allocate the fake linebreak indices on first use.
// TODO(adonovan): opt: save ~512KB using a more complex scheme?
fakeLinesOnce.Do(func() {
fakeLines = make([]int, maxlines)
for i := range fakeLines {
fakeLines[i] = i
}
})
f.SetLines(fakeLines)
}
if line > maxlines {
line = 1
}
if line > f.lastline {
f.lastline = line
}
// Treat the file as if it contained only newlines
// and column=1: use the line number as the offset.
return f.Pos(line - 1)
// Return a fake position assuming that f.file consists only of newlines.
return token.Pos(f.file.Base() + line - 1)
}
func (s *fakeFileSet) setLines() {
fakeLinesOnce.Do(func() {
fakeLines = make([]int, maxlines)
for i := range fakeLines {
fakeLines[i] = i
}
})
for _, f := range s.files {
f.file.SetLines(fakeLines[:f.lastline])
}
}
var (

View File

@ -16,7 +16,7 @@ import (
"strings"
)
func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
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)
@ -28,7 +28,8 @@ func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
fmt.Printf("header: %s", hdr)
}
s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
size, err = strconv.Atoi(s)
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")
return
@ -42,8 +43,8 @@ func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
// 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".
//
func FindExportData(r *bufio.Reader) (hdr string, err error) {
// 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) {
// Read first line to make sure this is an object file.
line, err := r.ReadSlice('\n')
if err != nil {
@ -54,7 +55,7 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) {
if string(line) == "!<arch>\n" {
// Archive file. Scan to __.PKGDEF.
var name string
if name, _, err = readGopackHeader(r); err != nil {
if name, size, err = readGopackHeader(r); err != nil {
return
}
@ -70,6 +71,7 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) {
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.
@ -86,8 +88,12 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) {
err = fmt.Errorf("can't find export data (%v)", err)
return
}
size -= int64(len(line))
}
hdr = string(line)
if size < 0 {
size = -1
}
return
}

View File

@ -29,8 +29,14 @@ import (
"text/scanner"
)
// debugging/development support
const debug = false
const (
// Enable debug during development: it adds some additional checks, and
// prevents errors from being recovered.
debug = false
// If trace is set, debugging output is printed to std out.
trace = false
)
var pkgExts = [...]string{".a", ".o"}
@ -179,7 +185,7 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func
var hdr string
buf := bufio.NewReader(rc)
if hdr, err = FindExportData(buf); err != nil {
if hdr, _, err = FindExportData(buf); err != nil {
return
}

View File

@ -11,6 +11,7 @@ package gcimporter
import (
"bytes"
"encoding/binary"
"fmt"
"go/ast"
"go/constant"
"go/token"
@ -19,6 +20,8 @@ import (
"math/big"
"reflect"
"sort"
"strconv"
"strings"
"golang.org/x/tools/internal/typeparams"
)
@ -33,15 +36,15 @@ const bundleVersion = 0
// The package path of the top-level package will not be recorded,
// so that calls to IImportData can override with a provided package path.
func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error {
return iexportCommon(out, fset, false, []*types.Package{pkg})
return iexportCommon(out, fset, false, iexportVersion, []*types.Package{pkg})
}
// IExportBundle writes an indexed export bundle for pkgs to out.
func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error {
return iexportCommon(out, fset, true, pkgs)
return iexportCommon(out, fset, true, iexportVersion, pkgs)
}
func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*types.Package) (err error) {
func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, version int, pkgs []*types.Package) (err error) {
if !debug {
defer func() {
if e := recover(); e != nil {
@ -57,9 +60,11 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*type
p := iexporter{
fset: fset,
version: version,
allPkgs: map[*types.Package]bool{},
stringIndex: map[string]uint64{},
declIndex: map[types.Object]uint64{},
tparamNames: map[types.Object]string{},
typIndex: map[types.Type]uint64{},
}
if !bundle {
@ -119,7 +124,7 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*type
if bundle {
hdr.uint64(bundleVersion)
}
hdr.uint64(iexportVersion)
hdr.uint64(uint64(p.version))
hdr.uint64(uint64(p.strings.Len()))
hdr.uint64(dataLen)
@ -136,8 +141,12 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle bool, pkgs []*type
// non-compiler tools and includes a complete package description
// (i.e., name and height).
func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
type pkgObj struct {
obj types.Object
name string // qualified name; differs from obj.Name for type params
}
// Build a map from packages to objects from that package.
pkgObjs := map[*types.Package][]types.Object{}
pkgObjs := map[*types.Package][]pkgObj{}
// For the main index, make sure to include every package that
// we reference, even if we're not exporting (or reexporting)
@ -150,7 +159,8 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
}
for obj := range index {
pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], obj)
name := w.p.exportName(obj)
pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], pkgObj{obj, name})
}
var pkgs []*types.Package
@ -158,7 +168,7 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
pkgs = append(pkgs, pkg)
sort.Slice(objs, func(i, j int) bool {
return indexName(objs[i]) < indexName(objs[j])
return objs[i].name < objs[j].name
})
}
@ -175,29 +185,25 @@ func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
objs := pkgObjs[pkg]
w.uint64(uint64(len(objs)))
for _, obj := range objs {
w.string(indexName(obj))
w.uint64(index[obj])
w.string(obj.name)
w.uint64(index[obj.obj])
}
}
}
// indexName returns the 'indexed' name of an object. It differs from
// obj.Name() only for type parameter names, where we include the subscripted
// type parameter ID.
//
// TODO(rfindley): remove this once we no longer need subscripts.
func indexName(obj types.Object) (res string) {
if _, ok := obj.(*types.TypeName); ok {
if tparam, ok := obj.Type().(*typeparams.TypeParam); ok {
return types.TypeString(tparam, func(*types.Package) string { return "" })
}
// exportName returns the 'exported' name of an object. It differs from
// obj.Name() only for type parameters (see tparamExportName for details).
func (p *iexporter) exportName(obj types.Object) (res string) {
if name := p.tparamNames[obj]; name != "" {
return name
}
return obj.Name()
}
type iexporter struct {
fset *token.FileSet
out *bytes.Buffer
fset *token.FileSet
out *bytes.Buffer
version int
localpkg *types.Package
@ -211,9 +217,21 @@ type iexporter struct {
strings intWriter
stringIndex map[string]uint64
data0 intWriter
declIndex map[types.Object]uint64
typIndex map[types.Type]uint64
data0 intWriter
declIndex map[types.Object]uint64
tparamNames map[types.Object]string // typeparam->exported name
typIndex map[types.Type]uint64
indent int // for tracing support
}
func (p *iexporter) trace(format string, args ...interface{}) {
if !trace {
// Call sites should also be guarded, but having this check here allows
// easily enabling/disabling debug trace statements.
return
}
fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
}
// stringOff returns the offset of s within the string section.
@ -239,7 +257,7 @@ func (p *iexporter) pushDecl(obj types.Object) {
return
}
p.declIndex[obj] = ^uint64(0) // mark n present in work queue
p.declIndex[obj] = ^uint64(0) // mark obj present in work queue
p.declTodo.pushTail(obj)
}
@ -262,6 +280,14 @@ func (w *exportWriter) exportPath(pkg *types.Package) string {
}
func (p *iexporter) doDecl(obj types.Object) {
if trace {
p.trace("exporting decl %v (%T)", obj, obj)
p.indent++
defer func() {
p.indent--
p.trace("=> %s", obj)
}()
}
w := p.newWriter()
w.setPkg(obj.Pkg(), false)
@ -284,14 +310,15 @@ func (p *iexporter) doDecl(obj types.Object) {
w.tag('G')
}
w.pos(obj.Pos())
// The tparam list of the function type is the
// declaration of the type params. So, write out the type
// params right now. Then those type params will be
// referenced via their type offset (via typOff) in all
// other places in the signature and function that they
// are used.
// The tparam list of the function type is the declaration of the type
// params. So, write out the type params right now. Then those type params
// will be referenced via their type offset (via typOff) in all other
// places in the signature and function where they are used.
//
// While importing the type parameters, tparamList computes and records
// their export name, so that it can be later used when writing the index.
if tparams := typeparams.ForSignature(sig); tparams.Len() > 0 {
w.tparamList(tparams, obj.Pkg())
w.tparamList(obj.Name(), tparams, obj.Pkg())
}
w.signature(sig)
@ -306,7 +333,15 @@ func (p *iexporter) doDecl(obj types.Object) {
if tparam, ok := t.(*typeparams.TypeParam); ok {
w.tag('P')
w.pos(obj.Pos())
w.typ(tparam.Constraint(), obj.Pkg())
constraint := tparam.Constraint()
if p.version >= iexportVersionGo1_18 {
implicit := false
if iface, _ := constraint.(*types.Interface); iface != nil {
implicit = typeparams.IsImplicit(iface)
}
w.bool(implicit)
}
w.typ(constraint, obj.Pkg())
break
}
@ -331,7 +366,9 @@ func (p *iexporter) doDecl(obj types.Object) {
w.pos(obj.Pos())
if typeparams.ForNamed(named).Len() > 0 {
w.tparamList(typeparams.ForNamed(named), obj.Pkg())
// While importing the type parameters, tparamList computes and records
// their export name, so that it can be later used when writing the index.
w.tparamList(obj.Name(), typeparams.ForNamed(named), obj.Pkg())
}
underlying := obj.Type().Underlying()
@ -348,6 +385,17 @@ func (p *iexporter) doDecl(obj types.Object) {
w.pos(m.Pos())
w.string(m.Name())
sig, _ := m.Type().(*types.Signature)
// Receiver type parameters are type arguments of the receiver type, so
// their name must be qualified before exporting recv.
if rparams := typeparams.RecvTypeParams(sig); rparams.Len() > 0 {
prefix := obj.Name() + "." + m.Name()
for i := 0; i < rparams.Len(); i++ {
rparam := rparams.At(i)
name := tparamExportName(prefix, rparam)
w.p.tparamNames[rparam.Obj()] = name
}
}
w.param(sig.Recv())
w.signature(sig)
}
@ -364,7 +412,7 @@ func (w *exportWriter) tag(tag byte) {
}
func (w *exportWriter) pos(pos token.Pos) {
if iexportVersion >= iexportVersionPosCol {
if w.p.version >= iexportVersionPosCol {
w.posV1(pos)
} else {
w.posV0(pos)
@ -447,9 +495,11 @@ func (w *exportWriter) pkg(pkg *types.Package) {
}
func (w *exportWriter) qualifiedIdent(obj types.Object) {
name := w.p.exportName(obj)
// Ensure any referenced declarations are written out too.
w.p.pushDecl(obj)
w.string(indexName(obj))
w.string(name)
w.pkg(obj.Pkg())
}
@ -483,6 +533,14 @@ func (w *exportWriter) startType(k itag) {
}
func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
if trace {
w.p.trace("exporting type %s (%T)", t, t)
w.p.indent++
defer func() {
w.p.indent--
w.p.trace("=> %s", t)
}()
}
switch t := t.(type) {
case *types.Named:
if targs := typeparams.NamedTypeArgs(t); targs.Len() > 0 {
@ -619,14 +677,49 @@ func (w *exportWriter) typeList(ts *typeparams.TypeList, pkg *types.Package) {
}
}
func (w *exportWriter) tparamList(list *typeparams.TypeParamList, pkg *types.Package) {
func (w *exportWriter) tparamList(prefix string, list *typeparams.TypeParamList, pkg *types.Package) {
ll := uint64(list.Len())
w.uint64(ll)
for i := 0; i < list.Len(); i++ {
tparam := list.At(i)
// Set the type parameter exportName before exporting its type.
exportName := tparamExportName(prefix, tparam)
w.p.tparamNames[tparam.Obj()] = exportName
w.typ(list.At(i), pkg)
}
}
const blankMarker = "$"
// tparamExportName returns the 'exported' name of a type parameter, which
// differs from its actual object name: it is prefixed with a qualifier, and
// blank type parameter names are disambiguated by their index in the type
// parameter list.
func tparamExportName(prefix string, tparam *typeparams.TypeParam) string {
assert(prefix != "")
name := tparam.Obj().Name()
if name == "_" {
name = blankMarker + strconv.Itoa(tparam.Index())
}
return prefix + "." + name
}
// tparamName returns the real name of a type parameter, after stripping its
// qualifying prefix and reverting blank-name encoding. See tparamExportName
// for details.
func tparamName(exportName string) string {
// Remove the "path" from the type param name that makes it unique.
ix := strings.LastIndex(exportName, ".")
if ix < 0 {
errorf("malformed type parameter export name %s: missing prefix", exportName)
}
name := exportName[ix+1:]
if strings.HasPrefix(name, blankMarker) {
return "_"
}
return name
}
func (w *exportWriter) paramList(tup *types.Tuple) {
n := tup.Len()
w.uint64(uint64(n))
@ -643,6 +736,9 @@ func (w *exportWriter) param(obj types.Object) {
func (w *exportWriter) value(typ types.Type, v constant.Value) {
w.typ(typ, nil)
if w.p.version >= iexportVersionGo1_18 {
w.int64(int64(v.Kind()))
}
switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
case types.IsBoolean:
@ -832,7 +928,7 @@ func (w *exportWriter) localIdent(obj types.Object) {
return
}
name := indexName(obj)
name := obj.Name()
if name == "_" {
w.string("_")
return

View File

@ -18,6 +18,7 @@ import (
"go/types"
"io"
"sort"
"strings"
"golang.org/x/tools/internal/typeparams"
)
@ -45,12 +46,10 @@ func (r *intReader) uint64() uint64 {
// Keep this in sync with constants in iexport.go.
const (
iexportVersionGo1_11 = 0
iexportVersionPosCol = 1
// TODO: before release, change this back to 2.
iexportVersionGenerics = iexportVersionPosCol
iexportVersionCurrent = iexportVersionGenerics
iexportVersionGo1_11 = 0
iexportVersionPosCol = 1
iexportVersionGo1_18 = 2
iexportVersionGenerics = 2
)
type ident struct {
@ -123,9 +122,9 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data
version = int64(r.uint64())
switch version {
case /* iexportVersionGenerics, */ iexportVersionPosCol, iexportVersionGo1_11:
case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11:
default:
if version > iexportVersionGenerics {
if version > iexportVersionGo1_18 {
errorf("unstable iexport format version %d, just rebuild compiler and std library", version)
} else {
errorf("unknown iexport format version %d", version)
@ -141,9 +140,8 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data
r.Seek(sLen+dLen, io.SeekCurrent)
p := iimporter{
exportVersion: version,
ipath: path,
version: int(version),
version: int(version),
ipath: path,
stringData: stringData,
stringCache: make(map[uint64]string),
@ -153,14 +151,15 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data
pkgIndex: make(map[*types.Package]map[string]uint64),
typCache: make(map[uint64]types.Type),
// Separate map for typeparams, keyed by their package and unique
// name (name with subscript).
// name.
tparamIndex: make(map[ident]types.Type),
fake: fakeFileSet{
fset: fset,
files: make(map[string]*token.File),
files: make(map[string]*fileInfo),
},
}
defer p.fake.setLines() // set lines for files in fset
for i, pt := range predeclared() {
p.typCache[uint64(i)] = pt
@ -246,9 +245,8 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data
}
type iimporter struct {
exportVersion int64
ipath string
version int
version int
ipath string
stringData []byte
stringCache map[uint64]string
@ -261,9 +259,28 @@ type iimporter struct {
fake fakeFileSet
interfaceList []*types.Interface
indent int // for tracing support
}
func (p *iimporter) trace(format string, args ...interface{}) {
if !trace {
// Call sites should also be guarded, but having this check here allows
// easily enabling/disabling debug trace statements.
return
}
fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
}
func (p *iimporter) doDecl(pkg *types.Package, name string) {
if debug {
p.trace("import decl %s", name)
p.indent++
defer func() {
p.indent--
p.trace("=> %s", name)
}()
}
// See if we've already imported this declaration.
if obj := pkg.Scope().Lookup(name); obj != nil {
return
@ -305,7 +322,7 @@ func (p *iimporter) pkgAt(off uint64) *types.Package {
}
func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) {
if t, ok := p.typCache[off]; ok && canReuse(base, t) {
return t
}
@ -317,12 +334,30 @@ func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
r.declReader.Reset(p.declData[off-predeclReserved:])
t := r.doType(base)
if base == nil || !isInterface(t) {
if canReuse(base, t) {
p.typCache[off] = t
}
return t
}
// canReuse reports whether the type rhs on the RHS of the declaration for def
// may be re-used.
//
// Specifically, if def is non-nil and rhs is an interface type with methods, it
// may not be re-used because we have a convention of setting the receiver type
// for interface methods to def.
func canReuse(def *types.Named, rhs types.Type) bool {
if def == nil {
return true
}
iface, _ := rhs.(*types.Interface)
if iface == nil {
return true
}
// Don't use iface.Empty() here as iface may not be complete.
return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0
}
type importReader struct {
p *iimporter
declReader bytes.Reader
@ -352,8 +387,7 @@ func (r *importReader) obj(name string) {
if tag == 'G' {
tparams = r.tparamList()
}
sig := r.signature(nil)
typeparams.SetForSignature(sig, tparams)
sig := r.signature(nil, nil, tparams)
r.declare(types.NewFunc(pos, r.currPkg, name, sig))
case 'T', 'U':
@ -377,23 +411,21 @@ func (r *importReader) obj(name string) {
mpos := r.pos()
mname := r.ident()
recv := r.param()
msig := r.signature(recv)
// If the receiver has any targs, set those as the
// rparams of the method (since those are the
// typeparams being used in the method sig/body).
targs := typeparams.NamedTypeArgs(baseType(msig.Recv().Type()))
base := baseType(recv.Type())
assert(base != nil)
targs := typeparams.NamedTypeArgs(base)
var rparams []*typeparams.TypeParam
if targs.Len() > 0 {
rparams := make([]*typeparams.TypeParam, targs.Len())
rparams = make([]*typeparams.TypeParam, targs.Len())
for i := range rparams {
// TODO(rfindley): this is less tolerant than the standard library
// go/internal/gcimporter, which calls under(...) and is tolerant
// of nil rparams. Bring them in sync by making the standard
// library importer stricter.
rparams[i] = targs.At(i).(*typeparams.TypeParam)
}
typeparams.SetRecvTypeParams(msig, rparams)
}
msig := r.signature(recv, rparams, nil)
named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
}
@ -403,25 +435,30 @@ func (r *importReader) obj(name string) {
// We need to "declare" a typeparam in order to have a name that
// can be referenced recursively (if needed) in the type param's
// bound.
if r.p.exportVersion < iexportVersionGenerics {
if r.p.version < iexportVersionGenerics {
errorf("unexpected type param type")
}
name0, sub := parseSubscript(name)
name0 := tparamName(name)
tn := types.NewTypeName(pos, r.currPkg, name0, nil)
t := typeparams.NewTypeParam(tn, nil)
if sub == 0 {
errorf("name %q missing subscript", name)
}
// TODO(rfindley): can we use a different, stable ID?
// t.SetId(sub)
// To handle recursive references to the typeparam within its
// bound, save the partial type in tparamIndex before reading the bounds.
id := ident{r.currPkg.Name(), name}
r.p.tparamIndex[id] = t
typeparams.SetTypeParamConstraint(t, r.typ())
var implicit bool
if r.p.version >= iexportVersionGo1_18 {
implicit = r.bool()
}
constraint := r.typ()
if implicit {
iface, _ := constraint.(*types.Interface)
if iface == nil {
errorf("non-interface constraint marked implicit")
}
typeparams.MarkImplicit(iface)
}
typeparams.SetTypeParamConstraint(t, constraint)
case 'V':
typ := r.typ()
@ -439,6 +476,10 @@ func (r *importReader) declare(obj types.Object) {
func (r *importReader) value() (typ types.Type, val constant.Value) {
typ = r.typ()
if r.p.version >= iexportVersionGo1_18 {
// TODO: add support for using the kind.
_ = constant.Kind(r.int64())
}
switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
case types.IsBoolean:
@ -581,7 +622,7 @@ func (r *importReader) qualifiedIdent() (*types.Package, string) {
}
func (r *importReader) pos() token.Pos {
if r.p.exportVersion >= iexportVersionPosCol {
if r.p.version >= iexportVersionPosCol {
r.posv1()
} else {
r.posv0()
@ -629,8 +670,17 @@ func isInterface(t types.Type) bool {
func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) }
func (r *importReader) string() string { return r.p.stringAt(r.uint64()) }
func (r *importReader) doType(base *types.Named) types.Type {
switch k := r.kind(); k {
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.indent++
defer func() {
r.p.indent--
r.p.trace("=> %s", res)
}()
}
switch k {
default:
errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
return nil
@ -653,7 +703,7 @@ func (r *importReader) doType(base *types.Named) types.Type {
return types.NewMap(r.typ(), r.typ())
case signatureType:
r.currPkg = r.pkg()
return r.signature(nil)
return r.signature(nil, nil, nil)
case structType:
r.currPkg = r.pkg()
@ -693,7 +743,7 @@ func (r *importReader) doType(base *types.Named) types.Type {
recv = types.NewVar(token.NoPos, r.currPkg, "", base)
}
msig := r.signature(recv)
msig := r.signature(recv, nil, nil)
methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig)
}
@ -702,7 +752,7 @@ func (r *importReader) doType(base *types.Named) types.Type {
return typ
case typeParamType:
if r.p.exportVersion < iexportVersionGenerics {
if r.p.version < iexportVersionGenerics {
errorf("unexpected type param type")
}
pkg, name := r.qualifiedIdent()
@ -716,7 +766,7 @@ func (r *importReader) doType(base *types.Named) types.Type {
return r.p.tparamIndex[id]
case instanceType:
if r.p.exportVersion < iexportVersionGenerics {
if r.p.version < iexportVersionGenerics {
errorf("unexpected instantiation type")
}
// pos does not matter for instances: they are positioned on the original
@ -735,7 +785,7 @@ func (r *importReader) doType(base *types.Named) types.Type {
return t
case unionType:
if r.p.exportVersion < iexportVersionGenerics {
if r.p.version < iexportVersionGenerics {
errorf("unexpected instantiation type")
}
terms := make([]*typeparams.Term, r.uint64())
@ -750,11 +800,11 @@ func (r *importReader) kind() itag {
return itag(r.uint64())
}
func (r *importReader) signature(recv *types.Var) *types.Signature {
func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature {
params := r.paramList()
results := r.paramList()
variadic := params.Len() > 0 && r.bool()
return types.NewSignature(recv, params, results, variadic)
return typeparams.NewSignatureType(recv, rparams, tparams, params, results, variadic)
}
func (r *importReader) tparamList() []*typeparams.TypeParam {
@ -823,23 +873,3 @@ func baseType(typ types.Type) *types.Named {
n, _ := typ.(*types.Named)
return n
}
func parseSubscript(name string) (string, uint64) {
// Extract the subscript value from the type param name. We export
// and import the subscript value, so that all type params have
// unique names.
sub := uint64(0)
startsub := -1
for i, r := range name {
if '₀' <= r && r < '₀'+10 {
if startsub == -1 {
startsub = i
}
sub = sub*10 + uint64(r-'₀')
}
}
if startsub >= 0 {
name = name[:startsub]
}
return name, sub
}

View File

@ -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 !typeparams || !go1.18
// +build !typeparams !go1.18
//go:build !go1.18
// +build !go1.18
package gcimporter

View File

@ -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 typeparams && go1.18
// +build typeparams,go1.18
//go:build go1.18
// +build go1.18
package gcimporter
@ -16,5 +16,8 @@ func additionalPredeclared() []types.Type {
return []types.Type{
// comparable
types.Universe.Lookup("comparable").Type(),
// any
types.Universe.Lookup("any").Type(),
}
}

View File

@ -26,6 +26,7 @@ import (
"golang.org/x/tools/go/gcexportdata"
"golang.org/x/tools/internal/gocommand"
"golang.org/x/tools/internal/packagesinternal"
"golang.org/x/tools/internal/typeparams"
"golang.org/x/tools/internal/typesinternal"
)
@ -327,6 +328,9 @@ type Package struct {
// The NeedSyntax LoadMode bit populates this field for packages matching the patterns.
// If NeedDeps and NeedImports are also set, this field will also be populated
// for dependencies.
//
// Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are
// removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles.
Syntax []*ast.File
// TypesInfo provides type information about the package's syntax trees.
@ -910,6 +914,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
Scopes: make(map[ast.Node]*types.Scope),
Selections: make(map[*ast.SelectorExpr]*types.Selection),
}
typeparams.InitInstanceInfo(lpkg.TypesInfo)
lpkg.TypesSizes = ld.sizes
importer := importerFunc(func(path string) (*types.Package, error) {