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