@@ -46,6 +46,10 @@ type M map[struct{x int}]struct{y int}
46
46
47
47
func unexportedFunc()
48
48
type unexportedType struct{}
49
+
50
+ type S struct{t struct{x int}}
51
+ type R []struct{y int}
52
+ type Q [2]struct{z int}
49
53
` },
50
54
"a" : {"a.go" : `
51
55
package a
@@ -80,6 +84,9 @@ type T struct{x, y int}
80
84
{"b" , "T.M0.RA0" , "var *interface{f()}" , "" }, // parameter
81
85
{"b" , "T.M0.RA0.EM0" , "func (interface).f()" , "" }, // interface method
82
86
{"b" , "unexportedType" , "type b.unexportedType struct{}" , "" },
87
+ {"b" , "S.UF0.F0" , "field x int" , "" },
88
+ {"b" , "R.UEF0" , "field y int" , "" },
89
+ {"b" , "Q.UEF0" , "field z int" , "" },
83
90
{"a" , "T" , "type a.T struct{x int; y int}" , "" },
84
91
{"a" , "T.UF0" , "field x int" , "" },
85
92
@@ -99,6 +106,13 @@ type T struct{x, y int}
99
106
{"b" , "A.UF0" , "" , "cannot apply 'U' to struct{x int} (got *types.Struct, want named)" },
100
107
{"b" , "M.UPO" , "" , "cannot apply 'P' to map[struct{x int}]struct{y int} (got *types.Map, want signature)" },
101
108
{"b" , "C.O" , "" , "path denotes type a.Int int, which belongs to a different package" },
109
+ {"b" , "T.M9" , "" , "method index 9 out of range [0-1)" },
110
+ {"b" , "M.UF0" , "" , "cannot apply 'F' to map[struct{x int}]struct{y int} (got *types.Map, want struct)" },
111
+ {"b" , "V.KO" , "" , "cannot apply 'K' to []*a.T (got *types.Slice, want map)" },
112
+ {"b" , "V.A4" , "" , "cannot apply 'A' to []*a.T (got *types.Slice, want tuple)" },
113
+ {"b" , "V.RA0" , "" , "cannot apply 'R' to []*a.T (got *types.Slice, want signature)" },
114
+ {"b" , "F.PA4" , "" , "tuple index 4 out of range [0-4)" },
115
+ {"b" , "F.XO" , "" , "invalid path: unknown code 'X'" },
102
116
}
103
117
conf := loader.Config {Build : buildutil .FakeContext (pkgs )}
104
118
conf .Import ("a" )
@@ -310,3 +324,65 @@ func objectString(obj types.Object) string {
310
324
311
325
return s
312
326
}
327
+
328
+ // TestOrdering uses objectpath over two Named types with the same method
329
+ // names but in a different source order and checks that objectpath is the
330
+ // same for methods with the same name.
331
+ func TestOrdering (t * testing.T ) {
332
+ pkgs := map [string ]map [string ]string {
333
+ "p" : {"p.go" : `
334
+ package p
335
+
336
+ type T struct{ A int }
337
+
338
+ func (T) M() { }
339
+ func (T) N() { }
340
+ func (T) X() { }
341
+ func (T) Y() { }
342
+ ` },
343
+ "q" : {"q.go" : `
344
+ package q
345
+
346
+ type T struct{ A int }
347
+
348
+ func (T) N() { }
349
+ func (T) M() { }
350
+ func (T) Y() { }
351
+ func (T) X() { }
352
+ ` }}
353
+ conf := loader.Config {Build : buildutil .FakeContext (pkgs )}
354
+ conf .Import ("p" )
355
+ conf .Import ("q" )
356
+ prog , err := conf .Load ()
357
+ if err != nil {
358
+ t .Fatal (err )
359
+ }
360
+ p := prog .Imported ["p" ].Pkg
361
+ q := prog .Imported ["q" ].Pkg
362
+
363
+ // From here, the objectpaths generated for p and q should be the
364
+ // same. If they are not, then we are generating an ordering that is
365
+ // dependent on the declaration of the types within the file.
366
+ for _ , test := range []struct {
367
+ path objectpath.Path
368
+ }{
369
+ {"T.M0" },
370
+ {"T.M1" },
371
+ {"T.M2" },
372
+ {"T.M3" },
373
+ } {
374
+ pobj , err := objectpath .Object (p , test .path )
375
+ if err != nil {
376
+ t .Errorf ("Object(%s) failed in a1: %v" , test .path , err )
377
+ continue
378
+ }
379
+ qobj , err := objectpath .Object (q , test .path )
380
+ if err != nil {
381
+ t .Errorf ("Object(%s) failed in a2: %v" , test .path , err )
382
+ continue
383
+ }
384
+ if pobj .Name () != pobj .Name () {
385
+ t .Errorf ("Objects(%s) not equal, got a1 = %v, a2 = %v" , test .path , pobj .Name (), qobj .Name ())
386
+ }
387
+ }
388
+ }
0 commit comments