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

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

View as plain text