diff options
Diffstat (limited to 'src/cmd/godoc/index.go')
-rw-r--r-- | src/cmd/godoc/index.go | 61 |
1 files changed, 48 insertions, 13 deletions
diff --git a/src/cmd/godoc/index.go b/src/cmd/godoc/index.go index b99363491..2543f9216 100644 --- a/src/cmd/godoc/index.go +++ b/src/cmd/godoc/index.go @@ -48,7 +48,7 @@ import ( "io" "os" "path/filepath" - "regexp" + "exp/regexp" "sort" "strings" ) @@ -344,6 +344,8 @@ func reduce(h0 RunList) HitList { return h } +// filter returns a new HitList created by filtering +// all PakRuns from h that have a matching pakname. func (h HitList) filter(pakname string) HitList { var hh HitList for _, p := range h { @@ -831,34 +833,58 @@ func NewIndex(dirnames <-chan string, fulltextIndex bool, throttle float64) *Ind return &Index{x.fset, suffixes, words, alts, x.snippets, x.stats} } -type FileIndex struct { +type fileIndex struct { Words map[string]*LookupResult Alts map[string]*AltWords Snippets []*Snippet + Fulltext bool } // Write writes the index x to w. func (x *Index) Write(w io.Writer) os.Error { + fulltext := false if x.suffixes != nil { - panic("no support for writing full text index yet") + fulltext = true } - fx := FileIndex{ + fx := fileIndex{ x.words, x.alts, x.snippets, + fulltext, } - return gob.NewEncoder(w).Encode(fx) + if err := gob.NewEncoder(w).Encode(fx); err != nil { + return err + } + if fulltext { + if err := x.fset.Write(w); err != nil { + return err + } + if err := x.suffixes.Write(w); err != nil { + return err + } + } + return nil } // Read reads the index from r into x; x must not be nil. func (x *Index) Read(r io.Reader) os.Error { - var fx FileIndex + var fx fileIndex if err := gob.NewDecoder(r).Decode(&fx); err != nil { return err } x.words = fx.Words x.alts = fx.Alts x.snippets = fx.Snippets + if fx.Fulltext { + x.fset = token.NewFileSet() + if err := x.fset.Read(r); err != nil { + return err + } + x.suffixes = new(suffixarray.Index) + if err := x.suffixes.Read(r); err != nil { + return err + } + } return nil } @@ -867,7 +893,7 @@ func (x *Index) Stats() Statistics { return x.stats } -func (x *Index) LookupWord(w string) (match *LookupResult, alt *AltWords) { +func (x *Index) lookupWord(w string) (match *LookupResult, alt *AltWords) { match = x.words[w] alt = x.alts[canonical(w)] // remove current spelling from alternatives @@ -891,9 +917,10 @@ func isIdentifier(s string) bool { } // 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. If the query syntax is wrong, an error is reported. -func (x *Index) Lookup(query string) (match *LookupResult, alt *AltWords, err os.Error) { +// identifier, Lookup returns a list of packages, a LookupResult, and a +// list of alternative spellings, if any. Any and all results may be nil. +// If the query syntax is wrong, an error is reported. +func (x *Index) Lookup(query string) (paks HitList, match *LookupResult, alt *AltWords, err os.Error) { ss := strings.Split(query, ".") // check query syntax @@ -904,15 +931,23 @@ func (x *Index) Lookup(query string) (match *LookupResult, alt *AltWords, err os } } + // handle simple and qualified identifiers switch len(ss) { case 1: - match, alt = x.LookupWord(ss[0]) + ident := ss[0] + match, alt = x.lookupWord(ident) + if match != nil { + // found a match - filter packages with same name + // for the list of packages called ident, if any + paks = match.Others.filter(ident) + } case 2: - pakname := ss[0] - match, alt = x.LookupWord(ss[1]) + pakname, ident := ss[0], ss[1] + match, alt = x.lookupWord(ident) if match != nil { // found a match - filter by package name + // (no paks - package names are not qualified) decls := match.Decls.filter(pakname) others := match.Others.filter(pakname) match = &LookupResult{decls, others} |