]> Cypherpunks repositories - gostls13.git/commitdiff
go/doc: remove brackets from receiver in example identifier
authorJonathan Amsterdam <jba@google.com>
Fri, 22 Apr 2022 17:18:15 +0000 (13:18 -0400)
committerJonathan Amsterdam <jba@google.com>
Tue, 10 May 2022 14:35:05 +0000 (14:35 +0000)
When constructing a string for a method that will match an example
function's name, remove brackets from the receiver. This makes it
possible to write an example associated with a method of a generic
type.

Also, modify the test for classifying examples to check that all the
expected examples actually appear.

Fixes golang/go#52496.

Change-Id: Iebc5768f6cb91df9671dd701b97958fb8081f986
Reviewed-on: https://go-review.googlesource.com/c/go/+/401761
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
src/go/doc/example.go
src/go/doc/example_test.go

index 3c02e2b454af620a1f516bb47b5095d4aadf39e4..74e6e77ac3cbceec9d2f57d6ba6c6d00509be940 100644 (file)
@@ -512,7 +512,6 @@ func classifyExamples(p *Package, examples []*Example) {
        if len(examples) == 0 {
                return
        }
-
        // Mapping of names for funcs, types, and methods to the example listing.
        ids := make(map[string]*[]*Example)
        ids[""] = &p.Examples // package-level examples have an empty name
@@ -537,7 +536,7 @@ func classifyExamples(p *Package, examples []*Example) {
                        if !token.IsExported(m.Name) {
                                continue
                        }
-                       ids[strings.TrimPrefix(m.Recv, "*")+"_"+m.Name] = &m.Examples
+                       ids[strings.TrimPrefix(nameWithoutInst(m.Recv), "*")+"_"+m.Name] = &m.Examples
                }
        }
 
@@ -572,6 +571,24 @@ func classifyExamples(p *Package, examples []*Example) {
        }
 }
 
+// nameWithoutInst returns name if name has no brackets. If name contains
+// brackets, then it returns name with all the contents between (and including)
+// the outermost left and right bracket removed.
+//
+// Adapted from debug/gosym/symtab.go:Sym.nameWithoutInst.
+func nameWithoutInst(name string) string {
+       start := strings.Index(name, "[")
+       if start < 0 {
+               return name
+       }
+       end := strings.LastIndex(name, "]")
+       if end < 0 {
+               // Malformed name, should contain closing bracket too.
+               return name
+       }
+       return name[0:start] + name[end+1:]
+}
+
 // splitExampleName attempts to split example name s at index i,
 // and reports if that produces a valid split. The suffix may be
 // absent. Otherwise, it must start with a lower-case letter and
index 030ee6e553975ea7cfad3b9180b883edb7026bac..4d87a654c9a9b899d3d7d6bc18f5ec966686f8d8 100644 (file)
@@ -617,6 +617,12 @@ type (
 )
 
 func (Conflict) Conflict() {}
+
+func GFunc[T any]() {}
+
+type GType[T any] int
+
+func (GType[T]) M() {}
 `
        const test = `
 package p_test
@@ -676,6 +682,12 @@ func ExampleConflict_Conflict()        {} // ambiguous with either Conflict or C
 func ExampleConflict_conflict()        {} // ambiguous with either Conflict or Conflict_conflict type
 func ExampleConflict_Conflict_suffix() {} // ambiguous with either Conflict or Conflict_Conflict type
 func ExampleConflict_conflict_suffix() {} // ambiguous with either Conflict or Conflict_conflict type
+
+func ExampleGFunc() {}
+func ExampleGFunc_suffix() {}
+
+func ExampleGType_M() {}
+func ExampleGType_M_suffix() {}
 `
 
        // Parse literal source code as a *doc.Package.
@@ -725,12 +737,19 @@ func ExampleConflict_conflict_suffix() {} // ambiguous with either Conflict or C
                // These are implementation dependent due to the ambiguous parsing.
                "Conflict_Conflict": {"", "suffix"},
                "Conflict_conflict": {"", "suffix"},
+
+               "GFunc":   {"", "suffix"},
+               "GType.M": {"", "suffix"},
        }
 
        for id := range got {
                if !reflect.DeepEqual(got[id], want[id]) {
                        t.Errorf("classification mismatch for %q:\ngot  %q\nwant %q", id, got[id], want[id])
                }
+               delete(want, id)
+       }
+       if len(want) > 0 {
+               t.Errorf("did not find:\n%q", want)
        }
 }