@@ -46,6 +46,10 @@ type M map[struct{x int}]struct{y int}
4646
4747func unexportedFunc()
4848type unexportedType struct{}
49+
50+ type S struct{t struct{x int}}
51+ type R []struct{y int}
52+ type Q [2]struct{z int}
4953` },
5054 "a" : {"a.go" : `
5155package a
@@ -80,6 +84,9 @@ type T struct{x, y int}
8084 {"b" , "T.M0.RA0" , "var *interface{f()}" , "" }, // parameter
8185 {"b" , "T.M0.RA0.EM0" , "func (interface).f()" , "" }, // interface method
8286 {"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" , "" },
8390 {"a" , "T" , "type a.T struct{x int; y int}" , "" },
8491 {"a" , "T.UF0" , "field x int" , "" },
8592
@@ -99,6 +106,13 @@ type T struct{x, y int}
99106 {"b" , "A.UF0" , "" , "cannot apply 'U' to struct{x int} (got *types.Struct, want named)" },
100107 {"b" , "M.UPO" , "" , "cannot apply 'P' to map[struct{x int}]struct{y int} (got *types.Map, want signature)" },
101108 {"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'" },
102116 }
103117 conf := loader.Config {Build : buildutil .FakeContext (pkgs )}
104118 conf .Import ("a" )
@@ -310,3 +324,65 @@ func objectString(obj types.Object) string {
310324
311325 return s
312326}
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