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

View as plain text