github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/godoc/corpus.go (about)

     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.
     4  
     5  package godoc
     6  
     7  import (
     8  	"errors"
     9  	pathpkg "path"
    10  	"time"
    11  
    12  	"golang.org/x/tools/godoc/analysis"
    13  	"golang.org/x/tools/godoc/util"
    14  	"golang.org/x/tools/godoc/vfs"
    15  )
    16  
    17  // A Corpus holds all the state related to serving and indexing a
    18  // collection of Go code.
    19  //
    20  // Construct a new Corpus with NewCorpus, then modify options,
    21  // then call its Init method.
    22  type Corpus struct {
    23  	fs vfs.FileSystem
    24  
    25  	// Verbose logging.
    26  	Verbose bool
    27  
    28  	// IndexEnabled controls whether indexing is enabled.
    29  	IndexEnabled bool
    30  
    31  	// IndexFiles specifies a glob pattern specifying index files.
    32  	// If not empty, the index is read from these files in sorted
    33  	// order.
    34  	IndexFiles string
    35  
    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.
    41  	IndexThrottle float64
    42  
    43  	// IndexInterval specifies the time to sleep between reindexing
    44  	// all the sources.
    45  	// If zero, a default is used. If negative, the index is only
    46  	// built once.
    47  	IndexInterval time.Duration
    48  
    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.
    53  	IndexDocs bool
    54  
    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
    58  	// source code.
    59  	IndexGoCode bool
    60  
    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.
    65  	IndexFullText bool
    66  
    67  	// MaxResults optionally specifies the maximum results for indexing.
    68  	MaxResults int
    69  
    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.
    73  	//
    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.
    77  	//
    78  	// If showList is false, the package is hidden from the
    79  	// package listing.
    80  	SummarizePackage func(pkg string) (summary string, showList, ok bool)
    81  
    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",
    85  	// "/src/io", etc.
    86  	// If nil, all directories are indexed if indexing is enabled.
    87  	IndexDirectory func(dir string) bool
    88  
    89  	testDir string // TODO(bradfitz,adg): migrate old godoc flag? looks unused.
    90  
    91  	// Send a value on this channel to trigger a metadata refresh.
    92  	// It is buffered so that if a signal is not lost if sent
    93  	// during a refresh.
    94  	refreshMetadataSignal chan bool
    95  
    96  	// file system information
    97  	fsTree      util.RWValue // *Directory tree of packages, updated with each sync (but sync code is removed now)
    98  	fsModified  util.RWValue // timestamp of last call to invalidateIndex
    99  	docMetadata util.RWValue // mapping from paths to *Metadata
   100  
   101  	// SearchIndex is the search index in use.
   102  	searchIndex util.RWValue
   103  
   104  	// Analysis is the result of type and pointer analysis.
   105  	Analysis analysis.Result
   106  }
   107  
   108  // NewCorpus returns a new Corpus from a filesystem.
   109  // The returned corpus has all indexing enabled and MaxResults set to 1000.
   110  // Change or set any options on Corpus before calling the Corpus.Init method.
   111  func NewCorpus(fs vfs.FileSystem) *Corpus {
   112  	c := &Corpus{
   113  		fs: fs,
   114  		refreshMetadataSignal: make(chan bool, 1),
   115  
   116  		MaxResults:    1000,
   117  		IndexEnabled:  true,
   118  		IndexDocs:     true,
   119  		IndexGoCode:   true,
   120  		IndexFullText: true,
   121  	}
   122  	return c
   123  }
   124  
   125  func (c *Corpus) CurrentIndex() (*Index, time.Time) {
   126  	v, t := c.searchIndex.Get()
   127  	idx, _ := v.(*Index)
   128  	return idx, t
   129  }
   130  
   131  func (c *Corpus) FSModifiedTime() time.Time {
   132  	_, ts := c.fsModified.Get()
   133  	return ts
   134  }
   135  
   136  // Init initializes Corpus, once options on Corpus are set.
   137  // It must be called before any subsequent method calls.
   138  func (c *Corpus) Init() error {
   139  	// TODO(bradfitz): do this in a goroutine because newDirectory might block for a long time?
   140  	// It used to be sometimes done in a goroutine before, at least in HTTP server mode.
   141  	if err := c.initFSTree(); err != nil {
   142  		return err
   143  	}
   144  	c.updateMetadata()
   145  	go c.refreshMetadataLoop()
   146  	return nil
   147  }
   148  
   149  func (c *Corpus) initFSTree() error {
   150  	dir := c.newDirectory(pathpkg.Join("/", c.testDir), -1)
   151  	if dir == nil {
   152  		return errors.New("godoc: corpus fstree is nil")
   153  	}
   154  	c.fsTree.Set(dir)
   155  	c.invalidateIndex()
   156  	return nil
   157  }