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