github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/internal/gcimporter/iimport.go (about)

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