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