@@ -96,76 +96,11 @@ func insertDeclsAfter(ctx context.Context, snapshot *cache.Snapshot, mp *metadat
96
96
return nil , nil , bug .Errorf ("can't find metadata for file %s among dependencies of %s" , declPGF .URI , mp )
97
97
}
98
98
99
- // Build import environment for the declaring file.
100
- // (typesinternal.FileQualifier works only for complete
101
- // import mappings, and requires types.)
102
- importEnv := make (map [ImportPath ]string ) // value is local name
103
- for _ , imp := range declPGF .File .Imports {
104
- importPath := metadata .UnquoteImportPath (imp )
105
- var name string
106
- if imp .Name != nil {
107
- name = imp .Name .Name
108
- if name == "_" {
109
- continue
110
- } else if name == "." {
111
- name = "" // see types.Qualifier
112
- }
113
- } else {
114
- // Use the correct name from the metadata of the imported
115
- // package---not a guess based on the import path.
116
- mp := snapshot .Metadata (declMeta .DepsByImpPath [importPath ])
117
- if mp == nil {
118
- continue // can't happen?
119
- }
120
- name = string (mp .Name )
121
- }
122
- importEnv [importPath ] = name // latest alias wins
99
+ newImports := make ([]newImport , 0 , len (declPGF .File .Imports ))
100
+ qual := newNamedImportQual (declPGF , snapshot , declMeta , sym , & newImports )
101
+ if len (newImports ) != 0 {
102
+ println ()
123
103
}
124
-
125
- // Create a package name qualifier that uses the
126
- // locally appropriate imported package name.
127
- // It records any needed new imports.
128
- // TODO(adonovan): factor with golang.FormatVarType?
129
- //
130
- // Prior to CL 469155 this logic preserved any renaming
131
- // imports from the file that declares the interface
132
- // method--ostensibly the preferred name for imports of
133
- // frequently renamed packages such as protobufs.
134
- // Now we use the package's declared name. If this turns out
135
- // to be a mistake, then use parseHeader(si.iface.Pos()).
136
- //
137
- type newImport struct { name , importPath string }
138
- var newImports []newImport // for AddNamedImport
139
- qual := func (pkg * types.Package ) string {
140
- // TODO(adonovan): don't ignore vendor prefix.
141
- //
142
- // Ignore the current package import.
143
- if pkg .Path () == sym .Pkg ().Path () {
144
- return ""
145
- }
146
-
147
- importPath := ImportPath (pkg .Path ())
148
- name , ok := importEnv [importPath ]
149
- if ! ok {
150
- // Insert new import using package's declared name.
151
- //
152
- // TODO(adonovan): resolve conflict between declared
153
- // name and existing file-level (declPGF.File.Imports)
154
- // or package-level (sym.Pkg.Scope) decls by
155
- // generating a fresh name.
156
- name = pkg .Name ()
157
- importEnv [importPath ] = name
158
- new := newImport {importPath : string (importPath )}
159
- // For clarity, use a renaming import whenever the
160
- // local name does not match the path's last segment.
161
- if name != pathpkg .Base (trimVersionSuffix (new .importPath )) {
162
- new .name = name
163
- }
164
- newImports = append (newImports , new )
165
- }
166
- return name
167
- }
168
-
169
104
// Compute insertion point for new declarations:
170
105
// after the top-level declaration enclosing the (package-level) type.
171
106
insertOffset , err := safetoken .Offset (declPGF .Tok , declPGF .File .End ())
@@ -252,7 +187,7 @@ func trimVersionSuffix(path string) string {
252
187
return path
253
188
}
254
189
255
- func insertStructField (ctx context.Context , snapshot * cache.Snapshot , meta * metadata.Package , fieldInfo * stubmethods.StructFieldInfo ) (* token.FileSet , * analysis.SuggestedFix , error ) {
190
+ func insertStructField (ctx context.Context , snapshot * cache.Snapshot , mp * metadata.Package , fieldInfo * stubmethods.StructFieldInfo ) (* token.FileSet , * analysis.SuggestedFix , error ) {
256
191
if fieldInfo == nil {
257
192
return nil , nil , fmt .Errorf ("no field info provided" )
258
193
}
@@ -284,6 +219,15 @@ func insertStructField(ctx context.Context, snapshot *cache.Snapshot, meta *meta
284
219
return nil , nil , fmt .Errorf ("could not find struct definition" )
285
220
}
286
221
222
+ // Find metadata for the symbol's declaring package
223
+ // as we'll need its import mapping.
224
+ declMeta := findFileInDeps (snapshot , mp , declPGF .URI )
225
+ if declMeta == nil {
226
+ return nil , nil , bug .Errorf ("can't find metadata for file %s among dependencies of %s" , declPGF .URI , mp )
227
+ }
228
+
229
+ qual := newNamedImportQual (declPGF , snapshot , declMeta , fieldInfo .Named .Obj (), new ([]newImport ))
230
+
287
231
// find the position to insert the new field (end of struct fields)
288
232
insertPos := structType .Fields .Closing - 1
289
233
if insertPos == structType .Fields .Opening {
@@ -292,7 +236,7 @@ func insertStructField(ctx context.Context, snapshot *cache.Snapshot, meta *meta
292
236
}
293
237
294
238
var buf bytes.Buffer
295
- if err := fieldInfo .Emit (& buf , types . RelativeTo ( fieldInfo . Named . Obj (). Pkg ()) ); err != nil {
239
+ if err := fieldInfo .Emit (& buf , qual ); err != nil {
296
240
return nil , nil , err
297
241
}
298
242
@@ -312,3 +256,78 @@ func insertStructField(ctx context.Context, snapshot *cache.Snapshot, meta *meta
312
256
TextEdits : []analysis.TextEdit {textEdit },
313
257
}, nil
314
258
}
259
+
260
+ type newImport struct {
261
+ name string
262
+ importPath string
263
+ }
264
+
265
+ func newNamedImportQual (declPGF * parsego.File , snapshot * cache.Snapshot , declMeta * metadata.Package , sym types.Object , newImports * []newImport ) func (* types.Package ) string {
266
+ // Build import environment for the declaring file.
267
+ // (typesinternal.FileQualifier works only for complete
268
+ // import mappings, and requires types.)
269
+ importEnv := make (map [ImportPath ]string ) // value is local name
270
+ for _ , imp := range declPGF .File .Imports {
271
+ importPath := metadata .UnquoteImportPath (imp )
272
+ var name string
273
+ if imp .Name != nil {
274
+ name = imp .Name .Name
275
+ if name == "_" {
276
+ continue
277
+ } else if name == "." {
278
+ name = "" // see types.Qualifier
279
+ }
280
+ } else {
281
+ // Use the correct name from the metadata of the imported
282
+ // package---not a guess based on the import path.
283
+ mp := snapshot .Metadata (declMeta .DepsByImpPath [importPath ])
284
+ if mp == nil {
285
+ continue // can't happen?
286
+ }
287
+ name = string (mp .Name )
288
+ }
289
+ importEnv [importPath ] = name // latest alias wins
290
+ }
291
+
292
+ // Create a package name qualifier that uses the
293
+ // locally appropriate imported package name.
294
+ // It records any needed new imports.
295
+ // TODO(adonovan): factor with golang.FormatVarType?
296
+ //
297
+ // Prior to CL 469155 this logic preserved any renaming
298
+ // imports from the file that declares the interface
299
+ // method--ostensibly the preferred name for imports of
300
+ // frequently renamed packages such as protobufs.
301
+ // Now we use the package's declared name. If this turns out
302
+ // to be a mistake, then use parseHeader(si.iface.Pos()).
303
+ //
304
+ return func (pkg * types.Package ) string {
305
+ // TODO(adonovan): don't ignore vendor prefix.
306
+ //
307
+ // Ignore the current package import.
308
+ if pkg .Path () == sym .Pkg ().Path () {
309
+ return ""
310
+ }
311
+
312
+ importPath := ImportPath (pkg .Path ())
313
+ name , ok := importEnv [importPath ]
314
+ if ! ok {
315
+ // Insert new import using package's declared name.
316
+ //
317
+ // TODO(adonovan): resolve conflict between declared
318
+ // name and existing file-level (declPGF.File.Imports)
319
+ // or package-level (sym.Pkg.Scope) decls by
320
+ // generating a fresh name.
321
+ name = pkg .Name ()
322
+ importEnv [importPath ] = name
323
+ new := newImport {importPath : string (importPath )}
324
+ // For clarity, use a renaming import whenever the
325
+ // local name does not match the path's last segment.
326
+ if name != pathpkg .Base (trimVersionSuffix (new .importPath )) {
327
+ new .name = name
328
+ }
329
+ * newImports = append (* newImports , new )
330
+ }
331
+ return name
332
+ }
333
+ }
0 commit comments