`type T1 = T2`,                                                 // Type alias
                },
                []string{
-                       `const internalConstant = 2`,        // No internal constants.
-                       `var internalVariable = 2`,          // No internal variables.
-                       `func internalFunc(a int) bool`,     // No internal functions.
-                       `Comment about exported constant`,   // No comment for single constant.
-                       `Comment about exported variable`,   // No comment for single variable.
-                       `Comment about block of constants.`, // No comment for constant block.
-                       `Comment about block of variables.`, // No comment for variable block.
-                       `Comment before ConstOne`,           // No comment for first entry in constant block.
-                       `Comment before VarOne`,             // No comment for first entry in variable block.
-                       `ConstTwo = 2`,                      // No second entry in constant block.
-                       `VarTwo = 2`,                        // No second entry in variable block.
-                       `VarFive = 5`,                       // From block starting with unexported variable.
-                       `type unexportedType`,               // No unexported type.
-                       `unexportedTypedConstant`,           // No unexported typed constant.
-                       `\bField`,                           // No fields.
-                       `Method`,                            // No methods.
-                       `someArgument[5-8]`,                 // No truncated arguments.
-                       `type T1 T2`,                        // Type alias does not display as type declaration.
+                       `const internalConstant = 2`,       // No internal constants.
+                       `var internalVariable = 2`,         // No internal variables.
+                       `func internalFunc(a int) bool`,    // No internal functions.
+                       `Comment about exported constant`,  // No comment for single constant.
+                       `Comment about exported variable`,  // No comment for single variable.
+                       `Comment about block of constants`, // No comment for constant block.
+                       `Comment about block of variables`, // No comment for variable block.
+                       `Comment before ConstOne`,          // No comment for first entry in constant block.
+                       `Comment before VarOne`,            // No comment for first entry in variable block.
+                       `ConstTwo = 2`,                     // No second entry in constant block.
+                       `VarTwo = 2`,                       // No second entry in variable block.
+                       `VarFive = 5`,                      // From block starting with unexported variable.
+                       `type unexportedType`,              // No unexported type.
+                       `unexportedTypedConstant`,          // No unexported typed constant.
+                       `\bField`,                          // No fields.
+                       `Method`,                           // No methods.
+                       `someArgument[5-8]`,                // No truncated arguments.
+                       `type T1 T2`,                       // Type alias does not display as type declaration.
                },
        },
        // Package dump -u
                },
                nil,
        },
+       // Block of constants -src.
+       {
+               "block of constants with -src",
+               []string{"-src", p, `ConstTwo`},
+               []string{
+                       `Comment about block of constants`, // Top comment.
+                       `ConstOne.*=.*1`,                   // Each constant seen.
+                       `ConstTwo.*=.*2.*Comment on line with ConstTwo`,
+                       `constThree`, // Even unexported constants.
+               },
+               nil,
+       },
        // Block of constants with carryover type from unexported field.
        {
                "block of constants with carryover type",
                },
                nil,
        },
+       // Function with -src.
+       {
+               "function with -src",
+               []string{"-src", p, `ExportedFunc`},
+               []string{
+                       `Comment about exported function`, // Include comment.
+                       `func ExportedFunc\(a int\) bool`,
+                       `return true != false`, // Include body.
+               },
+               nil,
+       },
 
        // Type.
        {
                        `Comment about exported type`, // Include comment.
                        `type ExportedType struct`,    // Type definition.
                        `Comment before exported field.*\n.*ExportedField +int` +
-                               `.*Comment on line with exported field.`,
-                       `ExportedEmbeddedType.*Comment on line with exported embedded field.`,
+                               `.*Comment on line with exported field`,
+                       `ExportedEmbeddedType.*Comment on line with exported embedded field`,
                        `Has unexported fields`,
                        `func \(ExportedType\) ExportedMethod\(a int\) bool`,
                        `const ExportedTypedConstant ExportedType = iota`, // Must include associated constant.
                        `func ExportedTypeConstructor\(\) \*ExportedType`, // Must include constructor.
-                       `io.Reader.*Comment on line with embedded Reader.`,
+                       `io.Reader.*Comment on line with embedded Reader`,
                },
                []string{
-                       `unexportedField`,                // No unexported field.
-                       `int.*embedded`,                  // No unexported embedded field.
-                       `Comment about exported method.`, // No comment about exported method.
-                       `unexportedMethod`,               // No unexported method.
-                       `unexportedTypedConstant`,        // No unexported constant.
-                       `error`,                          // No embedded error.
+                       `unexportedField`,               // No unexported field.
+                       `int.*embedded`,                 // No unexported embedded field.
+                       `Comment about exported method`, // No comment about exported method.
+                       `unexportedMethod`,              // No unexported method.
+                       `unexportedTypedConstant`,       // No unexported constant.
+                       `error`,                         // No embedded error.
+               },
+       },
+       // Type with -src. Will see unexported fields.
+       {
+               "type",
+               []string{"-src", p, `ExportedType`},
+               []string{
+                       `Comment about exported type`, // Include comment.
+                       `type ExportedType struct`,    // Type definition.
+                       `Comment before exported field.*\n.*ExportedField +int` +
+                               `.*Comment on line with exported field`,
+                       `ExportedEmbeddedType.*Comment on line with exported embedded field`,
+                       `unexportedType.*Comment on line with unexported embedded field`,
+                       `func \(ExportedType\) ExportedMethod\(a int\) bool`,
+                       `const ExportedTypedConstant ExportedType = iota`, // Must include associated constant.
+                       `func ExportedTypeConstructor\(\) \*ExportedType`, // Must include constructor.
+                       `io.Reader.*Comment on line with embedded Reader`,
+               },
+               []string{
+                       `int.*embedded`,                 // No unexported embedded field.
+                       `Comment about exported method`, // No comment about exported method.
+                       `unexportedMethod`,              // No unexported method.
+                       `unexportedTypedConstant`,       // No unexported constant.
                },
        },
        // Type T1 dump (alias).
                        `Comment about exported type`, // Include comment.
                        `type ExportedType struct`,    // Type definition.
                        `Comment before exported field.*\n.*ExportedField +int`,
-                       `unexportedField.*int.*Comment on line with unexported field.`,
-                       `ExportedEmbeddedType.*Comment on line with exported embedded field.`,
-                       `\*ExportedEmbeddedType.*Comment on line with exported embedded \*field.`,
-                       `\*qualified.ExportedEmbeddedType.*Comment on line with exported embedded \*selector.field.`,
-                       `unexportedType.*Comment on line with unexported embedded field.`,
-                       `\*unexportedType.*Comment on line with unexported embedded \*field.`,
-                       `io.Reader.*Comment on line with embedded Reader.`,
-                       `error.*Comment on line with embedded error.`,
+                       `unexportedField.*int.*Comment on line with unexported field`,
+                       `ExportedEmbeddedType.*Comment on line with exported embedded field`,
+                       `\*ExportedEmbeddedType.*Comment on line with exported embedded \*field`,
+                       `\*qualified.ExportedEmbeddedType.*Comment on line with exported embedded \*selector.field`,
+                       `unexportedType.*Comment on line with unexported embedded field`,
+                       `\*unexportedType.*Comment on line with unexported embedded \*field`,
+                       `io.Reader.*Comment on line with embedded Reader`,
+                       `error.*Comment on line with embedded error`,
                        `func \(ExportedType\) unexportedMethod\(a int\) bool`,
                        `unexportedTypedConstant`,
                },
                        `type ExportedInterface interface`, // Interface definition.
                        `Comment before exported method.*\n.*ExportedMethod\(\)` +
                                `.*Comment on line with exported method`,
-                       `io.Reader.*Comment on line with embedded Reader.`,
-                       `error.*Comment on line with embedded error.`,
+                       `io.Reader.*Comment on line with embedded Reader`,
+                       `error.*Comment on line with embedded error`,
                        `Has unexported methods`,
                },
                []string{
                        `type ExportedInterface interface`, // Interface definition.
                        `Comment before exported method.*\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.`,
+                       `unexportedMethod\(\).*Comment on line with unexported method`,
+                       `io.Reader.*Comment on line with embedded Reader`,
+                       `error.*Comment on line with embedded error`,
                },
                []string{
                        `Has unexported methods`,
                                `.*Comment on line with exported method`,
                },
                []string{
-                       `Comment about exported interface.`,
+                       `Comment about exported interface`,
                },
        },
 
                []string{p, `ExportedType.ExportedMethod`},
                []string{
                        `func \(ExportedType\) ExportedMethod\(a int\) bool`,
-                       `Comment about exported method.`,
+                       `Comment about exported method`,
                },
                nil,
        },
                []string{"-u", p, `ExportedType.unexportedMethod`},
                []string{
                        `func \(ExportedType\) unexportedMethod\(a int\) bool`,
-                       `Comment about unexported method.`,
+                       `Comment about unexported method`,
+               },
+               nil,
+       },
+       // Method with -src.
+       {
+               "method with -src",
+               []string{"-src", p, `ExportedType.ExportedMethod`},
+               []string{
+                       `func \(ExportedType\) ExportedMethod\(a int\) bool`,
+                       `Comment about exported method`,
+                       `return true != true`,
                },
                nil,
        },
                []string{
                        `type ExportedType struct`,
                        `ExportedField int`,
-                       `Comment before exported field.`,
-                       `Comment on line with exported field.`,
+                       `Comment before exported field`,
+                       `Comment on line with exported field`,
                        `other fields elided`,
                },
                nil,
                []string{"-u", p, `ExportedType.unexportedField`},
                []string{
                        `unexportedField int`,
-                       `Comment on line with unexported field.`,
+                       `Comment on line with unexported field`,
                },
                nil,
        },
 
        // from finding the symbol. Work around this for now, but we
        // should fix it in go/doc.
        // A similar story applies to factory functions.
-       docPkg := doc.New(astPkg, pkg.ImportPath, doc.AllDecls)
+       mode := doc.AllDecls
+       if showSrc {
+               mode |= doc.PreserveAST // See comment for Package.emit.
+       }
+       docPkg := doc.New(astPkg, pkg.ImportPath, mode)
        for _, typ := range docPkg.Types {
                docPkg.Consts = append(docPkg.Consts, typ.Consts...)
                docPkg.Vars = append(docPkg.Vars, typ.Vars...)
        }
 }
 
-// emit prints the node.
+// emit prints the node. If showSrc is true, it ignores the provided comment,
+// assuming the comment is in the node itself. Otherwise, the go/doc package
+// clears the stuff we don't want to print anyway. It's a bit of a magic trick.
 func (pkg *Package) emit(comment string, node ast.Node) {
        if node != nil {
                err := format.Node(&pkg.buf, pkg.fs, node)
                if err != nil {
                        log.Fatal(err)
                }
-               if comment != "" {
+               if comment != "" && !showSrc {
                        pkg.newlines(1)
                        doc.ToText(&pkg.buf, comment, "    ", indent, indentedWidth)
                        pkg.newlines(2) // Blank line after comment to separate from next item.
                }
                // Symbol is a function.
                decl := fun.Decl
-               decl.Body = nil
                pkg.emit(fun.Doc, decl)
                found = true
        }
                        }
 
                        for _, ident := range vspec.Names {
-                               if isExported(ident.Name) {
+                               if showSrc || isExported(ident.Name) {
                                        if vspec.Type == nil && vspec.Values == nil && typ != nil {
                                                // This a standalone identifier, as in the case of iota usage.
                                                // Thus, assume the type comes from the previous type.
 }
 
 // trimUnexportedElems modifies spec in place to elide unexported fields from
-// structs and methods from interfaces (unless the unexported flag is set).
+// structs and methods from interfaces (unless the unexported flag is set or we
+// are asked to show the original source).
 func trimUnexportedElems(spec *ast.TypeSpec) {
-       if unexported {
+       if unexported || showSrc {
                return
        }
        switch typ := spec.Type.(type) {
                        for _, meth := range typ.Methods {
                                if match(method, meth.Name) {
                                        decl := meth.Decl
-                                       decl.Body = nil
                                        pkg.emit(meth.Doc, decl)
                                        found = true
                                }