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