]> git.feebdaed.xyz Git - 0xmirror/go.git/commitdiff
go/doc: link to struct fields in the same package
authorSean Liao <sean@liao.dev>
Sun, 14 Dec 2025 18:48:51 +0000 (18:48 +0000)
committerSean Liao <sean@liao.dev>
Fri, 19 Dec 2025 21:19:23 +0000 (13:19 -0800)
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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Matloob <matloob@google.com>
src/go/doc/comment_test.go
src/go/doc/doc.go
src/go/doc/testdata/pkgdoc/doc.go

index 0e7de3eb78f38f67a8616c96df2d09599f0689ba..2569e73c7c23e2be6509de83763922d364043dd3 100644 (file)
@@ -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        = `<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"
+               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        = `<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.X">G.X</a> is a field, <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.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."
        )
index 0c23f1a46c87fda20f497727aed0ebfb054a543c..8c786896fd4b711be9121f8bb3890321adfe325e 100644 (file)
@@ -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
index d542dc2cdd0cb663058658d6ad4bc10a8f46008f..24e127c7fba17b4491ae65b655f3f3906ba84cac 100644 (file)
@@ -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() {}