...

Source file src/cmd/compile/internal/importer/iimport.go

Documentation: cmd/compile/internal/importer

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

View as plain text