Skip to content

Commit 77b690b

Browse files
authored
Derive the default transformer name from the function pointer (#113)
If the name is unspecified, try to derive the name from the function pointer. Deriving the name from the function pointer is not always reliable since it relies on runtime properties that are not specified to be stable.
1 parent 1bdd152 commit 77b690b

File tree

3 files changed

+23
-21
lines changed

3 files changed

+23
-21
lines changed

cmp/cmpopts/sort.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func SortSlices(less interface{}) cmp.Option {
3232
panic(fmt.Sprintf("invalid less function: %T", less))
3333
}
3434
ss := sliceSorter{vf.Type().In(0), vf}
35-
return cmp.FilterValues(ss.filter, cmp.Transformer("Sort", ss.sort))
35+
return cmp.FilterValues(ss.filter, cmp.Transformer("cmpopts.SortSlices", ss.sort))
3636
}
3737

3838
type sliceSorter struct {
@@ -103,7 +103,7 @@ func SortMaps(less interface{}) cmp.Option {
103103
panic(fmt.Sprintf("invalid less function: %T", less))
104104
}
105105
ms := mapSorter{vf.Type().In(0), vf}
106-
return cmp.FilterValues(ms.filter, cmp.Transformer("Sort", ms.sort))
106+
return cmp.FilterValues(ms.filter, cmp.Transformer("cmpopts.SortMaps", ms.sort))
107107
}
108108

