Source file src/cmd/vendor/golang.org/x/tools/internal/gcimporter/ureader.go

     1  // Copyright 2021 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  // Derived from go/internal/gcimporter/ureader.go
     6  
     7  package gcimporter
     8  
     9  import (
    10  	"fmt"
    11  	"go/token"
    12  	"go/types"
    13  	"sort"
    14  	"strings"
    15  
    16  	"golang.org/x/tools/internal/aliases"
    17  	"golang.org/x/tools/internal/pkgbits"
    18  	"golang.org/x/tools/internal/typesinternal"
    19  )
    20  
    21  // A pkgReader holds the shared state for reading a unified IR package
    22  // description.
    23  type pkgReader struct {
    24  	pkgbits.PkgDecoder
    25  
    26  	fake fakeFileSet
    27  
    28  	ctxt    *types.Context
    29  	imports map[string]*types.Package // previously imported packages, indexed by path
    30  
    31  	// lazily initialized arrays corresponding to the unified IR
    32  	// PosBase, Pkg, and Type sections, respectively.
    33  	posBases []string // position bases (i.e., file names)
    34  	pkgs     []*types.Package
    35  	typs     []types.Type
    36  
    37  	// laterFns holds functions that need to be invoked at the end of
    38  	// import reading.
    39  	//
    40  	// TODO(mdempsky): Is it safe to have a single "later" slice or do
    41  	// we need to have multiple passes? See comments on CL 386002 and
    42  	// go.dev/issue/52104.
    43  	laterFns []func()
    44  	// laterFors is used in case of 'type A B' to ensure that B is processed before A.
    45  	laterFors map[types.Type]int
    46  
    47  	// ifaces holds a list of constructed Interfaces, which need to have
    48  	// Complete called after importing is done.
    49  	ifaces []*types.Interface
    50  }
    51  
    52  // later adds a function to be invoked at the end of import reading.
    53  func (pr *pkgReader) later(fn func()) {
    54  	pr.laterFns = append(pr.laterFns, fn)
    55  }
    56  
    57  // See cmd/compile/internal/noder.derivedInfo.
    58  type derivedInfo struct {
    59  	idx pkgbits.Index
    60  }
    61  
    62  // See cmd/compile/internal/noder.typeInfo.
    63  type typeInfo struct {
    64  	idx     pkgbits.Index
    65  	derived bool
    66  }
    67  
    68  func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
    69  	if !debug {
    70  		defer func() {
    71  			if x := recover(); x != nil {
    72  				err = fmt.Errorf("internal error in importing %q (%v); please report an issue", path, x)
    73  			}
    74  		}()
    75  	}
    76  
    77  	s := string(data)
    78  	input := pkgbits.NewPkgDecoder(path, s)
    79  	pkg = readUnifiedPackage(fset, nil, imports, input)
    80  	return
    81  }
    82  
    83  // laterFor adds a function to be invoked at the end of import reading, and records the type that function is finishing.
    84  func (pr *pkgReader) laterFor(t types.Type, fn func()) {
    85  	if pr.laterFors == nil {
    86  		pr.laterFors = make(map[types.Type]int)
    87  	}
    88  	pr.laterFors[t] = len(pr.laterFns)
    89  	pr.laterFns = append(pr.laterFns, fn)
    90  }
    91  
    92  // readUnifiedPackage reads a package description from the given
    93  // unified IR export data decoder.
    94  func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package {
    95  	pr := pkgReader{
    96  		PkgDecoder: input,
    97  
    98  		fake: fakeFileSet{
    99  			fset:  fset,
   100  			files: make(map[string]*fileInfo),
   101  		},
   102  
   103  		ctxt:    ctxt,
   104  		imports: imports,
   105  
   106  		posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)),
   107  		pkgs:     make([]*types.Package, input.NumElems(pkgbits.RelocPkg)),
   108  		typs:     make([]types.Type, input.NumElems(pkgbits.RelocType)),
   109  	}
   110  	defer pr.fake.setLines()
   111  
   112  	r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
   113  	pkg := r.pkg()
   114  	if r.Version().Has(pkgbits.HasInit) {
   115  		r.Bool()
   116  	}
   117  
   118  	for i, n := 0, r.Len(); i < n; i++ {
   119  		// As if r.obj(), but avoiding the Scope.Lookup call,
   120  		// to avoid eager loading of imports.
   121  		r.Sync(pkgbits.SyncObject)
   122  		if r.Version().Has(pkgbits.DerivedFuncInstance) {
   123  			assert(!r.Bool())
   124  		}
   125  		r.p.objIdx(r.Reloc(pkgbits.RelocObj))
   126  		assert(r.Len() == 0)
   127  	}
   128  
   129  	r.Sync(pkgbits.SyncEOF)
   130  
   131  	for _, fn := range pr.laterFns {
   132  		fn()
   133  	}
   134  
   135  	for _, iface := range pr.ifaces {
   136  		iface.Complete()
   137  	}
   138  
   139  	// Imports() of pkg are all of the transitive packages that were loaded.
   140  	var imps []*types.Package
   141  	for _, imp := range pr.pkgs {
   142  		if imp != nil && imp != pkg {
   143  			imps = append(imps, imp)
   144  		}
   145  	}
   146  	sort.Sort(byPath(imps))
   147  	pkg.SetImports(imps)
   148  
   149  	pkg.MarkComplete()
   150  	return pkg
   151  }
   152  
   153  // A reader holds the state for reading a single unified IR element
   154  // within a package.
   155  type reader struct {
   156  	pkgbits.Decoder
   157  
   158  	p *pkgReader
   159  
   160  	dict *readerDict
   161  }
   162  
   163  // A readerDict holds the state for type parameters that parameterize
   164  // the current unified IR element.
   165  type readerDict struct {
   166  	rtbounds []typeInfo         // contains constraint types for each parameter in rtparams
   167  	rtparams []*types.TypeParam // contains receiver type parameters for an element
   168  
   169  	tbounds []typeInfo         // contains constraint types for each parameter in tparams
   170  	tparams []*types.TypeParam // contains type parameters for an element
   171  
   172  	// derived is a slice of types derived from tparams, which may be
   173  	// instantiated while reading the current element.
   174  	derived      []derivedInfo
   175  	derivedTypes []types.Type // lazily instantiated from derived
   176  }
   177  
   178  func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
   179  	return &reader{
   180  		Decoder: pr.NewDecoder(k, idx, marker),
   181  		p:       pr,
   182  	}
   183  }
   184  
   185  func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
   186  	return &reader{
   187  		Decoder: pr.TempDecoder(k, idx, marker),
   188  		p:       pr,
   189  	}
   190  }
   191  
   192  func (pr *pkgReader) retireReader(r *reader) {
   193  	pr.RetireDecoder(&r.Decoder)
   194  }
   195  
   196  // @@@ Positions
   197  
   198  func (r *reader) pos() token.Pos {
   199  	r.Sync(pkgbits.SyncPos)
   200  	if !r.Bool() {
   201  		return token.NoPos
   202  	}
   203  
   204  	// TODO(mdempsky): Delta encoding.
   205  	posBase := r.posBase()
   206  	line := r.Uint()
   207  	col := r.Uint()
   208  	return r.p.fake.pos(posBase, int(line), int(col))
   209  }
   210  
   211  func (r *reader) posBase() string {
   212  	return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase))
   213  }
   214  
   215  func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string {
   216  	if b := pr.posBases[idx]; b != "" {
   217  		return b
   218  	}
   219  
   220  	var filename string
   221  	{
   222  		r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
   223  
   224  		// Within types2, position bases have a lot more details (e.g.,
   225  		// keeping track of where //line directives appeared exactly).
   226  		//
   227  		// For go/types, we just track the file name.
   228  
   229  		filename = r.String()
   230  
   231  		if r.Bool() { // file base
   232  			// Was: "b = token.NewTrimmedFileBase(filename, true)"
   233  		} else { // line base
   234  			pos := r.pos()
   235  			line := r.Uint()
   236  			col := r.Uint()
   237  
   238  			// Was: "b = token.NewLineBase(pos, filename, true, line, col)"
   239  			_, _, _ = pos, line, col
   240  		}
   241  		pr.retireReader(r)
   242  	}
   243  	b := filename
   244  	pr.posBases[idx] = b
   245  	return b
   246  }
   247  
   248  // @@@ Packages
   249  
   250  func (r *reader) pkg() *types.Package {
   251  	r.Sync(pkgbits.SyncPkg)
   252  	return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
   253  }
   254  
   255  func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package {
   256  	// TODO(mdempsky): Consider using some non-nil pointer to indicate
   257  	// the universe scope, so we don't need to keep re-reading it.
   258  	if pkg := pr.pkgs[idx]; pkg != nil {
   259  		return pkg
   260  	}
   261  
   262  	pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg()
   263  	pr.pkgs[idx] = pkg
   264  	return pkg
   265  }
   266  
   267  func (r *reader) doPkg() *types.Package {
   268  	path := r.String()
   269  	switch path {
   270  	// cmd/compile emits path="main" for main packages because
   271  	// that's the linker symbol prefix it used; but we need
   272  	// the package's path as it would be reported by go list,
   273  	// hence "main" below.
   274  	// See test at go/packages.TestMainPackagePathInModeTypes.
   275  	case "", "main":
   276  		path = r.p.PkgPath()
   277  	case "builtin":
   278  		return nil // universe
   279  	case "unsafe":
   280  		return types.Unsafe
   281  	}
   282  
   283  	if pkg := r.p.imports[path]; pkg != nil {
   284  		return pkg
   285  	}
   286  
   287  	name := r.String()
   288  
   289  	pkg := types.NewPackage(path, name)
   290  	r.p.imports[path] = pkg
   291  
   292  	return pkg
   293  }
   294  
   295  // @@@ Types
   296  
   297  func (r *reader) typ() types.Type {
   298  	return r.p.typIdx(r.typInfo(), r.dict)
   299  }
   300  
   301  func (r *reader) typInfo() typeInfo {
   302  	r.Sync(pkgbits.SyncType)
   303  	if r.Bool() {
   304  		return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
   305  	}
   306  	return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
   307  }
   308  
   309  func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type {
   310  	idx := info.idx
   311  	var where *types.Type
   312  	if info.derived {
   313  		where = &dict.derivedTypes[idx]
   314  		idx = dict.derived[idx].idx
   315  	} else {
   316  		where = &pr.typs[idx]
   317  	}
   318  
   319  	if typ := *where; typ != nil {
   320  		return typ
   321  	}
   322  
   323  	var typ types.Type
   324  	{
   325  		r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
   326  		r.dict = dict
   327  
   328  		typ = r.doTyp()
   329  		assert(typ != nil)
   330  		pr.retireReader(r)
   331  	}
   332  	// See comment in pkgReader.typIdx explaining how this happens.
   333  	if prev := *where; prev != nil {
   334  		return prev
   335  	}
   336  
   337  	*where = typ
   338  	return typ
   339  }
   340  
   341  func (r *reader) doTyp() (res types.Type) {
   342  	switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
   343  	default:
   344  		errorf("unhandled type tag: %v", tag)
   345  		panic("unreachable")
   346  
   347  	case pkgbits.TypeBasic:
   348  		return types.Typ[r.Len()]
   349  
   350  	case pkgbits.TypeNamed:
   351  		obj, targs := r.obj()
   352  		name := obj.(*types.TypeName)
   353  		if len(targs) != 0 {
   354  			t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false)
   355  			return t
   356  		}
   357  		return name.Type()
   358  
   359  	case pkgbits.TypeTypeParam:
   360  		n := r.Len()
   361  		if n < len(r.dict.rtbounds) {
   362  			return r.dict.rtparams[n]
   363  		}
   364  		return r.dict.tparams[n-len(r.dict.rtbounds)]
   365  
   366  	case pkgbits.TypeArray:
   367  		len := int64(r.Uint64())
   368  		return types.NewArray(r.typ(), len)
   369  	case pkgbits.TypeChan:
   370  		dir := types.ChanDir(r.Len())
   371  		return types.NewChan(dir, r.typ())
   372  	case pkgbits.TypeMap:
   373  		return types.NewMap(r.typ(), r.typ())
   374  	case pkgbits.TypePointer:
   375  		return types.NewPointer(r.typ())
   376  	case pkgbits.TypeSignature:
   377  		return r.signature(nil, nil, nil)
   378  	case pkgbits.TypeSlice:
   379  		return types.NewSlice(r.typ())
   380  	case pkgbits.TypeStruct:
   381  		return r.structType()
   382  	case pkgbits.TypeInterface:
   383  		return r.interfaceType()
   384  	case pkgbits.TypeUnion:
   385  		return r.unionType()
   386  	}
   387  }
   388  
   389  func (r *reader) structType() *types.Struct {
   390  	fields := make([]*types.Var, r.Len())
   391  	var tags []string
   392  	for i := range fields {
   393  		pos := r.pos()
   394  		pkg, name := r.selector()
   395  		ftyp := r.typ()
   396  		tag := r.String()
   397  		embedded := r.Bool()
   398  
   399  		fields[i] = types.NewField(pos, pkg, name, ftyp, embedded)
   400  		if tag != "" {
   401  			for len(tags) < i {
   402  				tags = append(tags, "")
   403  			}
   404  			tags = append(tags, tag)
   405  		}
   406  	}
   407  	return types.NewStruct(fields, tags)
   408  }
   409  
   410  func (r *reader) unionType() *types.Union {
   411  	terms := make([]*types.Term, r.Len())
   412  	for i := range terms {
   413  		terms[i] = types.NewTerm(r.Bool(), r.typ())
   414  	}
   415  	return types.NewUnion(terms)
   416  }
   417  
   418  func (r *reader) interfaceType() *types.Interface {
   419  	methods := make([]*types.Func, r.Len())
   420  	embeddeds := make([]types.Type, r.Len())
   421  	implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool()
   422  
   423  	for i := range methods {
   424  		pos := r.pos()
   425  		pkg, name := r.selector()
   426  		mtyp := r.signature(nil, nil, nil)
   427  		methods[i] = types.NewFunc(pos, pkg, name, mtyp)
   428  	}
   429  
   430  	for i := range embeddeds {
   431  		embeddeds[i] = r.typ()
   432  	}
   433  
   434  	iface := types.NewInterfaceType(methods, embeddeds)
   435  	if implicit {
   436  		iface.MarkImplicit()
   437  	}
   438  
   439  	// We need to call iface.Complete(), but if there are any embedded
   440  	// defined types, then we may not have set their underlying
   441  	// interface type yet. So we need to defer calling Complete until
   442  	// after we've called SetUnderlying everywhere.
   443  	//
   444  	// TODO(mdempsky): After CL 424876 lands, it should be safe to call
   445  	// iface.Complete() immediately.
   446  	r.p.ifaces = append(r.p.ifaces, iface)
   447  
   448  	return iface
   449  }
   450  
   451  func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature {
   452  	r.Sync(pkgbits.SyncSignature)
   453  
   454  	params := r.params()
   455  	results := r.params()
   456  	variadic := r.Bool()
   457  
   458  	return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic)
   459  }
   460  
   461  func (r *reader) params() *types.Tuple {
   462  	r.Sync(pkgbits.SyncParams)
   463  
   464  	params := make([]*types.Var, r.Len())
   465  	for i := range params {
   466  		params[i] = r.param()
   467  	}
   468  
   469  	return types.NewTuple(params...)
   470  }
   471  
   472  func (r *reader) param() *types.Var {
   473  	r.Sync(pkgbits.SyncParam)
   474  
   475  	pos := r.pos()
   476  	pkg, name := r.localIdent()
   477  	typ := r.typ()
   478  
   479  	return types.NewParam(pos, pkg, name, typ)
   480  }
   481  
   482  // @@@ Objects
   483  
   484  func (r *reader) obj() (types.Object, []types.Type) {
   485  	r.Sync(pkgbits.SyncObject)
   486  
   487  	if r.Version().Has(pkgbits.DerivedFuncInstance) {
   488  		assert(!r.Bool())
   489  	}
   490  
   491  	pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj))
   492  	obj := pkgScope(pkg).Lookup(name)
   493  
   494  	targs := make([]types.Type, r.Len())
   495  	for i := range targs {
   496  		targs[i] = r.typ()
   497  	}
   498  
   499  	return obj, targs
   500  }
   501  
   502  func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
   503  
   504  	var objPkg *types.Package
   505  	var objName string
   506  	var tag pkgbits.CodeObj
   507  	{
   508  		rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
   509  
   510  		objPkg, objName = rname.qualifiedIdent()
   511  		assert(objName != "")
   512  
   513  		tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
   514  		pr.retireReader(rname)
   515  	}
   516  
   517  	if tag == pkgbits.ObjStub {
   518  		assert(objPkg == nil || objPkg == types.Unsafe)
   519  		return objPkg, objName
   520  	}
   521  
   522  	// Ignore local types promoted to global scope (#55110).
   523  	if _, suffix := splitVargenSuffix(objName); suffix != "" {
   524  		return objPkg, objName
   525  	}
   526  
   527  	// TODO(mark): This, like the above splitVargenSuffix, is not ideal.
   528  	// Ignore generic methods promoted to global scope.
   529  	if strings.Contains(objName, ".") {
   530  		return objPkg, objName
   531  	}
   532  
   533  	if objPkg.Scope().Lookup(objName) == nil {
   534  		dict := pr.objDictIdx(idx)
   535  
   536  		r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1)
   537  		r.dict = dict
   538  
   539  		declare := func(obj types.Object) {
   540  			objPkg.Scope().Insert(obj)
   541  		}
   542  
   543  		switch tag {
   544  		default:
   545  			panic("weird")
   546  
   547  		case pkgbits.ObjAlias:
   548  			pos := r.pos()
   549  			var tparams []*types.TypeParam
   550  			if r.Version().Has(pkgbits.AliasTypeParamNames) {
   551  				tparams = r.typeParamNames(false)
   552  			}
   553  			typ := r.typ()
   554  			declare(aliases.New(pos, objPkg, objName, typ, tparams))
   555  
   556  		case pkgbits.ObjConst:
   557  			pos := r.pos()
   558  			typ := r.typ()
   559  			val := r.Value()
   560  			declare(types.NewConst(pos, objPkg, objName, typ, val))
   561  
   562  		case pkgbits.ObjFunc:
   563  			pos := r.pos()
   564  			if r.Version().Has(pkgbits.GenericMethods) {
   565  				assert(!r.Bool()) // generic methods are read in their defining type
   566  			}
   567  			tparams := r.typeParamNames(false)
   568  			sig := r.signature(nil, nil, tparams)
   569  			declare(types.NewFunc(pos, objPkg, objName, sig))
   570  
   571  		case pkgbits.ObjType:
   572  			pos := r.pos()
   573  
   574  			obj := types.NewTypeName(pos, objPkg, objName, nil)
   575  			named := types.NewNamed(obj, nil, nil)
   576  			declare(obj)
   577  
   578  			named.SetTypeParams(r.typeParamNames(false))
   579  
   580  			setUnderlying := func(underlying types.Type) {
   581  				// If the underlying type is an interface, we need to
   582  				// duplicate its methods so we can replace the receiver
   583  				// parameter's type (#49906).
   584  				if iface, ok := types.Unalias(underlying).(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
   585  					methods := make([]*types.Func, iface.NumExplicitMethods())
   586  					for i := range methods {
   587  						fn := iface.ExplicitMethod(i)
   588  						sig := fn.Type().(*types.Signature)
   589  
   590  						recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named)
   591  						typesinternal.SetVarKind(recv, typesinternal.RecvVar)
   592  						methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignatureType(recv, nil, nil, sig.Params(), sig.Results(), sig.Variadic()))
   593  					}
   594  
   595  					embeds := make([]types.Type, iface.NumEmbeddeds())
   596  					for i := range embeds {
   597  						embeds[i] = iface.EmbeddedType(i)
   598  					}
   599  
   600  					newIface := types.NewInterfaceType(methods, embeds)
   601  					r.p.ifaces = append(r.p.ifaces, newIface)
   602  					underlying = newIface
   603  				}
   604  
   605  				named.SetUnderlying(underlying)
   606  			}
   607  
   608  			// Since go.dev/cl/455279, we can assume rhs.Underlying() will
   609  			// always be non-nil. However, to temporarily support users of
   610  			// older snapshot releases, we continue to fallback to the old
   611  			// behavior for now.
   612  			//
   613  			// TODO(mdempsky): Remove fallback code and simplify after
   614  			// allowing time for snapshot users to upgrade.
   615  			rhs := r.typ()
   616  			if underlying := rhs.Underlying(); underlying != nil {
   617  				setUnderlying(underlying)
   618  			} else {
   619  				pk := r.p
   620  				pk.laterFor(named, func() {
   621  					// First be sure that the rhs is initialized, if it needs to be initialized.
   622  					delete(pk.laterFors, named) // prevent cycles
   623  					if i, ok := pk.laterFors[rhs]; ok {
   624  						f := pk.laterFns[i]
   625  						pk.laterFns[i] = func() {} // function is running now, so replace it with a no-op
   626  						f()                        // initialize RHS
   627  					}
   628  					setUnderlying(rhs.Underlying())
   629  				})
   630  			}
   631  
   632  			for i, n := 0, r.Len(); i < n; i++ {
   633  				named.AddMethod(r.method())
   634  			}
   635  
   636  			if r.Version().Has(pkgbits.GenericMethods) {
   637  				for range r.Len() {
   638  					// Careful: objIdx is used to read in package-scoped declarations, which
   639  					// methods are not. Instead, decode it here. This makes it easier to
   640  					// associate it with the type and avoids the main objIdx loop.
   641  					idx := r.Reloc(pkgbits.RelocObj)
   642  
   643  					r := pr.tempReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1)
   644  					r.dict = pr.objDictIdx(idx)
   645  
   646  					pos := r.pos()
   647  					assert(r.Bool()) // generic method
   648  					pkg, name := r.selector()
   649  					rtparams := r.typeParamNames(true)
   650  					recv := r.param()
   651  					tparams := r.typeParamNames(false)
   652  					sig := r.signature(recv, rtparams, tparams)
   653  
   654  					pr.retireReader(r)
   655  					named.AddMethod(types.NewFunc(pos, pkg, name, sig))
   656  				}
   657  			}
   658  
   659  		case pkgbits.ObjVar:
   660  			pos := r.pos()
   661  			typ := r.typ()
   662  			v := types.NewVar(pos, objPkg, objName, typ)
   663  			typesinternal.SetVarKind(v, typesinternal.PackageVar)
   664  			declare(v)
   665  		}
   666  	}
   667  
   668  	return objPkg, objName
   669  }
   670  
   671  func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
   672  
   673  	var dict readerDict
   674  
   675  	{
   676  		r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
   677  		if implicits := r.Len(); implicits != 0 {
   678  			errorf("unexpected object with %v implicit type parameter(s)", implicits)
   679  		}
   680  
   681  		nreceivers := 0
   682  		if r.Version().Has(pkgbits.GenericMethods) {
   683  			nreceivers = r.Len()
   684  		}
   685  		nexplicits := r.Len()
   686  
   687  		dict.rtbounds = make([]typeInfo, nreceivers)
   688  		for i := range dict.rtbounds {
   689  			dict.rtbounds[i] = r.typInfo()
   690  		}
   691  
   692  		dict.tbounds = make([]typeInfo, nexplicits)
   693  		for i := range dict.tbounds {
   694  			dict.tbounds[i] = r.typInfo()
   695  		}
   696  
   697  		dict.derived = make([]derivedInfo, r.Len())
   698  		dict.derivedTypes = make([]types.Type, len(dict.derived))
   699  		for i := range dict.derived {
   700  			dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.RelocType)}
   701  			if r.Version().Has(pkgbits.DerivedInfoNeeded) {
   702  				assert(!r.Bool())
   703  			}
   704  		}
   705  
   706  		pr.retireReader(r)
   707  	}
   708  	// function references follow, but reader doesn't need those
   709  
   710  	return &dict
   711  }
   712  
   713  func (r *reader) typeParamNames(isGenMeth bool) []*types.TypeParam {
   714  	r.Sync(pkgbits.SyncTypeParamNames)
   715  
   716  	// Note: This code assumes there are no implicit type parameters.
   717  	// This is fine since it only reads exported declarations, which
   718  	// never have implicits.
   719  
   720  	var in []typeInfo
   721  	var out *[]*types.TypeParam
   722  	if isGenMeth {
   723  		in = r.dict.rtbounds
   724  		out = &r.dict.rtparams
   725  	} else {
   726  		in = r.dict.tbounds
   727  		out = &r.dict.tparams
   728  	}
   729  
   730  	if len(in) == 0 {
   731  		return nil
   732  	}
   733  
   734  	// Careful: Type parameter lists may have cycles. To allow for this,
   735  	// we construct the type parameter list in two passes: first we
   736  	// create all the TypeNames and TypeParams, then we construct and
   737  	// set the bound type.
   738  
   739  	// We have to save tparams outside of the closure, because typeParamNames
   740  	// can be called multiple times with the same dictionary instance.
   741  	tparams := make([]*types.TypeParam, len(in))
   742  	*out = tparams
   743  
   744  	for i := range in {
   745  		pos := r.pos()
   746  		pkg, name := r.localIdent()
   747  
   748  		tname := types.NewTypeName(pos, pkg, name, nil)
   749  		tparams[i] = types.NewTypeParam(tname, nil)
   750  	}
   751  
   752  	// The reader dictionary will continue mutating before we have time
   753  	// to call delayed functions; make a local copy of the constraints.
   754  	types := make([]types.Type, len(in))
   755  	for i, info := range in {
   756  		types[i] = r.p.typIdx(info, r.dict)
   757  	}
   758  
   759  	// This needs to happen later to make sure SetUnderlying has been called.
   760  	r.p.later(func() {
   761  		for i, typ := range types {
   762  			tparams[i].SetConstraint(typ)
   763  		}
   764  	})
   765  
   766  	return tparams
   767  }
   768  
   769  func (r *reader) method() *types.Func {
   770  	r.Sync(pkgbits.SyncMethod)
   771  	pos := r.pos()
   772  	pkg, name := r.selector()
   773  
   774  	rparams := r.typeParamNames(false)
   775  	sig := r.signature(r.param(), rparams, nil)
   776  
   777  	_ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go.
   778  	return types.NewFunc(pos, pkg, name, sig)
   779  }
   780  
   781  func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) }
   782  func (r *reader) localIdent() (*types.Package, string)     { return r.ident(pkgbits.SyncLocalIdent) }
   783  func (r *reader) selector() (*types.Package, string)       { return r.ident(pkgbits.SyncSelector) }
   784  
   785  func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) {
   786  	r.Sync(marker)
   787  	return r.pkg(), r.String()
   788  }
   789  
   790  // pkgScope returns pkg.Scope().
   791  // If pkg is nil, it returns types.Universe instead.
   792  //
   793  // TODO(mdempsky): Remove after x/tools can depend on Go 1.19.
   794  func pkgScope(pkg *types.Package) *types.Scope {
   795  	if pkg != nil {
   796  		return pkg.Scope()
   797  	}
   798  	return types.Universe
   799  }
   800  
   801  // See cmd/compile/internal/types.SplitVargenSuffix.
   802  func splitVargenSuffix(name string) (base, suffix string) {
   803  	i := len(name)
   804  	for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' {
   805  		i--
   806  	}
   807  	const dot = "ยท"
   808  	if i >= len(dot) && name[i-len(dot):i] == dot {
   809  		i -= len(dot)
   810  		return name[:i], name[i:]
   811  	}
   812  	return name, ""
   813  }
   814  

View as plain text