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