diff options
| author | Egon Elbre <egonelbre@gmail.com> | 2026-01-13 12:51:47 +0200 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2026-02-06 09:33:53 -0800 |
| commit | 2a8da3345a36148f4dca0cfb2b99cbe84ba9a50b (patch) | |
| tree | 669cb4011b06842042d19d6182d977cb4d204beb | |
| parent | d0bf40e3e777b94b6863e686523cb8cdc109b4f2 (diff) | |
| download | go-x-pkgsite-2a8da3345a36148f4dca0cfb2b99cbe84ba9a50b.tar.xz | |
internal/godoc/dochtml: use natural sorting for items
This ensures that simd/archsimd package items are sorted nicely.
For example:
"Uint8x64" < "Uint32x16" < "Uint64x8"
Fixes golang/go#77160
Change-Id: Ie08696262496e226120ae1b31ca81e02b7f20c65
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/736561
Auto-Submit: Sean Liao <sean@liao.dev>
kokoro-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Ethan Lee <ethanalee@google.com>
Reviewed-by: Sean Liao <sean@liao.dev>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
| -rw-r--r-- | internal/godoc/dochtml/dochtml.go | 21 | ||||
| -rw-r--r-- | internal/godoc/dochtml/dochtml_test.go | 2 | ||||
| -rw-r--r-- | internal/godoc/dochtml/testdata/order.go | 55 | ||||
| -rw-r--r-- | internal/godoc/dochtml/testdata/order.golden | 292 |
4 files changed, 368 insertions, 2 deletions
diff --git a/internal/godoc/dochtml/dochtml.go b/internal/godoc/dochtml/dochtml.go index 8264170e..8a80973a 100644 --- a/internal/godoc/dochtml/dochtml.go +++ b/internal/godoc/dochtml/dochtml.go @@ -19,6 +19,7 @@ import ( "go/doc" "go/printer" "go/token" + "slices" "sort" "strings" @@ -30,6 +31,7 @@ import ( "golang.org/x/pkgsite/internal/derrors" "golang.org/x/pkgsite/internal/godoc/dochtml/internal/render" "golang.org/x/pkgsite/internal/log" + "golang.org/x/pkgsite/internal/natural" "golang.org/x/text/cases" "golang.org/x/text/language" ) @@ -151,9 +153,26 @@ func packageToItems(p *doc.Package, exmap map[string][]*example) (consts, vars, for _, t := range p.Types { types = append(types, typeToItem(t, exmap)) } + + slices.SortFunc(consts, compareItems) + slices.SortFunc(vars, compareItems) + slices.SortFunc(funcs, compareItems) + slices.SortFunc(types, compareItems) + + for _, typ := range types { + slices.SortFunc(typ.Consts, compareItems) + slices.SortFunc(typ.Vars, compareItems) + slices.SortFunc(typ.Funcs, compareItems) + slices.SortFunc(typ.Methods, compareItems) + } + return consts, vars, funcs, types } +func compareItems(a, b *item) int { + return natural.Compare(a.Name, b.Name) +} + func valuesToItems(vs []*doc.Value) []*item { var r []*item for _, v := range vs { @@ -402,7 +421,7 @@ func collectExamples(p *doc.Package) *examples { sort.SliceStable(exs.List, func(i, j int) bool { // TODO: Break ties by sorting by suffix, unless // not needed because of upstream slice order. - return exs.List[i].ParentID < exs.List[j].ParentID + return natural.Less(exs.List[i].ParentID, exs.List[j].ParentID) }) return exs } diff --git a/internal/godoc/dochtml/dochtml_test.go b/internal/godoc/dochtml/dochtml_test.go index f57cce32..80feba96 100644 --- a/internal/godoc/dochtml/dochtml_test.go +++ b/internal/godoc/dochtml/dochtml_test.go @@ -48,7 +48,7 @@ var testRenderOptions = RenderOptions{ func TestRender(t *testing.T) { ctx := context.Background() LoadTemplates(templateFS) - for _, pkg := range []string{"everydecl", "comments"} { + for _, pkg := range []string{"everydecl", "comments", "order"} { t.Run(pkg, func(t *testing.T) { fset, d := mustLoadPackage(pkg) parts, err := Render(ctx, fset, d, testRenderOptions) diff --git a/internal/godoc/dochtml/testdata/order.go b/internal/godoc/dochtml/testdata/order.go new file mode 100644 index 00000000..b8a82bfd --- /dev/null +++ b/internal/godoc/dochtml/testdata/order.go @@ -0,0 +1,55 @@ +// Copyright 2026 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 order exercises natural sorting of symbols. +package order + +// Uint32x16 represents a 128-bit unsigned integer. +type Uint32x16 struct { + data [16]uint32 +} + +// AsUint8x64 converts a Uint32x16 to a Uint8x64. +func (u Uint32x16) AsUint8x64() Uint8x64 { + return Uint8x64{} +} + +// AsUint64x8 converts a Uint32x16 to a Uint64x8. +func (u Uint32x16) AsUint64x8() Uint8x64 { + return Uint64x8{} +} + +// Uint8x64 represents a 128-bit unsigned integer. +type Uint8x64 struct { + data [64]uint8 +} + +// AsUint32x16 converts a Uint8x64 to a Uint32x16. +func (u Uint8x64) AsUint32x16() Uint32x16 { + return Uint32x16{} +} + +// AsUint64x8 converts a Uint8x64 to a Uint64x8. +func (u Uint8x64) AsUint64x8() Uint64x8 { + return Uint64x8{} +} + +// Uint64x8 represents a 128-bit unsigned integer. +type Uint64x8 struct { + data [8]uint64 +} + +// AsUint8x64 converts a Uint64x8 to a Uint8x64. +func (u Uint64x8) AsUint8x64() Uint8x64 { + return Uint8x64{} +} + +// AsUint32x16 converts a Uint64x8 to a Uint32x16. +func (u Uint64x8) AsUint32x16() Uint32x16 { + return Uint32x16{} +} + +func ExampleUint64x8_AsUint32x16() {} + +func ExampleUint64x8_AsUint8x64() {} diff --git a/internal/godoc/dochtml/testdata/order.golden b/internal/godoc/dochtml/testdata/order.golden new file mode 100644 index 00000000..2695cf2c --- /dev/null +++ b/internal/godoc/dochtml/testdata/order.golden @@ -0,0 +1,292 @@ +<div class="Documentation-content js-docContent"> <section class="Documentation-overview"> +<h3 tabindex="-1" id="pkg-overview" class="Documentation-overviewHeader">Overview <a href="#pkg-overview" title="Go to Overview" aria-label="Go to Overview">¶</a></h3> +<p>Package order exercises natural sorting of symbols. +</p> +</section><section class="Documentation-index"> +<h3 id="pkg-index" class="Documentation-indexHeader">Index <a href="#pkg-index" title="Go to Index" aria-label="Go to Index">¶</a></h3> +<ul class="Documentation-indexList"> +<li class="Documentation-indexFunction"> +<a href="#ExampleUint64x8_AsUint8x64">func ExampleUint64x8_AsUint8x64()</a></li> +<li class="Documentation-indexFunction"> +<a href="#ExampleUint64x8_AsUint32x16">func ExampleUint64x8_AsUint32x16()</a></li> +<li class="Documentation-indexType"> +<a href="#Uint8x64">type Uint8x64</a></li> +<li><ul class="Documentation-indexTypeMethods"> +<li> +<a href="#Uint8x64.AsUint32x16">func (u Uint8x64) AsUint32x16() Uint32x16</a></li> +<li> +<a href="#Uint8x64.AsUint64x8">func (u Uint8x64) AsUint64x8() Uint64x8</a></li> +</ul></li> +<li class="Documentation-indexType"> +<a href="#Uint32x16">type Uint32x16</a></li> +<li><ul class="Documentation-indexTypeMethods"> +<li> +<a href="#Uint32x16.AsUint8x64">func (u Uint32x16) AsUint8x64() Uint8x64</a></li> +<li> +<a href="#Uint32x16.AsUint64x8">func (u Uint32x16) AsUint64x8() Uint8x64</a></li> +</ul></li> +<li class="Documentation-indexType"> +<a href="#Uint64x8">type Uint64x8</a></li> +<li><ul class="Documentation-indexTypeMethods"> +<li> +<a href="#Uint64x8.AsUint8x64">func (u Uint64x8) AsUint8x64() Uint8x64</a></li> +<li> +<a href="#Uint64x8.AsUint32x16">func (u Uint64x8) AsUint32x16() Uint32x16</a></li> +</ul></li> +</ul> +</section><h3 tabindex="-1" id="pkg-constants" class="Documentation-constantsHeader">Constants <a href="#pkg-constants" title="Go to Constants" aria-label="Go to Constants">¶</a></h3> +<section class="Documentation-constants"><p class="Documentation-empty">This section is empty.</p></section> +<h3 tabindex="-1" id="pkg-variables" class="Documentation-variablesHeader">Variables <a href="#pkg-variables" title="Go to Variables" aria-label="Go to Variables">¶</a></h3> +<section class="Documentation-variables"><p class="Documentation-empty">This section is empty.</p></section> +<h3 tabindex="-1" id="pkg-functions" class="Documentation-functionsHeader">Functions <a href="#pkg-functions" title="Go to Functions" aria-label="Go to Functions">¶</a></h3> +<section class="Documentation-functions"><div class="Documentation-function"> +<h4 tabindex="-1" id="ExampleUint64x8_AsUint8x64" data-kind="function" class="Documentation-functionHeader"> +<span>func <a class="Documentation-source" href="src">ExampleUint64x8_AsUint8x64</a> <a class="Documentation-idLink" href="#ExampleUint64x8_AsUint8x64" title="Go to ExampleUint64x8_AsUint8x64" aria-label="Go to ExampleUint64x8_AsUint8x64">¶</a></span> +<span class="Documentation-sinceVersion"> +</span> +</h4> +<div class="Documentation-declaration"> +<pre>func ExampleUint64x8_AsUint8x64()</pre> +</div> +</div><div class="Documentation-function"> +<h4 tabindex="-1" id="ExampleUint64x8_AsUint32x16" data-kind="function" class="Documentation-functionHeader"> +<span>func <a class="Documentation-source" href="src">ExampleUint64x8_AsUint32x16</a> <a class="Documentation-idLink" href="#ExampleUint64x8_AsUint32x16" title="Go to ExampleUint64x8_AsUint32x16" aria-label="Go to ExampleUint64x8_AsUint32x16">¶</a></span> +<span class="Documentation-sinceVersion"> +</span> +</h4> +<div class="Documentation-declaration"> +<pre>func ExampleUint64x8_AsUint32x16()</pre> +</div> +</div></section> +<h3 tabindex="-1" id="pkg-types" class="Documentation-typesHeader">Types <a href="#pkg-types" title="Go to Types" aria-label="Go to Types">¶</a></h3> +<section class="Documentation-types"><div class="Documentation-type"> +<h4 tabindex="-1" id="Uint8x64" data-kind="type" class="Documentation-typeHeader"> +<span>type <a class="Documentation-source" href="src">Uint8x64</a> <a class="Documentation-idLink" href="#Uint8x64" title="Go to Uint8x64" aria-label="Go to Uint8x64">¶</a></span> +<span class="Documentation-sinceVersion"> +</span> +</h4> +<div class="Documentation-declaration"> +<pre>type Uint8x64 struct { +<span id="Uint8x64.data" data-kind="field"> data [64]<a href="/builtin#uint8">uint8</a> +</span>}</pre> +</div> +<p>Uint8x64 represents a 128-bit unsigned integer. +</p> +<div class="Documentation-typeMethod"> +<h4 tabindex="-1" id="Uint8x64.AsUint32x16" data-kind="method" class="Documentation-typeMethodHeader"> +<span>func (Uint8x64) <a class="Documentation-source" href="src">AsUint32x16</a> <a class="Documentation-idLink" href="#Uint8x64.AsUint32x16" title="Go to Uint8x64.AsUint32x16" aria-label="Go to Uint8x64.AsUint32x16">¶</a></span> +<span class="Documentation-sinceVersion"> +</span> +</h4> +<div class="Documentation-declaration"> +<pre>func (u <a href="#Uint8x64">Uint8x64</a>) AsUint32x16() <a href="#Uint32x16">Uint32x16</a></pre> +</div> +<p>AsUint32x16 converts a Uint8x64 to a Uint32x16. +</p> +</div><div class="Documentation-typeMethod"> +<h4 tabindex="-1" id="Uint8x64.AsUint64x8" data-kind="method" class="Documentation-typeMethodHeader"> +<span>func (Uint8x64) <a class="Documentation-source" href="src">AsUint64x8</a> <a class="Documentation-idLink" href="#Uint8x64.AsUint64x8" title="Go to Uint8x64.AsUint64x8" aria-label="Go to Uint8x64.AsUint64x8">¶</a></span> +<span class="Documentation-sinceVersion"> +</span> +</h4> +<div class="Documentation-declaration"> +<pre>func (u <a href="#Uint8x64">Uint8x64</a>) AsUint64x8() <a href="#Uint64x8">Uint64x8</a></pre> +</div> +<p>AsUint64x8 converts a Uint8x64 to a Uint64x8. +</p> +</div> +</div><div class="Documentation-type"> +<h4 tabindex="-1" id="Uint32x16" data-kind="type" class="Documentation-typeHeader"> +<span>type <a class="Documentation-source" href="src">Uint32x16</a> <a class="Documentation-idLink" href="#Uint32x16" title="Go to Uint32x16" aria-label="Go to Uint32x16">¶</a></span> +<span class="Documentation-sinceVersion"> +</span> +</h4> +<div class="Documentation-declaration"> +<pre>type Uint32x16 struct { +<span id="Uint32x16.data" data-kind="field"> data [16]<a href="/builtin#uint32">uint32</a> +</span>}</pre> +</div> +<p>Uint32x16 represents a 128-bit unsigned integer. +</p> +<div class="Documentation-typeMethod"> +<h4 tabindex="-1" id="Uint32x16.AsUint8x64" data-kind="method" class="Documentation-typeMethodHeader"> +<span>func (Uint32x16) <a class="Documentation-source" href="src">AsUint8x64</a> <a class="Documentation-idLink" href="#Uint32x16.AsUint8x64" title="Go to Uint32x16.AsUint8x64" aria-label="Go to Uint32x16.AsUint8x64">¶</a></span> +<span class="Documentation-sinceVersion"> +</span> +</h4> +<div class="Documentation-declaration"> +<pre>func (u <a href="#Uint32x16">Uint32x16</a>) AsUint8x64() <a href="#Uint8x64">Uint8x64</a></pre> +</div> +<p>AsUint8x64 converts a Uint32x16 to a Uint8x64. +</p> +</div><div class="Documentation-typeMethod"> +<h4 tabindex="-1" id="Uint32x16.AsUint64x8" data-kind="method" class="Documentation-typeMethodHeader"> +<span>func (Uint32x16) <a class="Documentation-source" href="src">AsUint64x8</a> <a class="Documentation-idLink" href="#Uint32x16.AsUint64x8" title="Go to Uint32x16.AsUint64x8" aria-label="Go to Uint32x16.AsUint64x8">¶</a></span> +<span class="Documentation-sinceVersion"> +</span> +</h4> +<div class="Documentation-declaration"> +<pre>func (u <a href="#Uint32x16">Uint32x16</a>) AsUint64x8() <a href="#Uint8x64">Uint8x64</a></pre> +</div> +<p>AsUint64x8 converts a Uint32x16 to a Uint64x8. +</p> +</div> +</div><div class="Documentation-type"> +<h4 tabindex="-1" id="Uint64x8" data-kind="type" class="Documentation-typeHeader"> +<span>type <a class="Documentation-source" href="src">Uint64x8</a> <a class="Documentation-idLink" href="#Uint64x8" title="Go to Uint64x8" aria-label="Go to Uint64x8">¶</a></span> +<span class="Documentation-sinceVersion"> +</span> +</h4> +<div class="Documentation-declaration"> +<pre>type Uint64x8 struct { +<span id="Uint64x8.data" data-kind="field"> data [8]<a href="/builtin#uint64">uint64</a> +</span>}</pre> +</div> +<p>Uint64x8 represents a 128-bit unsigned integer. +</p> +<div class="Documentation-typeMethod"> +<h4 tabindex="-1" id="Uint64x8.AsUint8x64" data-kind="method" class="Documentation-typeMethodHeader"> +<span>func (Uint64x8) <a class="Documentation-source" href="src">AsUint8x64</a> <a class="Documentation-idLink" href="#Uint64x8.AsUint8x64" title="Go to Uint64x8.AsUint8x64" aria-label="Go to Uint64x8.AsUint8x64">¶</a></span> +<span class="Documentation-sinceVersion"> +</span> +</h4> +<div class="Documentation-declaration"> +<pre>func (u <a href="#Uint64x8">Uint64x8</a>) AsUint8x64() <a href="#Uint8x64">Uint8x64</a></pre> +</div> +<p>AsUint8x64 converts a Uint64x8 to a Uint8x64. +</p> +</div><div class="Documentation-typeMethod"> +<h4 tabindex="-1" id="Uint64x8.AsUint32x16" data-kind="method" class="Documentation-typeMethodHeader"> +<span>func (Uint64x8) <a class="Documentation-source" href="src">AsUint32x16</a> <a class="Documentation-idLink" href="#Uint64x8.AsUint32x16" title="Go to Uint64x8.AsUint32x16" aria-label="Go to Uint64x8.AsUint32x16">¶</a></span> +<span class="Documentation-sinceVersion"> +</span> +</h4> +<div class="Documentation-declaration"> +<pre>func (u <a href="#Uint64x8">Uint64x8</a>) AsUint32x16() <a href="#Uint32x16">Uint32x16</a></pre> +</div> +<p>AsUint32x16 converts a Uint64x8 to a Uint32x16. +</p> +</div> +</div></section></div> +---- +<ul> +<li> +<a href="#pkg-overview" data-gtmc="doc outline link">Overview</a> +</li> +<li class="DocNav-overview"> +<a href="#pkg-index" data-gtmc="doc outline link"> +Index +</a> +</li> +<li class="DocNav-constants"> +<a href="#pkg-constants" data-gtmc="doc outline link"> +Constants +</a> +</li> +<li class="DocNav-variables"> +<a href="#pkg-variables" data-gtmc="doc outline link"> +Variables +</a> +</li> +<li class="DocNav-functions"> +<a href="#pkg-functions" data-gtmc="doc outline link"> +Functions +</a> +<ul> +<li> +<a href="#ExampleUint64x8_AsUint8x64" title="ExampleUint64x8_AsUint8x64()" data-gtmc="doc outline link"> +ExampleUint64x8_AsUint8x64() +</a> +</li> +<li> +<a href="#ExampleUint64x8_AsUint32x16" title="ExampleUint64x8_AsUint32x16()" data-gtmc="doc outline link"> +ExampleUint64x8_AsUint32x16() +</a> +</li> +</ul> +</li> +<li class="DocNav-types"> +<a href="#pkg-types" data-gtmc="doc outline link"> +Types +</a> +<ul> +<li> +<a href="#Uint8x64" title="type Uint8x64" data-gtmc="doc outline link"> +type Uint8x64 +</a> +<ul> +<li> +<a href="#Uint8x64.AsUint32x16" title="(u) AsUint32x16()" +data-gtmc="doc outline link"> +(u) AsUint32x16() +</a> +</li> +<li> +<a href="#Uint8x64.AsUint64x8" title="(u) AsUint64x8()" +data-gtmc="doc outline link"> +(u) AsUint64x8() +</a> +</li> +</ul> +</li> +<li> +<a href="#Uint32x16" title="type Uint32x16" data-gtmc="doc outline link"> +type Uint32x16 +</a> +<ul> +<li> +<a href="#Uint32x16.AsUint8x64" title="(u) AsUint8x64()" +data-gtmc="doc outline link"> +(u) AsUint8x64() +</a> +</li> +<li> +<a href="#Uint32x16.AsUint64x8" title="(u) AsUint64x8()" +data-gtmc="doc outline link"> +(u) AsUint64x8() +</a> +</li> +</ul> +</li> +<li> +<a href="#Uint64x8" title="type Uint64x8" data-gtmc="doc outline link"> +type Uint64x8 +</a> +<ul> +<li> +<a href="#Uint64x8.AsUint8x64" title="(u) AsUint8x64()" +data-gtmc="doc outline link"> +(u) AsUint8x64() +</a> +</li> +<li> +<a href="#Uint64x8.AsUint32x16" title="(u) AsUint32x16()" +data-gtmc="doc outline link"> +(u) AsUint32x16() +</a> +</li> +</ul> +</li> +</ul> +</li> +</ul> +---- +<optgroup label="Documentation"> +<option value="pkg-overview">Overview</option> +<option value="pkg-index">Index</option> +</optgroup> +<optgroup label="Functions"> +<option value="ExampleUint64x8_AsUint8x64">ExampleUint64x8_AsUint8x64()</option> +<option value="ExampleUint64x8_AsUint32x16">ExampleUint64x8_AsUint32x16()</option> +</optgroup> +<optgroup label="Types"> +<option value="Uint8x64">type Uint8x64</option> +<option value="Uint8x64.AsUint32x16">(u) AsUint32x16()</option> +<option value="Uint8x64.AsUint64x8">(u) AsUint64x8()</option> +<option value="Uint32x16">type Uint32x16</option> +<option value="Uint32x16.AsUint8x64">(u) AsUint8x64()</option> +<option value="Uint32x16.AsUint64x8">(u) AsUint64x8()</option> +<option value="Uint64x8">type Uint64x8</option> +<option value="Uint64x8.AsUint8x64">(u) AsUint8x64()</option> +<option value="Uint64x8.AsUint32x16">(u) AsUint32x16()</option> +</optgroup> |
