From: Sean Liao Date: Sun, 14 Dec 2025 18:48:51 +0000 (+0000) Subject: go/doc: link to struct fields in the same package X-Git-Tag: go1.26rc2~7^2~55 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=d46c58debb;p=gostls13.git go/doc: link to struct fields in the same package This collects up any struct direct field references for linking. It does not attempt to do any validation of embedded field conflicts as in CL 510315. For #61394 Change-Id: I57dc0a0e8a71ce0bcb4e6c0963f459f76a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/729980 LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Matloob Reviewed-by: Michael Knyszek Reviewed-by: Michael Matloob --- diff --git a/src/go/doc/comment_test.go b/src/go/doc/comment_test.go index 0e7de3eb78..2569e73c7c 100644 --- a/src/go/doc/comment_test.go +++ b/src/go/doc/comment_test.go @@ -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. [I.F] is an interface method and [I.V] is a broken link.\n" - wantHTML = `

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" - wantOldHTML = "

[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" - 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" + 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.X] is a field, [G.M1] and [G.M2] are generic methods. [I.F] is an interface method and [I.V] is a broken link.\n" + wantHTML = `

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.X is a field, G.M1 and G.M2 are generic methods. I.F is an interface method and [I.V] is a broken link.` + "\n" + wantOldHTML = "

[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.X] is a field, [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.X](#G.X) is a field, [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.X is a field, G.M1 and G.M2 are generic methods.\nI.F is an interface method 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.X] is a field, [G.M1] and [G.M2]\nare generic methods. [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." ) diff --git a/src/go/doc/doc.go b/src/go/doc/doc.go index 0c23f1a46c..8c786896fd 100644 --- a/src/go/doc/doc.go +++ b/src/go/doc/doc.go @@ -168,6 +168,7 @@ func (p *Package) collectTypes(types []*Type) { p.collectFuncs(t.Funcs) p.collectFuncs(t.Methods) p.collectInterfaceMethods(t) + p.collectStructFields(t) } } @@ -212,6 +213,24 @@ func (p *Package) collectInterfaceMethods(t *Type) { } } +func (p *Package) collectStructFields(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 diff --git a/src/go/doc/testdata/pkgdoc/doc.go b/src/go/doc/testdata/pkgdoc/doc.go index d542dc2cdd..24e127c7fb 100644 --- a/src/go/doc/testdata/pkgdoc/doc.go +++ b/src/go/doc/testdata/pkgdoc/doc.go @@ -18,7 +18,7 @@ func (T) M() {} var _ = rand.Int var _ = crand.Reader -type G[T any] struct{ x T } +type G[T any] struct{ X T } func (g G[T]) M1() {} func (g *G[T]) M2() {}