@@ -26,9 +26,10 @@ type CallStubInfo struct {
26
26
Fset * token.FileSet // the FileSet used to type-check the types below
27
27
Receiver typesinternal.NamedOrAlias // the method's receiver type
28
28
MethodName string
29
+ After types.Object // decl after which to insert the new decl
29
30
pointer bool
30
- Info * types.Info
31
- Path []ast.Node // path enclosing the CallExpr
31
+ info * types.Info
32
+ path []ast.Node // path enclosing the CallExpr
32
33
}
33
34
34
35
// GetCallStubInfo extracts necessary information to generate a method definition from
@@ -58,13 +59,29 @@ func GetCallStubInfo(fset *token.FileSet, info *types.Info, path []ast.Node, pos
58
59
if recv .Parent () != recv .Pkg ().Scope () {
59
60
return nil
60
61
}
62
+
63
+ after := types .Object (recv )
64
+ // If the enclosing function declaration is a method declaration,
65
+ // and matches the receiver type of the diagnostic,
66
+ // insert after the enclosing method.
67
+ decl , ok := path [len (path )- 2 ].(* ast.FuncDecl )
68
+ if ok && decl .Recv != nil {
69
+ if len (decl .Recv .List ) != 1 {
70
+ return nil
71
+ }
72
+ mrt := info .TypeOf (decl .Recv .List [0 ].Type )
73
+ if mrt != nil && types .Identical (types .Unalias (typesinternal .Unpointer (mrt )), recv .Type ()) {
74
+ after = info .ObjectOf (decl .Name )
75
+ }
76
+ }
61
77
return & CallStubInfo {
62
78
Fset : fset ,
63
79
Receiver : recvType ,
64
80
MethodName : s .Sel .Name ,
81
+ After : after ,
65
82
pointer : pointer ,
66
- Path : path [i :],
67
- Info : info ,
83
+ path : path [i :],
84
+ info : info ,
68
85
}
69
86
}
70
87
}
@@ -74,7 +91,7 @@ func GetCallStubInfo(fset *token.FileSet, info *types.Info, path []ast.Node, pos
74
91
// Emit writes to out the missing method based on type info of si.Receiver and CallExpr.
75
92
func (si * CallStubInfo ) Emit (out * bytes.Buffer , qual types.Qualifier ) error {
76
93
params := si .collectParams ()
77
- rets := typesFromContext (si .Info , si .Path , si .Path [0 ].Pos ())
94
+ rets := typesFromContext (si .info , si .path , si .path [0 ].Pos ())
78
95
recv := si .Receiver .Obj ()
79
96
// Pointer receiver?
80
97
var star string
@@ -159,9 +176,9 @@ func (si *CallStubInfo) collectParams() []param {
159
176
params = append (params , p )
160
177
}
161
178
162
- args := si .Path [0 ].(* ast.CallExpr ).Args
179
+ args := si .path [0 ].(* ast.CallExpr ).Args
163
180
for _ , arg := range args {
164
- t := si .Info .TypeOf (arg )
181
+ t := si .info .TypeOf (arg )
165
182
switch t := t .(type ) {
166
183
// This is the case where another function call returning multiple
167
184
// results is used as an argument.
0 commit comments