aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2012-01-13 09:32:35 -0800
committerRobert Griesemer <gri@golang.org>2012-01-13 09:32:35 -0800
commitc7cdce13f55070383efd8251bce6e95118c32bb2 (patch)
tree951086007d39d6c09958078e2dce2db84cbc2b8a
parent1627b46eaa6403775611017e91cceae2e45662b2 (diff)
downloadgo-c7cdce13f55070383efd8251bce6e95118c32bb2.tar.gz
go-c7cdce13f55070383efd8251bce6e95118c32bb2.zip
godoc: make ?m=src mode deterministic
Merge package files in the go/ast MergePackageFiles function always in the same order (sorted by filename) instead of map iteration order to obtain the same package file each time. This functionality is used by godoc when displaying packages in ?m=src mode. Also: minor cleanup in godoc.go. R=rsc CC=golang-dev https://golang.org/cl/5540054
-rw-r--r--src/cmd/godoc/godoc.go12
-rw-r--r--src/pkg/go/ast/filter.go31
2 files changed, 27 insertions, 16 deletions
diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go
index c544d5d4c4..92273ceaed 100644
--- a/src/cmd/godoc/godoc.go
+++ b/src/cmd/godoc/godoc.go
@@ -1086,18 +1086,18 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf
var past *ast.File
var pdoc *doc.Package
if pkg != nil {
- var docMode doc.Mode
- if mode&noFiltering != 0 {
- docMode = doc.AllDecls
- }
if mode&showSource == 0 {
// show extracted documentation
- pdoc = doc.New(pkg, path.Clean(relpath), docMode) // no trailing '/' in importpath
+ var m doc.Mode
+ if mode&noFiltering != 0 {
+ m = doc.AllDecls
+ }
+ pdoc = doc.New(pkg, path.Clean(relpath), m) // no trailing '/' in importpath
} else {
// show source code
// TODO(gri) Consider eliminating export filtering in this mode,
// or perhaps eliminating the mode altogether.
- if docMode&doc.AllDecls == 0 {
+ if mode&noFiltering == 0 {
ast.PackageExports(pkg)
}
past = ast.MergePackageFiles(pkg, ast.FilterUnassociatedComments)
diff --git a/src/pkg/go/ast/filter.go b/src/pkg/go/ast/filter.go
index bec235e2f9..b3f3f74856 100644
--- a/src/pkg/go/ast/filter.go
+++ b/src/pkg/go/ast/filter.go
@@ -4,7 +4,10 @@
package ast
-import "go/token"
+import (
+ "go/token"
+ "sort"
+)
// ----------------------------------------------------------------------------
// Export filtering
@@ -291,29 +294,35 @@ var separator = &Comment{noPos, "//"}
//
func MergePackageFiles(pkg *Package, mode MergeMode) *File {
// Count the number of package docs, comments and declarations across
- // all package files.
+ // all package files. Also, compute sorted list of filenames, so that
+ // subsequent iterations can always iterate in the same order.
ndocs := 0
ncomments := 0
ndecls := 0
- for _, f := range pkg.Files {
+ filenames := make([]string, len(pkg.Files))
+ i := 0
+ for filename, f := range pkg.Files {
+ filenames[i] = filename
+ i++
if f.Doc != nil {
ndocs += len(f.Doc.List) + 1 // +1 for separator
}
ncomments += len(f.Comments)
ndecls += len(f.Decls)
}
+ sort.Strings(filenames)
// Collect package comments from all package files into a single
- // CommentGroup - the collected package documentation. The order
- // is unspecified. In general there should be only one file with
- // a package comment; but it's better to collect extra comments
- // than drop them on the floor.
+ // CommentGroup - the collected package documentation. In general
+ // there should be only one file with a package comment; but it's
+ // better to collect extra comments than drop them on the floor.
var doc *CommentGroup
var pos token.Pos
if ndocs > 0 {
list := make([]*Comment, ndocs-1) // -1: no separator before first group
i := 0
- for _, f := range pkg.Files {
+ for _, filename := range filenames {
+ f := pkg.Files[filename]
if f.Doc != nil {
if i > 0 {
// not the first group - add separator
@@ -342,7 +351,8 @@ func MergePackageFiles(pkg *Package, mode MergeMode) *File {
funcs := make(map[string]int) // map of global function name -> decls index
i := 0 // current index
n := 0 // number of filtered entries
- for _, f := range pkg.Files {
+ for _, filename := range filenames {
+ f := pkg.Files[filename]
for _, d := range f.Decls {
if mode&FilterFuncDuplicates != 0 {
// A language entity may be declared multiple
@@ -398,7 +408,8 @@ func MergePackageFiles(pkg *Package, mode MergeMode) *File {
var imports []*ImportSpec
if mode&FilterImportDuplicates != 0 {
seen := make(map[string]bool)
- for _, f := range pkg.Files {
+ for _, filename := range filenames {
+ f := pkg.Files[filename]
for _, imp := range f.Imports {
if path := imp.Path.Value; !seen[path] {
// TODO: consider handling cases where: