|  | // Copyright 2013 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 godoc | 
|  |  | 
|  | import ( | 
|  | "errors" | 
|  | "sync" | 
|  | "time" | 
|  |  | 
|  | "golang.org/x/tools/godoc/analysis" | 
|  | "golang.org/x/tools/godoc/util" | 
|  | "golang.org/x/tools/godoc/vfs" | 
|  | ) | 
|  |  | 
|  | // A Corpus holds all the state related to serving and indexing a | 
|  | // collection of Go code. | 
|  | // | 
|  | // Construct a new Corpus with NewCorpus, then modify options, | 
|  | // then call its Init method. | 
|  | type Corpus struct { | 
|  | fs vfs.FileSystem | 
|  |  | 
|  | // Verbose logging. | 
|  | Verbose bool | 
|  |  | 
|  | // IndexEnabled controls whether indexing is enabled. | 
|  | IndexEnabled bool | 
|  |  | 
|  | // IndexFiles specifies a glob pattern specifying index files. | 
|  | // If not empty, the index is read from these files in sorted | 
|  | // order. | 
|  | IndexFiles string | 
|  |  | 
|  | // IndexThrottle specifies the indexing throttle value | 
|  | // between 0.0 and 1.0. At 0.0, the indexer always sleeps. | 
|  | // At 1.0, the indexer never sleeps. Because 0.0 is useless | 
|  | // and redundant with setting IndexEnabled to false, the | 
|  | // zero value for IndexThrottle means 0.9. | 
|  | IndexThrottle float64 | 
|  |  | 
|  | // IndexInterval specifies the time to sleep between reindexing | 
|  | // all the sources. | 
|  | // If zero, a default is used. If negative, the index is only | 
|  | // built once. | 
|  | IndexInterval time.Duration | 
|  |  | 
|  | // IndexDocs enables indexing of Go documentation. | 
|  | // This will produce search results for exported types, functions, | 
|  | // methods, variables, and constants, and will link to the godoc | 
|  | // documentation for those identifiers. | 
|  | IndexDocs bool | 
|  |  | 
|  | // IndexGoCode enables indexing of Go source code. | 
|  | // This will produce search results for internal and external identifiers | 
|  | // and will link to both declarations and uses of those identifiers in | 
|  | // source code. | 
|  | IndexGoCode bool | 
|  |  | 
|  | // IndexFullText enables full-text indexing. | 
|  | // This will provide search results for any matching text in any file that | 
|  | // is indexed, including non-Go files (see whitelisted in index.go). | 
|  | // Regexp searching is supported via full-text indexing. | 
|  | IndexFullText bool | 
|  |  | 
|  | // MaxResults optionally specifies the maximum results for indexing. | 
|  | MaxResults int | 
|  |  | 
|  | // SummarizePackage optionally specifies a function to | 
|  | // summarize a package. It exists as an optimization to | 
|  | // avoid reading files to parse package comments. | 
|  | // | 
|  | // If SummarizePackage returns false for ok, the caller | 
|  | // ignores all return values and parses the files in the package | 
|  | // as if SummarizePackage were nil. | 
|  | // | 
|  | // If showList is false, the package is hidden from the | 
|  | // package listing. | 
|  | SummarizePackage func(pkg string) (summary string, showList, ok bool) | 
|  |  | 
|  | // IndexDirectory optionally specifies a function to determine | 
|  | // whether the provided directory should be indexed.  The dir | 
|  | // will be of the form "/src/cmd/6a", "/doc/play", | 
|  | // "/src/io", etc. | 
|  | // If nil, all directories are indexed if indexing is enabled. | 
|  | IndexDirectory func(dir string) bool | 
|  |  | 
|  | // Send a value on this channel to trigger a metadata refresh. | 
|  | // It is buffered so that if a signal is not lost if sent | 
|  | // during a refresh. | 
|  | refreshMetadataSignal chan bool | 
|  |  | 
|  | // file system information | 
|  | fsTree      util.RWValue // *Directory tree of packages, updated with each sync (but sync code is removed now) | 
|  | fsModified  util.RWValue // timestamp of last call to invalidateIndex | 
|  | docMetadata util.RWValue // mapping from paths to *Metadata | 
|  |  | 
|  | // SearchIndex is the search index in use. | 
|  | searchIndex util.RWValue | 
|  |  | 
|  | // Analysis is the result of type and pointer analysis. | 
|  | Analysis analysis.Result | 
|  |  | 
|  | // flag to check whether a corpus is initialized or not | 
|  | initMu   sync.RWMutex | 
|  | initDone bool | 
|  |  | 
|  | // pkgAPIInfo contains the information about which package API | 
|  | // features were added in which version of Go. | 
|  | pkgAPIInfo apiVersions | 
|  | } | 
|  |  | 
|  | // NewCorpus returns a new Corpus from a filesystem. | 
|  | // The returned corpus has all indexing enabled and MaxResults set to 1000. | 
|  | // Change or set any options on Corpus before calling the Corpus.Init method. | 
|  | func NewCorpus(fs vfs.FileSystem) *Corpus { | 
|  | c := &Corpus{ | 
|  | fs:                    fs, | 
|  | refreshMetadataSignal: make(chan bool, 1), | 
|  |  | 
|  | MaxResults:    1000, | 
|  | IndexEnabled:  true, | 
|  | IndexDocs:     true, | 
|  | IndexGoCode:   true, | 
|  | IndexFullText: true, | 
|  | } | 
|  | return c | 
|  | } | 
|  |  | 
|  | func (c *Corpus) CurrentIndex() (*Index, time.Time) { | 
|  | v, t := c.searchIndex.Get() | 
|  | idx, _ := v.(*Index) | 
|  | return idx, t | 
|  | } | 
|  |  | 
|  | func (c *Corpus) FSModifiedTime() time.Time { | 
|  | _, ts := c.fsModified.Get() | 
|  | return ts | 
|  | } | 
|  |  | 
|  | // Init initializes Corpus, once options on Corpus are set. | 
|  | // It must be called before any subsequent method calls. | 
|  | func (c *Corpus) Init() error { | 
|  | if err := c.initFSTree(); err != nil { | 
|  | return err | 
|  | } | 
|  | c.updateMetadata() | 
|  | go c.refreshMetadataLoop() | 
|  |  | 
|  | c.initMu.Lock() | 
|  | c.initDone = true | 
|  | c.initMu.Unlock() | 
|  | return nil | 
|  | } | 
|  |  | 
|  | func (c *Corpus) initFSTree() error { | 
|  | dir := c.newDirectory("/", -1) | 
|  | if dir == nil { | 
|  | return errors.New("godoc: corpus fstree is nil") | 
|  | } | 
|  | c.fsTree.Set(dir) | 
|  | c.invalidateIndex() | 
|  | return nil | 
|  | } |