From ed3ae9a340e506d873e57444a8eb28cd06e933a2 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Thu, 17 Dec 2020 12:43:19 +0530 Subject: [PATCH] cmd/doc: properly display interface methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, we used to call doc.ToText to print each comment in a comment group attached to an interface method. This broke any preformatted code block attached to the comment, and displayed everything aligned to a single column. Additionally, the name of the interface also wasn't displayed which didn't show which interface the method belonged to. To fix this, we print the entire interface node using format.Node which takes care of displaying the comments correctly, and we also filter out the methods that don't match, so that the method can be displayed as belonging to an interface. As an example, previously it would show: // Comment before exported method. // // // Code block showing how to use ExportedMethod // func DoSomething() error { // ExportedMethod() // return nil // } func ExportedMethod() // Comment on line with exported method. Now, it shows: type ExportedInterface interface { // Comment before exported method. // // // Code block showing how to use ExportedMethod // func DoSomething() error { // ExportedMethod() // return nil // } ExportedMethod() // Comment on line with exported method. } Fixes #43188 Change-Id: I28099fe4aab35e08049b2616a3506240f57133cc Reviewed-on: https://go-review.googlesource.com/c/go/+/279433 Trust: Agniva De Sarker Trust: Daniel Martí Reviewed-by: Rob Pike --- src/cmd/doc/doc_test.go | 7 +++---- src/cmd/doc/pkg.go | 28 +++++++++++++++------------- src/cmd/doc/testdata/pkg.go | 7 +++++++ 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/cmd/doc/doc_test.go b/src/cmd/doc/doc_test.go index 39530e3c2d..af7793133e 100644 --- a/src/cmd/doc/doc_test.go +++ b/src/cmd/doc/doc_test.go @@ -579,7 +579,7 @@ var tests = []test{ []string{ `Comment about exported interface`, // Include comment. `type ExportedInterface interface`, // Interface definition. - `Comment before exported method.*\n.*ExportedMethod\(\)` + + `Comment before exported method.\n.*//\n.*// // Code block showing how to use ExportedMethod\n.*// func DoSomething\(\) error {\n.*// ExportedMethod\(\)\n.*// return nil\n.*// }\n.*//.*\n.*ExportedMethod\(\)` + `.*Comment on line with exported method`, `io.Reader.*Comment on line with embedded Reader`, `error.*Comment on line with embedded error`, @@ -599,8 +599,7 @@ var tests = []test{ []string{ `Comment about exported interface`, // Include comment. `type ExportedInterface interface`, // Interface definition. - `Comment before exported method.*\n.*ExportedMethod\(\)` + - `.*Comment on line with exported method`, + `Comment before exported method.\n.*//\n.*// // Code block showing how to use ExportedMethod\n.*// func DoSomething\(\) error {\n.*// ExportedMethod\(\)\n.*// return nil\n.*// }\n.*//.*\n.*ExportedMethod\(\)` + `.*Comment on line with exported method`, `unexportedMethod\(\).*Comment on line with unexported method`, `io.Reader.*Comment on line with embedded Reader`, `error.*Comment on line with embedded error`, @@ -615,7 +614,7 @@ var tests = []test{ "interface method", []string{p, `ExportedInterface.ExportedMethod`}, []string{ - `Comment before exported method.*\n.*ExportedMethod\(\)` + + `Comment before exported method.\n.*//\n.*// // Code block showing how to use ExportedMethod\n.*// func DoSomething\(\) error {\n.*// ExportedMethod\(\)\n.*// return nil\n.*// }\n.*//.*\n.*ExportedMethod\(\)` + `.*Comment on line with exported method`, }, []string{ diff --git a/src/cmd/doc/pkg.go b/src/cmd/doc/pkg.go index c2e06ebc8b..587f0bdc14 100644 --- a/src/cmd/doc/pkg.go +++ b/src/cmd/doc/pkg.go @@ -950,6 +950,9 @@ func (pkg *Package) printMethodDoc(symbol, method string) bool { // Not an interface type. continue } + + // Collect and print only the methods that match. + var methods []*ast.Field for _, iMethod := range inter.Methods.List { // This is an interface, so there can be only one name. // TODO: Anonymous methods (embedding) @@ -958,22 +961,21 @@ func (pkg *Package) printMethodDoc(symbol, method string) bool { } name := iMethod.Names[0].Name if match(method, name) { - if iMethod.Doc != nil { - for _, comment := range iMethod.Doc.List { - doc.ToText(&pkg.buf, comment.Text, "", indent, indentedWidth) - } - } - s := pkg.oneLineNode(iMethod.Type) - // Hack: s starts "func" but there is no name present. - // We could instead build a FuncDecl but it's not worthwhile. - lineComment := "" - if iMethod.Comment != nil { - lineComment = fmt.Sprintf(" %s", iMethod.Comment.List[0].Text) - } - pkg.Printf("func %s%s%s\n", name, s[4:], lineComment) + methods = append(methods, iMethod) found = true } } + if found { + pkg.Printf("type %s ", spec.Name) + inter.Methods.List, methods = methods, inter.Methods.List + err := format.Node(&pkg.buf, pkg.fs, inter) + if err != nil { + log.Fatal(err) + } + pkg.newlines(1) + // Restore the original methods. + inter.Methods.List = methods + } } return found } diff --git a/src/cmd/doc/testdata/pkg.go b/src/cmd/doc/testdata/pkg.go index d695bdf1c5..5ece832565 100644 --- a/src/cmd/doc/testdata/pkg.go +++ b/src/cmd/doc/testdata/pkg.go @@ -111,6 +111,13 @@ const unexportedTypedConstant ExportedType = 1 // In a separate section to test // Comment about exported interface. type ExportedInterface interface { // Comment before exported method. + // + // // Code block showing how to use ExportedMethod + // func DoSomething() error { + // ExportedMethod() + // return nil + // } + // ExportedMethod() // Comment on line with exported method. unexportedMethod() // Comment on line with unexported method. io.Reader // Comment on line with embedded Reader.