Source file src/go/internal/gcimporter/iimport.go

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Indexed package import.
     6  // See cmd/compile/internal/gc/iexport.go for the export data format.
     7  
     8  package gcimporter
     9  
    10  import (
    11  	"bufio"
    12  	"bytes"
    13  	"encoding/binary"
    14  	"fmt"
    15  	"go/constant"
    16  	"go/token"
    17  	"go/types"
    18  	"internal/saferio"
    19  	"io"
    20  	"math"
    21  	"math/big"
    22  	"sort"
    23  	"strings"
    24  )
    25  
    26  type intReader struct {
    27  	*bufio.Reader
    28  	path string
    29  }
    30  
    31  func (r *intReader) int64() int64 {
    32  	i, err := binary.ReadVarint(r.Reader)
    33  	if err != nil {
    34  		errorf("import %q: read varint error: %v", r.path, err)
    35  	}
    36  	return i
    37  }
    38  
    39  func (r *intReader) uint64() uint64 {
    40  	i, err := binary.ReadUvarint(r.Reader)
    41  	if err != nil {
    42  		errorf("import %q: read varint error: %v", r.path, err)
    43  	}
    44  	return i
    45  }
    46  
    47  // Keep this in sync with constants in iexport.go.
    48  const (
    49  	iexportVersionGo1_11   = 0
    50  	iexportVersionPosCol   = 1
    51  	iexportVersionGenerics = 2
    52  	iexportVersionGo1_18   = 2
    53  
    54  	iexportVersionCurrent = 2
    55  )
    56  
    57  type ident struct {
    58  	pkg  *types.Package
    59  	name string
    60  }
    61  
    62  const predeclReserved = 32
    63  
    64  type itag uint64
    65  
    66  const (
    67  	// Types
    68  	definedType itag = iota
    69  	pointerType
    70  	sliceType
    71  	arrayType
    72  	chanType
    73  	mapType
    74  	signatureType
    75  	structType
    76  	interfaceType
    77  	typeParamType
    78  	instanceType
    79  	unionType
    80  )
    81  
    82  // iImportData imports a package from the serialized package data
    83  // and returns the number of bytes consumed and a reference to the package.
    84  // If the export data version is not recognized or the format is otherwise
    85  // compromised, an error is returned.
    86  func iImportData(fset *token.FileSet, imports map[string]*types.Package, dataReader *bufio.Reader, path string) (pkg *types.Package, err error) {
    87  	const currentVersion = iexportVersionCurrent
    88  	version := int64(-1)
    89  	defer func() {
    90  		if e := recover(); e != nil {
    91  			if version > currentVersion {
    92  				err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
    93  			} else {
    94  				err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
    95  			}
    96  		}
    97  	}()
    98  
    99  	r := &intReader{dataReader, path}
   100  
   101  	version = int64(r.uint64())
   102  	switch version {
   103  	case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11:
   104  	default:
   105  		errorf("unknown iexport format version %d", version)
   106  	}
   107  
   108  	sLen := r.uint64()
   109  	dLen := r.uint64()
   110  
   111  	if sLen > math.MaxUint64-dLen {
   112  		errorf("lengths out of range (%d, %d)", sLen, dLen)
   113  	}
   114  
   115  	data, err := saferio.ReadData(r, sLen+dLen)
   116  	if err != nil {
   117  		errorf("cannot read %d bytes of stringData and declData: %s", sLen+dLen, err)
   118  	}
   119  	stringData := data[:sLen]
   120  	declData := data[sLen:]
   121  
   122  	p := iimporter{
   123  		exportVersion: version,
   124  		ipath:         path,
   125  		version:       int(version),
   126  
   127  		stringData:  stringData,
   128  		stringCache: make(map[uint64]string),
   129  		pkgCache:    make(map[uint64]*types.Package),
   130  
   131  		declData: declData,
   132  		pkgIndex: make(map[*types.Package]map[string]uint64),
   133  		typCache: make(map[uint64]types.Type),
   134  		// Separate map for typeparams, keyed by their package and unique
   135  		// name (name with subscript).
   136  		tparamIndex: make(map[ident]*types.TypeParam),
   137  
   138  		fake: fakeFileSet{
   139  			fset:  fset,
   140  			files: make(map[string]*fileInfo),
   141  		},
   142  	}
   143  	defer p.fake.setLines() // set lines for files in fset
   144  
   145  	for i, pt := range predeclared {
   146  		p.typCache[uint64(i)] = pt
   147  	}
   148  
   149  	pkgList := make([]*types.Package, r.uint64())
   150  	for i := range pkgList {
   151  		pkgPathOff := r.uint64()
   152  		pkgPath := p.stringAt(pkgPathOff)
   153  		pkgName := p.stringAt(r.uint64())
   154  		_ = r.uint64() // package height; unused by go/types
   155  
   156  		if pkgPath == "" {
   157  			pkgPath = path
   158  		}
   159  		pkg := imports[pkgPath]
   160  		if pkg == nil {
   161  			pkg = types.NewPackage(pkgPath, pkgName)
   162  			imports[pkgPath] = pkg
   163  		} else if pkg.Name() != pkgName {
   164  			errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
   165  		}
   166  
   167  		p.pkgCache[pkgPathOff] = pkg
   168  
   169  		nameIndex := make(map[string]uint64)
   170  		for nSyms := r.uint64(); nSyms > 0; nSyms-- {
   171  			name := p.stringAt(r.uint64())
   172  			nameIndex[name] = r.uint64()
   173  		}
   174  
   175  		p.pkgIndex[pkg] = nameIndex
   176  		pkgList[i] = pkg
   177  	}
   178  
   179  	localpkg := pkgList[0]
   180  
   181  	names := make([]string, 0, len(p.pkgIndex[localpkg]))
   182  	for name := range p.pkgIndex[localpkg] {
   183  		names = append(names, name)
   184  	}
   185  	sort.Strings(names)
   186  	for _, name := range names {
   187  		p.doDecl(localpkg, name)
   188  	}
   189  
   190  	// SetConstraint can't be called if the constraint type is not yet complete.
   191  	// When type params are created in the 'P' case of (*importReader).obj(),
   192  	// the associated constraint type may not be complete due to recursion.
   193  	// Therefore, we defer calling SetConstraint there, and call it here instead
   194  	// after all types are complete.
   195  	for _, d := range p.later {
   196  		d.t.SetConstraint(d.constraint)
   197  	}
   198  
   199  	for _, typ := range p.interfaceList {
   200  		typ.Complete()
   201  	}
   202  
   203  	// record all referenced packages as imports
   204  	list := append(([]*types.Package)(nil), pkgList[1:]...)
   205  	sort.Sort(byPath(list))
   206  	localpkg.SetImports(list)
   207  
   208  	// package was imported completely and without errors
   209  	localpkg.MarkComplete()
   210  	return localpkg, nil
   211  }
   212  
   213  type setConstraintArgs struct {
   214  	t          *types.TypeParam
   215  	constraint types.Type
   216  }
   217  
   218  type iimporter struct {
   219  	exportVersion int64
   220  	ipath         string
   221  	version       int
   222  
   223  	stringData  []byte
   224  	stringCache map[uint64]string
   225  	pkgCache    map[uint64]*types.Package
   226  
   227  	declData    []byte
   228  	pkgIndex    map[*types.Package]map[string]uint64
   229  	typCache    map[uint64]types.Type
   230  	tparamIndex map[ident]*types.TypeParam
   231  
   232  	fake          fakeFileSet
   233  	interfaceList []*types.Interface
   234  
   235  	// Arguments for calls to SetConstraint that are deferred due to recursive types
   236  	later []setConstraintArgs
   237  }
   238  
   239  func (p *iimporter) doDecl(pkg *types.Package, name string) {
   240  	// See if we've already imported this declaration.
   241  	if obj := pkg.Scope().Lookup(name); obj != nil {
   242  		return
   243  	}
   244  
   245  	off, ok := p.pkgIndex[pkg][name]
   246  	if !ok {
   247  		errorf("%v.%v not in index", pkg, name)
   248  	}
   249  
   250  	r := &importReader{p: p, currPkg: pkg}
   251  	r.declReader.Reset(p.declData[off:])
   252  
   253  	r.obj(name)
   254  }
   255  
   256  func (p *iimporter) stringAt(off uint64) string {
   257  	if s, ok := p.stringCache[off]; ok {
   258  		return s
   259  	}
   260  
   261  	slen, n := binary.Uvarint(p.stringData[off:])
   262  	if n <= 0 {
   263  		errorf("varint failed")
   264  	}
   265  	spos := off + uint64(n)
   266  	s := string(p.stringData[spos : spos+slen])
   267  	p.stringCache[off] = s
   268  	return s
   269  }
   270  
   271  func (p *iimporter) pkgAt(off uint64) *types.Package {
   272  	if pkg, ok := p.pkgCache[off]; ok {
   273  		return pkg
   274  	}
   275  	path := p.stringAt(off)
   276  	errorf("missing package %q in %q", path, p.ipath)
   277  	return nil
   278  }
   279  
   280  func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
   281  	if t, ok := p.typCache[off]; ok && canReuse(base, t) {
   282  		return t
   283  	}
   284  
   285  	if off < predeclReserved {
   286  		errorf("predeclared type missing from cache: %v", off)
   287  	}
   288  
   289  	r := &importReader{p: p}
   290  	r.declReader.Reset(p.declData[off-predeclReserved:])
   291  	t := r.doType(base)
   292  
   293  	if canReuse(base, t) {
   294  		p.typCache[off] = t
   295  	}
   296  	return t
   297  }
   298  
   299  // canReuse reports whether the type rhs on the RHS of the declaration for def
   300  // may be re-used.
   301  //
   302  // Specifically, if def is non-nil and rhs is an interface type with methods, it
   303  // may not be re-used because we have a convention of setting the receiver type
   304  // for interface methods to def.
   305  func canReuse(def *types.Named, rhs types.Type) bool {
   306  	if def == nil {
   307  		return true
   308  	}
   309  	iface, _ := rhs.(*types.Interface)
   310  	if iface == nil {
   311  		return true
   312  	}
   313  	// Don't use iface.Empty() here as iface may not be complete.
   314  	return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0
   315  }
   316  
   317  type importReader struct {
   318  	p          *iimporter
   319  	declReader bytes.Reader
   320  	currPkg    *types.Package
   321  	prevFile   string
   322  	prevLine   int64
   323  	prevColumn int64
   324  }
   325  
   326  func (r *importReader) obj(name string) {
   327  	tag := r.byte()
   328  	pos := r.pos()
   329  
   330  	switch tag {
   331  	case 'A':
   332  		typ := r.typ()
   333  
   334  		r.declare(types.NewTypeName(pos, r.currPkg, name, typ))
   335  
   336  	case 'C':
   337  		typ, val := r.value()
   338  
   339  		r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
   340  
   341  	case 'F', 'G':
   342  		var tparams []*types.TypeParam
   343  		if tag == 'G' {
   344  			tparams = r.tparamList()
   345  		}
   346  		sig := r.signature(nil, nil, tparams)
   347  		r.declare(types.NewFunc(pos, r.currPkg, name, sig))
   348  
   349  	case 'T', 'U':
   350  		// Types can be recursive. We need to setup a stub
   351  		// declaration before recurring.
   352  		obj := types.NewTypeName(pos, r.currPkg, name, nil)
   353  		named := types.NewNamed(obj, nil, nil)
   354  		// Declare obj before calling r.tparamList, so the new type name is recognized
   355  		// if used in the constraint of one of its own typeparams (see #48280).
   356  		r.declare(obj)
   357  		if tag == 'U' {
   358  			tparams := r.tparamList()
   359  			named.SetTypeParams(tparams)
   360  		}
   361  
   362  		underlying := r.p.typAt(r.uint64(), named).Underlying()
   363  		named.SetUnderlying(underlying)
   364  
   365  		if !isInterface(underlying) {
   366  			for n := r.uint64(); n > 0; n-- {
   367  				mpos := r.pos()
   368  				mname := r.ident()
   369  				recv := r.param()
   370  
   371  				// If the receiver has any targs, set those as the
   372  				// rparams of the method (since those are the
   373  				// typeparams being used in the method sig/body).
   374  				targs := baseType(recv.Type()).TypeArgs()
   375  				var rparams []*types.TypeParam
   376  				if targs.Len() > 0 {
   377  					rparams = make([]*types.TypeParam, targs.Len())
   378  					for i := range rparams {
   379  						rparams[i], _ = targs.At(i).(*types.TypeParam)
   380  					}
   381  				}
   382  				msig := r.signature(recv, rparams, nil)
   383  
   384  				named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
   385  			}
   386  		}
   387  
   388  	case 'P':
   389  		// We need to "declare" a typeparam in order to have a name that
   390  		// can be referenced recursively (if needed) in the type param's
   391  		// bound.
   392  		if r.p.exportVersion < iexportVersionGenerics {
   393  			errorf("unexpected type param type")
   394  		}
   395  		// Remove the "path" from the type param name that makes it unique,
   396  		// and revert any unique name used for blank typeparams.
   397  		name0 := tparamName(name)
   398  		tn := types.NewTypeName(pos, r.currPkg, name0, nil)
   399  		t := types.NewTypeParam(tn, nil)
   400  		// To handle recursive references to the typeparam within its
   401  		// bound, save the partial type in tparamIndex before reading the bounds.
   402  		id := ident{r.currPkg, name}
   403  		r.p.tparamIndex[id] = t
   404  
   405  		var implicit bool
   406  		if r.p.exportVersion >= iexportVersionGo1_18 {
   407  			implicit = r.bool()
   408  		}
   409  		constraint := r.typ()
   410  		if implicit {
   411  			iface, _ := constraint.(*types.Interface)
   412  			if iface == nil {
   413  				errorf("non-interface constraint marked implicit")
   414  			}
   415  			iface.MarkImplicit()
   416  		}
   417  		// The constraint type may not be complete, if we
   418  		// are in the middle of a type recursion involving type
   419  		// constraints. So, we defer SetConstraint until we have
   420  		// completely set up all types in ImportData.
   421  		r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint})
   422  
   423  	case 'V':
   424  		typ := r.typ()
   425  
   426  		r.declare(types.NewVar(pos, r.currPkg, name, typ))
   427  
   428  	default:
   429  		errorf("unexpected tag: %v", tag)
   430  	}
   431  }
   432  
   433  func (r *importReader) declare(obj types.Object) {
   434  	obj.Pkg().Scope().Insert(obj)
   435  }
   436  
   437  func (r *importReader) value() (typ types.Type, val constant.Value) {
   438  	typ = r.typ()
   439  	if r.p.exportVersion >= iexportVersionGo1_18 {
   440  		// TODO: add support for using the kind
   441  		_ = constant.Kind(r.int64())
   442  	}
   443  
   444  	switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
   445  	case types.IsBoolean:
   446  		val = constant.MakeBool(r.bool())
   447  
   448  	case types.IsString:
   449  		val = constant.MakeString(r.string())
   450  
   451  	case types.IsInteger:
   452  		var x big.Int
   453  		r.mpint(&x, b)
   454  		val = constant.Make(&x)
   455  
   456  	case types.IsFloat:
   457  		val = r.mpfloat(b)
   458  
   459  	case types.IsComplex:
   460  		re := r.mpfloat(b)
   461  		im := r.mpfloat(b)
   462  		val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
   463  
   464  	default:
   465  		errorf("unexpected type %v", typ) // panics
   466  		panic("unreachable")
   467  	}
   468  
   469  	return
   470  }
   471  
   472  func intSize(b *types.Basic) (signed bool, maxBytes uint) {
   473  	if (b.Info() & types.IsUntyped) != 0 {
   474  		return true, 64
   475  	}
   476  
   477  	switch b.Kind() {
   478  	case types.Float32, types.Complex64:
   479  		return true, 3
   480  	case types.Float64, types.Complex128:
   481  		return true, 7
   482  	}
   483  
   484  	signed = (b.Info() & types.IsUnsigned) == 0
   485  	switch b.Kind() {
   486  	case types.Int8, types.Uint8:
   487  		maxBytes = 1
   488  	case types.Int16, types.Uint16:
   489  		maxBytes = 2
   490  	case types.Int32, types.Uint32:
   491  		maxBytes = 4
   492  	default:
   493  		maxBytes = 8
   494  	}
   495  
   496  	return
   497  }
   498  
   499  func (r *importReader) mpint(x *big.Int, typ *types.Basic) {
   500  	signed, maxBytes := intSize(typ)
   501  
   502  	maxSmall := 256 - maxBytes
   503  	if signed {
   504  		maxSmall = 256 - 2*maxBytes
   505  	}
   506  	if maxBytes == 1 {
   507  		maxSmall = 256
   508  	}
   509  
   510  	n, _ := r.declReader.ReadByte()
   511  	if uint(n) < maxSmall {
   512  		v := int64(n)
   513  		if signed {
   514  			v >>= 1
   515  			if n&1 != 0 {
   516  				v = ^v
   517  			}
   518  		}
   519  		x.SetInt64(v)
   520  		return
   521  	}
   522  
   523  	v := -n
   524  	if signed {
   525  		v = -(n &^ 1) >> 1
   526  	}
   527  	if v < 1 || uint(v) > maxBytes {
   528  		errorf("weird decoding: %v, %v => %v", n, signed, v)
   529  	}
   530  	b := make([]byte, v)
   531  	io.ReadFull(&r.declReader, b)
   532  	x.SetBytes(b)
   533  	if signed && n&1 != 0 {
   534  		x.Neg(x)
   535  	}
   536  }
   537  
   538  func (r *importReader) mpfloat(typ *types.Basic) constant.Value {
   539  	var mant big.Int
   540  	r.mpint(&mant, typ)
   541  	var f big.Float
   542  	f.SetInt(&mant)
   543  	if f.Sign() != 0 {
   544  		f.SetMantExp(&f, int(r.int64()))
   545  	}
   546  	return constant.Make(&f)
   547  }
   548  
   549  func (r *importReader) ident() string {
   550  	return r.string()
   551  }
   552  
   553  func (r *importReader) qualifiedIdent() (*types.Package, string) {
   554  	name := r.string()
   555  	pkg := r.pkg()
   556  	return pkg, name
   557  }
   558  
   559  func (r *importReader) pos() token.Pos {
   560  	if r.p.version >= 1 {
   561  		r.posv1()
   562  	} else {
   563  		r.posv0()
   564  	}
   565  
   566  	if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 {
   567  		return token.NoPos
   568  	}
   569  	return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn))
   570  }
   571  
   572  func (r *importReader) posv0() {
   573  	delta := r.int64()
   574  	if delta != deltaNewFile {
   575  		r.prevLine += delta
   576  	} else if l := r.int64(); l == -1 {
   577  		r.prevLine += deltaNewFile
   578  	} else {
   579  		r.prevFile = r.string()
   580  		r.prevLine = l
   581  	}
   582  }
   583  
   584  func (r *importReader) posv1() {
   585  	delta := r.int64()
   586  	r.prevColumn += delta >> 1
   587  	if delta&1 != 0 {
   588  		delta = r.int64()
   589  		r.prevLine += delta >> 1
   590  		if delta&1 != 0 {
   591  			r.prevFile = r.string()
   592  		}
   593  	}
   594  }
   595  
   596  func (r *importReader) typ() types.Type {
   597  	return r.p.typAt(r.uint64(), nil)
   598  }
   599  
   600  func isInterface(t types.Type) bool {
   601  	_, ok := t.(*types.Interface)
   602  	return ok
   603  }
   604  
   605  func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) }
   606  func (r *importReader) string() string      { return r.p.stringAt(r.uint64()) }
   607  
   608  func (r *importReader) doType(base *types.Named) types.Type {
   609  	switch k := r.kind(); k {
   610  	default:
   611  		errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
   612  		return nil
   613  
   614  	case definedType:
   615  		pkg, name := r.qualifiedIdent()
   616  		r.p.doDecl(pkg, name)
   617  		return pkg.Scope().Lookup(name).(*types.TypeName).Type()
   618  	case pointerType:
   619  		return types.NewPointer(r.typ())
   620  	case sliceType:
   621  		return types.NewSlice(r.typ())
   622  	case arrayType:
   623  		n := r.uint64()
   624  		return types.NewArray(r.typ(), int64(n))
   625  	case chanType:
   626  		dir := chanDir(int(r.uint64()))
   627  		return types.NewChan(dir, r.typ())
   628  	case mapType:
   629  		return types.NewMap(r.typ(), r.typ())
   630  	case signatureType:
   631  		r.currPkg = r.pkg()
   632  		return r.signature(nil, nil, nil)
   633  
   634  	case structType:
   635  		r.currPkg = r.pkg()
   636  
   637  		fields := make([]*types.Var, r.uint64())
   638  		tags := make([]string, len(fields))
   639  		for i := range fields {
   640  			fpos := r.pos()
   641  			fname := r.ident()
   642  			ftyp := r.typ()
   643  			emb := r.bool()
   644  			tag := r.string()
   645  
   646  			fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb)
   647  			tags[i] = tag
   648  		}
   649  		return types.NewStruct(fields, tags)
   650  
   651  	case interfaceType:
   652  		r.currPkg = r.pkg()
   653  
   654  		embeddeds := make([]types.Type, r.uint64())
   655  		for i := range embeddeds {
   656  			_ = r.pos()
   657  			embeddeds[i] = r.typ()
   658  		}
   659  
   660  		methods := make([]*types.Func, r.uint64())
   661  		for i := range methods {
   662  			mpos := r.pos()
   663  			mname := r.ident()
   664  
   665  			// TODO(mdempsky): Matches bimport.go, but I
   666  			// don't agree with this.
   667  			var recv *types.Var
   668  			if base != nil {
   669  				recv = types.NewVar(token.NoPos, r.currPkg, "", base)
   670  			}
   671  
   672  			msig := r.signature(recv, nil, nil)
   673  			methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig)
   674  		}
   675  
   676  		typ := types.NewInterfaceType(methods, embeddeds)
   677  		r.p.interfaceList = append(r.p.interfaceList, typ)
   678  		return typ
   679  
   680  	case typeParamType:
   681  		if r.p.exportVersion < iexportVersionGenerics {
   682  			errorf("unexpected type param type")
   683  		}
   684  		pkg, name := r.qualifiedIdent()
   685  		id := ident{pkg, name}
   686  		if t, ok := r.p.tparamIndex[id]; ok {
   687  			// We're already in the process of importing this typeparam.
   688  			return t
   689  		}
   690  		// Otherwise, import the definition of the typeparam now.
   691  		r.p.doDecl(pkg, name)
   692  		return r.p.tparamIndex[id]
   693  
   694  	case instanceType:
   695  		if r.p.exportVersion < iexportVersionGenerics {
   696  			errorf("unexpected instantiation type")
   697  		}
   698  		// pos does not matter for instances: they are positioned on the original
   699  		// type.
   700  		_ = r.pos()
   701  		len := r.uint64()
   702  		targs := make([]types.Type, len)
   703  		for i := range targs {
   704  			targs[i] = r.typ()
   705  		}
   706  		baseType := r.typ()
   707  		// The imported instantiated type doesn't include any methods, so
   708  		// we must always use the methods of the base (orig) type.
   709  		// TODO provide a non-nil *Context
   710  		t, _ := types.Instantiate(nil, baseType, targs, false)
   711  		return t
   712  
   713  	case unionType:
   714  		if r.p.exportVersion < iexportVersionGenerics {
   715  			errorf("unexpected instantiation type")
   716  		}
   717  		terms := make([]*types.Term, r.uint64())
   718  		for i := range terms {
   719  			terms[i] = types.NewTerm(r.bool(), r.typ())
   720  		}
   721  		return types.NewUnion(terms)
   722  	}
   723  }
   724  
   725  func (r *importReader) kind() itag {
   726  	return itag(r.uint64())
   727  }
   728  
   729  func (r *importReader) signature(recv *types.Var, rparams, tparams []*types.TypeParam) *types.Signature {
   730  	params := r.paramList()
   731  	results := r.paramList()
   732  	variadic := params.Len() > 0 && r.bool()
   733  	return types.NewSignatureType(recv, rparams, tparams, params, results, variadic)
   734  }
   735  
   736  func (r *importReader) tparamList() []*types.TypeParam {
   737  	n := r.uint64()
   738  	if n == 0 {
   739  		return nil
   740  	}
   741  	xs := make([]*types.TypeParam, n)
   742  	for i := range xs {
   743  		xs[i], _ = r.typ().(*types.TypeParam)
   744  	}
   745  	return xs
   746  }
   747  
   748  func (r *importReader) paramList() *types.Tuple {
   749  	xs := make([]*types.Var, r.uint64())
   750  	for i := range xs {
   751  		xs[i] = r.param()
   752  	}
   753  	return types.NewTuple(xs...)
   754  }
   755  
   756  func (r *importReader) param() *types.Var {
   757  	pos := r.pos()
   758  	name := r.ident()
   759  	typ := r.typ()
   760  	return types.NewParam(pos, r.currPkg, name, typ)
   761  }
   762  
   763  func (r *importReader) bool() bool {
   764  	return r.uint64() != 0
   765  }
   766  
   767  func (r *importReader) int64() int64 {
   768  	n, err := binary.ReadVarint(&r.declReader)
   769  	if err != nil {
   770  		errorf("readVarint: %v", err)
   771  	}
   772  	return n
   773  }
   774  
   775  func (r *importReader) uint64() uint64 {
   776  	n, err := binary.ReadUvarint(&r.declReader)
   777  	if err != nil {
   778  		errorf("readUvarint: %v", err)
   779  	}
   780  	return n
   781  }
   782  
   783  func (r *importReader) byte() byte {
   784  	x, err := r.declReader.ReadByte()
   785  	if err != nil {
   786  		errorf("declReader.ReadByte: %v", err)
   787  	}
   788  	return x
   789  }
   790  
   791  func baseType(typ types.Type) *types.Named {
   792  	// pointer receivers are never types.Named types
   793  	if p, _ := typ.(*types.Pointer); p != nil {
   794  		typ = p.Elem()
   795  	}
   796  	// receiver base types are always (possibly generic) types.Named types
   797  	n, _ := typ.(*types.Named)
   798  	return n
   799  }
   800  
   801  const blankMarker = "$"
   802  
   803  // tparamName returns the real name of a type parameter, after stripping its
   804  // qualifying prefix and reverting blank-name encoding. See tparamExportName
   805  // for details.
   806  func tparamName(exportName string) string {
   807  	// Remove the "path" from the type param name that makes it unique.
   808  	ix := strings.LastIndex(exportName, ".")
   809  	if ix < 0 {
   810  		errorf("malformed type parameter export name %s: missing prefix", exportName)
   811  	}
   812  	name := exportName[ix+1:]
   813  	if strings.HasPrefix(name, blankMarker) {
   814  		return "_"
   815  	}
   816  	return name
   817  }
   818  

View as plain text