diff --git a/internal/godoc/internal/doc/comment.go b/internal/godoc/internal/doc/comment.go
index 9dbd6b8..75b3726 100644
--- a/internal/godoc/internal/doc/comment.go
+++ b/internal/godoc/internal/doc/comment.go
@@ -38,10 +38,9 @@
 		text = convertQuotes(text)
 		var buf bytes.Buffer
 		template.HTMLEscape(&buf, []byte(text))
-		// Now we convert the unicode quotes to their HTML escaped entities to
-		// maintain old behavior. We need to use a temp buffer to read the
-		// string back and do the conversion, otherwise HTMLEscape will escape &
-		// to &amp;
+		// Now we convert the unicode quotes to their HTML escaped entities to maintain old behavior.
+		// We need to use a temp buffer to read the string back and do the conversion,
+		// otherwise HTMLEscape will escape & to &amp;
 		htmlQuoteReplacer.WriteString(w, buf.String())
 		return
 	}
@@ -300,9 +299,8 @@
 // in the words map, the link is taken from the map (if the corresponding map
 // value is the empty string, the URL is not converted into a link).
 //
-// A pair of (consecutive) backticks (`) is converted to a unicode left quote
-// (“), and a pair of (consecutive) single quotes (') is converted to a unicode
-// right quote (”).
+// A pair of (consecutive) backticks (`) is converted to a unicode left quote (“), and a pair of (consecutive)
+// single quotes (') is converted to a unicode right quote (”).
 //
 // Go identifiers that appear in the words map are italicized; if the corresponding
 // map value is not the empty string, it is considered a URL and the word is converted
@@ -422,9 +420,8 @@
 // and then prefixes each line with the indent. In preformatted sections
 // (such as program text), it prefixes each non-blank line with preIndent.
 //
-// A pair of (consecutive) backticks (`) is converted to a unicode left quote
-// (“), and a pair of (consecutive) single quotes (') is converted to a unicode
-// right quote (”).
+// A pair of (consecutive) backticks (`) is converted to a unicode left quote (“), and a pair of (consecutive)
+// single quotes (') is converted to a unicode right quote (”).
 func ToText(w io.Writer, text string, indent, preIndent string, width int) {
 	l := lineWrapper{
 		out:    w,
diff --git a/internal/godoc/internal/doc/doc.go b/internal/godoc/internal/doc/doc.go
index 21ae510..8f684ee 100644
--- a/internal/godoc/internal/doc/doc.go
+++ b/internal/godoc/internal/doc/doc.go
@@ -10,8 +10,6 @@
 	"go/ast"
 	"go/token"
 	"strings"
-
-	"golang.org/x/mod/module"
 )
 
 // Package is the documentation for an entire package.
@@ -146,6 +144,7 @@
 // match the desired build context. "go/build".Context.MatchFile can
 // be used for determining whether a file matches a build context with
 // the desired GOOS and GOARCH values, and other build constraints.
+// The import path of the package is specified by importPath.
 //
 // Examples found in _test.go files are associated with the corresponding
 // type, function, method, or the package, based on their name.
@@ -203,7 +202,7 @@
 	// Compute package documentation.
 	pkg, _ := ast.NewPackage(fset, goFiles, simpleImporter, nil) // Ignore errors that can happen due to unresolved identifiers.
 	p := New(pkg, importPath, mode)
-	classifyExamples(p, Examples(fset, testGoFiles...))
+	classifyExamples(p, Examples2(fset, testGoFiles...))
 	return p, nil
 }
 
@@ -214,17 +213,10 @@
 func simpleImporter(imports map[string]*ast.Object, path string) (*ast.Object, error) {
 	pkg := imports[path]
 	if pkg == nil {
-		pkg = ast.NewObj(ast.Pkg, packageName(path))
+		// note that strings.LastIndex returns -1 if there is no "/"
+		pkg = ast.NewObj(ast.Pkg, path[strings.LastIndex(path, "/")+1:])
 		pkg.Data = ast.NewScope(nil) // required by ast.NewPackage for dot-import
 		imports[path] = pkg
 	}
 	return pkg, nil
 }
-
-// packageName returns the last path component of the provided package,
-// stripping the major version component, if any.
-func packageName(path string) string {
-	pathPrefix, _, _ := module.SplitPathVersion(path)
-	// Note that strings.LastIndex returns -1 if there is no "/".
-	return pathPrefix[strings.LastIndex(pathPrefix, "/")+1:]
-}
diff --git a/internal/godoc/internal/doc/doc_test.go b/internal/godoc/internal/doc/doc_test.go
index 1dfa87d..5a5fbd8 100644
--- a/internal/godoc/internal/doc/doc_test.go
+++ b/internal/godoc/internal/doc/doc_test.go
@@ -100,93 +100,56 @@
 
 	// test packages
 	for _, pkg := range pkgs {
-		importPath := dataDir + "/" + pkg.Name
-		var files []*ast.File
-		for _, f := range pkg.Files {
-			files = append(files, f)
-		}
-		doc, err := NewFromFiles(fset, files, importPath, mode)
-		if err != nil {
-			t.Error(err)
-			continue
-		}
-
-		// golden files always use / in filenames - canonicalize them
-		for i, filename := range doc.Filenames {
-			doc.Filenames[i] = filepath.ToSlash(filename)
-		}
-
-		// print documentation
-		var buf bytes.Buffer
-		if err := templateTxt.Execute(&buf, bundle{doc, fset}); err != nil {
-			t.Error(err)
-			continue
-		}
-		got := buf.Bytes()
-
-		// update golden file if necessary
-		golden := filepath.Join(dataDir, fmt.Sprintf("%s.%d.golden", pkg.Name, mode))
-		if *update {
-			err := os.WriteFile(golden, got, 0644)
-			if err != nil {
-				t.Error(err)
+		t.Run(pkg.Name, func(t *testing.T) {
+			importPath := dataDir + "/" + pkg.Name
+			var files []*ast.File
+			for _, f := range pkg.Files {
+				files = append(files, f)
 			}
-			continue
-		}
+			doc, err := NewFromFiles(fset, files, importPath, mode)
+			if err != nil {
+				t.Fatal(err)
+			}
 
-		// get golden file
-		want, err := os.ReadFile(golden)
-		if err != nil {
-			t.Error(err)
-			continue
-		}
+			// golden files always use / in filenames - canonicalize them
+			for i, filename := range doc.Filenames {
+				doc.Filenames[i] = filepath.ToSlash(filename)
+			}
 
-		// compare
-		if !bytes.Equal(got, want) {
-			t.Errorf("package %s\n\tgot:\n%s\n\twant:\n%s", pkg.Name, got, want)
-		}
+			// print documentation
+			var buf bytes.Buffer
+			if err := templateTxt.Execute(&buf, bundle{doc, fset}); err != nil {
+				t.Fatal(err)
+			}
+			got := buf.Bytes()
+
+			// update golden file if necessary
+			golden := filepath.Join(dataDir, fmt.Sprintf("%s.%d.golden", pkg.Name, mode))
+			if *update {
+				err := os.WriteFile(golden, got, 0644)
+				if err != nil {
+					t.Fatal(err)
+				}
+			}
+
+			// get golden file
+			want, err := os.ReadFile(golden)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			// compare
+			if !bytes.Equal(got, want) {
+				t.Errorf("package %s\n\tgot:\n%s\n\twant:\n%s", pkg.Name, got, want)
+			}
+		})
 	}
 }
 
 func Test(t *testing.T) {
-	test(t, 0)
-	test(t, AllDecls)
-	test(t, AllMethods)
-}
-
-func TestPackageName(t *testing.T) {
-	for _, test := range []struct {
-		path string
-		want string
-	}{
-		{
-			path: "net/http",
-			want: "http",
-		},
-		{
-			path: "github.com/golang/pkgsite",
-			want: "pkgsite",
-		},
-		{
-			path: "k8s.io/client-go/listers/apps/v1",
-			want: "v1",
-		},
-		{
-			path: "github.com/googleapis/gax-go/v2",
-			want: "gax-go",
-		},
-		{
-			path: "google.golang.org/api/drive/v3",
-			want: "drive",
-		},
-	} {
-		t.Run(test.path, func(t *testing.T) {
-			got := packageName(test.path)
-			if got != test.want {
-				t.Errorf("packageName(%q) = %q, want %q", test.path, got, test.want)
-			}
-		})
-	}
+	t.Run("default", func(t *testing.T) { test(t, 0) })
+	t.Run("AllDecls", func(t *testing.T) { test(t, AllDecls) })
+	t.Run("AllMethods", func(t *testing.T) { test(t, AllMethods) })
 }
 
 func TestAnchorID(t *testing.T) {
@@ -197,3 +160,142 @@
 		t.Errorf("anchorID(%q) = %q; want %q", in, got, want)
 	}
 }
+
+func TestFuncs(t *testing.T) {
+	fset := token.NewFileSet()
+	file, err := parser.ParseFile(fset, "funcs.go", strings.NewReader(funcsTestFile), parser.ParseComments)
+	if err != nil {
+		t.Fatal(err)
+	}
+	doc, err := NewFromFiles(fset, []*ast.File{file}, "importPath", Mode(0))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	for _, f := range doc.Funcs {
+		f.Decl = nil
+	}
+	for _, ty := range doc.Types {
+		for _, f := range ty.Funcs {
+			f.Decl = nil
+		}
+		for _, m := range ty.Methods {
+			m.Decl = nil
+		}
+	}
+
+	compareFuncs := func(t *testing.T, msg string, got, want *Func) {
+		// ignore Decl and Examples
+		got.Decl = nil
+		got.Examples = nil
+		if !(got.Doc == want.Doc &&
+			got.Name == want.Name &&
+			got.Recv == want.Recv &&
+			got.Orig == want.Orig &&
+			got.Level == want.Level) {
+			t.Errorf("%s:\ngot  %+v\nwant %+v", msg, got, want)
+		}
+	}
+
+	compareSlices(t, "Funcs", doc.Funcs, funcsPackage.Funcs, compareFuncs)
+	compareSlices(t, "Types", doc.Types, funcsPackage.Types, func(t *testing.T, msg string, got, want *Type) {
+		if got.Name != want.Name {
+			t.Errorf("%s.Name: got %q, want %q", msg, got.Name, want.Name)
+		} else {
+			compareSlices(t, got.Name+".Funcs", got.Funcs, want.Funcs, compareFuncs)
+			compareSlices(t, got.Name+".Methods", got.Methods, want.Methods, compareFuncs)
+		}
+	})
+}
+
+func compareSlices[E any](t *testing.T, name string, got, want []E, compareElem func(*testing.T, string, E, E)) {
+	if len(got) != len(want) {
+		t.Errorf("%s: got %d, want %d", name, len(got), len(want))
+	}
+	for i := 0; i < len(got) && i < len(want); i++ {
+		compareElem(t, fmt.Sprintf("%s[%d]", name, i), got[i], want[i])
+	}
+}
+
+const funcsTestFile = `
+package funcs
+
+func F() {}
+
+type S1 struct {
+	S2  // embedded, exported
+	s3  // embedded, unexported
+}
+
+func NewS1()  S1 {return S1{} }
+func NewS1p() *S1 { return &S1{} }
+
+func (S1) M1() {}
+func (r S1) M2() {}
+func(S1) m3() {}		// unexported not shown
+func (*S1) P1() {}		// pointer receiver
+
+type S2 int
+func (S2) M3() {}		// shown on S2
+
+type s3 int
+func (s3) M4() {}		// shown on S1
+
+type G1[T any] struct {
+	*s3
+}
+
+func NewG1[T any]() G1[T] { return G1[T]{} }
+
+func (G1[T]) MG1() {}
+func (*G1[U]) MG2() {}
+
+type G2[T, U any] struct {}
+
+func NewG2[T, U any]() G2[T, U] { return G2[T, U]{} }
+
+func (G2[T, U]) MG3() {}
+func (*G2[A, B]) MG4() {}
+
+
+`
+
+var funcsPackage = &Package{
+	Funcs: []*Func{{Name: "F"}},
+	Types: []*Type{
+		{
+			Name:  "G1",
+			Funcs: []*Func{{Name: "NewG1"}},
+			Methods: []*Func{
+				{Name: "M4", Recv: "G1", // TODO: synthesize a param for G1?
+					Orig: "s3", Level: 1},
+				{Name: "MG1", Recv: "G1[T]", Orig: "G1[T]", Level: 0},
+				{Name: "MG2", Recv: "*G1[U]", Orig: "*G1[U]", Level: 0},
+			},
+		},
+		{
+			Name:  "G2",
+			Funcs: []*Func{{Name: "NewG2"}},
+			Methods: []*Func{
+				{Name: "MG3", Recv: "G2[T, U]", Orig: "G2[T, U]", Level: 0},
+				{Name: "MG4", Recv: "*G2[A, B]", Orig: "*G2[A, B]", Level: 0},
+			},
+		},
+		{
+			Name:  "S1",
+			Funcs: []*Func{{Name: "NewS1"}, {Name: "NewS1p"}},
+			Methods: []*Func{
+				{Name: "M1", Recv: "S1", Orig: "S1", Level: 0},
+				{Name: "M2", Recv: "S1", Orig: "S1", Level: 0},
+				{Name: "M4", Recv: "S1", Orig: "s3", Level: 1},
+				{Name: "P1", Recv: "*S1", Orig: "*S1", Level: 0},
+			},
+		},
+		{
+			Name: "S2",
+			Methods: []*Func{
+				{Name: "M3", Recv: "S2", Orig: "S2", Level: 0},
+			},
+		},
+	},
+}
diff --git a/internal/godoc/internal/doc/example.go b/internal/godoc/internal/doc/example.go
index 6dc1a53..792ba56 100644
--- a/internal/godoc/internal/doc/example.go
+++ b/internal/godoc/internal/doc/example.go
@@ -48,7 +48,7 @@
 //     example function, zero test, fuzz test, or benchmark function, and at
 //     least one top-level function, type, variable, or constant declaration
 //     other than the example function.
