1
2
3
4
5 package gcimporter
6
7 import (
8 "cmp"
9 "go/token"
10 "go/types"
11 "internal/pkgbits"
12 "slices"
13 "strings"
14 )
15
16
17
18 type pkgReader struct {
19 pkgbits.PkgDecoder
20
21 fake fakeFileSet
22
23 ctxt *types.Context
24 imports map[string]*types.Package
25
26
27
28 posBases []string
29 pkgs []*types.Package
30 typs []types.Type
31
32
33
34
35
36
37
38 laterFns []func()
39
40
41
42 ifaces []*types.Interface
43 }
44
45
46 func (pr *pkgReader) later(fn func()) {
47 pr.laterFns = append(pr.laterFns, fn)
48 }
49
50
51
52 func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package {
53 pr := pkgReader{
54 PkgDecoder: input,
55
56 fake: fakeFileSet{
57 fset: fset,
58 files: make(map[string]*fileInfo),
59 },
60
61 ctxt: ctxt,
62 imports: imports,
63
64 posBases: make([]string, input.NumElems(pkgbits.SectionPosBase)),
65 pkgs: make([]*types.Package, input.NumElems(pkgbits.SectionPkg)),
66 typs: make([]types.Type, input.NumElems(pkgbits.SectionType)),
67 }
68 defer pr.fake.setLines()
69
70 r := pr.newReader(pkgbits.SectionMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
71 pkg := r.pkg()
72 if r.Version().Has(pkgbits.HasInit) {
73 r.Bool()
74 }
75
76 for i, n := 0, r.Len(); i < n; i++ {
77
78
79 r.Sync(pkgbits.SyncObject)
80 if r.Version().Has(pkgbits.DerivedFuncInstance) {
81 assert(!r.Bool())
82 }
83 r.p.objIdx(r.Reloc(pkgbits.SectionObj))
84 assert(r.Len() == 0)
85 }
86
87 r.Sync(pkgbits.SyncEOF)
88
89 for _, fn := range pr.laterFns {
90 fn()
91 }
92
93 for _, iface := range pr.ifaces {
94 iface.Complete()
95 }
96
97
98 var imps []*types.Package
99 for _, imp := range pr.pkgs {
100 if imp != nil && imp != pkg {
101 imps = append(imps, imp)
102 }
103 }
104 slices.SortFunc(imps, func(a, b *types.Package) int {
105 return strings.Compare(a.Path(), b.Path())
106 })
107 pkg.SetImports(imps)
108
109 pkg.MarkComplete()
110 return pkg
111 }
112
113
114
115 type reader struct {
116 pkgbits.Decoder
117
118 p *pkgReader
119
120 dict *readerDict
121 }
122
123
124
125 type readerDict struct {
126 rtbounds []typeInfo
127 rtparams []*types.TypeParam
128
129 tbounds []typeInfo
130 tparams []*types.TypeParam
131
132
133
134 derived []derivedInfo
135 derivedTypes []types.Type
136 }
137
138 func (pr *pkgReader) newReader(k pkgbits.SectionKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
139 return &reader{
140 Decoder: pr.NewDecoder(k, idx, marker),
141 p: pr,
142 }
143 }
144
145 func (pr *pkgReader) tempReader(k pkgbits.SectionKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
146 return &reader{
147 Decoder: pr.TempDecoder(k, idx, marker),
148 p: pr,
149 }
150 }
151
152 func (pr *pkgReader) retireReader(r *reader) {
153 pr.RetireDecoder(&r.Decoder)
154 }
155
156
157
158 func (r *reader) pos() token.Pos {
159 r.Sync(pkgbits.SyncPos)
160 if !r.Bool() {
161 return token.NoPos
162 }
163
164
165 posBase := r.posBase()
166 line := r.Uint()
167 col := r.Uint()
168 return r.p.fake.pos(posBase, int(line), int(col))
169 }
170
171 func (r *reader) posBase() string {
172 return r.p.posBaseIdx(r.Reloc(pkgbits.SectionPosBase))
173 }
174
175 func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string {
176 if b := pr.posBases[idx]; b != "" {
177 return b
178 }
179
180 var filename string
181 {
182 r := pr.tempReader(pkgbits.SectionPosBase, idx, pkgbits.SyncPosBase)
183
184
185
186
187
188
189 filename = r.String()
190
191 if r.Bool() {
192
193 } else {
194 pos := r.pos()
195 line := r.Uint()
196 col := r.Uint()
197
198
199 _, _, _ = pos, line, col
200 }
201 pr.retireReader(r)
202 }
203 b := filename
204 pr.posBases[idx] = b
205 return b
206 }
207
208
209
210 func (r *reader) pkg() *types.Package {
211 r.Sync(pkgbits.SyncPkg)
212 return r.p.pkgIdx(r.Reloc(pkgbits.SectionPkg))
213 }
214
215 func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package {
216
217
218 if pkg := pr.pkgs[idx]; pkg != nil {
219 return pkg
220 }
221
222 pkg := pr.newReader(pkgbits.SectionPkg, idx, pkgbits.SyncPkgDef).doPkg()
223 pr.pkgs[idx] = pkg
224 return pkg
225 }
226
227 func (r *reader) doPkg() *types.Package {
228 path := r.String()
229 switch path {
230 case "":
231 path = r.p.PkgPath()
232 case "builtin":
233 return nil
234 case "unsafe":
235 return types.Unsafe
236 }
237
238 if pkg := r.p.imports[path]; pkg != nil {
239 return pkg
240 }
241
242 name := r.String()
243
244 pkg := types.NewPackage(path, name)
245 r.p.imports[path] = pkg
246
247 return pkg
248 }
249
250
251
252 func (r *reader) typ() types.Type {
253 return r.p.typIdx(r.typInfo(), r.dict)
254 }
255
256 func (r *reader) typInfo() typeInfo {
257 r.Sync(pkgbits.SyncType)
258 if r.Bool() {
259 return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
260 }
261 return typeInfo{idx: r.Reloc(pkgbits.SectionType), derived: false}
262 }
263
264 func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type {
265 idx := info.idx
266 var where *types.Type
267 if info.derived {
268 where = &dict.derivedTypes[idx]
269 idx = dict.derived[idx].idx
270 } else {
271 where = &pr.typs[idx]
272 }
273
274 if typ := *where; typ != nil {
275 return typ
276 }
277
278 var typ types.Type
279 {
280 r := pr.tempReader(pkgbits.SectionType, idx, pkgbits.SyncTypeIdx)
281 r.dict = dict
282
283 typ = r.doTyp()
284 assert(typ != nil)
285 pr.retireReader(r)
286 }
287
288 if prev := *where; prev != nil {
289 return prev
290 }
291
292 *where = typ
293 return typ
294 }
295
296 func (r *reader) doTyp() (res types.Type) {
297 switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
298 default:
299 errorf("unhandled type tag: %v", tag)
300 panic("unreachable")
301
302 case pkgbits.TypeBasic:
303 return types.Typ[r.Len()]
304
305 case pkgbits.TypeNamed:
306 obj, targs := r.obj()
307 name := obj.(*types.TypeName)
308 if len(targs) != 0 {
309 t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false)
310 return t
311 }
312 return name.Type()
313
314 case pkgbits.TypeTypeParam:
315 n := r.Len()
316 if n < len(r.dict.rtbounds) {
317 return r.dict.rtparams[n]
318 }
319 return r.dict.tparams[n-len(r.dict.rtbounds)]
320
321 case pkgbits.TypeArray:
322 len := int64(r.Uint64())
323 return types.NewArray(r.typ(), len)
324 case pkgbits.TypeChan:
325 dir := types.ChanDir(r.Len())
326 return types.NewChan(dir, r.typ())
327 case pkgbits.TypeMap:
328 return types.NewMap(r.typ(), r.typ())
329 case pkgbits.TypePointer:
330 return types.NewPointer(r.typ())
331 case pkgbits.TypeSignature:
332 return r.signature(nil, nil, nil)
333 case pkgbits.TypeSlice:
334 return types.NewSlice(r.typ())
335 case pkgbits.TypeStruct:
336 return r.structType()
337 case pkgbits.TypeInterface:
338 return r.interfaceType()
339 case pkgbits.TypeUnion:
340 return r.unionType()
341 }
342 }
343
344 func (r *reader) structType() *types.Struct {
345 fields := make([]*types.Var, r.Len())
346 var tags []string
347 for i := range fields {
348 pos := r.pos()
349 pkg, name := r.selector()
350 ftyp := r.typ()
351 tag := r.String()
352 embedded := r.Bool()
353
354 fields[i] = types.NewField(pos, pkg, name, ftyp, embedded)
355 if tag != "" {
356 for len(tags) < i {
357 tags = append(tags, "")
358 }
359 tags = append(tags, tag)
360 }
361 }
362 return types.NewStruct(fields, tags)
363 }
364
365 func (r *reader) unionType() *types.Union {
366 terms := make([]*types.Term, r.Len())
367 for i := range terms {
368 terms[i] = types.NewTerm(r.Bool(), r.typ())
369 }
370 return types.NewUnion(terms)
371 }
372
373 func (r *reader) interfaceType() *types.Interface {
374 methods := make([]*types.Func, r.Len())
375 embeddeds := make([]types.Type, r.Len())
376 implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool()
377
378 for i := range methods {
379 pos := r.pos()
380 pkg, name := r.selector()
381 mtyp := r.signature(nil, nil, nil)
382 methods[i] = types.NewFunc(pos, pkg, name, mtyp)
383 }
384
385 for i := range embeddeds {
386 embeddeds[i] = r.typ()
387 }
388
389 iface := types.NewInterfaceType(methods, embeddeds)
390 if implicit {
391 iface.MarkImplicit()
392 }
393
394
395
396
397
398
399
400
401 r.p.ifaces = append(r.p.ifaces, iface)
402
403 return iface
404 }
405
406 func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature {
407 r.Sync(pkgbits.SyncSignature)
408
409 params := r.params(types.ParamVar)
410 results := r.params(types.ResultVar)
411 variadic := r.Bool()
412
413 return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic)
414 }
415
416 func (r *reader) params(kind types.VarKind) *types.Tuple {
417 r.Sync(pkgbits.SyncParams)
418
419 params := make([]*types.Var, r.Len())
420 for i := range params {
421 params[i] = r.param(kind)
422 }
423
424 return types.NewTuple(params...)
425 }
426
427 func (r *reader) param(kind types.VarKind) *types.Var {
428 r.Sync(pkgbits.SyncParam)
429
430 pos := r.pos()
431 pkg, name := r.localIdent()
432 typ := r.typ()
433
434 param := types.NewParam(pos, pkg, name, typ)
435 param.SetKind(kind)
436 return param
437 }
438
439
440
441 func (r *reader) obj() (types.Object, []types.Type) {
442 r.Sync(pkgbits.SyncObject)
443
444 if r.Version().Has(pkgbits.DerivedFuncInstance) {
445 assert(!r.Bool())
446 }
447
448 pkg, name := r.p.objIdx(r.Reloc(pkgbits.SectionObj))
449 obj := pkgScope(pkg).Lookup(name)
450
451 targs := make([]types.Type, r.Len())
452 for i := range targs {
453 targs[i] = r.typ()
454 }
455
456 return obj, targs
457 }
458
459 func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
460
461 var objPkg *types.Package
462 var objName string
463 var tag pkgbits.CodeObj
464 {
465 rname := pr.tempReader(pkgbits.SectionName, idx, pkgbits.SyncObject1)
466
467 objPkg, objName = rname.qualifiedIdent()
468 assert(objName != "")
469
470 tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
471 pr.retireReader(rname)
472 }
473
474 if tag == pkgbits.ObjStub {
475 assert(objPkg == nil || objPkg == types.Unsafe)
476 return objPkg, objName
477 }
478
479
480 if _, suffix := splitVargenSuffix(objName); suffix != "" {
481 return objPkg, objName
482 }
483
484
485
486 if strings.Contains(objName, ".") {
487 return objPkg, objName
488 }
489
490 if objPkg.Scope().Lookup(objName) == nil {
491 dict := pr.objDictIdx(idx)
492
493 r := pr.newReader(pkgbits.SectionObj, idx, pkgbits.SyncObject1)
494 r.dict = dict
495
496 declare := func(obj types.Object) {
497 objPkg.Scope().Insert(obj)
498 }
499
500 switch tag {
501 default:
502 panic("weird")
503
504 case pkgbits.ObjAlias:
505 pos := r.pos()
506 var tparams []*types.TypeParam
507 if r.Version().Has(pkgbits.AliasTypeParamNames) {
508 tparams = r.typeParamNames(false)
509 }
510 typ := r.typ()
511 declare(newAliasTypeName(pos, objPkg, objName, typ, tparams))
512
513 case pkgbits.ObjConst:
514 pos := r.pos()
515 typ := r.typ()
516 val := r.Value()
517 declare(types.NewConst(pos, objPkg, objName, typ, val))
518
519 case pkgbits.ObjFunc:
520 pos := r.pos()
521 if r.Version().Has(pkgbits.GenericMethods) {
522 assert(!r.Bool())
523 }
524 tparams := r.typeParamNames(false)
525 sig := r.signature(nil, nil, tparams)
526 declare(types.NewFunc(pos, objPkg, objName, sig))
527
528 case pkgbits.ObjType:
529 pos := r.pos()
530
531 obj := types.NewTypeName(pos, objPkg, objName, nil)
532 named := types.NewNamed(obj, nil, nil)
533 declare(obj)
534
535 named.SetTypeParams(r.typeParamNames(false))
536
537 underlying := r.typ().Underlying()
538
539
540
541
542 if iface, ok := underlying.(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
543 methods := make([]*types.Func, iface.NumExplicitMethods())
544 for i := range methods {
545 fn := iface.ExplicitMethod(i)
546 sig := fn.Signature()
547
548 recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named)
549 recv.SetKind(types.RecvVar)
550 methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic()))
551 }
552
553 embeds := make([]types.Type, iface.NumEmbeddeds())
554 for i := range embeds {
555 embeds[i] = iface.EmbeddedType(i)
556 }
557
558 newIface := types.NewInterfaceType(methods, embeds)
559 r.p.ifaces = append(r.p.ifaces, newIface)
560 underlying = newIface
561 }
562
563 named.SetUnderlying(underlying)
564
565 if r.Version().Has(pkgbits.GenericMethods) {
566
567
568
569
570
571 type indexedMethod struct {
572 index int
573 fn *types.Func
574 }
575
576 var methods []indexedMethod
577
578
579 for range r.Len() {
580 idx, m := r.method()
581 methods = append(methods, indexedMethod{idx, m})
582 }
583
584
585 for range r.Len() {
586
587
588
589 idx := r.Reloc(pkgbits.SectionObj)
590
591 r := pr.tempReader(pkgbits.SectionObj, idx, pkgbits.SyncObject1)
592 r.dict = pr.objDictIdx(idx)
593
594 pos := r.pos()
595 assert(r.Bool())
596 pkg, name := r.selector()
597 rtparams := r.typeParamNames(true)
598 recv := r.param(types.RecvVar)
599 methodIdx := -1
600 if r.Version().Has(pkgbits.PreserveMethodOrder) {
601 methodIdx = r.Len()
602 }
603 tparams := r.typeParamNames(false)
604 sig := r.signature(recv, rtparams, tparams)
605
606 pr.retireReader(r)
607 methods = append(methods, indexedMethod{methodIdx, types.NewFunc(pos, pkg, name, sig)})
608 }
609
610 if r.Version().Has(pkgbits.PreserveMethodOrder) {
611 slices.SortFunc(methods, func(a, b indexedMethod) int {
612 return cmp.Compare(a.index, b.index)
613 })
614 }
615
616 for _, m := range methods {
617 named.AddMethod(m.fn)
618 }
619
620 } else {
621 for range r.Len() {
622 _, m := r.method()
623 named.AddMethod(m)
624 }
625 }
626
627 case pkgbits.ObjVar:
628 pos := r.pos()
629 typ := r.typ()
630 declare(types.NewVar(pos, objPkg, objName, typ))
631 }
632 }
633
634 return objPkg, objName
635 }
636
637 func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
638
639 var dict readerDict
640
641 {
642 r := pr.tempReader(pkgbits.SectionObjDict, idx, pkgbits.SyncObject1)
643 if implicits := r.Len(); implicits != 0 {
644 errorf("unexpected object with %v implicit type parameter(s)", implicits)
645 }
646
647 nreceivers := 0
648 if r.Version().Has(pkgbits.GenericMethods) {
649 nreceivers = r.Len()
650 }
651 nexplicits := r.Len()
652
653 dict.rtbounds = make([]typeInfo, nreceivers)
654 for i := range dict.rtbounds {
655 dict.rtbounds[i] = r.typInfo()
656 }
657
658 dict.tbounds = make([]typeInfo, nexplicits)
659 for i := range dict.tbounds {
660 dict.tbounds[i] = r.typInfo()
661 }
662
663 dict.derived = make([]derivedInfo, r.Len())
664 dict.derivedTypes = make([]types.Type, len(dict.derived))
665 for i := range dict.derived {
666 dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.SectionType)}
667 if r.Version().Has(pkgbits.DerivedInfoNeeded) {
668 assert(!r.Bool())
669 }
670 }
671
672 pr.retireReader(r)
673 }
674
675
676 return &dict
677 }
678
679 func (r *reader) typeParamNames(isGenMeth bool) []*types.TypeParam {
680 r.Sync(pkgbits.SyncTypeParamNames)
681
682
683
684
685
686 var in []typeInfo
687 var out *[]*types.TypeParam
688 if isGenMeth {
689 in = r.dict.rtbounds
690 out = &r.dict.rtparams
691 } else {
692 in = r.dict.tbounds
693 out = &r.dict.tparams
694 }
695
696 if len(in) == 0 {
697 return nil
698 }
699
700
701
702
703
704
705
706
707 tparams := make([]*types.TypeParam, len(in))
708 *out = tparams
709
710 for i := range in {
711 pos := r.pos()
712 pkg, name := r.localIdent()
713
714 tname := types.NewTypeName(pos, pkg, name, nil)
715 tparams[i] = types.NewTypeParam(tname, nil)
716 }
717
718
719
720 types := make([]types.Type, len(in))
721 for i, info := range in {
722 types[i] = r.p.typIdx(info, r.dict)
723 }
724
725
726 r.p.later(func() {
727 for i, typ := range types {
728 tparams[i].SetConstraint(typ)
729 }
730 })
731
732 return tparams
733 }
734
735 func (r *reader) method() (int, *types.Func) {
736 r.Sync(pkgbits.SyncMethod)
737 idx := -1
738 if r.Version().Has(pkgbits.PreserveMethodOrder) {
739 idx = r.Len()
740 }
741 pos := r.pos()
742 pkg, name := r.selector()
743
744 rparams := r.typeParamNames(false)
745 sig := r.signature(r.param(types.RecvVar), rparams, nil)
746
747 _ = r.pos()
748 return idx, types.NewFunc(pos, pkg, name, sig)
749 }
750
751 func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) }
752 func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) }
753 func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) }
754
755 func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) {
756 r.Sync(marker)
757 return r.pkg(), r.String()
758 }
759
760
761
762
763
764 func pkgScope(pkg *types.Package) *types.Scope {
765 if pkg != nil {
766 return pkg.Scope()
767 }
768 return types.Universe
769 }
770
771
772 func newAliasTypeName(pos token.Pos, pkg *types.Package, name string, rhs types.Type, tparams []*types.TypeParam) *types.TypeName {
773 tname := types.NewTypeName(pos, pkg, name, nil)
774 a := types.NewAlias(tname, rhs)
775 a.SetTypeParams(tparams)
776 return tname
777 }
778
View as plain text