@@ -453,11 +453,28 @@ func concreteType(e ast.Expr, info *types.Info) (*types.Named, bool) {
453453
454454func GetFieldStubInfo (fset * token.FileSet , info * types.Info , path []ast.Node ) * StructFieldInfo {
455455 for _ , node := range path {
456- n , ok := node .(* ast.SelectorExpr )
456+ s , ok := node .(* ast.SelectorExpr )
457457 if ! ok {
458458 continue
459459 }
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 ]
461478 if ! ok {
462479 break
463480 }
@@ -474,11 +491,12 @@ func GetFieldStubInfo(fset *token.FileSet, info *types.Info, path []ast.Node) *S
474491
475492 return & StructFieldInfo {
476493 Fset : fset ,
477- Expr : n ,
494+ Expr : s ,
478495 Struct : structType ,
479496 Named : named ,
480497 Info : info ,
481498 Path : path ,
499+ Object : obj ,
482500 }
483501 }
484502
@@ -493,6 +511,7 @@ type StructFieldInfo struct {
493511 Named * types.Named
494512 Info * types.Info
495513 Path []ast.Node
514+ Object types.Object
496515}
497516
498517// Emit writes to out the missing field based on type info.
0 commit comments