mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/doc: show documentation for interface methods when requested explicitly
For historical reasons, the go/doc package does not include the methods within an interface as part of the documented methods for that type. Thus, go doc ast.Node.Pos gives an incorrect and confusing error message: doc: no method Node.Pos in package go/ast This CL does some dirty work to dig down to the methods so interface methods now present their documentation: % go doc ast.node.pos func Pos() token.Pos // position of first character belonging to the node % It must largely sidestep the doc package to do this, which is a shame. Perhaps things will improve there one day. The change does not handle embeddings, and in principle the same approach could be done for struct fields, but that is also not here yet. But this CL fixes the thing that was bugging me. Change-Id: Ic10a91936da96f54ee0b2f4a4fe4a8c9b93a5b4a Reviewed-on: https://go-review.googlesource.com/31852 Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
050f378085
commit
2ee82edfc2
2 changed files with 57 additions and 7 deletions
|
|
@ -755,11 +755,48 @@ func (pkg *Package) printMethodDoc(symbol, method string) bool {
|
|||
}
|
||||
found := false
|
||||
for _, typ := range types {
|
||||
for _, meth := range typ.Methods {
|
||||
if match(method, meth.Name) {
|
||||
decl := meth.Decl
|
||||
decl.Body = nil
|
||||
pkg.emit(meth.Doc, decl)
|
||||
if len(typ.Methods) > 0 {
|
||||
for _, meth := range typ.Methods {
|
||||
if match(method, meth.Name) {
|
||||
decl := meth.Decl
|
||||
decl.Body = nil
|
||||
pkg.emit(meth.Doc, decl)
|
||||
found = true
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
// Type may be an interface. The go/doc package does not attach
|
||||
// an interface's methods to the doc.Type. We need to dig around.
|
||||
spec := pkg.findTypeSpec(typ.Decl, typ.Name)
|
||||
inter, ok := spec.Type.(*ast.InterfaceType)
|
||||
if !ok {
|
||||
// Not an interface type.
|
||||
// TODO? Maybe handle struct fields here.
|
||||
continue
|
||||
}
|
||||
for _, iMethod := range inter.Methods.List {
|
||||
// This is an interface, so there can be only one name.
|
||||
// TODO: Anonymous methods (embedding)
|
||||
if len(iMethod.Names) == 0 {
|
||||
continue
|
||||
}
|
||||
name := iMethod.Names[0].Name
|
||||
if match(method, name) {
|
||||
// pkg.oneLineField(iMethod, 0)
|
||||
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)
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue