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 if objPkg.Scope().Lookup(objName) == nil {
484 dict := pr.objDictIdx(idx)
485
486 r := pr.newReader(pkgbits.SectionObj, idx, pkgbits.SyncObject1)
487 r.dict = dict
488
489 declare := func(obj types.Object) {
490 objPkg.Scope().Insert(obj)
491 }
492
493 switch tag {
494 default:
495 panic("weird")
496
497 case pkgbits.ObjAlias:
498 pos := r.pos()
499 var tparams []*types.TypeParam
500 if r.Version().Has(pkgbits.AliasTypeParamNames) {
501 tparams = r.typeParamNames(false)
502 }
503 typ := r.typ()
504 declare(newAliasTypeName(pos, objPkg, objName, typ, tparams))
505
506 case pkgbits.ObjConst:
507 pos := r.pos()
508 typ := r.typ()
509 val := r.Value()
510 declare(types.NewConst(pos, objPkg, objName, typ, val))
511
512 case pkgbits.ObjFunc:
513 pos := r.pos()
514 var rtparams []*types.TypeParam
515 var recv *types.Var
516 if r.Version().Has(pkgbits.GenericMethods) && r.Bool() {
517 r.selector()
518 rtparams = r.typeParamNames(true)
519 recv = r.param(types.RecvVar)
520 }
521 tparams := r.typeParamNames(false)
522 sig := r.signature(recv, rtparams, tparams)
523 declare(types.NewFunc(pos, objPkg, objName, sig))
524
525 case pkgbits.ObjType:
526 pos := r.pos()
527
528 obj := types.NewTypeName(pos, objPkg, objName, nil)
529 named := types.NewNamed(obj, nil, nil)
530 declare(obj)
531
532 named.SetTypeParams(r.typeParamNames(false))
533
534 underlying := r.typ().Underlying()
535
536
537
538
539 if iface, ok := underlying.(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
540 methods := make([]*types.Func, iface.NumExplicitMethods())
541 for i := range methods {
542 fn := iface.ExplicitMethod(i)
543 sig := fn.Signature()
544
545 recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named)
546 recv.SetKind(types.RecvVar)
547 methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic()))
548 }
549
550 embeds := make([]types.Type, iface.NumEmbeddeds())
551 for i := range embeds {
552 embeds[i] = iface.EmbeddedType(i)
553 }
554
555 newIface := types.NewInterfaceType(methods, embeds)
556 r.p.ifaces = append(r.p.ifaces, newIface)
557 underlying = newIface
558 }
559
560 named.SetUnderlying(underlying)
561
562 for i, n := 0, r.Len(); i < n; i++ {
563 named.AddMethod(r.method())
564 }
565
566 case pkgbits.ObjVar:
567 pos := r.pos()
568 typ := r.typ()
569 declare(types.NewVar(pos, objPkg, objName, typ))
570 }
571 }
572
573 return objPkg, objName
574 }
575
576 func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
577
578 var dict readerDict
579
580 {
581 r := pr.tempReader(pkgbits.SectionObjDict, idx, pkgbits.SyncObject1)
582 if implicits := r.Len(); implicits != 0 {
583 errorf("unexpected object with %v implicit type parameter(s)", implicits)
584 }
585
586 nreceivers := 0
587 if r.Version().Has(pkgbits.GenericMethods) && r.Bool() {
588 nreceivers = r.Len()
589 }
590 nexplicits := r.Len()
591
592 dict.rtbounds = make([]typeInfo, nreceivers)
593 for i := range dict.rtbounds {
594 dict.rtbounds[i] = r.typInfo()
595 }
596
597 dict.tbounds = make([]typeInfo, nexplicits)
598 for i := range dict.tbounds {
599 dict.tbounds[i] = r.typInfo()
600 }
601
602 dict.derived = make([]derivedInfo, r.Len())
603 dict.derivedTypes = make([]types.Type, len(dict.derived))
604 for i := range dict.derived {
605 dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.SectionType)}
606 if r.Version().Has(pkgbits.DerivedInfoNeeded) {
607 assert(!r.Bool())
608 }
609 }
610
611 pr.retireReader(r)
612 }
613
614
615 return &dict
616 }
617
618 func (r *reader) typeParamNames(isGenMeth bool) []*types.TypeParam {
619 r.Sync(pkgbits.SyncTypeParamNames)
620
621
622
623
624
625 var in []typeInfo
626 var out *[]*types.TypeParam
627 if isGenMeth {
628 in = r.dict.rtbounds
629 out = &r.dict.rtparams
630 } else {
631 in = r.dict.tbounds
632 out = &r.dict.tparams
633 }
634
635 if len(in) == 0 {
636 return nil
637 }
638
639
640
641
642
643
644
645
646 tparams := make([]*types.TypeParam, len(in))
647 *out = tparams
648
649 for i := range in {
650 pos := r.pos()
651 pkg, name := r.localIdent()
652
653 tname := types.NewTypeName(pos, pkg, name, nil)
654 tparams[i] = types.NewTypeParam(tname, nil)
655 }
656
657
658
659 types := make([]types.Type, len(in))
660 for i, info := range in {
661 types[i] = r.p.typIdx(info, r.dict)
662 }
663
664
665 r.p.later(func() {
666 for i, typ := range types {
667 tparams[i].SetConstraint(typ)
668 }
669 })
670
671 return tparams
672 }
673
674 func (r *reader) method() *types.Func {
675 r.Sync(pkgbits.SyncMethod)
676 pos := r.pos()
677 pkg, name := r.selector()
678
679 rparams := r.typeParamNames(false)
680 sig := r.signature(r.param(types.RecvVar), rparams, nil)
681
682 _ = r.pos()
683 return types.NewFunc(pos, pkg, name, sig)
684 }
685
686 func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) }
687 func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) }
688 func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) }
689
690 func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) {
691 r.Sync(marker)
692 return r.pkg(), r.String()
693 }
694
695
696
697
698
699 func pkgScope(pkg *types.Package) *types.Scope {
700 if pkg != nil {
701 return pkg.Scope()
702 }
703 return types.Universe
704 }
705
706
707 func newAliasTypeName(pos token.Pos, pkg *types.Package, name string, rhs types.Type, tparams []*types.TypeParam) *types.TypeName {
708 tname := types.NewTypeName(pos, pkg, name, nil)
709 a := types.NewAlias(tname, rhs)
710 a.SetTypeParams(tparams)
711 return tname
712 }
713
View as plain text