From 5d7261870e73f10c90c903a329eeb99b151d9f9f Mon Sep 17 00:00:00 2001 From: Jonathan Amsterdam Date: Thu, 20 Aug 2020 11:35:17 -0400 Subject: [PATCH] go/doc: support examples on methods from embedded unexported types In type T1 struct { t2 } type t2 int func (t2) M() T1 has method M because it embeds t2, which has M. Classify the example func ExampleT1_M with T1 instead of ignoring it, as is done currently. There is no other way to provide an example for such a method, since its original type is unexported. Continue to ignore examples on methods from embedded types that are exported, unless in AllMethods mode. Examples for those methods could be written on the original type. The change involves removing a check in classifyExamples. The check isn't necessary to get the above behavior because reader.collectEmbeddedMethods and sortedFuncs already generate the appropriate list of methods. For #40172. Change-Id: Ibe7d965ecba6426466184e6e6655fc05989e9caf Reviewed-on: https://go-review.googlesource.com/c/go/+/249557 Reviewed-by: Dmitri Shuralyov --- src/go/doc/example.go | 2 +- src/go/doc/example_test.go | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/go/doc/example.go b/src/go/doc/example.go index ebf81189b5..125fd530b1 100644 --- a/src/go/doc/example.go +++ b/src/go/doc/example.go @@ -486,7 +486,7 @@ func classifyExamples(p *Package, examples []*Example) { ids[f.Name] = &f.Examples } for _, m := range t.Methods { - if !token.IsExported(m.Name) || m.Level != 0 { // avoid forwarded methods from embedding + if !token.IsExported(m.Name) { continue } ids[strings.TrimPrefix(m.Recv, "*")+"_"+m.Name] = &m.Examples diff --git a/src/go/doc/example_test.go b/src/go/doc/example_test.go index 32db3cd7da..7c96f0300a 100644 --- a/src/go/doc/example_test.go +++ b/src/go/doc/example_test.go @@ -563,6 +563,7 @@ type ( type2 int Embed struct { Type1 } + Uembed struct { type2 } ) func Func1() {} @@ -575,6 +576,8 @@ func (Type1) Func1_Foo() {} func (Type1) Func1_foo() {} func (Type1) func2() {} +func (type2) Func1() {} + type ( Conflict int Conflict_Conflict int @@ -633,7 +636,9 @@ func ExampleType1_Func1_foo_suffix() {} func ExampleType1_Func1_foo_Suffix() {} // matches Type1.Func1, instead of Type1.Func1_foo func ExampleType1_func2() {} // matches Type1, instead of Type1.func2 -func ExampleEmbed_Func1() {} // invalid - no support for forwarded methods from embedding +func ExampleEmbed_Func1() {} // invalid - no support for forwarded methods from embedding exported type +func ExampleUembed_Func1() {} // methods from embedding unexported types are OK +func ExampleUembed_Func1_suffix() {} func ExampleConflict_Conflict() {} // ambiguous with either Conflict or Conflict_Conflict type func ExampleConflict_conflict() {} // ambiguous with either Conflict or Conflict_conflict type @@ -683,6 +688,8 @@ func ExampleConflict_conflict_suffix() {} // ambiguous with either Conflict or C "Type1.Func1_Foo": {"", "suffix"}, "Type1.Func1_foo": {"", "suffix"}, + "Uembed.Func1": {"", "suffix"}, + // These are implementation dependent due to the ambiguous parsing. "Conflict_Conflict": {"", "suffix"}, "Conflict_conflict": {"", "suffix"}, -- 2.50.0