parsePackage turns the build package we found into a parsed package we can then use to generate documentation.
(writer io.Writer, pkg *build.Package, userPath string)
| 104 | // parsePackage turns the build package we found into a parsed package |
| 105 | // we can then use to generate documentation. |
| 106 | func parsePackage(writer io.Writer, pkg *build.Package, userPath string) *Package { |
| 107 | // include tells parser.ParseDir which files to include. |
| 108 | // That means the file must be in the build package's GoFiles or CgoFiles |
| 109 | // list only (no tag-ignored files, tests, swig or other non-Go files). |
| 110 | include := func(info fs.FileInfo) bool { |
| 111 | return slices.Contains(pkg.GoFiles, info.Name()) || slices.Contains(pkg.CgoFiles, info.Name()) |
| 112 | } |
| 113 | fset := token.NewFileSet() |
| 114 | // Parse declarations (not just imports) so that doc.Package knows the |
| 115 | // package's symbols; the Markdown printer needs this to resolve |
| 116 | // [Symbol] doc links in package comments. |
| 117 | pkgs, err := parser.ParseDir(fset, pkg.Dir, include, parser.ParseComments) |
| 118 | if err != nil { |
| 119 | log.Fatal(err) |
| 120 | } |
| 121 | // Make sure they are all in one package. |
| 122 | if len(pkgs) == 0 { |
| 123 | log.Fatalf("no source-code package in directory %s", pkg.Dir) |
| 124 | } |
| 125 | if len(pkgs) > 1 { |
| 126 | log.Fatalf("multiple packages in directory %s", pkg.Dir) |
| 127 | } |
| 128 | astPkg := pkgs[pkg.Name] |
| 129 | |
| 130 | // TODO: go/doc does not include typed constants in the constants |
| 131 | // list, which is what we want. For instance, time.Sunday is of type |
| 132 | // time.Weekday, so it is defined in the type but not in the |
| 133 | // Consts list for the package. This prevents |
| 134 | // go doc time.Sunday |
| 135 | // from finding the symbol. Work around this for now, but we |
| 136 | // should fix it in go/doc. |
| 137 | // A similar story applies to factory functions. |
| 138 | mode := doc.AllDecls |
| 139 | docPkg := doc.New(astPkg, pkg.ImportPath, mode) |
| 140 | |
| 141 | p := &Package{ |
| 142 | writer: writer, |
| 143 | name: pkg.Name, |
| 144 | userPath: userPath, |
| 145 | pkg: astPkg, |
| 146 | file: ast.MergePackageFiles(astPkg, 0), |
| 147 | doc: docPkg, |
| 148 | build: pkg, |
| 149 | fs: fset, |
| 150 | } |
| 151 | p.buf.pkg = p |
| 152 | return p |
| 153 | } |
| 154 | |
| 155 | func (pkg *Package) Printf(format string, args ...any) { |
| 156 | fmt.Fprintf(&pkg.buf, format, args...) |