]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/doc: print documentation for all matches in a package, not just the first
authorRob Pike <r@golang.org>
Tue, 28 Apr 2015 19:38:09 +0000 (12:38 -0700)
committerGerrit Code Review <noreply-gerritcodereview@google.com>
Tue, 28 Apr 2015 19:42:57 +0000 (19:42 +0000)
Change-Id: Id0d4ac7169f741dfeec7b1e67bdc21e49ae37b9e
Reviewed-on: https://go-review.googlesource.com/9430
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/doc/pkg.go
src/cmd/go/alldocs.go
src/cmd/go/doc.go

index b7cd870865708eb2dd12ae1d93e91469e2404952..e08b756239c2d707ef2822fb0332ea2d7d2336b8 100644 (file)
@@ -218,89 +218,89 @@ func (pkg *Package) typeSummary() {
        }
 }
 
-// findValue finds the doc.Value that describes the symbol.
-func (pkg *Package) findValue(symbol string, values []*doc.Value) *doc.Value {
-       for _, value := range values {
+// findValues finds the doc.Values that describe the symbol.
+func (pkg *Package) findValues(symbol string, docValues []*doc.Value) (values []*doc.Value) {
+       for _, value := range docValues {
                for _, name := range value.Names {
                        if match(symbol, name) {
-                               return value
+                               values = append(values, value)
                        }
                }
        }
-       return nil
+       return
 }
 
-// findType finds the doc.Func that describes the symbol.
-func (pkg *Package) findFunc(symbol string) *doc.Func {
+// findFuncs finds the doc.Funcs that describes the symbol.
+func (pkg *Package) findFuncs(symbol string) (funcs []*doc.Func) {
        for _, fun := range pkg.doc.Funcs {
                if match(symbol, fun.Name) {
-                       return fun
+                       funcs = append(funcs, fun)
                }
        }
-       return nil
+       return
 }
 
-// findType finds the doc.Type that describes the symbol.
-func (pkg *Package) findType(symbol string) *doc.Type {
+// findTypes finds the doc.Types that describes the symbol.
+func (pkg *Package) findTypes(symbol string) (types []*doc.Type) {
        for _, typ := range pkg.doc.Types {
                if match(symbol, typ.Name) {
-                       return typ
+                       types = append(types, typ)
                }
        }
-       return nil
+       return
 }
 
 // findTypeSpec returns the ast.TypeSpec within the declaration that defines the symbol.
+// The name must match exactly.
 func (pkg *Package) findTypeSpec(decl *ast.GenDecl, symbol string) *ast.TypeSpec {
        for _, spec := range decl.Specs {
                typeSpec := spec.(*ast.TypeSpec) // Must succeed.
-               if match(symbol, typeSpec.Name.Name) {
+               if symbol == typeSpec.Name.Name {
                        return typeSpec
                }
        }
        return nil
 }
 
-// symbolDoc prints the doc for symbol. If it is a type, this includes its methods,
-// factories (TODO) and associated constants.
+// symbolDoc prints the docs for symbol. There may be multiple matches.
+// If symbol matches a type, output includes its methods factories and associated constants.
 func (pkg *Package) symbolDoc(symbol string) {
-       // TODO: resolve ambiguity in doc foo vs. doc Foo.
+       found := false
        // Functions.
-       if fun := pkg.findFunc(symbol); fun != nil {
+       for _, fun := range pkg.findFuncs(symbol) {
                // Symbol is a function.
                decl := fun.Decl
                decl.Body = nil
                pkg.emit(fun.Doc, decl)
-               return
+               found = true
        }
        // Constants and variables behave the same.
-       value := pkg.findValue(symbol, pkg.doc.Consts)
-       if value == nil {
-               value = pkg.findValue(symbol, pkg.doc.Vars)
-       }
-       if value != nil {
+       values := pkg.findValues(symbol, pkg.doc.Consts)
+       values = append(values, pkg.findValues(symbol, pkg.doc.Vars)...)
+       for _, value := range values {
                pkg.emit(value.Doc, value.Decl)
-               return
+               found = true
        }
        // Types.
-       typ := pkg.findType(symbol)
-       if typ == nil {
+       for _, typ := range pkg.findTypes(symbol) {
+               decl := typ.Decl
+               spec := pkg.findTypeSpec(decl, typ.Name)
+               trimUnexportedFields(spec)
+               // If there are multiple types defined, reduce to just this one.
+               if len(decl.Specs) > 1 {
+                       decl.Specs = []ast.Spec{spec}
+               }
+               pkg.emit(typ.Doc, decl)
+               // Show associated methods, constants, etc.
+               pkg.valueSummary(typ.Consts)
+               pkg.valueSummary(typ.Vars)
+               pkg.funcSummary(typ.Funcs)
+               pkg.funcSummary(typ.Methods)
+               found = true
+       }
+       if !found {
                log.Fatalf("symbol %s not present in package %s installed in %q", symbol, pkg.name, pkg.build.ImportPath)
        }
-       decl := typ.Decl
-       spec := pkg.findTypeSpec(decl, symbol)
-       trimUnexportedFields(spec)
-       // If there are multiple types defined, reduce to just this one.
-       if len(decl.Specs) > 1 {
-               decl.Specs = []ast.Spec{spec}
-       }
-       pkg.emit(typ.Doc, decl)
-       // TODO: Show factory functions.
-       // Show associated methods, constants, etc.
-       pkg.valueSummary(typ.Consts)
-       pkg.valueSummary(typ.Vars)
-       pkg.funcSummary(typ.Funcs)
-       pkg.funcSummary(typ.Methods)
 }
 
 // trimUnexportedFields modifies spec in place to elide unexported fields (unless
@@ -347,21 +347,26 @@ func trimUnexportedFields(spec *ast.TypeSpec) {
        }
 }
 
-// methodDoc prints the doc for symbol.method.
+// methodDoc prints the docs for matches of symbol.method.
 func (pkg *Package) methodDoc(symbol, method string) {
-       typ := pkg.findType(symbol)
-       if typ == nil {
+       types := pkg.findTypes(symbol)
+       if types == nil {
                log.Fatalf("symbol %s is not a type in package %s installed in %q", symbol, pkg.name, pkg.build.ImportPath)
        }
-       for _, meth := range typ.Methods {
-               if match(method, meth.Name) {
-                       decl := meth.Decl
-                       decl.Body = nil
-                       pkg.emit(meth.Doc, decl)
-                       return
+       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)
+                               found = true
+                       }
                }
        }
-       log.Fatalf("no method %s.%s in package %s installed in %q", symbol, method, pkg.name, pkg.build.ImportPath)
+       if !found {
+               log.Fatalf("no method %s.%s in package %s installed in %q", symbol, method, pkg.name, pkg.build.ImportPath)
+       }
 }
 
 // match reports whether the user's symbol matches the program's.
index 66fc80d8a5bb32356327a45e484e82cd88966787..59d7962a458b5b7d018472890139e29800e3e861 100644 (file)
@@ -220,7 +220,9 @@ The package paths must be either a qualified path or a proper suffix of a path
 path elements like . and ... are not implemented by go doc.
 
 When matching symbols, lower-case letters match either case but upper-case letters
-match exactly.
+match exactly. This means that there may be multiple matches in a package if
+different symbols have different cases. If this occurs, documentation for all
+matches is printed.
 
 Examples:
        go doc
index 2250d171d59710d250efdaa6519045d7d5f9d0ea..98ce34077b6a1cacaeafd7c3bce97e8b88ba18a2 100644 (file)
@@ -40,7 +40,9 @@ The package paths must be either a qualified path or a proper suffix of a path
 path elements like . and ... are not implemented by go doc.
 
 When matching symbols, lower-case letters match either case but upper-case letters
-match exactly.
+match exactly. This means that there may be multiple matches in a package if
+different symbols have different cases. If this occurs, documentation for all
+matches is printed.
 
 Examples:
        go doc