-func Examples(fset *token.FileSet, testFiles ...*ast.File) []*Example {
+func Examples(testFiles ...*ast.File) []*Example {
 	var list []*Example
 	for _, file := range testFiles {
 		hasTests := false // file contains tests, fuzz test, or benchmarks
@@ -87,7 +87,7 @@
 				Name:        name[len("Example"):],
 				Doc:         doc,
 				Code:        f.Body,
-				Play:        playExample(fset, file, f),
+				Play:        playExample(file, f),
 				Comments:    file.Comments,
 				Output:      output,
 				Unordered:   unordered,
@@ -150,9 +150,9 @@
 
 // playExample synthesizes a new *ast.File based on the provided
 // file with the provided function body as the body of main.
-func playExample(fset *token.FileSet, file *ast.File, f *ast.FuncDecl) *ast.File {
+func playExample(file *ast.File, f *ast.FuncDecl) *ast.File {
 	body := f.Body
-	tokenFile := fset.File(file.Package)
+
 	if !strings.HasSuffix(file.Name.Name, "_test") {
 		// We don't support examples that are part of the
 		// greater package (yet).
@@ -190,7 +190,76 @@
 	}
 
 	// Find unresolved identifiers and uses of top-level declarations.
-	depDecls, unresolved := findDeclsAndUnresolved(body, topDecls, typMethods)
+	unresolved := make(map[string]bool)
+	var depDecls []ast.Decl
+	hasDepDecls := make(map[ast.Decl]bool)
+
+	var inspectFunc func(ast.Node) bool
+	inspectFunc = func(n ast.Node) bool {
+		switch e := n.(type) {
+		case *ast.Ident:
+			if e.Obj == nil && e.Name != "_" {
+				unresolved[e.Name] = true
+			} else if d := topDecls[e.Obj]; d != nil {
+				if !hasDepDecls[d] {
+					hasDepDecls[d] = true
+					depDecls = append(depDecls, d)
+				}
+			}
+			return true
+		case *ast.SelectorExpr:
+			// For selector expressions, only inspect the left hand side.
+			// (For an expression like fmt.Println, only add "fmt" to the
+			// set of unresolved names, not "Println".)
+			ast.Inspect(e.X, inspectFunc)
+			return false
+		case *ast.KeyValueExpr:
+			// For key value expressions, only inspect the value
+			// as the key should be resolved by the type of the
+			// composite literal.
+			ast.Inspect(e.Value, inspectFunc)
+			return false
+		}
+		return true
+	}
+	ast.Inspect(body, inspectFunc)
+	for i := 0; i < len(depDecls); i++ {
+		switch d := depDecls[i].(type) {
+		case *ast.FuncDecl:
+			// Inspect types of parameters and results. See #28492.
+			if d.Type.Params != nil {
+				for _, p := range d.Type.Params.List {
+					ast.Inspect(p.Type, inspectFunc)
+				}
+			}
+			if d.Type.Results != nil {
+				for _, r := range d.Type.Results.List {
+					ast.Inspect(r.Type, inspectFunc)
+				}
+			}
+
+			// Functions might not have a body. See #42706.
+			if d.Body != nil {
+				ast.Inspect(d.Body, inspectFunc)
+			}
+		case *ast.GenDecl:
+			for _, spec := range d.Specs {
+				switch s := spec.(type) {
+				case *ast.TypeSpec:
+					ast.Inspect(s.Type, inspectFunc)
+
+					depDecls = append(depDecls, typMethods[s.Name.Name]...)
+				case *ast.ValueSpec:
+					if s.Type != nil {
+						ast.Inspect(s.Type, inspectFunc)
+					}
+					for _, val := range s.Values {
+						ast.Inspect(val, inspectFunc)
+					}
+				}
+			}
+		}
+	}
 
 	// Remove predeclared identifiers from unresolved list.
 	for n := range unresolved {
@@ -271,7 +340,20 @@
 		}
 	}
 
-	importDecl := synthesizeImportDecl(namedImports, blankImports, tokenFile)
+	// Synthesize import declaration.
+	importDecl := &ast.GenDecl{
+		Tok:    token.IMPORT,
+		Lparen: 1, // Need non-zero Lparen and Rparen so that printer
+		Rparen: 1, // treats this as a factored import.
+	}
+	for n, p := range namedImports {
+		s := &ast.ImportSpec{Path: &ast.BasicLit{Value: strconv.Quote(p)}}
+		if path.Base(p) != n {
+			s.Name = ast.NewIdent(n)
+		}
+		importDecl.Specs = append(importDecl.Specs, s)
+	}
+	importDecl.Specs = append(importDecl.Specs, blankImports...)
 
 	// Synthesize main function.
 	funcDecl := &ast.FuncDecl{
@@ -301,202 +383,6 @@
 	}
 }
 
-func findDeclsAndUnresolved(body ast.Node, topDecls map[*ast.Object]ast.Decl, typMethods map[string][]ast.Decl) ([]ast.Decl, map[string]bool) {
-	var depDecls []ast.Decl
-	unresolved := make(map[string]bool)
-	hasDepDecls := make(map[ast.Decl]bool)
-	objs := map[*ast.Object]bool{}
-
-	var inspectFunc func(ast.Node) bool
-	inspectFunc = func(n ast.Node) bool {
-		switch e := n.(type) {
-		case *ast.Ident:
-			if e.Obj == nil && e.Name != "_" {
-				unresolved[e.Name] = true
-			} else if d := topDecls[e.Obj]; d != nil {
-				objs[e.Obj] = true
-				if !hasDepDecls[d] {
-					hasDepDecls[d] = true
-					depDecls = append(depDecls, d)
-				}
-			}
-			return true
-		case *ast.SelectorExpr:
-			// For selector expressions, only inspect the left hand side.
-			// (For an expression like fmt.Println, only add "fmt" to the
-			// set of unresolved names, not "Println".)
-			ast.Inspect(e.X, inspectFunc)
-			return false
-		case *ast.KeyValueExpr:
-			// For key value expressions, only inspect the value
-			// as the key should be resolved by the type of the
-			// composite literal.
-			ast.Inspect(e.Value, inspectFunc)
-			return false
-		}
-		return true
-	}
-	ast.Inspect(body, inspectFunc)
-	for i := 0; i < len(depDecls); i++ {
-		switch d := depDecls[i].(type) {
-		case *ast.FuncDecl:
-			// Inspect types of parameters and results. See #28492.
-			if d.Type.Params != nil {
-				for _, p := range d.Type.Params.List {
-					ast.Inspect(p.Type, inspectFunc)
-				}
-			}
-			if d.Type.Results != nil {
-				for _, r := range d.Type.Results.List {
-					ast.Inspect(r.Type, inspectFunc)
-				}
-			}
-
-			ast.Inspect(d.Body, inspectFunc)
-		case *ast.GenDecl:
-			for _, spec := range d.Specs {
-				switch s := spec.(type) {
-				case *ast.TypeSpec:
-					ast.Inspect(s.Type, inspectFunc)
-					depDecls = append(depDecls, typMethods[s.Name.Name]...)
-				case *ast.ValueSpec:
-					if s.Type != nil {
-						ast.Inspect(s.Type, inspectFunc)
-					}
-					for _, val := range s.Values {
-						ast.Inspect(val, inspectFunc)
-					}
-				}
-			}
-		}
-	}
-	// Some decls include multiple specs, such as a variable declaration with
-	// multiple variables on the same line, or a parenthesized declaration. Trim
-	// the declarations to include only the specs that are actually mentioned.
-	// However, if there is a constant group with iota, leave it all: later
-	// constant declarations in the group may have no value and so cannot stand
-	// on their own, and furthermore, removing any constant from the group could
-	// change the values of subsequent ones.
-	// See testdata/examples/iota.go for a minimal example.
-	ds := depDecls[:0]
-	for _, d := range depDecls {
-		switch d := d.(type) {
-		case *ast.FuncDecl:
-			ds = append(ds, d)
-		case *ast.GenDecl:
-			// Collect all Specs that were mentioned in the example.
-			var specs []ast.Spec
-			for _, s := range d.Specs {
-				switch s := s.(type) {
-				case *ast.TypeSpec:
-					if objs[s.Name.Obj] {
-						specs = append(specs, s)
-					}
-				case *ast.ValueSpec:
-					// A ValueSpec may have multiple names (e.g. "var a, b int").
-					// Keep only the names that were mentioned in the example.
-					// Exception: the multiple names have a single initializer (which
-					// would be a function call with multiple return values). In that
-					// case, keep everything.
-					if len(s.Names) > 1 && len(s.Values) == 1 {
-						specs = append(specs, s)
-						continue
-					}
-					ns := *s
-					ns.Names = nil
-					ns.Values = nil
-					for i, n := range s.Names {
-						if objs[n.Obj] {
-							ns.Names = append(ns.Names, n)
-							if s.Values != nil {
-								ns.Values = append(ns.Values, s.Values[i])
-							}
-						}
-					}
-					if len(ns.Names) > 0 {
-						specs = append(specs, &ns)
-					}
-				}
-			}
-			if len(specs) > 0 {
-				// Constant with iota? Keep it all.
-				if d.Tok == token.CONST && hasIota(d.Specs[0]) {
-					ds = append(ds, d)
-				} else {
-					// Synthesize a GenDecl with just the Specs we need.
-					nd := *d // copy the GenDecl
-					nd.Specs = specs
-					if len(specs) == 1 {
-						// Remove grouping parens if there is only one spec.
-						nd.Lparen = 0
-					}
-					ds = append(ds, &nd)
-				}
-			}
-		}
-	}
-	return ds, unresolved
-}
-
-func hasIota(s ast.Spec) bool {
-	has := false
-	ast.Inspect(s, func(n ast.Node) bool {
-		if id, ok := n.(*ast.Ident); ok && id.Name == "iota" {
-			has = true
-			return false
-		}
-		return true
-	})
-	return has
-}
-
-// synthesizeImportDecl creates the imports for the example. We want the imports
-// divided into two groups, one for the standard library and one for all others.
-// To get ast.SortImports (called by the formatter) to do that, we must assign
-// file positions to the import specs so that there is a blank line between the
-// two groups. The exact positions don't matter, and they don't have to be
-// distinct within a group; ast.SortImports just looks for a gap of more than
-// one line between specs.
-func synthesizeImportDecl(namedImports map[string]string, blankImports []ast.Spec, tfile *token.File) *ast.GenDecl {
-	importDecl := &ast.GenDecl{
-		Tok:    token.IMPORT,
-		Lparen: 1, // Need non-zero Lparen and Rparen so that printer
-		Rparen: 1, // treats this as a factored import.
-	}
-	var stds, others []ast.Spec
-	var stdPos, otherPos token.Pos
-	if tfile.LineCount() >= 3 {
-		stdPos = tfile.LineStart(1)
-		otherPos = tfile.LineStart(3)
-	}
-	for n, p := range namedImports {
-		var (
-			pos   token.Pos
-			specs *[]ast.Spec
-		)
-		if !strings.ContainsRune(p, '.') {
-			pos = stdPos
-			specs = &stds
-		} else {
-			pos = otherPos
-			specs = &others
-		}
-		s := &ast.ImportSpec{
-			Path:   &ast.BasicLit{Value: strconv.Quote(p), Kind: token.STRING, ValuePos: pos},
-			EndPos: pos,
-		}
-		if path.Base(p) != n {
-			s.Name = ast.NewIdent(n)
-			s.Name.NamePos = pos
-		}
-		*specs = append(*specs, s)
-	}
-	importDecl.Specs = append(stds, others...)
-	importDecl.Specs = append(importDecl.Specs, blankImports...)
-
-	return importDecl
-}
-
 // playExampleFile takes a whole file example and synthesizes a new *ast.File
 // such that the example is function main in package main.
 func playExampleFile(file *ast.File) *ast.File {
@@ -604,7 +490,7 @@
 			ids[f.Name] = &f.Examples
 		}
 		for _, m := range t.Methods {
-			if !token.IsExported(m.Name) { // avoid unexported methods
+			if !token.IsExported(m.Name) {
 				continue
 			}
 			ids[strings.TrimPrefix(m.Recv, "*")+"_"+m.Name] = &m.Examples
diff --git a/internal/godoc/internal/doc/example_pkgsite.go b/internal/godoc/internal/doc/example_pkgsite.go
new file mode 100644
index 0000000..b2575e7
--- /dev/null
+++ b/internal/godoc/internal/doc/example_pkgsite.go
@@ -0,0 +1,443 @@
+// Copyright 2011 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.
+
+// Extract example functions from file ASTs.
+
+package doc
+
+import (
+	"go/ast"
+	"go/token"
+	"path"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+// Examples returns the examples found in testFiles, sorted by Name field.
+// The Order fields record the order in which the examples were encountered.
+// The Suffix field is not populated when Examples is called directly, it is
+// only populated by NewFromFiles for examples it finds in _test.go files.
+//
+// Playable Examples must be in a package whose name ends in "_test".
+// An Example is "playable" (the Play field is non-nil) in either of these
+// circumstances:
+//   - The example function is self-contained: the function references only
+//     identifiers from other packages (or predeclared identifiers, such as
+//     "int") and the test file does not include a dot import.
+//   - The entire test file is the example: the file contains exactly one
+//     example function, zero test, fuzz test, or benchmark function, and at
+//     least one top-level function, type, variable, or constant declaration
+//     other than the example function.
+func Examples2(fset *token.FileSet, testFiles ...*ast.File) []*Example {
+	var list []*Example
+	for _, file := range testFiles {
+		hasTests := false // file contains tests, fuzz test, or benchmarks
+		numDecl := 0      // number of non-import declarations in the file
+		var flist []*Example
+		for _, decl := range file.Decls {
+			if g, ok := decl.(*ast.GenDecl); ok && g.Tok != token.IMPORT {
+				numDecl++
+				continue
+			}
+			f, ok := decl.(*ast.FuncDecl)
+			if !ok || f.Recv != nil {
+				continue
+			}
+			numDecl++
+			name := f.Name.Name
+			if isTest(name, "Test") || isTest(name, "Benchmark") || isTest(name, "Fuzz") {
+				hasTests = true
+				continue
+			}
+			if !isTest(name, "Example") {
+				continue
+			}
+			if params := f.Type.Params; len(params.List) != 0 {
+				continue // function has params; not a valid example
+			}
+			if f.Body == nil { // ast.File.Body nil dereference (see issue 28044)
+				continue
+			}
+			var doc string
+			if f.Doc != nil {
+				doc = f.Doc.Text()
+			}
+			output, unordered, hasOutput := exampleOutput(f.Body, file.Comments)
+			flist = append(flist, &Example{
+				Name:        name[len("Example"):],
+				Doc:         doc,
+				Code:        f.Body,
+				Play:        playExample2(fset, file, f),
+				Comments:    file.Comments,
+				Output:      output,
+				Unordered:   unordered,
+				EmptyOutput: output == "" && hasOutput,
+				Order:       len(flist),
+			})
+		}
+		if !hasTests && numDecl > 1 && len(flist) == 1 {
+			// If this file only has one example function, some
+			// other top-level declarations, and no tests or
+			// benchmarks, use the whole file as the example.
+			flist[0].Code = file
+			flist[0].Play = playExampleFile(file)
+		}
+		list = append(list, flist...)
+	}
+	// sort by name
+	sort.Slice(list, func(i, j int) bool {
+		return list[i].Name < list[j].Name
+	})
+	return list
+}
+
+// playExample synthesizes a new *ast.File based on the provided
+// file with the provided function body as the body of main.
+func playExample2(fset *token.FileSet, file *ast.File, f *ast.FuncDecl) *ast.File {
+	body := f.Body
+	tokenFile := fset.File(file.Package)
+	if !strings.HasSuffix(file.Name.Name, "_test") {
+		// We don't support examples that are part of the
+		// greater package (yet).
+		return nil
+	}
+
+	// Collect top-level declarations in the file.
+	topDecls := make(map[*ast.Object]ast.Decl)
+	typMethods := make(map[string][]ast.Decl)
+
+	for _, decl := range file.Decls {
+		switch d := decl.(type) {
+		case *ast.FuncDecl:
+			if d.Recv == nil {
+				topDecls[d.Name.Obj] = d
+			} else {
+				if len(d.Recv.List) == 1 {
+					t := d.Recv.List[0].Type
+					tname, _ := baseTypeName(t)
+					typMethods[tname] = append(typMethods[tname], d)
+				}
+			}
+		case *ast.GenDecl:
+			for _, spec := range d.Specs {
+				switch s := spec.(type) {
+				case *ast.TypeSpec:
+					topDecls[s.Name.Obj] = d
+				case *ast.ValueSpec:
+					for _, name := range s.Names {
+						topDecls[name.Obj] = d
+					}
+				}
+			}
+		}
+	}
+
+	// Find unresolved identifiers and uses of top-level declarations.
+	depDecls, unresolved := findDeclsAndUnresolved(body, topDecls, typMethods)
+
+	// Remove predeclared identifiers from unresolved list.
+	for n := range unresolved {
+		if predeclaredTypes[n] || predeclaredConstants[n] || predeclaredFuncs[n] {
+			delete(unresolved, n)
+		}
+	}
+
+	// Use unresolved identifiers to determine the imports used by this
+	// example. The heuristic assumes package names match base import
+	// paths for imports w/o renames (should be good enough most of the time).
+	namedImports := make(map[string]string) // [name]path
+	var blankImports []ast.Spec             // _ imports
+	for _, s := range file.Imports {
+		p, err := strconv.Unquote(s.Path.Value)
+		if err != nil {
+			continue
+		}
+		if p == "syscall/js" {
+			// We don't support examples that import syscall/js,
+			// because the package syscall/js is not available in the playground.
+			return nil
+		}
+		n := path.Base(p)
+		if s.Name != nil {
+			n = s.Name.Name
+			switch n {
+			case "_":
+				blankImports = append(blankImports, s)
+				continue
+			case ".":
+				// We can't resolve dot imports (yet).
+				return nil
+			}
+		}
+		if unresolved[n] {
+			namedImports[n] = p
+			delete(unresolved, n)
+		}
+	}
+
+	// If there are other unresolved identifiers, give up because this
+	// synthesized file is not going to build.
+	if len(unresolved) > 0 {
+		return nil
+	}
+
+	// Include documentation belonging to blank imports.
+	var comments []*ast.CommentGroup
+	for _, s := range blankImports {
+		if c := s.(*ast.ImportSpec).Doc; c != nil {
+			comments = append(comments, c)
+		}
+	}
+
+	// Include comments that are inside the function body.
+	for _, c := range file.Comments {
+		if body.Pos() <= c.Pos() && c.End() <= body.End() {
+			comments = append(comments, c)
+		}
+	}
+
+	// Strip the "Output:" or "Unordered output:" comment and adjust body
+	// end position.
+	body, comments = stripOutputComment(body, comments)
+
+	// Include documentation belonging to dependent declarations.
+	for _, d := range depDecls {
+		switch d := d.(type) {
+		case *ast.GenDecl:
+			if d.Doc != nil {
+				comments = append(comments, d.Doc)
+			}
+		case *ast.FuncDecl:
+			if d.Doc != nil {
+				comments = append(comments, d.Doc)
+			}
+		}
+	}
+
+	importDecl := synthesizeImportDecl(namedImports, blankImports, tokenFile)
+
+	// Synthesize main function.
+	funcDecl := &ast.FuncDecl{
+		Name: ast.NewIdent("main"),
+		Type: f.Type,
+		Body: body,
+	}
+
+	decls := make([]ast.Decl, 0, 2+len(depDecls))
+	decls = append(decls, importDecl)
+	decls = append(decls, depDecls...)
+	decls = append(decls, funcDecl)
+
+	sort.Slice(decls, func(i, j int) bool {
+		return decls[i].Pos() < decls[j].Pos()
+	})
+
+	sort.Slice(comments, func(i, j int) bool {
+		return comments[i].Pos() < comments[j].Pos()
+	})
+
+	// Synthesize file.
+	return &ast.File{
+		Name:     ast.NewIdent("main"),
+		Decls:    decls,
+		Comments: comments,
+	}
+}
+
+func findDeclsAndUnresolved(body ast.Node, topDecls map[*ast.Object]ast.Decl, typMethods map[string][]ast.Decl) ([]ast.Decl, map[string]bool) {
+	var depDecls []ast.Decl
+	unresolved := make(map[string]bool)
+	hasDepDecls := make(map[ast.Decl]bool)
+	objs := map[*ast.Object]bool{}
+
+	var inspectFunc func(ast.Node) bool
+	inspectFunc = func(n ast.Node) bool {
+		switch e := n.(type) {
+		case *ast.Ident:
+			if e.Obj == nil && e.Name != "_" {
+				unresolved[e.Name] = true
+			} else if d := topDecls[e.Obj]; d != nil {
+				objs[e.Obj] = true
+				if !hasDepDecls[d] {
+					hasDepDecls[d] = true
+					depDecls = append(depDecls, d)
+				}
+			}
+			return true
+		case *ast.SelectorExpr:
+			// For selector expressions, only inspect the left hand side.
+			// (For an expression like fmt.Println, only add "fmt" to the
+			// set of unresolved names, not "Println".)
+			ast.Inspect(e.X, inspectFunc)
+			return false
+		case *ast.KeyValueExpr:
+			// For key value expressions, only inspect the value
+			// as the key should be resolved by the type of the
+			// composite literal.
+			ast.Inspect(e.Value, inspectFunc)
+			return false
+		}
+		return true
+	}
+	ast.Inspect(body, inspectFunc)
+	for i := 0; i < len(depDecls); i++ {
+		switch d := depDecls[i].(type) {
+		case *ast.FuncDecl:
+			// Inspect types of parameters and results. See #28492.
+			if d.Type.Params != nil {
+				for _, p := range d.Type.Params.List {
+					ast.Inspect(p.Type, inspectFunc)
+				}
+			}
+			if d.Type.Results != nil {
+				for _, r := range d.Type.Results.List {
+					ast.Inspect(r.Type, inspectFunc)
+				}
+			}
+
+			ast.Inspect(d.Body, inspectFunc)
+		case *ast.GenDecl:
+			for _, spec := range d.Specs {
+				switch s := spec.(type) {
+				case *ast.TypeSpec:
+					ast.Inspect(s.Type, inspectFunc)
+					depDecls = append(depDecls, typMethods[s.Name.Name]...)
+				case *ast.ValueSpec:
+					if s.Type != nil {
+						ast.Inspect(s.Type, inspectFunc)
+					}
+					for _, val := range s.Values {
+						ast.Inspect(val, inspectFunc)
+					}
+				}
+			}
+		}
+	}
+	// Some decls include multiple specs, such as a variable declaration with
+	// multiple variables on the same line, or a parenthesized declaration. Trim
+	// the declarations to include only the specs that are actually mentioned.
+	// However, if there is a constant group with iota, leave it all: later
+	// constant declarations in the group may have no value and so cannot stand
+	// on their own, and furthermore, removing any constant from the group could
+	// change the values of subsequent ones.
+	// See testdata/examples/iota.go for a minimal example.
+	ds := depDecls[:0]
+	for _, d := range depDecls {
+		switch d := d.(type) {
+		case *ast.FuncDecl:
+			ds = append(ds, d)
+		case *ast.GenDecl:
+			// Collect all Specs that were mentioned in the example.
+			var specs []ast.Spec
+			for _, s := range d.Specs {
+				switch s := s.(type) {
+				case *ast.TypeSpec:
+					if objs[s.Name.Obj] {
+						specs = append(specs, s)
+					}
+				case *ast.ValueSpec:
+					// A ValueSpec may have multiple names (e.g. "var a, b int").
+					// Keep only the names that were mentioned in the example.
+					// Exception: the multiple names have a single initializer (which
+					// would be a function call with multiple return values). In that
+					// case, keep everything.
+					if len(s.Names) > 1 && len(s.Values) == 1 {
+						specs = append(specs, s)
+						continue
+					}
+					ns := *s
+					ns.Names = nil
+					ns.Values = nil
+					for i, n := range s.Names {
+						if objs[n.Obj] {
+							ns.Names = append(ns.Names, n)
+							if s.Values != nil {
+								ns.Values = append(ns.Values, s.Values[i])
+							}
+						}
+					}
+					if len(ns.Names) > 0 {
+						specs = append(specs, &ns)
+					}
+				}
+			}
+			if len(specs) > 0 {
+				// Constant with iota? Keep it all.
+				if d.Tok == token.CONST && hasIota(d.Specs[0]) {
+					ds = append(ds, d)
+				} else {
+					// Synthesize a GenDecl with just the Specs we need.
+					nd := *d // copy the GenDecl
+					nd.Specs = specs
+					if len(specs) == 1 {
+						// Remove grouping parens if there is only one spec.
+						nd.Lparen = 0
+					}
+					ds = append(ds, &nd)
+				}
+			}
+		}
+	}
+	return ds, unresolved
+}
+
+func hasIota(s ast.Spec) bool {
+	has := false
+	ast.Inspect(s, func(n ast.Node) bool {
+		if id, ok := n.(*ast.Ident); ok && id.Name == "iota" {
+			has = true
+			return false
+		}
+		return true
+	})
+	return has
+}
+
+// synthesizeImportDecl creates the imports for the example. We want the imports
+// divided into two groups, one for the standard library and one for all others.
+// To get ast.SortImports (called by the formatter) to do that, we must assign
+// file positions to the import specs so that there is a blank line between the
+// two groups. The exact positions don't matter, and they don't have to be
+// distinct within a group; ast.SortImports just looks for a gap of more than
+// one line between specs.
+func synthesizeImportDecl(namedImports map[string]string, blankImports []ast.Spec, tfile *token.File) *ast.GenDecl {
+	importDecl := &ast.GenDecl{
+		Tok:    token.IMPORT,
+		Lparen: 1, // Need non-zero Lparen and Rparen so that printer
+		Rparen: 1, // treats this as a factored import.
+	}
+	var stds, others []ast.Spec
+	var stdPos, otherPos token.Pos
+	if tfile.LineCount() >= 3 {
+		stdPos = tfile.LineStart(1)
+		otherPos = tfile.LineStart(3)
+	}
+	for n, p := range namedImports {
+		var (
+			pos   token.Pos
+			specs *[]ast.Spec
+		)
+		if !strings.ContainsRune(p, '.') {
+			pos = stdPos
+			specs = &stds
+		} else {
+			pos = otherPos
+			specs = &others
+		}
+		s := &ast.ImportSpec{
+			Path:   &ast.BasicLit{Value: strconv.Quote(p), Kind: token.STRING, ValuePos: pos},
+			EndPos: pos,
+		}
+		if path.Base(p) != n {
+			s.Name = ast.NewIdent(n)
+			s.Name.NamePos = pos
+		}
+		*specs = append(*specs, s)
+	}
+	importDecl.Specs = append(stds, others...)
+	importDecl.Specs = append(importDecl.Specs, blankImports...)
+
+	return importDecl
+}
diff --git a/internal/godoc/internal/doc/example_pkgsite_test.go b/internal/godoc/internal/doc/example_pkgsite_test.go
new file mode 100644
index 0000000..e7d051a
--- /dev/null
+++ b/internal/godoc/internal/doc/example_pkgsite_test.go
@@ -0,0 +1,91 @@
+// Copyright 2013 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 doc_test
+
+import (
+	"go/parser"
+	"go/token"
+	"path/filepath"
+	"strings"
+	"testing"
+
+	"github.com/google/go-cmp/cmp"
+	"golang.org/x/pkgsite/internal/godoc/internal/doc"
+	"golang.org/x/tools/txtar"
+)
+
+func TestExamples2(t *testing.T) {
+	dir := filepath.Join("testdata", "examples")
+	filenames, err := filepath.Glob(filepath.Join(dir, "*.go"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, filename := range filenames {
+		t.Run(strings.TrimSuffix(filepath.Base(filename), ".go"), func(t *testing.T) {
+			fset := token.NewFileSet()
+			astFile, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
+			if err != nil {
+				t.Fatal(err)
+			}
+			goldenFilename := strings.TrimSuffix(filename, ".go") + ".golden"
+			golden, err := readSectionFile(goldenFilename)
+			if err != nil {
+				t.Fatal(err)
+			}
+			examples := map[string]*doc.Example{}
+			unseen := map[string]bool{} // examples we haven't seen yet
+			for _, e := range doc.Examples2(fset, astFile) {
+				examples[e.Name] = e
+				unseen[e.Name] = true
+			}
+			for section, want := range golden {
+				words := strings.Split(section, ".")
+				if len(words) != 2 {
+					t.Fatalf("bad section name %q", section)
+				}
+				name, kind := words[0], words[1]
+				ex := examples[name]
+				if ex == nil {
+					t.Fatalf("no example named %q", name)
+				}
+				switch kind {
+				case "Play":
+					got := strings.TrimSpace(formatFile(t, fset, ex.Play))
+					if diff := cmp.Diff(want, got); diff != "" {
+						t.Errorf("%s Play: mismatch (-want, +got):\n%s", name, diff)
+					}
+					delete(unseen, name)
+				case "Output":
+					got := strings.TrimSpace(ex.Output)
+					if got != want {
+						t.Errorf("%s Output: got\n%q\n---- want ----\n%q", ex.Name, got, want)
+					}
+				default:
+					t.Fatalf("bad section kind %q", kind)
+				}
+			}
+			for name := range unseen {
+				t.Errorf("no Play golden for example %q", name)
+			}
+		})
+	}
+}
+
+// readSectionFile reads a file that is divided into sections, and returns
+// a map from section name to contents.
+//
+// We use the txtar format for the file. See https://pkg.go.dev/golang.org/x/tools/txtar.
+// Although the format talks about filenames as the keys, they can be arbitrary strings.
+func readSectionFile(filename string) (map[string]string, error) {
+	archive, err := txtar.ParseFile(filename)
+	if err != nil {
+		return nil, err
+	}
+	m := map[string]string{}
+	for _, f := range archive.Files {
+		m[f.Name] = strings.TrimSpace(string(f.Data))
+	}
+	return m, nil
+}
diff --git a/internal/godoc/internal/doc/example_test.go b/internal/godoc/internal/doc/example_test.go
index 2a860ac..21b7129 100644
--- a/internal/godoc/internal/doc/example_test.go
+++ b/internal/godoc/internal/doc/example_test.go
@@ -8,78 +8,520 @@
 	"bytes"
 	"fmt"
 	"go/ast"
+	"go/doc"
 	"go/format"
 	"go/parser"
 	"go/token"
-	"path/filepath"
 	"reflect"
 	"strings"
 	"testing"
-
-	"github.com/google/go-cmp/cmp"
-	"golang.org/x/pkgsite/internal/godoc/internal/doc"
-	"golang.org/x/tools/txtar"
 )
 
+const exampleTestFile = `
+package foo_test
+
+import (
+	"flag"
+	"fmt"
+	"log"
+	"sort"
+	"os/exec"
+)
+
+func ExampleHello() {
+	fmt.Println("Hello, world!")
+	// Output: Hello, world!
+}
+
+func ExampleImport() {
+	out, err := exec.Command("date").Output()
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Printf("The date is %s\n", out)
+}
+
+func ExampleKeyValue() {
+	v := struct {
+		a string
+		b int
+	}{
+		a: "A",
+		b: 1,
+	}
+	fmt.Print(v)
+	// Output: a: "A", b: 1
+}
+
+func ExampleKeyValueImport() {
+	f := flag.Flag{
+		Name: "play",
+	}
+	fmt.Print(f)
+	// Output: Name: "play"
+}
+
+var keyValueTopDecl = struct {
+	a string
+	b int
+}{
+	a: "B",
+	b: 2,
+}
+
+func ExampleKeyValueTopDecl() {
+	fmt.Print(keyValueTopDecl)
+	// Output: a: "B", b: 2
+}
+
+// Person represents a person by name and age.
+type Person struct {
+    Name string
+    Age  int
+}
+
+// String returns a string representation of the Person.
+func (p Person) String() string {
+    return fmt.Sprintf("%s: %d", p.Name, p.Age)
+}
+
+// ByAge implements sort.Interface for []Person based on
+// the Age field.
+type ByAge []Person
+
+// Len returns the number of elements in ByAge.
+func (a (ByAge)) Len() int { return len(a) }
+
+// Swap swaps the elements in ByAge.
+func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
+
+// people is the array of Person
+var people = []Person{
+	{"Bob", 31},
+	{"John", 42},
+	{"Michael", 17},
+	{"Jenny", 26},
+}
+
+func ExampleSort() {
+    fmt.Println(people)
+    sort.Sort(ByAge(people))
+    fmt.Println(people)
+    // Output:
+    // [Bob: 31 John: 42 Michael: 17 Jenny: 26]
+    // [Michael: 17 Jenny: 26 Bob: 31 John: 42]
+}
+`
+
+var exampleTestCases = []struct {
+	Name, Play, Output string
+}{
+	{
+		Name:   "Hello",
+		Play:   exampleHelloPlay,
+		Output: "Hello, world!\n",
+	},
+	{
+		Name: "Import",
+		Play: exampleImportPlay,
+	},
+	{
+		Name:   "KeyValue",
+		Play:   exampleKeyValuePlay,
+		Output: "a: \"A\", b: 1\n",
+	},
+	{
+		Name:   "KeyValueImport",
+		Play:   exampleKeyValueImportPlay,
+		Output: "Name: \"play\"\n",
+	},
+	{
+		Name:   "KeyValueTopDecl",
+		Play:   exampleKeyValueTopDeclPlay,
+		Output: "a: \"B\", b: 2\n",
+	},
+	{
+		Name:   "Sort",
+		Play:   exampleSortPlay,
+		Output: "[Bob: 31 John: 42 Michael: 17 Jenny: 26]\n[Michael: 17 Jenny: 26 Bob: 31 John: 42]\n",
+	},
+}
+
+const exampleHelloPlay = `package main
+
+import (
+	"fmt"
+)
+
+func main() {
+	fmt.Println("Hello, world!")
+}
+`
+const exampleImportPlay = `package main
+
+import (
+	"fmt"
+	"log"
+	"os/exec"
+)
+
+func main() {
+	out, err := exec.Command("date").Output()
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Printf("The date is %s\n", out)
+}
+`
+
+const exampleKeyValuePlay = `package main
+
+import (
+	"fmt"
+)
+
+func main() {
+	v := struct {
+		a string
+		b int
+	}{
+		a: "A",
+		b: 1,
+	}
+	fmt.Print(v)
+}
+`
+
+const exampleKeyValueImportPlay = `package main
+
+import (
+	"flag"
+	"fmt"
+)
+
+func main() {
+	f := flag.Flag{
+		Name: "play",
+	}
+	fmt.Print(f)
+}
+`
+
+const exampleKeyValueTopDeclPlay = `package main
+
+import (
+	"fmt"
+)
+
+var keyValueTopDecl = struct {
+	a string
+	b int
+}{
+	a: "B",
+	b: 2,
+}
+
+func main() {
+	fmt.Print(keyValueTopDecl)
+}
+`
+
+const exampleSortPlay = `package main
+
+import (
+	"fmt"
+	"sort"
+)
+
+// Person represents a person by name and age.
+type Person struct {
+	Name string
+	Age  int
+}
+
+// String returns a string representation of the Person.
+func (p Person) String() string {
+	return fmt.Sprintf("%s: %d", p.Name, p.Age)
+}
+
+// ByAge implements sort.Interface for []Person based on
+// the Age field.
+type ByAge []Person
+
+// Len returns the number of elements in ByAge.
+func (a ByAge) Len() int { return len(a) }
+
+// Swap swaps the elements in ByAge.
+func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
+
+// people is the array of Person
+var people = []Person{
+	{"Bob", 31},
+	{"John", 42},
+	{"Michael", 17},
+	{"Jenny", 26},
+}
+
+func main() {
+	fmt.Println(people)
+	sort.Sort(ByAge(people))
+	fmt.Println(people)
+}
+`
+
 func TestExamples(t *testing.T) {
-	dir := filepath.Join("testdata", "examples")
-	filenames, err := filepath.Glob(filepath.Join(dir, "*.go"))
+	fset := token.NewFileSet()
+	file, err := parser.ParseFile(fset, "test.go", strings.NewReader(exampleTestFile), parser.ParseComments)
 	if err != nil {
 		t.Fatal(err)
 	}
-	for _, filename := range filenames {
-		t.Run(strings.TrimSuffix(filepath.Base(filename), ".go"), func(t *testing.T) {
-			fset := token.NewFileSet()
-			astFile, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
-			if err != nil {
-				t.Fatal(err)
+	for i, e := range doc.Examples(file) {
+		c := exampleTestCases[i]
+		if e.Name != c.Name {
+			t.Errorf("got Name == %q, want %q", e.Name, c.Name)
+		}
+		if w := c.Play; w != "" {
+			g := formatFile(t, fset, e.Play)
+			if g != w {
+				t.Errorf("%s: got Play == %q, want %q", c.Name, g, w)
 			}
-			goldenFilename := strings.TrimSuffix(filename, ".go") + ".golden"
-			golden, err := readSectionFile(goldenFilename)
-			if err != nil {
-				t.Fatal(err)
-			}
-			examples := map[string]*doc.Example{}
-			unseen := map[string]bool{} // examples we haven't seen yet
-			for _, e := range doc.Examples(fset, astFile) {
-				examples[e.Name] = e
-				unseen[e.Name] = true
-			}
-			for section, want := range golden {
-				words := strings.Split(section, ".")
-				if len(words) != 2 {
-					t.Fatalf("bad section name %q", section)
-				}
-				name, kind := words[0], words[1]
-				ex := examples[name]
-				if ex == nil {
-					t.Fatalf("no example named %q", name)
-				}
-				switch kind {
-				case "Play":
-					got := strings.TrimSpace(formatFile(t, fset, ex.Play))
-					if diff := cmp.Diff(want, got); diff != "" {
-						t.Errorf("%s Play: mismatch (-want, +got):\n%s", name, diff)
-					}
-					delete(unseen, name)
-				case "Output":
-					got := strings.TrimSpace(ex.Output)
-					if got != want {
-						t.Errorf("%s Output: got\n%q\n---- want ----\n%q", ex.Name, got, want)
-					}
-				default:
-					t.Fatalf("bad section kind %q", kind)
-				}
-			}
-			for name := range unseen {
-				t.Errorf("no Play golden for example %q", name)
-			}
-		})
+		}
+		if g, w := e.Output, c.Output; g != w {
+			t.Errorf("%s: got Output == %q, want %q", c.Name, g, w)
+		}
+	}
+}
+
+const exampleWholeFile = `package foo_test
+
+type X int
+
+func (X) Foo() {
+}
+
+func (X) TestBlah() {
+}
+
+func (X) BenchmarkFoo() {
+}
+
+func (X) FuzzFoo() {
+}
+
+func Example() {
+	fmt.Println("Hello, world!")
+	// Output: Hello, world!
+}
+`
+
+const exampleWholeFileOutput = `package main
+
+type X int
+
+func (X) Foo() {
+}
+
+func (X) TestBlah() {
+}
+
+func (X) BenchmarkFoo() {
+}
+
+func (X) FuzzFoo() {
+}
+
+func main() {
+	fmt.Println("Hello, world!")
+}
+`
+
+const exampleWholeFileFunction = `package foo_test
+
+func Foo(x int) {
+}
+
+func Example() {
+	fmt.Println("Hello, world!")
+	// Output: Hello, world!
+}
+`
+
+const exampleWholeFileFunctionOutput = `package main
+
+func Foo(x int) {
+}
+
+func main() {
+	fmt.Println("Hello, world!")
+}
+`
+
+const exampleWholeFileExternalFunction = `package foo_test
+
+func foo(int)
+
+func Example() {
+	foo(42)
+	// Output:
+}
+`
+
+const exampleWholeFileExternalFunctionOutput = `package main
+
+func foo(int)
+
+func main() {
+	foo(42)
+}
+`
+
+var exampleWholeFileTestCases = []struct {
+	Title, Source, Play, Output string
+}{
+	{
+		"Methods",
+		exampleWholeFile,
+		exampleWholeFileOutput,
+		"Hello, world!\n",
+	},
+	{
+		"Function",
+		exampleWholeFileFunction,
+		exampleWholeFileFunctionOutput,
+		"Hello, world!\n",
+	},
+	{
+		"ExternalFunction",
+		exampleWholeFileExternalFunction,
+		exampleWholeFileExternalFunctionOutput,
+		"",
+	},
+}
+
+func TestExamplesWholeFile(t *testing.T) {
+	for _, c := range exampleWholeFileTestCases {
+		fset := token.NewFileSet()
+		file, err := parser.ParseFile(fset, "test.go", strings.NewReader(c.Source), parser.ParseComments)
+		if err != nil {
+			t.Fatal(err)
+		}
+		es := doc.Examples(file)
+		if len(es) != 1 {
+			t.Fatalf("%s: wrong number of examples; got %d want 1", c.Title, len(es))
+		}
+		e := es[0]
+		if e.Name != "" {
+			t.Errorf("%s: got Name == %q, want %q", c.Title, e.Name, "")
+		}
+		if g, w := formatFile(t, fset, e.Play), c.Play; g != w {
+			t.Errorf("%s: got Play == %q, want %q", c.Title, g, w)
+		}
+		if g, w := e.Output, c.Output; g != w {
+			t.Errorf("%s: got Output == %q, want %q", c.Title, g, w)
+		}
+	}
+}
+
+const exampleInspectSignature = `package foo_test
+
+import (
+	"bytes"
+	"io"
+)
+
+func getReader() io.Reader { return nil }
+
+func do(b bytes.Reader) {}
+
+func Example() {
+	getReader()
+	do()
+	// Output:
+}
+
+func ExampleIgnored() {
+}
+`
+
+const exampleInspectSignatureOutput = `package main
+
+import (
+	"bytes"
+	"io"
+)
+
+func getReader() io.Reader { return nil }
+
+func do(b bytes.Reader) {}
+
+func main() {
+	getReader()
+	do()
+}
+`
+
+func TestExampleInspectSignature(t *testing.T) {
+	// Verify that "bytes" and "io" are imported. See issue #28492.
+	fset := token.NewFileSet()
+	file, err := parser.ParseFile(fset, "test.go", strings.NewReader(exampleInspectSignature), parser.ParseComments)
+	if err != nil {
+		t.Fatal(err)
+	}
+	es := doc.Examples(file)
+	if len(es) != 2 {
+		t.Fatalf("wrong number of examples; got %d want 2", len(es))
+	}
+	// We are interested in the first example only.
+	e := es[0]
+	if e.Name != "" {
+		t.Errorf("got Name == %q, want %q", e.Name, "")
+	}
+	if g, w := formatFile(t, fset, e.Play), exampleInspectSignatureOutput; g != w {
+		t.Errorf("got Play == %q, want %q", g, w)
+	}
+	if g, w := e.Output, ""; g != w {
+		t.Errorf("got Output == %q, want %q", g, w)
+	}
+}
+
+const exampleEmpty = `
+package p
+func Example() {}
+func Example_a()
+`
+
+const exampleEmptyOutput = `package main
+
+func main() {}
+func main()
+`
+
+func TestExampleEmpty(t *testing.T) {
+	fset := token.NewFileSet()
+	file, err := parser.ParseFile(fset, "test.go", strings.NewReader(exampleEmpty), parser.ParseComments)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	es := doc.Examples(file)
+	if len(es) != 1 {
+		t.Fatalf("wrong number of examples; got %d want 1", len(es))
+	}
+	e := es[0]
+	if e.Name != "" {
+		t.Errorf("got Name == %q, want %q", e.Name, "")
+	}
+	if g, w := formatFile(t, fset, e.Play), exampleEmptyOutput; g != w {
+		t.Errorf("got Play == %q, want %q", g, w)
+	}
+	if g, w := e.Output, ""; g != w {
+		t.Errorf("got Output == %q, want %q", g, w)
 	}
 }
 
 func formatFile(t *testing.T, fset *token.FileSet, n *ast.File) string {
-	t.Helper()
 	if n == nil {
 		return "<nil>"
 	}
@@ -305,20 +747,3 @@
 	}
 	return f
 }
-
-// readSectionFile reads a file that is divided into sections, and returns
-// a map from section name to contents.
-//
-// We use the txtar format for the file. See https://pkg.go.dev/golang.org/x/tools/txtar.
-// Although the format talks about filenames as the keys, they can be arbitrary strings.
-func readSectionFile(filename string) (map[string]string, error) {
-	archive, err := txtar.ParseFile(filename)
-	if err != nil {
-		return nil, err
-	}
-	m := map[string]string{}
-	for _, f := range archive.Files {
-		m[f.Name] = strings.TrimSpace(string(f.Data))
-	}
-	return m, nil
-}
