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