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

View as plain text