Skip to content

Commit 66a7097

Browse files
committed
go/importer: fix field/method package for binary importer
This is the equivalent of https://golang.org/cl/18549 for the binary importer (which is usually not used because by default the gc compiler produces the traditional textual export format). For #13898. Change-Id: Idb6b515f2ee49e6d0362c71846994b0bd4dae8f7 Reviewed-on: https://go-review.googlesource.com/18598 Reviewed-by: Alan Donovan <[email protected]> Run-TryBot: Robert Griesemer <[email protected]>
1 parent 7ec5508 commit 66a7097

File tree

1 file changed

+38
-29
lines changed

1 file changed

+38
-29
lines changed

src/go/internal/gcimporter/bimport.go

+38-29
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,22 @@ func BImportData(imports map[string]*types.Package, data []byte, path string) (i
7272
// read consts
7373
for i := p.int(); i > 0; i-- {
7474
name := p.string()
75-
typ := p.typ()
75+
typ := p.typ(nil)
7676
val := p.value()
7777
p.declare(types.NewConst(token.NoPos, pkg, name, typ, val))
7878
}
7979

8080
// read vars
8181
for i := p.int(); i > 0; i-- {
8282
name := p.string()
83-
typ := p.typ()
83+
typ := p.typ(nil)
8484
p.declare(types.NewVar(token.NoPos, pkg, name, typ))
8585
}
8686

8787
// read funcs
8888
for i := p.int(); i > 0; i-- {
8989
name := p.string()
90-
sig := p.typ().(*types.Signature)
90+
sig := p.typ(nil).(*types.Signature)
9191
p.int() // read and discard index of inlined function body
9292
p.declare(types.NewFunc(token.NoPos, pkg, name, sig))
9393
}
@@ -97,7 +97,7 @@ func BImportData(imports map[string]*types.Package, data []byte, path string) (i
9797
// name is parsed as part of named type and the
9898
// type object is added to scope via respective
9999
// named type
100-
_ = p.typ().(*types.Named)
100+
_ = p.typ(nil).(*types.Named)
101101
}
102102

103103
// ignore compiler-specific import data
@@ -190,7 +190,11 @@ type dddSlice struct {
190190
func (t *dddSlice) Underlying() types.Type { return t }
191191
func (t *dddSlice) String() string { return "..." + t.elem.String() }
192192

193-
func (p *importer) typ() types.Type {
193+
// parent is the package which declared the type; parent == nil means
194+
// the package currently imported. The parent package is needed for
195+
// exported struct fields and interface methods which don't contain
196+
// explicit package information in the export data.
197+
func (p *importer) typ(parent *types.Package) types.Type {
194198
// if the type was seen before, i is its index (>= 0)
195199
i := p.tagOrIndex()
196200
if i >= 0 {
@@ -202,18 +206,18 @@ func (p *importer) typ() types.Type {
202206
case namedTag:
203207
// read type object
204208
name := p.string()
205-
tpkg := p.pkg()
206-
scope := tpkg.Scope()
209+
parent = p.pkg()
210+
scope := parent.Scope()
207211
obj := scope.Lookup(name)
208212

209213
// if the object doesn't exist yet, create and insert it
210214
if obj == nil {
211-
obj = types.NewTypeName(token.NoPos, tpkg, name, nil)
215+
obj = types.NewTypeName(token.NoPos, parent, name, nil)
212216
scope.Insert(obj)
213217
}
214218

215219
if _, ok := obj.(*types.TypeName); !ok {
216-
panic(fmt.Sprintf("pkg = %s, name = %s => %s", tpkg, name, obj))
220+
panic(fmt.Sprintf("pkg = %s, name = %s => %s", parent, name, obj))
217221
}
218222

219223
// associate new named type with obj if it doesn't exist yet
@@ -224,7 +228,7 @@ func (p *importer) typ() types.Type {
224228
p.record(t)
225229

226230
// read underlying type
227-
t0.SetUnderlying(p.typ())
231+
t0.SetUnderlying(p.typ(parent))
228232

229233
// interfaces don't have associated methods
230234
if _, ok := t0.Underlying().(*types.Interface); ok {
@@ -239,7 +243,7 @@ func (p *importer) typ() types.Type {
239243
result, _ := p.paramList()
240244
p.int() // read and discard index of inlined function body
241245
sig := types.NewSignature(recv.At(0), params, result, isddd)
242-
t0.AddMethod(types.NewFunc(token.NoPos, tpkg, name, sig))
246+
t0.AddMethod(types.NewFunc(token.NoPos, parent, name, sig))
243247
}
244248

245249
return t
@@ -249,21 +253,21 @@ func (p *importer) typ() types.Type {
249253
p.record(t)
250254

251255
n := p.int64()
252-
*t = *types.NewArray(p.typ(), n)
256+
*t = *types.NewArray(p.typ(parent), n)
253257
return t
254258

255259
case sliceTag:
256260
t := new(types.Slice)
257261
p.record(t)
258262

259-
*t = *types.NewSlice(p.typ())
263+
*t = *types.NewSlice(p.typ(parent))
260264
return t
261265

262266
case dddTag:
263267
t := new(dddSlice)
264268
p.record(t)
265269

266-
t.elem = p.typ()
270+
t.elem = p.typ(parent)
267271
return t
268272

269273
case structTag:
@@ -274,7 +278,7 @@ func (p *importer) typ() types.Type {
274278
fields := make([]*types.Var, n)
275279
tags := make([]string, n)
276280
for i := range fields {
277-
fields[i] = p.field()
281+
fields[i] = p.field(parent)
278282
tags[i] = p.string()
279283
}
280284
*t = *types.NewStruct(fields, tags)
@@ -284,7 +288,7 @@ func (p *importer) typ() types.Type {
284288
t := new(types.Pointer)
285289
p.record(t)
286290

287-
*t = *types.NewPointer(p.typ())
291+
*t = *types.NewPointer(p.typ(parent))
288292
return t
289293

290294
case signatureTag:
@@ -312,7 +316,7 @@ func (p *importer) typ() types.Type {
312316
// read methods
313317
methods := make([]*types.Func, p.int())
314318
for i := range methods {
315-
pkg, name := p.fieldName()
319+
pkg, name := p.fieldName(parent)
316320
params, isddd := p.paramList()
317321
result, _ := p.paramList()
318322
sig := types.NewSignature(nil, params, result, isddd)
@@ -327,8 +331,8 @@ func (p *importer) typ() types.Type {
327331
t := new(types.Map)
328332
p.record(t)
329333

330-
key := p.typ()
331-
val := p.typ()
334+
key := p.typ(parent)
335+
val := p.typ(parent)
332336
*t = *types.NewMap(key, val)
333337
return t
334338

@@ -348,7 +352,7 @@ func (p *importer) typ() types.Type {
348352
default:
349353
panic(fmt.Sprintf("unexpected channel dir %d", d))
350354
}
351-
val := p.typ()
355+
val := p.typ(parent)
352356
*t = *types.NewChan(dir, val)
353357
return t
354358

@@ -357,18 +361,18 @@ func (p *importer) typ() types.Type {
357361
}
358362
}
359363

360-
func (p *importer) field() *types.Var {
361-
pkg, name := p.fieldName()
362-
typ := p.typ()
364+
func (p *importer) field(parent *types.Package) *types.Var {
365+
pkg, name := p.fieldName(parent)
366+
typ := p.typ(parent)
363367

364368
anonymous := false
365369
if name == "" {
366370
// anonymous field - typ must be T or *T and T must be a type name
367371
switch typ := deref(typ).(type) {
368372
case *types.Basic: // basic types are named types
373+
pkg = nil // // objects defined in Universe scope have no package
369374
name = typ.Name()
370375
case *types.Named:
371-
pkg = p.pkgList[0]
372376
name = typ.Obj().Name()
373377
default:
374378
panic("anonymous field expected")
@@ -379,15 +383,20 @@ func (p *importer) field() *types.Var {
379383
return types.NewField(token.NoPos, pkg, name, typ, anonymous)
380384
}
381385

382-
func (p *importer) fieldName() (*types.Package, string) {
386+
func (p *importer) fieldName(parent *types.Package) (*types.Package, string) {
387+
pkg := parent
388+
if pkg == nil {
389+
// use the imported package instead
390+
pkg = p.pkgList[0]
391+
}
383392
name := p.string()
384393
if name == "" {
385-
return nil, "" // anonymous field
394+
return pkg, "" // anonymous
386395
}
387-
pkg := p.pkgList[0]
388396
if name == "?" || name != "_" && !exported(name) {
397+
// explicitly qualified field
389398
if name == "?" {
390-
name = ""
399+
name = "" // anonymous
391400
}
392401
pkg = p.pkg()
393402
}
@@ -415,7 +424,7 @@ func (p *importer) paramList() (*types.Tuple, bool) {
415424
}
416425

417426
func (p *importer) param(named bool) (*types.Var, bool) {
418-
t := p.typ()
427+
t := p.typ(nil)
419428
td, isddd := t.(*dddSlice)
420429
if isddd {
421430
t = types.NewSlice(td.elem)

0 commit comments

Comments
 (0)