internal/godoc,fetch: move doc rendering to godoc package
Write a Render method in the godoc package that does all
doc rendering.
Modify the internal/fetch package to use it.
This required moving the dochtml and internal/doc packages under
internal/godoc.
It's redundant to have the set of module package paths in both
godoc.Package and dochtml.ModuleInfo, but we'll leave that
for now to keep the number of changes to a minimum.
The new Render method is effectively tested by TestFetchModule
in internal/fetch.
Change-Id: I655451386c55c883682eae4277d2d5b2d9c4fc3b
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/258423
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/internal/fetch/fetch_test.go b/internal/fetch/fetch_test.go
index afe50be..b7010c2 100644
--- a/internal/fetch/fetch_test.go
+++ b/internal/fetch/fetch_test.go
@@ -17,6 +17,7 @@
"github.com/google/go-cmp/cmp/cmpopts"
"golang.org/x/pkgsite/internal"
"golang.org/x/pkgsite/internal/derrors"
+ "golang.org/x/pkgsite/internal/godoc"
"golang.org/x/pkgsite/internal/proxy"
"golang.org/x/pkgsite/internal/source"
"golang.org/x/pkgsite/internal/stdlib"
@@ -40,8 +41,8 @@
}
defer func() { httpPost = origPost }()
- defer func(oldmax int) { MaxDocumentationHTML = oldmax }(MaxDocumentationHTML)
- MaxDocumentationHTML = 1 * megabyte
+ defer func(oldmax int) { godoc.MaxDocumentationHTML = oldmax }(godoc.MaxDocumentationHTML)
+ godoc.MaxDocumentationHTML = 1 * megabyte
for _, test := range []struct {
name string
diff --git a/internal/fetch/limit.go b/internal/fetch/limit.go
index 436862e..d929449 100644
--- a/internal/fetch/limit.go
+++ b/internal/fetch/limit.go
@@ -15,12 +15,4 @@
MaxFileSize = 30 * megabyte
)
-// MaxDocumentationHTML is a limit on the rendered documentation HTML size.
-//
-// The current limit of is based on the largest packages that
-// pkg.go.dev has encountered. See https://golang.org/issue/40576.
-//
-// It is a variable for testing.
-var MaxDocumentationHTML = 20 * megabyte
-
const megabyte = 1000 * 1000
diff --git a/internal/fetch/load.go b/internal/fetch/load.go
index 287c7fe..9c4f836 100644
--- a/internal/fetch/load.go
+++ b/internal/fetch/load.go
@@ -22,18 +22,13 @@
"os"
"path"
"runtime"
- "sort"
"strings"
- "github.com/google/safehtml"
- "github.com/google/safehtml/template"
"go.opencensus.io/trace"
"golang.org/x/pkgsite/internal"
"golang.org/x/pkgsite/internal/config"
"golang.org/x/pkgsite/internal/derrors"
"golang.org/x/pkgsite/internal/experiment"
- "golang.org/x/pkgsite/internal/fetch/dochtml"
- "golang.org/x/pkgsite/internal/fetch/internal/doc"
"golang.org/x/pkgsite/internal/godoc"
"golang.org/x/pkgsite/internal/log"
"golang.org/x/pkgsite/internal/source"
@@ -66,14 +61,14 @@
// loadPackage returns nil, nil.
//
// If the package is fine except that its documentation is too large, loadPackage
-// returns both a package and a non-nil error with dochtml.ErrTooLarge in its chain.
-func loadPackage(ctx context.Context, zipGoFiles []*zip.File, innerPath string, sourceInfo *source.Info, modInfo *dochtml.ModuleInfo) (_ *goPackage, err error) {
+// returns both a package and a non-nil error with godoc.ErrTooLarge in its chain.
+func loadPackage(ctx context.Context, zipGoFiles []*zip.File, innerPath string, sourceInfo *source.Info, modInfo *godoc.ModuleInfo) (_ *goPackage, err error) {
defer derrors.Wrap(&err, "loadPackage(ctx, zipGoFiles, %q, sourceInfo, modInfo)", innerPath)
ctx, span := trace.StartSpan(ctx, "fetch.loadPackage")
defer span.End()
for _, env := range goEnvs {
pkg, err := loadPackageWithBuildContext(ctx, env.GOOS, env.GOARCH, zipGoFiles, innerPath, sourceInfo, modInfo)
- if err != nil && !errors.Is(err, dochtml.ErrTooLarge) && !errors.Is(err, derrors.NotFound) {
+ if err != nil && !errors.Is(err, godoc.ErrTooLarge) && !errors.Is(err, derrors.NotFound) {
return nil, err
}
if pkg != nil {
@@ -103,7 +98,7 @@
// or all .go files have been excluded by constraints.
// A *BadPackageError error is returned if the directory
// contains .go files but do not make up a valid package.
-func loadPackageWithBuildContext(ctx context.Context, goos, goarch string, zipGoFiles []*zip.File, innerPath string, sourceInfo *source.Info, modInfo *dochtml.ModuleInfo) (_ *goPackage, err error) {
+func loadPackageWithBuildContext(ctx context.Context, goos, goarch string, zipGoFiles []*zip.File, innerPath string, sourceInfo *source.Info, modInfo *godoc.ModuleInfo) (_ *goPackage, err error) {
modulePath := modInfo.ModulePath
defer derrors.Wrap(&err, "loadPackageWithBuildContext(%q, %q, zipGoFiles, %q, %q, %+v)",
goos, goarch, innerPath, modulePath, sourceInfo)
@@ -113,25 +108,21 @@
return nil, err
}
docPkg := godoc.NewPackage(fset, modInfo.ModulePackages)
- var allGoFiles []*ast.File
for _, pf := range goFiles {
+ var removeNodes bool
if experiment.IsActive(ctx, internal.ExperimentRemoveUnusedAST) {
- removeNodes := true
+ removeNodes = true
// Don't strip the seemingly unexported functions from the builtin package;
// they are actually Go builtins like make, new, etc.
if !(modulePath == stdlib.ModulePath && innerPath == "builtin") {
removeNodes = false
}
- docPkg.AddFile(pf, removeNodes)
}
- allGoFiles = append(allGoFiles, pf)
+ docPkg.AddFile(pf, removeNodes)
}
- d, err := loadPackageWithFiles(modulePath, innerPath, packageName, allGoFiles, fset)
- if err != nil {
- return nil, err
- }
- docHTML, err := renderDocHTML(ctx, innerPath, d, fset, sourceInfo, modInfo)
- if err != nil && !errors.Is(err, dochtml.ErrTooLarge) {
+
+ synopsis, imports, docHTML, err := docPkg.Render(ctx, innerPath, sourceInfo, modInfo, goos, goarch)
+ if err != nil && !errors.Is(err, godoc.ErrTooLarge) {
return nil, err
}
var src []byte
@@ -149,9 +140,9 @@
return &goPackage{
path: importPath,
name: packageName,
- synopsis: doc.Synopsis(d.Doc),
+ synopsis: synopsis,
v1path: v1path,
- imports: d.Imports,
+ imports: imports,
documentationHTML: docHTML,
goos: goos,
goarch: goarch,
@@ -169,7 +160,6 @@
if err != nil {
return "", nil, nil, err
}
-
// Parse .go files and add them to the goFiles slice.
var (
fset = token.NewFileSet()
@@ -214,81 +204,6 @@
return packageName, goFiles, fset, nil
}
-func loadPackageWithFiles(modulePath, innerPath, packageName string, allGoFiles []*ast.File, fset *token.FileSet) (_ *doc.Package, err error) {
- defer derrors.Wrap(&err, "loadPackageWithFiles")
- // The "builtin" package in the standard library is a special case.
- // We want to show documentation for all globals (not just exported ones),
- // and avoid association of consts, vars, and factory functions with types
- // since it's not helpful (see golang.org/issue/6645).
- var noFiltering, noTypeAssociation bool
- if modulePath == stdlib.ModulePath && innerPath == "builtin" {
- noFiltering = true
- noTypeAssociation = true
- }
-
- // Compute package documentation.
- importPath := path.Join(modulePath, innerPath)
- var m doc.Mode
- if noFiltering {
- m |= doc.AllDecls
- }
- d, err := doc.NewFromFiles(fset, allGoFiles, importPath, m)
- if err != nil {
- return nil, fmt.Errorf("doc.NewFromFiles: %v", err)
- }
- if d.ImportPath != importPath || d.Name != packageName {
- panic(fmt.Errorf("internal error: *doc.Package has an unexpected import path (%q != %q) or package name (%q != %q)", d.ImportPath, importPath, d.Name, packageName))
- }
- if noTypeAssociation {
- for _, t := range d.Types {
- d.Consts, t.Consts = append(d.Consts, t.Consts...), nil
- d.Vars, t.Vars = append(d.Vars, t.Vars...), nil
- d.Funcs, t.Funcs = append(d.Funcs, t.Funcs...), nil
- }
- sort.Slice(d.Funcs, func(i, j int) bool { return d.Funcs[i].Name < d.Funcs[j].Name })
- }
-
- // Process package imports.
- if len(d.Imports) > maxImportsPerPackage {
- return nil, fmt.Errorf("%d imports found package %q; exceeds limit %d for maxImportsPerPackage", len(d.Imports), importPath, maxImportsPerPackage)
- }
- return d, nil
-}
-
-// renderDocHTML renders documentation HTML for a given package.
-func renderDocHTML(ctx context.Context, innerPath string, d *doc.Package, fset *token.FileSet, sourceInfo *source.Info, modInfo *dochtml.ModuleInfo) (_ safehtml.HTML, err error) {
- defer derrors.Wrap(&err, "renderDocHTML")
- sourceLinkFunc := func(n ast.Node) string {
- if sourceInfo == nil {
- return ""
- }
- p := fset.Position(n.Pos())
- if p.Line == 0 { // invalid Position
- return ""
- }
- return sourceInfo.LineURL(path.Join(innerPath, p.Filename), p.Line)
- }
- fileLinkFunc := func(filename string) string {
- if sourceInfo == nil {
- return ""
- }
- return sourceInfo.FileURL(path.Join(innerPath, filename))
- }
-
- docHTML, err := dochtml.Render(ctx, fset, d, dochtml.RenderOptions{
- FileLinkFunc: fileLinkFunc,
- SourceLinkFunc: sourceLinkFunc,
- ModInfo: modInfo,
- Limit: int64(MaxDocumentationHTML),
- })
- if errors.Is(err, dochtml.ErrTooLarge) {
- docHTML = template.MustParseAndExecuteToHTML(docTooLargeReplacement)
- } else if err != nil {
- return safehtml.HTML{}, err
- }
- return docHTML, err
-}
-
// matchingFiles returns a map from file names to their contents, read from zipGoFiles.
// It includes only those files that match the build context determined by goos and goarch.
func matchingFiles(goos, goarch string, zipGoFiles []*zip.File) (files map[string][]byte, err error) {
diff --git a/internal/fetch/package.go b/internal/fetch/package.go
index cefd898..6645c10 100644
--- a/internal/fetch/package.go
+++ b/internal/fetch/package.go
@@ -20,7 +20,7 @@
"golang.org/x/mod/module"
"golang.org/x/pkgsite/internal"
"golang.org/x/pkgsite/internal/derrors"
- "golang.org/x/pkgsite/internal/fetch/dochtml"
+ "golang.org/x/pkgsite/internal/godoc"
"golang.org/x/pkgsite/internal/licenses"
"golang.org/x/pkgsite/internal/log"
"golang.org/x/pkgsite/internal/source"
@@ -94,7 +94,7 @@
// modInfo contains all the module information a package in the module
// needs to render its documentation, to be populated during phase 1
// and used during phase 2.
- modInfo = &dochtml.ModuleInfo{
+ modInfo = &godoc.ModuleInfo{
ModulePath: modulePath,
ResolvedVersion: resolvedVersion,
ModulePackages: make(map[string]bool),
@@ -199,7 +199,7 @@
incompleteDirs[innerPath] = true
status = derrors.PackageInvalidContents
errMsg = err.Error()
- } else if errors.Is(err, dochtml.ErrTooLarge) {
+ } else if errors.Is(err, godoc.ErrTooLarge) {
status = derrors.PackageDocumentationHTMLTooLarge
errMsg = err.Error()
} else if err != nil {
diff --git a/internal/fetch/dochtml/dochtml.go b/internal/godoc/dochtml/dochtml.go
similarity index 98%
rename from internal/fetch/dochtml/dochtml.go
rename to internal/godoc/dochtml/dochtml.go
index 3239ef6..c268abd 100644
--- a/internal/fetch/dochtml/dochtml.go
+++ b/internal/godoc/dochtml/dochtml.go
@@ -27,8 +27,8 @@
"github.com/google/safehtml/template"
"github.com/google/safehtml/uncheckedconversions"
"golang.org/x/pkgsite/internal/derrors"
- "golang.org/x/pkgsite/internal/fetch/dochtml/internal/render"
- "golang.org/x/pkgsite/internal/fetch/internal/doc"
+ "golang.org/x/pkgsite/internal/godoc/dochtml/internal/render"
+ "golang.org/x/pkgsite/internal/godoc/internal/doc"
)
var (
diff --git a/internal/fetch/dochtml/dochtml_test.go b/internal/godoc/dochtml/dochtml_test.go
similarity index 99%
rename from internal/fetch/dochtml/dochtml_test.go
rename to internal/godoc/dochtml/dochtml_test.go
index 1b9baa5..c465371 100644
--- a/internal/fetch/dochtml/dochtml_test.go
+++ b/internal/godoc/dochtml/dochtml_test.go
@@ -18,7 +18,7 @@
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"golang.org/x/net/html"
- "golang.org/x/pkgsite/internal/fetch/internal/doc"
+ "golang.org/x/pkgsite/internal/godoc/internal/doc"
"golang.org/x/pkgsite/internal/testing/htmlcheck"
)
diff --git a/internal/fetch/dochtml/internal/render/idents.go b/internal/godoc/dochtml/internal/render/idents.go
similarity index 99%
rename from internal/fetch/dochtml/internal/render/idents.go
rename to internal/godoc/dochtml/internal/render/idents.go
index 63e176d..b7911f1 100644
--- a/internal/fetch/dochtml/internal/render/idents.go
+++ b/internal/godoc/dochtml/internal/render/idents.go
@@ -13,7 +13,7 @@
"github.com/google/safehtml"
"github.com/google/safehtml/template"
- "golang.org/x/pkgsite/internal/fetch/internal/doc"
+ "golang.org/x/pkgsite/internal/godoc/internal/doc"
)
/*
diff --git a/internal/fetch/dochtml/internal/render/idents_test.go b/internal/godoc/dochtml/internal/render/idents_test.go
similarity index 98%
rename from internal/fetch/dochtml/internal/render/idents_test.go
rename to internal/godoc/dochtml/internal/render/idents_test.go
index 926df21..f89d464 100644
--- a/internal/fetch/dochtml/internal/render/idents_test.go
+++ b/internal/godoc/dochtml/internal/render/idents_test.go
@@ -8,7 +8,7 @@
"go/ast"
"testing"
- "golang.org/x/pkgsite/internal/fetch/internal/doc"
+ "golang.org/x/pkgsite/internal/godoc/internal/doc"
)
func TestResolveIdentifier(t *testing.T) {
diff --git a/internal/fetch/dochtml/internal/render/linkify.go b/internal/godoc/dochtml/internal/render/linkify.go
similarity index 99%
rename from internal/fetch/dochtml/internal/render/linkify.go
rename to internal/godoc/dochtml/internal/render/linkify.go
index b404678..34d9604 100644
--- a/internal/fetch/dochtml/internal/render/linkify.go
+++ b/internal/godoc/dochtml/internal/render/linkify.go
@@ -21,7 +21,7 @@
"github.com/google/safehtml"
"github.com/google/safehtml/legacyconversions"
safetemplate "github.com/google/safehtml/template"
- "golang.org/x/pkgsite/internal/fetch/internal/doc"
+ "golang.org/x/pkgsite/internal/godoc/internal/doc"
"golang.org/x/pkgsite/internal/log"
)
diff --git a/internal/fetch/dochtml/internal/render/linkify_test.go b/internal/godoc/dochtml/internal/render/linkify_test.go
similarity index 99%
rename from internal/fetch/dochtml/internal/render/linkify_test.go
rename to internal/godoc/dochtml/internal/render/linkify_test.go
index 728e662..563743a 100644
--- a/internal/fetch/dochtml/internal/render/linkify_test.go
+++ b/internal/godoc/dochtml/internal/render/linkify_test.go
@@ -15,7 +15,7 @@
"github.com/google/go-cmp/cmp"
"github.com/google/safehtml"
"github.com/google/safehtml/testconversions"
- "golang.org/x/pkgsite/internal/fetch/internal/doc"
+ "golang.org/x/pkgsite/internal/godoc/internal/doc"
)
func TestDocHTML(t *testing.T) {
diff --git a/internal/fetch/dochtml/internal/render/render.go b/internal/godoc/dochtml/internal/render/render.go
similarity index 99%
rename from internal/fetch/dochtml/internal/render/render.go
rename to internal/godoc/dochtml/internal/render/render.go
index 232df05..382cd49 100644
--- a/internal/fetch/dochtml/internal/render/render.go
+++ b/internal/godoc/dochtml/internal/render/render.go
@@ -14,7 +14,7 @@
"strings"
"github.com/google/safehtml"
- "golang.org/x/pkgsite/internal/fetch/internal/doc"
+ "golang.org/x/pkgsite/internal/godoc/internal/doc"
)
var (
diff --git a/internal/fetch/dochtml/internal/render/render_test.go b/internal/godoc/dochtml/internal/render/render_test.go
similarity index 98%
rename from internal/fetch/dochtml/internal/render/render_test.go
rename to internal/godoc/dochtml/internal/render/render_test.go
index 410fbac..b2e1517 100644
--- a/internal/fetch/dochtml/internal/render/render_test.go
+++ b/internal/godoc/dochtml/internal/render/render_test.go
@@ -14,7 +14,7 @@
"strings"
"testing"
- "golang.org/x/pkgsite/internal/fetch/internal/doc"
+ "golang.org/x/pkgsite/internal/godoc/internal/doc"
)
var (
diff --git a/internal/fetch/dochtml/internal/render/short_synopsis.go b/internal/godoc/dochtml/internal/render/short_synopsis.go
similarity index 100%
rename from internal/fetch/dochtml/internal/render/short_synopsis.go
rename to internal/godoc/dochtml/internal/render/short_synopsis.go
diff --git a/internal/fetch/dochtml/internal/render/short_synopsis_test.go b/internal/godoc/dochtml/internal/render/short_synopsis_test.go
similarity index 100%
rename from internal/fetch/dochtml/internal/render/short_synopsis_test.go
rename to internal/godoc/dochtml/internal/render/short_synopsis_test.go
diff --git a/internal/fetch/dochtml/internal/render/synopsis.go b/internal/godoc/dochtml/internal/render/synopsis.go
similarity index 100%
rename from internal/fetch/dochtml/internal/render/synopsis.go
rename to internal/godoc/dochtml/internal/render/synopsis.go
diff --git a/internal/fetch/dochtml/internal/render/synopsis_test.go b/internal/godoc/dochtml/internal/render/synopsis_test.go
similarity index 100%
rename from internal/fetch/dochtml/internal/render/synopsis_test.go
rename to internal/godoc/dochtml/internal/render/synopsis_test.go
diff --git a/internal/fetch/dochtml/internal/render/testdata/io.go b/internal/godoc/dochtml/internal/render/testdata/io.go
similarity index 100%
rename from internal/fetch/dochtml/internal/render/testdata/io.go
rename to internal/godoc/dochtml/internal/render/testdata/io.go
diff --git a/internal/fetch/dochtml/internal/render/testdata/os.go b/internal/godoc/dochtml/internal/render/testdata/os.go
similarity index 100%
rename from internal/fetch/dochtml/internal/render/testdata/os.go
rename to internal/godoc/dochtml/internal/render/testdata/os.go
diff --git a/internal/fetch/dochtml/internal/render/testdata/tar.go b/internal/godoc/dochtml/internal/render/testdata/tar.go
similarity index 100%
rename from internal/fetch/dochtml/internal/render/testdata/tar.go
rename to internal/godoc/dochtml/internal/render/testdata/tar.go
diff --git a/internal/fetch/dochtml/internal/render/testdata/time.go b/internal/godoc/dochtml/internal/render/testdata/time.go
similarity index 100%
rename from internal/fetch/dochtml/internal/render/testdata/time.go
rename to internal/godoc/dochtml/internal/render/testdata/time.go
diff --git a/internal/fetch/dochtml/io.go b/internal/godoc/dochtml/io.go
similarity index 100%
rename from internal/fetch/dochtml/io.go
rename to internal/godoc/dochtml/io.go
diff --git a/internal/fetch/dochtml/template.go b/internal/godoc/dochtml/template.go
similarity index 92%
rename from internal/fetch/dochtml/template.go
rename to internal/godoc/dochtml/template.go
index a6f9dc6..d10974e 100644
--- a/internal/fetch/dochtml/template.go
+++ b/internal/godoc/dochtml/template.go
@@ -8,8 +8,8 @@
"reflect"
"github.com/google/safehtml/template"
- "golang.org/x/pkgsite/internal/fetch/dochtml/internal/render"
- "golang.org/x/pkgsite/internal/fetch/internal/doc"
+ "golang.org/x/pkgsite/internal/godoc/dochtml/internal/render"
+ "golang.org/x/pkgsite/internal/godoc/internal/doc"
)
// htmlPackage is the template used to render documentation HTML.
diff --git a/internal/fetch/dochtml/template_body.go b/internal/godoc/dochtml/template_body.go
similarity index 100%
rename from internal/fetch/dochtml/template_body.go
rename to internal/godoc/dochtml/template_body.go
diff --git a/internal/fetch/dochtml/template_sidenav.go b/internal/godoc/dochtml/template_sidenav.go
similarity index 100%
rename from internal/fetch/dochtml/template_sidenav.go
rename to internal/godoc/dochtml/template_sidenav.go
diff --git a/internal/fetch/dochtml/template_test.go b/internal/godoc/dochtml/template_test.go
similarity index 100%
rename from internal/fetch/dochtml/template_test.go
rename to internal/godoc/dochtml/template_test.go
diff --git a/internal/fetch/dochtml/testdata/everydecl.go b/internal/godoc/dochtml/testdata/everydecl.go
similarity index 100%
rename from internal/fetch/dochtml/testdata/everydecl.go
rename to internal/godoc/dochtml/testdata/everydecl.go
diff --git a/internal/fetch/dochtml/testdata/example_test.go b/internal/godoc/dochtml/testdata/example_test.go
similarity index 100%
rename from internal/fetch/dochtml/testdata/example_test.go
rename to internal/godoc/dochtml/testdata/example_test.go
diff --git a/internal/godoc/encode.go b/internal/godoc/encode.go
index 2bd4315..93f4445 100644
--- a/internal/godoc/encode.go
+++ b/internal/godoc/encode.go
@@ -132,7 +132,7 @@
ast.Inspect(f, func(n ast.Node) bool {
switch n := n.(type) {
case *ast.File:
- n.Scope = nil // doc doesn't use scopes
+ n.Scope.Objects = nil // doc doesn't use scopes
case *ast.Ident:
if n.Obj != nil {
if _, ok := n.Obj.Decl.(int); !ok {
diff --git a/internal/godoc/godoc.go b/internal/godoc/godoc.go
index 6b62d76..cf6579a 100644
--- a/internal/godoc/godoc.go
+++ b/internal/godoc/godoc.go
@@ -8,8 +8,14 @@
import (
"go/ast"
"go/token"
+
+ "golang.org/x/pkgsite/internal/godoc/dochtml"
)
+var ErrTooLarge = dochtml.ErrTooLarge
+
+type ModuleInfo = dochtml.ModuleInfo
+
// A package contains everything needed to render Go documentation for a package.
type Package struct {
Fset *token.FileSet
diff --git a/internal/fetch/internal/doc/doc.go b/internal/godoc/internal/doc/doc.go
similarity index 100%
rename from internal/fetch/internal/doc/doc.go
rename to internal/godoc/internal/doc/doc.go
diff --git a/internal/fetch/internal/doc/doc_test.go b/internal/godoc/internal/doc/doc_test.go
similarity index 100%
rename from internal/fetch/internal/doc/doc_test.go
rename to internal/godoc/internal/doc/doc_test.go
diff --git a/internal/fetch/internal/doc/example.go b/internal/godoc/internal/doc/example.go
similarity index 100%
rename from internal/fetch/internal/doc/example.go
rename to internal/godoc/internal/doc/example.go
diff --git a/internal/fetch/internal/doc/example_test.go b/internal/godoc/internal/doc/example_test.go
similarity index 99%
rename from internal/fetch/internal/doc/example_test.go
rename to internal/godoc/internal/doc/example_test.go
index 8f3dcef..657e62e 100644
--- a/internal/fetch/internal/doc/example_test.go
+++ b/internal/godoc/internal/doc/example_test.go
@@ -15,7 +15,7 @@
"strings"
"testing"
- "golang.org/x/pkgsite/internal/fetch/internal/doc"
+ "golang.org/x/pkgsite/internal/godoc/internal/doc"
)
const exampleTestFile = `
diff --git a/internal/fetch/internal/doc/exports.go b/internal/godoc/internal/doc/exports.go
similarity index 100%
rename from internal/fetch/internal/doc/exports.go
rename to internal/godoc/internal/doc/exports.go
diff --git a/internal/fetch/internal/doc/filter.go b/internal/godoc/internal/doc/filter.go
similarity index 100%
rename from internal/fetch/internal/doc/filter.go
rename to internal/godoc/internal/doc/filter.go
diff --git a/internal/fetch/internal/doc/reader.go b/internal/godoc/internal/doc/reader.go
similarity index 100%
rename from internal/fetch/internal/doc/reader.go
rename to internal/godoc/internal/doc/reader.go
diff --git a/internal/fetch/internal/doc/synopsis.go b/internal/godoc/internal/doc/synopsis.go
similarity index 100%
rename from internal/fetch/internal/doc/synopsis.go
rename to internal/godoc/internal/doc/synopsis.go
diff --git a/internal/fetch/internal/doc/synopsis_test.go b/internal/godoc/internal/doc/synopsis_test.go
similarity index 100%
rename from internal/fetch/internal/doc/synopsis_test.go
rename to internal/godoc/internal/doc/synopsis_test.go
diff --git a/internal/fetch/internal/doc/testdata/a.0.golden b/internal/godoc/internal/doc/testdata/a.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/a.0.golden
rename to internal/godoc/internal/doc/testdata/a.0.golden
diff --git a/internal/fetch/internal/doc/testdata/a.1.golden b/internal/godoc/internal/doc/testdata/a.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/a.1.golden
rename to internal/godoc/internal/doc/testdata/a.1.golden
diff --git a/internal/fetch/internal/doc/testdata/a.2.golden b/internal/godoc/internal/doc/testdata/a.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/a.2.golden
rename to internal/godoc/internal/doc/testdata/a.2.golden
diff --git a/internal/fetch/internal/doc/testdata/a0.go b/internal/godoc/internal/doc/testdata/a0.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/a0.go
rename to internal/godoc/internal/doc/testdata/a0.go
diff --git a/internal/fetch/internal/doc/testdata/a1.go b/internal/godoc/internal/doc/testdata/a1.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/a1.go
rename to internal/godoc/internal/doc/testdata/a1.go
diff --git a/internal/fetch/internal/doc/testdata/b.0.golden b/internal/godoc/internal/doc/testdata/b.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/b.0.golden
rename to internal/godoc/internal/doc/testdata/b.0.golden
diff --git a/internal/fetch/internal/doc/testdata/b.1.golden b/internal/godoc/internal/doc/testdata/b.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/b.1.golden
rename to internal/godoc/internal/doc/testdata/b.1.golden
diff --git a/internal/fetch/internal/doc/testdata/b.2.golden b/internal/godoc/internal/doc/testdata/b.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/b.2.golden
rename to internal/godoc/internal/doc/testdata/b.2.golden
diff --git a/internal/fetch/internal/doc/testdata/b.go b/internal/godoc/internal/doc/testdata/b.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/b.go
rename to internal/godoc/internal/doc/testdata/b.go
diff --git a/internal/fetch/internal/doc/testdata/benchmark.go b/internal/godoc/internal/doc/testdata/benchmark.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/benchmark.go
rename to internal/godoc/internal/doc/testdata/benchmark.go
diff --git a/internal/fetch/internal/doc/testdata/blank.0.golden b/internal/godoc/internal/doc/testdata/blank.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/blank.0.golden
rename to internal/godoc/internal/doc/testdata/blank.0.golden
diff --git a/internal/fetch/internal/doc/testdata/blank.1.golden b/internal/godoc/internal/doc/testdata/blank.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/blank.1.golden
rename to internal/godoc/internal/doc/testdata/blank.1.golden
diff --git a/internal/fetch/internal/doc/testdata/blank.2.golden b/internal/godoc/internal/doc/testdata/blank.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/blank.2.golden
rename to internal/godoc/internal/doc/testdata/blank.2.golden
diff --git a/internal/fetch/internal/doc/testdata/blank.go b/internal/godoc/internal/doc/testdata/blank.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/blank.go
rename to internal/godoc/internal/doc/testdata/blank.go
diff --git a/internal/fetch/internal/doc/testdata/bugpara.0.golden b/internal/godoc/internal/doc/testdata/bugpara.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/bugpara.0.golden
rename to internal/godoc/internal/doc/testdata/bugpara.0.golden
diff --git a/internal/fetch/internal/doc/testdata/bugpara.1.golden b/internal/godoc/internal/doc/testdata/bugpara.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/bugpara.1.golden
rename to internal/godoc/internal/doc/testdata/bugpara.1.golden
diff --git a/internal/fetch/internal/doc/testdata/bugpara.2.golden b/internal/godoc/internal/doc/testdata/bugpara.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/bugpara.2.golden
rename to internal/godoc/internal/doc/testdata/bugpara.2.golden
diff --git a/internal/fetch/internal/doc/testdata/bugpara.go b/internal/godoc/internal/doc/testdata/bugpara.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/bugpara.go
rename to internal/godoc/internal/doc/testdata/bugpara.go
diff --git a/internal/fetch/internal/doc/testdata/c.0.golden b/internal/godoc/internal/doc/testdata/c.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/c.0.golden
rename to internal/godoc/internal/doc/testdata/c.0.golden
diff --git a/internal/fetch/internal/doc/testdata/c.1.golden b/internal/godoc/internal/doc/testdata/c.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/c.1.golden
rename to internal/godoc/internal/doc/testdata/c.1.golden
diff --git a/internal/fetch/internal/doc/testdata/c.2.golden b/internal/godoc/internal/doc/testdata/c.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/c.2.golden
rename to internal/godoc/internal/doc/testdata/c.2.golden
diff --git a/internal/fetch/internal/doc/testdata/c.go b/internal/godoc/internal/doc/testdata/c.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/c.go
rename to internal/godoc/internal/doc/testdata/c.go
diff --git a/internal/fetch/internal/doc/testdata/d.0.golden b/internal/godoc/internal/doc/testdata/d.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/d.0.golden
rename to internal/godoc/internal/doc/testdata/d.0.golden
diff --git a/internal/fetch/internal/doc/testdata/d.1.golden b/internal/godoc/internal/doc/testdata/d.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/d.1.golden
rename to internal/godoc/internal/doc/testdata/d.1.golden
diff --git a/internal/fetch/internal/doc/testdata/d.2.golden b/internal/godoc/internal/doc/testdata/d.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/d.2.golden
rename to internal/godoc/internal/doc/testdata/d.2.golden
diff --git a/internal/fetch/internal/doc/testdata/d1.go b/internal/godoc/internal/doc/testdata/d1.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/d1.go
rename to internal/godoc/internal/doc/testdata/d1.go
diff --git a/internal/fetch/internal/doc/testdata/d2.go b/internal/godoc/internal/doc/testdata/d2.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/d2.go
rename to internal/godoc/internal/doc/testdata/d2.go
diff --git a/internal/fetch/internal/doc/testdata/e.0.golden b/internal/godoc/internal/doc/testdata/e.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/e.0.golden
rename to internal/godoc/internal/doc/testdata/e.0.golden
diff --git a/internal/fetch/internal/doc/testdata/e.1.golden b/internal/godoc/internal/doc/testdata/e.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/e.1.golden
rename to internal/godoc/internal/doc/testdata/e.1.golden
diff --git a/internal/fetch/internal/doc/testdata/e.2.golden b/internal/godoc/internal/doc/testdata/e.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/e.2.golden
rename to internal/godoc/internal/doc/testdata/e.2.golden
diff --git a/internal/fetch/internal/doc/testdata/e.go b/internal/godoc/internal/doc/testdata/e.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/e.go
rename to internal/godoc/internal/doc/testdata/e.go
diff --git a/internal/fetch/internal/doc/testdata/error1.0.golden b/internal/godoc/internal/doc/testdata/error1.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/error1.0.golden
rename to internal/godoc/internal/doc/testdata/error1.0.golden
diff --git a/internal/fetch/internal/doc/testdata/error1.1.golden b/internal/godoc/internal/doc/testdata/error1.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/error1.1.golden
rename to internal/godoc/internal/doc/testdata/error1.1.golden
diff --git a/internal/fetch/internal/doc/testdata/error1.2.golden b/internal/godoc/internal/doc/testdata/error1.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/error1.2.golden
rename to internal/godoc/internal/doc/testdata/error1.2.golden
diff --git a/internal/fetch/internal/doc/testdata/error1.go b/internal/godoc/internal/doc/testdata/error1.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/error1.go
rename to internal/godoc/internal/doc/testdata/error1.go
diff --git a/internal/fetch/internal/doc/testdata/error2.0.golden b/internal/godoc/internal/doc/testdata/error2.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/error2.0.golden
rename to internal/godoc/internal/doc/testdata/error2.0.golden
diff --git a/internal/fetch/internal/doc/testdata/error2.1.golden b/internal/godoc/internal/doc/testdata/error2.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/error2.1.golden
rename to internal/godoc/internal/doc/testdata/error2.1.golden
diff --git a/internal/fetch/internal/doc/testdata/error2.2.golden b/internal/godoc/internal/doc/testdata/error2.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/error2.2.golden
rename to internal/godoc/internal/doc/testdata/error2.2.golden
diff --git a/internal/fetch/internal/doc/testdata/error2.go b/internal/godoc/internal/doc/testdata/error2.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/error2.go
rename to internal/godoc/internal/doc/testdata/error2.go
diff --git a/internal/fetch/internal/doc/testdata/example.go b/internal/godoc/internal/doc/testdata/example.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/example.go
rename to internal/godoc/internal/doc/testdata/example.go
diff --git a/internal/fetch/internal/doc/testdata/f.0.golden b/internal/godoc/internal/doc/testdata/f.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/f.0.golden
rename to internal/godoc/internal/doc/testdata/f.0.golden
diff --git a/internal/fetch/internal/doc/testdata/f.1.golden b/internal/godoc/internal/doc/testdata/f.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/f.1.golden
rename to internal/godoc/internal/doc/testdata/f.1.golden
diff --git a/internal/fetch/internal/doc/testdata/f.2.golden b/internal/godoc/internal/doc/testdata/f.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/f.2.golden
rename to internal/godoc/internal/doc/testdata/f.2.golden
diff --git a/internal/fetch/internal/doc/testdata/f.go b/internal/godoc/internal/doc/testdata/f.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/f.go
rename to internal/godoc/internal/doc/testdata/f.go
diff --git a/internal/fetch/internal/doc/testdata/g.0.golden b/internal/godoc/internal/doc/testdata/g.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/g.0.golden
rename to internal/godoc/internal/doc/testdata/g.0.golden
diff --git a/internal/fetch/internal/doc/testdata/g.1.golden b/internal/godoc/internal/doc/testdata/g.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/g.1.golden
rename to internal/godoc/internal/doc/testdata/g.1.golden
diff --git a/internal/fetch/internal/doc/testdata/g.2.golden b/internal/godoc/internal/doc/testdata/g.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/g.2.golden
rename to internal/godoc/internal/doc/testdata/g.2.golden
diff --git a/internal/fetch/internal/doc/testdata/g.go b/internal/godoc/internal/doc/testdata/g.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/g.go
rename to internal/godoc/internal/doc/testdata/g.go
diff --git a/internal/fetch/internal/doc/testdata/issue12839.0.golden b/internal/godoc/internal/doc/testdata/issue12839.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue12839.0.golden
rename to internal/godoc/internal/doc/testdata/issue12839.0.golden
diff --git a/internal/fetch/internal/doc/testdata/issue12839.1.golden b/internal/godoc/internal/doc/testdata/issue12839.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue12839.1.golden
rename to internal/godoc/internal/doc/testdata/issue12839.1.golden
diff --git a/internal/fetch/internal/doc/testdata/issue12839.2.golden b/internal/godoc/internal/doc/testdata/issue12839.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue12839.2.golden
rename to internal/godoc/internal/doc/testdata/issue12839.2.golden
diff --git a/internal/fetch/internal/doc/testdata/issue12839.go b/internal/godoc/internal/doc/testdata/issue12839.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue12839.go
rename to internal/godoc/internal/doc/testdata/issue12839.go
diff --git a/internal/fetch/internal/doc/testdata/issue13742.0.golden b/internal/godoc/internal/doc/testdata/issue13742.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue13742.0.golden
rename to internal/godoc/internal/doc/testdata/issue13742.0.golden
diff --git a/internal/fetch/internal/doc/testdata/issue13742.1.golden b/internal/godoc/internal/doc/testdata/issue13742.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue13742.1.golden
rename to internal/godoc/internal/doc/testdata/issue13742.1.golden
diff --git a/internal/fetch/internal/doc/testdata/issue13742.2.golden b/internal/godoc/internal/doc/testdata/issue13742.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue13742.2.golden
rename to internal/godoc/internal/doc/testdata/issue13742.2.golden
diff --git a/internal/fetch/internal/doc/testdata/issue13742.go b/internal/godoc/internal/doc/testdata/issue13742.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue13742.go
rename to internal/godoc/internal/doc/testdata/issue13742.go
diff --git a/internal/fetch/internal/doc/testdata/issue16153.0.golden b/internal/godoc/internal/doc/testdata/issue16153.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue16153.0.golden
rename to internal/godoc/internal/doc/testdata/issue16153.0.golden
diff --git a/internal/fetch/internal/doc/testdata/issue16153.1.golden b/internal/godoc/internal/doc/testdata/issue16153.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue16153.1.golden
rename to internal/godoc/internal/doc/testdata/issue16153.1.golden
diff --git a/internal/fetch/internal/doc/testdata/issue16153.2.golden b/internal/godoc/internal/doc/testdata/issue16153.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue16153.2.golden
rename to internal/godoc/internal/doc/testdata/issue16153.2.golden
diff --git a/internal/fetch/internal/doc/testdata/issue16153.go b/internal/godoc/internal/doc/testdata/issue16153.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue16153.go
rename to internal/godoc/internal/doc/testdata/issue16153.go
diff --git a/internal/fetch/internal/doc/testdata/issue17788.0.golden b/internal/godoc/internal/doc/testdata/issue17788.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue17788.0.golden
rename to internal/godoc/internal/doc/testdata/issue17788.0.golden
diff --git a/internal/fetch/internal/doc/testdata/issue17788.1.golden b/internal/godoc/internal/doc/testdata/issue17788.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue17788.1.golden
rename to internal/godoc/internal/doc/testdata/issue17788.1.golden
diff --git a/internal/fetch/internal/doc/testdata/issue17788.2.golden b/internal/godoc/internal/doc/testdata/issue17788.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue17788.2.golden
rename to internal/godoc/internal/doc/testdata/issue17788.2.golden
diff --git a/internal/fetch/internal/doc/testdata/issue17788.go b/internal/godoc/internal/doc/testdata/issue17788.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue17788.go
rename to internal/godoc/internal/doc/testdata/issue17788.go
diff --git a/internal/fetch/internal/doc/testdata/issue22856.0.golden b/internal/godoc/internal/doc/testdata/issue22856.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue22856.0.golden
rename to internal/godoc/internal/doc/testdata/issue22856.0.golden
diff --git a/internal/fetch/internal/doc/testdata/issue22856.1.golden b/internal/godoc/internal/doc/testdata/issue22856.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue22856.1.golden
rename to internal/godoc/internal/doc/testdata/issue22856.1.golden
diff --git a/internal/fetch/internal/doc/testdata/issue22856.2.golden b/internal/godoc/internal/doc/testdata/issue22856.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue22856.2.golden
rename to internal/godoc/internal/doc/testdata/issue22856.2.golden
diff --git a/internal/fetch/internal/doc/testdata/issue22856.go b/internal/godoc/internal/doc/testdata/issue22856.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/issue22856.go
rename to internal/godoc/internal/doc/testdata/issue22856.go
diff --git a/internal/fetch/internal/doc/testdata/predeclared.0.golden b/internal/godoc/internal/doc/testdata/predeclared.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/predeclared.0.golden
rename to internal/godoc/internal/doc/testdata/predeclared.0.golden
diff --git a/internal/fetch/internal/doc/testdata/predeclared.1.golden b/internal/godoc/internal/doc/testdata/predeclared.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/predeclared.1.golden
rename to internal/godoc/internal/doc/testdata/predeclared.1.golden
diff --git a/internal/fetch/internal/doc/testdata/predeclared.2.golden b/internal/godoc/internal/doc/testdata/predeclared.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/predeclared.2.golden
rename to internal/godoc/internal/doc/testdata/predeclared.2.golden
diff --git a/internal/fetch/internal/doc/testdata/predeclared.go b/internal/godoc/internal/doc/testdata/predeclared.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/predeclared.go
rename to internal/godoc/internal/doc/testdata/predeclared.go
diff --git a/internal/fetch/internal/doc/testdata/template.txt b/internal/godoc/internal/doc/testdata/template.txt
similarity index 100%
rename from internal/fetch/internal/doc/testdata/template.txt
rename to internal/godoc/internal/doc/testdata/template.txt
diff --git a/internal/fetch/internal/doc/testdata/testing.0.golden b/internal/godoc/internal/doc/testdata/testing.0.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/testing.0.golden
rename to internal/godoc/internal/doc/testdata/testing.0.golden
diff --git a/internal/fetch/internal/doc/testdata/testing.1.golden b/internal/godoc/internal/doc/testdata/testing.1.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/testing.1.golden
rename to internal/godoc/internal/doc/testdata/testing.1.golden
diff --git a/internal/fetch/internal/doc/testdata/testing.2.golden b/internal/godoc/internal/doc/testdata/testing.2.golden
similarity index 100%
rename from internal/fetch/internal/doc/testdata/testing.2.golden
rename to internal/godoc/internal/doc/testdata/testing.2.golden
diff --git a/internal/fetch/internal/doc/testdata/testing.go b/internal/godoc/internal/doc/testdata/testing.go
similarity index 100%
rename from internal/fetch/internal/doc/testdata/testing.go
rename to internal/godoc/internal/doc/testdata/testing.go
diff --git a/internal/godoc/parse.go b/internal/godoc/parse.go
index 4e64b02..12d441f 100644
--- a/internal/godoc/parse.go
+++ b/internal/godoc/parse.go
@@ -15,7 +15,7 @@
"github.com/google/safehtml"
"github.com/google/safehtml/uncheckedconversions"
"golang.org/x/pkgsite/internal/derrors"
- "golang.org/x/pkgsite/internal/fetch/dochtml"
+ "golang.org/x/pkgsite/internal/godoc/dochtml"
)
// SectionType is a section of the docHTML.
diff --git a/internal/godoc/render.go b/internal/godoc/render.go
new file mode 100644
index 0000000..dc48c56
--- /dev/null
+++ b/internal/godoc/render.go
@@ -0,0 +1,117 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package godoc
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "go/ast"
+ "path"
+ "sort"
+
+ "github.com/google/safehtml"
+ "github.com/google/safehtml/template"
+ "golang.org/x/pkgsite/internal/derrors"
+ "golang.org/x/pkgsite/internal/godoc/dochtml"
+ "golang.org/x/pkgsite/internal/godoc/internal/doc"
+ "golang.org/x/pkgsite/internal/source"
+ "golang.org/x/pkgsite/internal/stdlib"
+)
+
+const (
+ megabyte = 1000 * 1000
+ maxImportsPerPackage = 1000
+ docTooLargeReplacement = `<p>Documentation is too large to display.</p>`
+)
+
+// MaxDocumentationHTML is a limit on the rendered documentation HTML size.
+//
+// The current limit of is based on the largest packages that
+// pkg.go.dev has encountered. See https://golang.org/issue/40576.
+//
+// It is a variable for testing.
+var MaxDocumentationHTML = 20 * megabyte
+
+// Render renders the documentation for the package.
+// This is mostly copied from internal/fetch/fetch.go.
+func (p *Package) Render(ctx context.Context, innerPath string, sourceInfo *source.Info, modInfo *ModuleInfo, goos, goarch string) (synopsis string, imports []string, html safehtml.HTML, err error) {
+ defer derrors.Wrap(&err, "godoc.Package.Render(%q, %q, %q, %q, %q)", modInfo.ModulePath, modInfo.ResolvedVersion, innerPath, goos, goarch)
+
+ importPath := path.Join(modInfo.ModulePath, innerPath)
+ if modInfo.ModulePath == stdlib.ModulePath {
+ importPath = innerPath
+ }
+ // The "builtin" package in the standard library is a special case.
+ // We want to show documentation for all globals (not just exported ones),
+ // and avoid association of consts, vars, and factory functions with types
+ // since it's not helpful (see golang.org/issue/6645).
+ var noFiltering, noTypeAssociation bool
+ if modInfo.ModulePath == stdlib.ModulePath && importPath == "builtin" {
+ noFiltering = true
+ noTypeAssociation = true
+ }
+
+ // Compute package documentation.
+ var m doc.Mode
+ if noFiltering {
+ m |= doc.AllDecls
+ }
+ var allGoFiles []*ast.File
+ for _, f := range p.Files {
+ allGoFiles = append(allGoFiles, f.AST)
+ }
+ d, err := doc.NewFromFiles(p.Fset, allGoFiles, importPath, m)
+ if err != nil {
+ return "", nil, safehtml.HTML{}, fmt.Errorf("doc.NewFromFiles: %v", err)
+ }
+ if d.ImportPath != importPath {
+ panic(fmt.Errorf("internal error: *doc.Package has an unexpected import path (%q != %q)", d.ImportPath, importPath))
+ }
+ if noTypeAssociation {
+ for _, t := range d.Types {
+ d.Consts, t.Consts = append(d.Consts, t.Consts...), nil
+ d.Vars, t.Vars = append(d.Vars, t.Vars...), nil
+ d.Funcs, t.Funcs = append(d.Funcs, t.Funcs...), nil
+ }
+ sort.Slice(d.Funcs, func(i, j int) bool { return d.Funcs[i].Name < d.Funcs[j].Name })
+ }
+
+ // Process package imports.
+ if len(d.Imports) > maxImportsPerPackage {
+ return "", nil, safehtml.HTML{}, fmt.Errorf("%d imports found package %q; exceeds limit %d for maxImportsPerPackage", len(d.Imports), importPath, maxImportsPerPackage)
+ }
+
+ // Render documentation HTML.
+ sourceLinkFunc := func(n ast.Node) string {
+ if sourceInfo == nil {
+ return ""
+ }
+ p := p.Fset.Position(n.Pos())
+ if p.Line == 0 { // invalid Position
+ return ""
+ }
+ return sourceInfo.LineURL(path.Join(innerPath, p.Filename), p.Line)
+ }
+ fileLinkFunc := func(filename string) string {
+ if sourceInfo == nil {
+ return ""
+ }
+ return sourceInfo.FileURL(path.Join(innerPath, filename))
+ }
+
+ docHTML, err := dochtml.Render(ctx, p.Fset, d, dochtml.RenderOptions{
+ FileLinkFunc: fileLinkFunc,
+ SourceLinkFunc: sourceLinkFunc,
+ ModInfo: modInfo,
+ Limit: int64(MaxDocumentationHTML),
+ })
+ if errors.Is(err, ErrTooLarge) {
+ docHTML = template.MustParseAndExecuteToHTML(docTooLargeReplacement)
+ } else if err != nil {
+ return "", nil, safehtml.HTML{}, fmt.Errorf("dochtml.Render: %v", err)
+ }
+ return doc.Synopsis(d.Doc), d.Imports, docHTML, err
+}
diff --git a/internal/worker/fetcherror_test.go b/internal/worker/fetcherror_test.go
index be301d7..05c1636 100644
--- a/internal/worker/fetcherror_test.go
+++ b/internal/worker/fetcherror_test.go
@@ -19,6 +19,7 @@
"golang.org/x/pkgsite/internal"
"golang.org/x/pkgsite/internal/derrors"
"golang.org/x/pkgsite/internal/fetch"
+ "golang.org/x/pkgsite/internal/godoc"
"golang.org/x/pkgsite/internal/postgres"
"golang.org/x/pkgsite/internal/proxy"
"golang.org/x/pkgsite/internal/source"
@@ -299,7 +300,7 @@
var b strings.Builder
b.WriteString("package bar\n\n")
b.WriteString("const Bar = `\n")
- for b.Len() <= fetch.MaxDocumentationHTML {
+ for b.Len() <= godoc.MaxDocumentationHTML {
b.WriteString("All work and no play makes Jack a dull boy.\n")
}
b.WriteString("`\n")
@@ -310,7 +311,7 @@
var b strings.Builder
b.WriteString("package baz\n\n")
b.WriteString("var Baz = []string{\n")
- for b.Len() <= fetch.MaxDocumentationHTML {
+ for b.Len() <= godoc.MaxDocumentationHTML {
b.WriteString("`All work and no play makes Jack a dull boy.`,\n")
}
b.WriteString("}\n")