diff --git a/lib/godoc/search.html b/lib/godoc/search.html index 927910f6565..e715df3439c 100644 --- a/lib/godoc/search.html +++ b/lib/godoc/search.html @@ -22,7 +22,7 @@ {.section Decls}

Package-level declarations

{.repeated section @} -

package {Pak.Name|html}

+

package {Pak.Name|html}

{.repeated section Files} {.repeated section Groups} {.repeated section Infos} @@ -36,7 +36,7 @@ {.section Others}

Local declarations and uses

{.repeated section @} -

package {Pak.Name|html}

+

package {Pak.Name|html}

{.repeated section Files} {File.Path|html} @@ -56,7 +56,11 @@ {.end} {.end} {.end} -{.or} +{.end} +{.section Illegal} +

+ Illegal query syntax +

A legal query is a single identifier (such as ToLower) or a qualified identifier (such as math.Sin). diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go index eb97253508c..91e21ea463e 100644 --- a/src/cmd/godoc/godoc.go +++ b/src/cmd/godoc/godoc.go @@ -1088,6 +1088,7 @@ type SearchResult struct { Query string; Hit *LookupResult; Alt *AltWords; + Illegal bool; Accurate bool; } @@ -1097,7 +1098,7 @@ func search(c *http.Conn, r *http.Request) { if index, timestamp := searchIndex.get(); index != nil { result.Query = query; - result.Hit, result.Alt = index.(*Index).Lookup(query); + result.Hit, result.Alt, result.Illegal = index.(*Index).Lookup(query); _, ts := fsTree.get(); result.Accurate = timestamp >= ts; } diff --git a/src/cmd/godoc/index.go b/src/cmd/godoc/index.go index 00c8cf2c731..223019cf87f 100644 --- a/src/cmd/godoc/index.go +++ b/src/cmd/godoc/index.go @@ -29,6 +29,7 @@ import ( "go/ast"; "go/parser"; "go/token"; + "go/scanner"; "os"; pathutil "path"; "sort"; @@ -411,6 +412,11 @@ func (a *AltWords) filter(s string) *AltWords { // ---------------------------------------------------------------------------- // Indexer +// Adjust these flags as seems best. +const excludeMainPackages = false +const excludeTestFiles = false + + type IndexResult struct { Decls RunList; // package-level declarations (with snippets) Others RunList; // all other occurences @@ -583,6 +589,14 @@ func (x *Indexer) VisitFile(path string, d *os.Dir) { return; } + if excludeTestFiles && (!isPkgFile(d) || strings.HasPrefix(path, "test/")) { + return; + } + + if excludeMainPackages && pkgName(path) == "main" { + return; + } + file, err := parser.ParseFile(path, nil, parser.ParseComments); if err != nil { return; // ignore files with (parse) errors @@ -681,11 +695,30 @@ func (x *Index) LookupWord(w string) (match *LookupResult, alt *AltWords) { } -// For a given string s, which is either a single identifier or a qualified +func isIdentifier(s string) bool { + var S scanner.Scanner; + S.Init("", strings.Bytes(s), nil, 0); + if _, tok, _ := S.Scan(); tok == token.IDENT { + _, tok, _ := S.Scan(); + return tok == token.EOF; + } + return false; +} + + +// For a given query, which is either a single identifier or a qualified // identifier, Lookup returns a LookupResult, and a list of alternative -// spellings, if any. -func (x *Index) Lookup(s string) (match *LookupResult, alt *AltWords) { - ss := strings.Split(s, ".", 0); +// spellings, if any. If the query syntax is wrong, illegal is set. +func (x *Index) Lookup(query string) (match *LookupResult, alt *AltWords, illegal bool) { + ss := strings.Split(query, ".", 0); + + // check query syntax + for _, s := range ss { + if !isIdentifier(s) { + illegal = true; + return; + } + } switch len(ss) { case 1: @@ -700,18 +733,9 @@ func (x *Index) Lookup(s string) (match *LookupResult, alt *AltWords) { others := match.Others.filter(pakname); match = &LookupResult{decls, others}; } - if alt != nil { - // alternative spellings found - add package name - // TODO(gri): At the moment this is not very smart - // and likely will produce suggestions that have - // no match. Should filter incorrect alternatives. - canon := pakname + "." + alt.Canon; // for completeness (currently not used) - alts := make([]string, len(alt.Alts)); - for i, a := range alt.Alts { - alts[i] = pakname+"."+a; - } - alt = &AltWords{canon, alts}; - } + + default: + illegal = true; } return;