mirror of
https://github.com/golang/go.git
synced 2025-10-19 11:03:18 +00:00
go/doc: linkify interface methods
Create doc links for references to interface methods, such as "[Context.Err]". This does not attempt to handle embedded interfaces: The linked-to method must be declared within the named type. Fixes #54033 Change-Id: I4d7a132affe682c85958ca785bcc96571404e6c1 Reviewed-on: https://go-review.googlesource.com/c/go/+/687395 Reviewed-by: Robert Findley <rfindley@google.com> Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Sean Liao <sean@liao.dev> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
7bba745820
commit
1eec830f54
3 changed files with 39 additions and 7 deletions
|
@ -24,12 +24,12 @@ func TestComment(t *testing.T) {
|
|||
pkg := New(pkgs["pkgdoc"], "testdata/pkgdoc", 0)
|
||||
|
||||
var (
|
||||
input = "[T] and [U] are types, and [T.M] is a method, but [V] is a broken link. [rand.Int] and [crand.Reader] are things. [G.M1] and [G.M2] are generic methods.\n"
|
||||
wantHTML = `<p><a href="#T">T</a> and <a href="#U">U</a> are types, and <a href="#T.M">T.M</a> is a method, but [V] is a broken link. <a href="/math/rand#Int">rand.Int</a> and <a href="/crypto/rand#Reader">crand.Reader</a> are things. <a href="#G.M1">G.M1</a> and <a href="#G.M2">G.M2</a> are generic methods.` + "\n"
|
||||
wantOldHTML = "<p>[T] and [U] are <i>types</i>, and [T.M] is a method, but [V] is a broken link. [rand.Int] and [crand.Reader] are things. [G.M1] and [G.M2] are generic methods.\n"
|
||||
wantMarkdown = "[T](#T) and [U](#U) are types, and [T.M](#T.M) is a method, but \\[V] is a broken link. [rand.Int](/math/rand#Int) and [crand.Reader](/crypto/rand#Reader) are things. [G.M1](#G.M1) and [G.M2](#G.M2) are generic methods.\n"
|
||||
wantText = "T and U are types, and T.M is a method, but [V] is a broken link. rand.Int and\ncrand.Reader are things. G.M1 and G.M2 are generic methods.\n"
|
||||
wantOldText = "[T] and [U] are types, and [T.M] is a method, but [V] is a broken link.\n[rand.Int] and [crand.Reader] are things. [G.M1] and [G.M2] are generic methods.\n"
|
||||
input = "[T] and [U] are types, and [T.M] is a method, but [V] is a broken link. [rand.Int] and [crand.Reader] are things. [G.M1] and [G.M2] are generic methods. [I.F] is an interface method and [I.V] is a broken link.\n"
|
||||
wantHTML = `<p><a href="#T">T</a> and <a href="#U">U</a> are types, and <a href="#T.M">T.M</a> is a method, but [V] is a broken link. <a href="/math/rand#Int">rand.Int</a> and <a href="/crypto/rand#Reader">crand.Reader</a> are things. <a href="#G.M1">G.M1</a> and <a href="#G.M2">G.M2</a> are generic methods. <a href="#I.F">I.F</a> is an interface method and [I.V] is a broken link.` + "\n"
|
||||
wantOldHTML = "<p>[T] and [U] are <i>types</i>, and [T.M] is a method, but [V] is a broken link. [rand.Int] and [crand.Reader] are things. [G.M1] and [G.M2] are generic methods. [I.F] is an interface method and [I.V] is a broken link.\n"
|
||||
wantMarkdown = "[T](#T) and [U](#U) are types, and [T.M](#T.M) is a method, but \\[V] is a broken link. [rand.Int](/math/rand#Int) and [crand.Reader](/crypto/rand#Reader) are things. [G.M1](#G.M1) and [G.M2](#G.M2) are generic methods. [I.F](#I.F) is an interface method and \\[I.V] is a broken link.\n"
|
||||
wantText = "T and U are types, and T.M is a method, but [V] is a broken link. rand.Int and\ncrand.Reader are things. G.M1 and G.M2 are generic methods. I.F is an interface\nmethod and [I.V] is a broken link.\n"
|
||||
wantOldText = "[T] and [U] are types, and [T.M] is a method, but [V] is a broken link.\n[rand.Int] and [crand.Reader] are things. [G.M1] and [G.M2] are generic methods.\n[I.F] is an interface method and [I.V] is a broken link.\n"
|
||||
wantSynopsis = "T and U are types, and T.M is a method, but [V] is a broken link."
|
||||
wantOldSynopsis = "[T] and [U] are types, and [T.M] is a method, but [V] is a broken link."
|
||||
)
|
||||
|
|
|
@ -167,6 +167,7 @@ func (p *Package) collectTypes(types []*Type) {
|
|||
p.collectValues(t.Vars)
|
||||
p.collectFuncs(t.Funcs)
|
||||
p.collectFuncs(t.Methods)
|
||||
p.collectInterfaceMethods(t)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,6 +185,33 @@ func (p *Package) collectFuncs(funcs []*Func) {
|
|||
}
|
||||
}
|
||||
|
||||
// collectInterfaceMethods adds methods of interface types within t to p.syms.
|
||||
// Note that t.Methods will contain methods of non-interface types, but not interface types.
|
||||
// Adding interface methods to t.Methods might make sense, but would cause us to
|
||||
// include those methods in the documentation index. Adding interface methods to p.syms
|
||||
// here allows us to linkify references like [io.Reader.Read] without making any other
|
||||
// changes to the documentation formatting at this time.
|
||||
//
|
||||
// If we do start adding interface methods to t.Methods in the future,
|
||||
// collectInterfaceMethods can be dropped as redundant with collectFuncs(t.Methods).
|
||||
func (p *Package) collectInterfaceMethods(t *Type) {
|
||||
for _, s := range t.Decl.Specs {
|
||||
spec, ok := s.(*ast.TypeSpec)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
list, isStruct := fields(spec.Type)
|
||||
if isStruct {
|
||||
continue
|
||||
}
|
||||
for _, field := range list {
|
||||
for _, name := range field.Names {
|
||||
p.syms[t.Name+"."+name.Name] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NewFromFiles computes documentation for a package.
|
||||
//
|
||||
// The package is specified by a list of *ast.Files and corresponding
|
||||
|
|
6
src/go/doc/testdata/pkgdoc/doc.go
vendored
6
src/go/doc/testdata/pkgdoc/doc.go
vendored
|
@ -20,5 +20,9 @@ var _ = crand.Reader
|
|||
|
||||
type G[T any] struct{ x T }
|
||||
|
||||
func (g G[T]) M1() {}
|
||||
func (g G[T]) M1() {}
|
||||
func (g *G[T]) M2() {}
|
||||
|
||||
type I interface {
|
||||
F()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue