apidiff: dedupe embedded method set removal reports When an embedded method is removed, apidiff reports the same removal for both the value and pointer method sets. Report it only from the pointer method set check. Add tests for joining object and field names. Change-Id: I2c9d520483c61f0489c84da1c073b5c5d25728cc Reviewed-on: https://go-review.googlesource.com/c/exp/+/802620 Reviewed-by: Jonathan Amsterdam <jba@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Alan Donovan <adonovan@google.com>
diff --git a/apidiff/compatibility.go b/apidiff/compatibility.go index e83fdc3..64f98c9 100644 --- a/apidiff/compatibility.go +++ b/apidiff/compatibility.go
@@ -302,6 +302,11 @@ // object. So use the part string to distinguish them. if receiverNamedType(oldMethod).Obj() != otn { part = fmt.Sprintf(", method set of %s", msname) + // The same embedded method removal appears in both the value and + // pointer method sets. Report it only once, from the pointer check. + if _, ok := oldt.(*types.Pointer); !ok { + continue + } } d.incompatible(objectWithSide{oldMethod, false}, part, "removed") } else {
diff --git a/apidiff/messageset.go b/apidiff/messageset.go index 633ae58..5232d0a 100644 --- a/apidiff/messageset.go +++ b/apidiff/messageset.go
@@ -1,6 +1,3 @@ -// TODO: show that two-non-empty dotjoin can happen, by using an anon struct as a field type -// TODO: don't report removed/changed methods for both value and pointer method sets? - package apidiff import (
diff --git a/apidiff/messageset_test.go b/apidiff/messageset_test.go new file mode 100644 index 0000000..003526d --- /dev/null +++ b/apidiff/messageset_test.go
@@ -0,0 +1,19 @@ +package apidiff + +import "testing" + +func TestDotjoin(t *testing.T) { + tests := []struct { + s1, s2 string + want string + }{ + {"", "part", "part"}, + {"obj", "", "obj"}, + {"AnonField", "Inner", "AnonField.Inner"}, + } + for _, test := range tests { + if got := dotjoin(test.s1, test.s2); got != test.want { + t.Errorf("dotjoin(%q, %q) = %q, want %q", test.s1, test.s2, got, test.want) + } + } +}
diff --git a/apidiff/testdata/messageset.go b/apidiff/testdata/messageset.go new file mode 100644 index 0000000..2f29f7e --- /dev/null +++ b/apidiff/testdata/messageset.go
@@ -0,0 +1,13 @@ +package p + +// old +type AnonField struct { + Inner struct { + X int + } +} + +// new +type AnonField struct { + // i AnonField.Inner: removed +}
diff --git a/apidiff/testdata/method_sets.go b/apidiff/testdata/method_sets.go index 5d0dbb5..d4b0339 100644 --- a/apidiff/testdata/method_sets.go +++ b/apidiff/testdata/method_sets.go
@@ -92,7 +92,6 @@ // i embedm.EV1: changed from func() to func(int) func (embedm2) EV1(int) {} -// i embedm.EV2, method set of SM: removed // i embedm.EV2, method set of *SM: removed // i (*embedm).EP2, method set of *SM: removed