@@ -453,11 +453,28 @@ func concreteType(e ast.Expr, info *types.Info) (*types.Named, bool) {
453
453
454
454
func GetFieldStubInfo (fset * token.FileSet , info * types.Info , path []ast.Node ) * StructFieldInfo {
455
455
for _ , node := range path {
456
- n , ok := node .(* ast.SelectorExpr )
456
+ s , ok := node .(* ast.SelectorExpr )
457
457
if ! ok {
458
458
continue
459
459
}
460
- tv , ok := info .Types [n .X ]
460
+ // If recvExpr is a package name, compiler error would be
461
+ // e.g., "undefined: http.bar", thus will not hit this code path.
462
+ recvExpr := s .X
463
+ recvType , _ := concreteType (recvExpr , info )
464
+
465
+ if recvType == nil || recvType .Obj ().Pkg () == nil {
466
+ return nil
467
+ }
468
+
469
+ // A method of a function-local type cannot be stubbed
470
+ // since there's nowhere to put the methods.
471
+ recv := recvType .Obj ()
472
+ if recv .Parent () != recv .Pkg ().Scope () {
473
+ return nil
474
+ }
475
+
476
+ obj := types .Object (recv )
477
+ tv , ok := info .Types [s .X ]
461
478
if ! ok {
462
479
break
463
480
}
@@ -474,11 +491,12 @@ func GetFieldStubInfo(fset *token.FileSet, info *types.Info, path []ast.Node) *S
474
491
475
492
return & StructFieldInfo {
476
493
Fset : fset ,
477
- Expr : n ,
494
+ Expr : s ,
478
495
Struct : structType ,
479
496
Named : named ,
480
497
Info : info ,
481
498
Path : path ,
499
+ Object : obj ,
482
500
}
483
501
}
484
502
@@ -493,6 +511,7 @@ type StructFieldInfo struct {
493
511
Named * types.Named
494
512
Info * types.Info
495
513
Path []ast.Node
514
+ Object types.Object
496
515
}
497
516
498
517
// Emit writes to out the missing field based on type info.
0 commit comments