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