]> Cypherpunks repositories - gostls13.git/commitdiff
godoc: make ?m=src mode deterministic
authorRobert Griesemer <gri@golang.org>
Fri, 13 Jan 2012 17:32:35 +0000 (09:32 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 13 Jan 2012 17:32:35 +0000 (09:32 -0800)
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

src/cmd/godoc/godoc.go
src/pkg/go/ast/filter.go

index c544d5d4c4c01ca1c35a8d1fb0bfd0ebba336bee..92273ceaedc5433db31ad02517a41cbed05f44f2 100644 (file)
@@ -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)
index bec235e2f98480c54dc2bf9ae9688b132eb9245e..b3f3f7485647e87fc8fe496a9794333a8362c198 100644 (file)
@@ -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: