)
type Package struct {
- writer io.Writer // Destination for output.
- name string // Package name, json for encoding/json.
- userPath string // String the user used to find this package.
- pkg *ast.Package // Parsed package.
- file *ast.File // Merged from all files in the package
- doc *doc.Package
- build *build.Package
- typedValue map[*doc.Value]bool // Consts and vars related to types.
- constructor map[*doc.Func]bool // Constructors.
- packageClausePrinted bool // Prevent repeated package clauses.
- fs *token.FileSet // Needed for printing.
- buf bytes.Buffer
+ writer io.Writer // Destination for output.
+ name string // Package name, json for encoding/json.
+ userPath string // String the user used to find this package.
+ pkg *ast.Package // Parsed package.
+ file *ast.File // Merged from all files in the package
+ doc *doc.Package
+ build *build.Package
+ typedValue map[*doc.Value]bool // Consts and vars related to types.
+ constructor map[*doc.Func]bool // Constructors.
+ fs *token.FileSet // Needed for printing.
+ buf pkgBuffer
+}
+
+// pkgBuffer is a wrapper for bytes.Buffer that prints a package clause the
+// first time Write is called.
+type pkgBuffer struct {
+ pkg *Package
+ printed bool // Prevent repeated package clauses.
+ bytes.Buffer
+}
+
+func (pb *pkgBuffer) Write(p []byte) (int, error) {
+ if !pb.printed && len(p) > 0 {
+ pb.printed = true
+ // Only show package clause for commands if requested explicitly.
+ if pb.pkg.pkg.Name != "main" || showCmd {
+ pb.pkg.packageClause()
+ }
+ }
+ return pb.Buffer.Write(p)
}
type PackageError string // type returned by pkg.Fatalf.
}
}
- return &Package{
+ p := &Package{
writer: writer,
name: pkg.Name,
userPath: userPath,
build: pkg,
fs: fs,
}
+ p.buf.pkg = p
+ return p
}
func (pkg *Package) Printf(format string, args ...interface{}) {
// allDoc prints all the docs for the package.
func (pkg *Package) allDoc() {
defer pkg.flush()
- if pkg.showInternals() {
- pkg.packageClause(false)
- }
doc.ToText(&pkg.buf, pkg.doc.Doc, "", indent, indentedWidth)
pkg.newlines(1)
// packageDoc prints the docs for the package (package doc plus one-liners of the rest).
func (pkg *Package) packageDoc() {
defer pkg.flush()
- if pkg.showInternals() {
- pkg.packageClause(false)
- }
doc.ToText(&pkg.buf, pkg.doc.Doc, "", indent, indentedWidth)
pkg.newlines(1)
- if !pkg.showInternals() {
+ if pkg.pkg.Name == "main" && !showCmd {
// Show only package docs for commands.
return
}
pkg.bugs()
}
-// showInternals reports whether we should show the internals
-// of a package as opposed to just the package docs.
-// Used to decide whether to suppress internals for commands.
-// Called only by Package.packageDoc.
-func (pkg *Package) showInternals() bool {
- return pkg.pkg.Name != "main" || showCmd
-}
-
// packageClause prints the package clause.
-// The argument boolean, if true, suppresses the output if the
-// user's argument is identical to the actual package path or
-// is empty, meaning it's the current directory.
-func (pkg *Package) packageClause(checkUserPath bool) {
- if pkg.packageClausePrinted {
- return
- }
-
- if checkUserPath {
- if pkg.userPath == "" || pkg.userPath == pkg.build.ImportPath {
- return
- }
- }
-
+func (pkg *Package) packageClause() {
importPath := pkg.build.ImportComment
if importPath == "" {
importPath = pkg.build.ImportPath
if !usingModules && importPath != pkg.build.ImportPath {
pkg.Printf("WARNING: package source is installed in %q\n", pkg.build.ImportPath)
}
- pkg.packageClausePrinted = true
}
// valueSummary prints a one-line summary for each set of values and constants.
found := false
// Functions.
for _, fun := range pkg.findFuncs(symbol) {
- if !found {
- pkg.packageClause(true)
- }
// Symbol is a function.
decl := fun.Decl
pkg.emit(fun.Doc, decl)