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