109109
type mapSorter struct {

cmp/compare_test.go

+16-16
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,15 @@ func comparerTests() []test {
143143
label: label,
144144
x: 1,
145145
y: 1,
146-
opts: []cmp.Option{cmp.Transformer("", func(x interface{}) interface{} { return x })},
146+
opts: []cmp.Option{cmp.Transformer("λ", func(x interface{}) interface{} { return x })},
147147
wantPanic: "cannot use an unfiltered option",
148148
}, {
149149
label: label,
150150
x: 1,
151151
y: 1,
152152
opts: []cmp.Option{
153153
cmp.Comparer(func(x, y int) bool { return true }),
154-
cmp.Transformer("", func(x int) float64 { return float64(x) }),
154+
cmp.Transformer("λ", func(x int) float64 { return float64(x) }),
155155
},
156156
wantPanic: "ambiguous set of applicable options",
157157
}, {
@@ -163,7 +163,7 @@ func comparerTests() []test {
163163
return len(p) > 0 && p[len(p)-1].Type().Kind() == reflect.Int
164164
}, cmp.Options{cmp.Ignore(), cmp.Ignore(), cmp.Ignore()}),
165165
cmp.Comparer(func(x, y int) bool { return true }),
166-
cmp.Transformer("", func(x int) float64 { return float64(x) }),
166+
cmp.Transformer("λ", func(x int) float64 { return float64(x) }),
167167
},
168168
}, {
169169
label: label,
@@ -393,7 +393,7 @@ root:
393393
x: make([]string, 1000),
394394
y: make([]string, 1000),
395395
opts: []cmp.Option{
396-
cmp.Transformer("", func(x string) int {
396+
cmp.Transformer("λ", func(x string) int {
397397
return rand.Int()
398398
}),
399399
},
@@ -405,7 +405,7 @@ root:
405405
x: make([]int, 10),
406406
y: make([]int, 10),
407407
opts: []cmp.Option{
408-
cmp.Transformer("", func(x int) float64 {
408+
cmp.Transformer("λ", func(x int) float64 {
409409
return math.NaN()
410410
}),
411411
},
@@ -441,7 +441,7 @@ root:
441441
x: struct{ I Iface2 }{},
442442
y: struct{ I Iface2 }{},
443443
opts: []cmp.Option{
444-
cmp.Transformer("", func(v Iface1) bool {
444+
cmp.Transformer("λ", func(v Iface1) bool {
445445
return v == nil
446446
}),
447447
},
@@ -497,9 +497,9 @@ func transformerTests() []test {
497497
x: uint8(0),
498498
y: uint8(1),
499499
opts: []cmp.Option{
500-
cmp.Transformer("", func(in uint8) uint16 { return uint16(in) }),
501-
cmp.Transformer("", func(in uint16) uint32 { return uint32(in) }),
502-
cmp.Transformer("", func(in uint32) uint64 { return uint64(in) }),
500+
cmp.Transformer("λ", func(in uint8) uint16 { return uint16(in) }),
501+
cmp.Transformer("λ", func(in uint16) uint32 { return uint32(in) }),
502+
cmp.Transformer("λ", func(in uint32) uint64 { return uint64(in) }),
503503
},
504504
wantDiff: `
505505
λ(λ(λ({uint8}))):
@@ -510,8 +510,8 @@ func transformerTests() []test {
510510
x: 0,
511511
y: 1,
512512
opts: []cmp.Option{
513-
cmp.Transformer("", func(in int) int { return in / 2 }),
514-
cmp.Transformer("", func(in int) int { return in }),
513+
cmp.Transformer("λ", func(in int) int { return in / 2 }),
514+
cmp.Transformer("λ", func(in int) int { return in }),
515515
},
516516
wantPanic: "ambiguous set of applicable options",
517517
}, {
@@ -521,11 +521,11 @@ func transformerTests() []test {
521521
opts: []cmp.Option{
522522
cmp.FilterValues(
523523
func(x, y int) bool { return x+y >= 0 },
524-
cmp.Transformer("", func(in int) int64 { return int64(in / 2) }),
524+
cmp.Transformer("λ", func(in int) int64 { return int64(in / 2) }),
525525
),
526526
cmp.FilterValues(
527527
func(x, y int) bool { return x+y < 0 },
528-
cmp.Transformer("", func(in int) int64 { return int64(in) }),
528+
cmp.Transformer("λ", func(in int) int64 { return int64(in) }),
529529
),
530530
},
531531
wantDiff: `
@@ -540,7 +540,7 @@ func transformerTests() []test {
540540
x: 0,
541541
y: 1,
542542
opts: []cmp.Option{
543-
cmp.Transformer("", func(in int) interface{} {
543+
cmp.Transformer("λ", func(in int) interface{} {
544544
if in == 0 {
545545
return "string"
546546
}
@@ -1816,7 +1816,7 @@ func project3Tests() []test {
18161816

18171817
ignoreLocker := cmpopts.IgnoreInterfaces(struct{ sync.Locker }{})
18181818

1819-
transformProtos := cmp.Transformer("", func(x pb.Dirt) *pb.Dirt {
1819+
transformProtos := cmp.Transformer("λ", func(x pb.Dirt) *pb.Dirt {
18201820
return &x
18211821
})
18221822

@@ -1903,7 +1903,7 @@ func project4Tests() []test {
19031903
ts.Poison{},
19041904
)
19051905

1906-
transformProtos := cmp.Transformer("", func(x pb.Restrictions) *pb.Restrictions {
1906+
transformProtos := cmp.Transformer("λ", func(x pb.Restrictions) *pb.Restrictions {
19071907
return &x
19081908
})
19091909

cmp/options.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,11 @@ func Transformer(name string, f interface{}) Option {
237237
panic(fmt.Sprintf("invalid transformer function: %T", f))
238238
}
239239
if name == "" {
240-
name = "λ" // Lambda-symbol as place-holder for anonymous transformer
241-
}
242-
if !identsRx.MatchString(name) {
240+
name = function.NameOf(v)
241+
if !identsRx.MatchString(name) {
242+
name = "λ" // Lambda-symbol as placeholder name
243+
}
244+
} else if !identsRx.MatchString(name) {
243245
panic(fmt.Sprintf("invalid name: %q", name))
244246
}
245247
tr := &transformer{name: name, fnc: reflect.ValueOf(f)}

0 commit comments

Comments
 (0)