@@ -234,51 +234,87 @@ func (p goTypes) cvtFunc(sig *types.Signature, recv *types.Var) (raw *types.Sign
234234
235235func (p goTypes ) cvtTuple (t * types.Tuple ) (* types.Tuple , bool ) {
236236 n := t .Len ()
237- vars := make ([]* types.Var , n )
238- needcvt := false
237+ var vars []* types.Var
239238 for i := 0 ; i < n ; i ++ {
240239 v := t .At (i )
241- if t , cvt := p .cvtType (v .Type ()); cvt {
242- v = types .NewParam (v .Pos (), v .Pkg (), v .Name (), t )
243- needcvt = true
240+ if raw , cvt := p .cvtType (v .Type ()); cvt {
241+ if vars == nil {
242+ vars = make ([]* types.Var , n )
243+ for j := 0 ; j < i ; j ++ {
244+ vars [j ] = t .At (j )
245+ }
246+ }
247+ v = types .NewParam (v .Pos (), v .Pkg (), v .Name (), raw )
248+ }
249+ if vars != nil {
250+ vars [i ] = v
244251 }
245- vars [i ] = v
246252 }
247- if needcvt {
253+ if vars != nil {
248254 return types .NewTuple (vars ... ), true
249255 }
250256 return t , false
251257}
252258
253- func ( p goTypes ) cvtExplicitMethods ( typ * types.Interface ) ( []* types.Func , bool ) {
259+ func explicitMethods ( typ * types.Interface ) []* types.Func {
254260 n := typ .NumExplicitMethods ()
255261 methods := make ([]* types.Func , n )
256- needcvt := false
262+ for i := 0 ; i < n ; i ++ {
263+ methods [i ] = typ .ExplicitMethod (i )
264+ }
265+ return methods
266+ }
267+
268+ func embeddedTypes (typ * types.Interface ) []types.Type {
269+ n := typ .NumEmbeddeds ()
270+ embeddeds := make ([]types.Type , n )
271+ for i := 0 ; i < n ; i ++ {
272+ embeddeds [i ] = typ .EmbeddedType (i )
273+ }
274+ return embeddeds
275+ }
276+
277+ func (p goTypes ) cvtExplicitMethods (typ * types.Interface ) ([]* types.Func , bool ) {
278+ n := typ .NumExplicitMethods ()
279+ var methods []* types.Func
257280 for i := 0 ; i < n ; i ++ {
258281 m := typ .ExplicitMethod (i )
259282 sig := m .Type ().(* types.Signature )
260283 if raw := p .cvtFunc (sig , nil ); sig != raw {
284+ if methods == nil {
285+ methods = make ([]* types.Func , n )
286+ for j := 0 ; j < i ; j ++ {
287+ methods [j ] = typ .ExplicitMethod (j )
288+ }
289+ }
261290 m = types .NewFunc (m .Pos (), m .Pkg (), m .Name (), raw )
262- needcvt = true
263291 }
264- methods [i ] = m
292+ if methods != nil {
293+ methods [i ] = m
294+ }
265295 }
266- return methods , needcvt
296+ return methods , methods != nil
267297}
268298
269299func (p goTypes ) cvtEmbeddedTypes (typ * types.Interface ) ([]types.Type , bool ) {
270300 n := typ .NumEmbeddeds ()
271- embeddeds := make ([]types.Type , n )
272- needcvt := false
301+ var embeddeds []types.Type
273302 for i := 0 ; i < n ; i ++ {
274303 t := typ .EmbeddedType (i )
275304 if raw , cvt := p .cvtType (t ); cvt {
305+ if embeddeds == nil {
306+ embeddeds = make ([]types.Type , n )
307+ for j := 0 ; j < i ; j ++ {
308+ embeddeds [j ] = typ .EmbeddedType (j )
309+ }
310+ }
276311 t = raw
277- needcvt = true
278312 }
279- embeddeds [i ] = t
313+ if embeddeds != nil {
314+ embeddeds [i ] = t
315+ }
280316 }
281- return embeddeds , needcvt
317+ return embeddeds , embeddeds != nil
282318}
283319
284320func (p goTypes ) cvtInterface (typ * types.Interface ) (raw * types.Interface , cvt bool ) {
@@ -293,6 +329,12 @@ func (p goTypes) cvtInterface(typ *types.Interface) (raw *types.Interface, cvt b
293329 methods , cvt1 := p .cvtExplicitMethods (typ )
294330 embeddeds , cvt2 := p .cvtEmbeddedTypes (typ )
295331 if cvt1 || cvt2 {
332+ if ! cvt1 {
333+ methods = explicitMethods (typ )
334+ }
335+ if ! cvt2 {
336+ embeddeds = embeddedTypes (typ )
337+ }
296338 return types .NewInterfaceType (methods , embeddeds ), true
297339 }
298340 return typ , false
@@ -308,17 +350,23 @@ func (p goTypes) cvtStruct(typ *types.Struct) (raw *types.Struct, cvt bool) {
308350 p .typs [unsafe .Pointer (typ )] = unsafe .Pointer (raw )
309351 }()
310352 n := typ .NumFields ()
311- flds := make ([]* types.Var , n )
312- needcvt := false
353+ var flds []* types.Var
313354 for i := 0 ; i < n ; i ++ {
314355 f := typ .Field (i )
315- if t , cvt := p .cvtType (f .Type ()); cvt {
316- f = types .NewField (f .Pos (), f .Pkg (), f .Name (), t , f .Anonymous ())
317- needcvt = true
356+ if raw , cvt := p .cvtType (f .Type ()); cvt {
357+ if flds == nil {
358+ flds = make ([]* types.Var , n )
359+ for j := 0 ; j < i ; j ++ {
360+ flds [j ] = typ .Field (j )
361+ }
362+ }
363+ f = types .NewField (f .Pos (), f .Pkg (), f .Name (), raw , f .Anonymous ())
364+ }
365+ if flds != nil {
366+ flds [i ] = f
318367 }
319- flds [i ] = f
320368 }
321- if needcvt {
369+ if flds != nil {
322370 return types .NewStruct (flds , nil ), true
323371 }
324372 return typ , false
0 commit comments