x/tools/cmd/godoc: fix broken links in composite literals

Previously, field names in composite literals were treated as normal
identifiers. For example, in Foo{X: 42}, X was treated link a normal
variable and was linked to "#X".

With this change, field links now include a prefix for their type
definition, for example, "#Foo.X".

Fixes golang/go#16031

Change-Id: I9cb501704f284fbbc05424555312307c61843e47
Reviewed-on: https://go-review.googlesource.com/36830
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
diff --git a/godoc/godoc_test.go b/godoc/godoc_test.go
index 0c32f39..0595a15 100644
--- a/godoc/godoc_test.go
+++ b/godoc/godoc_test.go
@@ -5,7 +5,7 @@
 package godoc
 
 import (
-	"go/ast"
+	"bytes"
 	"go/parser"
 	"go/token"
 	"strings"
@@ -124,7 +124,7 @@
 // Test that we add <span id="StructName.FieldName"> elements
 // to the HTML of struct fields.
 func TestStructFieldsIDAttributes(t *testing.T) {
-	got := linkifyStructFields(t, []byte(`
+	got := linkifySource(t, []byte(`
 package foo
 
 type T struct {
@@ -157,7 +157,25 @@
 	}
 }
 
-func linkifyStructFields(t *testing.T, src []byte) string {
+func TestCompositeLitLinkFields(t *testing.T) {
+	got := linkifySource(t, []byte(`
+package foo
+
+type T struct {
+	X int
+}
+
+var S T = T{X: 12}`))
+	want := `type T struct {
+<span id="T.X"></span>X <a href="/pkg/builtin/#int">int</a>
+}
+var S <a href="#T">T</a> = <a href="#T">T</a>{<a href="#T.X">X</a>: 12}`
+	if got != want {
+		t.Errorf("got: %s\n\nwant: %s\n", got, want)
+	}
+}
+
+func linkifySource(t *testing.T, src []byte) string {
 	p := &Presentation{
 		DeclLinks: true,
 	}
@@ -166,11 +184,17 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	genDecl := af.Decls[0].(*ast.GenDecl)
+	var buf bytes.Buffer
 	pi := &PageInfo{
 		FSet: fset,
 	}
-	return p.node_htmlFunc(pi, genDecl, true)
+	sep := ""
+	for _, decl := range af.Decls {
+		buf.WriteString(sep)
+		sep = "\n"
+		buf.WriteString(p.node_htmlFunc(pi, decl, true))
+	}
+	return buf.String()
 }
 
 func TestScanIdentifier(t *testing.T) {