1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 "golang.org/x/tools/godoc/analysis"
13 "golang.org/x/tools/godoc/util"
14 "golang.org/x/tools/godoc/vfs"
17 // A Corpus holds all the state related to serving and indexing a
18 // collection of Go code.
20 // Construct a new Corpus with NewCorpus, then modify options,
21 // then call its Init method.
28 // IndexEnabled controls whether indexing is enabled.
31 // IndexFiles specifies a glob pattern specifying index files.
32 // If not empty, the index is read from these files in sorted
36 // IndexThrottle specifies the indexing throttle value
37 // between 0.0 and 1.0. At 0.0, the indexer always sleeps.
38 // At 1.0, the indexer never sleeps. Because 0.0 is useless
39 // and redundant with setting IndexEnabled to false, the
40 // zero value for IndexThrottle means 0.9.
43 // IndexInterval specifies the time to sleep between reindexing
45 // If zero, a default is used. If negative, the index is only
47 IndexInterval time.Duration
49 // IndexDocs enables indexing of Go documentation.
50 // This will produce search results for exported types, functions,
51 // methods, variables, and constants, and will link to the godoc
52 // documentation for those identifiers.
55 // IndexGoCode enables indexing of Go source code.
56 // This will produce search results for internal and external identifiers
57 // and will link to both declarations and uses of those identifiers in
61 // IndexFullText enables full-text indexing.
62 // This will provide search results for any matching text in any file that
63 // is indexed, including non-Go files (see whitelisted in index.go).
64 // Regexp searching is supported via full-text indexing.
67 // MaxResults optionally specifies the maximum results for indexing.
70 // SummarizePackage optionally specifies a function to
71 // summarize a package. It exists as an optimization to
72 // avoid reading files to parse package comments.
74 // If SummarizePackage returns false for ok, the caller
75 // ignores all return values and parses the files in the package
76 // as if SummarizePackage were nil.
78 // If showList is false, the package is hidden from the
80 SummarizePackage func(pkg string) (summary string, showList, ok bool)
82 // IndexDirectory optionally specifies a function to determine
83 // whether the provided directory should be indexed. The dir
84 // will be of the form "/src/cmd/6a", "/doc/play",
86 // If nil, all directories are indexed if indexing is enabled.
87 IndexDirectory func(dir string) bool
89 // Send a value on this channel to trigger a metadata refresh.
90 // It is buffered so that if a signal is not lost if sent
92 refreshMetadataSignal chan bool
94 // file system information
95 fsTree util.RWValue // *Directory tree of packages, updated with each sync (but sync code is removed now)
96 fsModified util.RWValue // timestamp of last call to invalidateIndex
97 docMetadata util.RWValue // mapping from paths to *Metadata
99 // SearchIndex is the search index in use.
100 searchIndex util.RWValue
102 // Analysis is the result of type and pointer analysis.
103 Analysis analysis.Result
105 // flag to check whether a corpus is initialized or not
109 // pkgAPIInfo contains the information about which package API
110 // features were added in which version of Go.
111 pkgAPIInfo apiVersions
114 // NewCorpus returns a new Corpus from a filesystem.
115 // The returned corpus has all indexing enabled and MaxResults set to 1000.
116 // Change or set any options on Corpus before calling the Corpus.Init method.
117 func NewCorpus(fs vfs.FileSystem) *Corpus {
120 refreshMetadataSignal: make(chan bool, 1),
131 func (c *Corpus) CurrentIndex() (*Index, time.Time) {
132 v, t := c.searchIndex.Get()
137 func (c *Corpus) FSModifiedTime() time.Time {
138 _, ts := c.fsModified.Get()
142 // Init initializes Corpus, once options on Corpus are set.
143 // It must be called before any subsequent method calls.
144 func (c *Corpus) Init() error {
145 if err := c.initFSTree(); err != nil {
149 go c.refreshMetadataLoop()
157 func (c *Corpus) initFSTree() error {
158 dir := c.newDirectory("/", -1)
160 return errors.New("godoc: corpus fstree is nil")