LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // This file contains the infrastructure to create an | 5 // This file contains the infrastructure to create an |
6 // identifier and full-text index for a set of Go files. | 6 // identifier and full-text index for a set of Go files. |
7 // | 7 // |
8 // Algorithm for identifier index: | 8 // Algorithm for identifier index: |
9 // - traverse all .go files of the file tree specified by root | 9 // - traverse all .go files of the file tree specified by root |
10 // - for each word (identifier) encountered, collect all occurences (spots) | 10 // - for each word (identifier) encountered, collect all occurrences (spots) |
11 // into a list; this produces a list of spots for each word | 11 // into a list; this produces a list of spots for each word |
12 // - reduce the lists: from a list of spots to a list of FileRuns, | 12 // - reduce the lists: from a list of spots to a list of FileRuns, |
13 // and from a list of FileRuns into a list of PakRuns | 13 // and from a list of FileRuns into a list of PakRuns |
14 // - make a HitList from the PakRuns | 14 // - make a HitList from the PakRuns |
15 // | 15 // |
16 // Details: | 16 // Details: |
17 // - keep two lists per word: one containing package-level declarations | 17 // - keep two lists per word: one containing package-level declarations |
18 // that have snippets, and one containing all other spots | 18 // that have snippets, and one containing all other spots |
19 // - keep the snippets in a separate table indexed by snippet index | 19 // - keep the snippets in a separate table indexed by snippet index |
20 // and store the snippet index in place of the line number in a SpotInfo | 20 // and store the snippet index in place of the line number in a SpotInfo |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 } | 241 } |
242 | 242 |
243 | 243 |
244 // A File describes a Go file. | 244 // A File describes a Go file. |
245 type File struct { | 245 type File struct { |
246 Path string // complete file name | 246 Path string // complete file name |
247 Pak Pak // the package to which the file belongs | 247 Pak Pak // the package to which the file belongs |
248 } | 248 } |
249 | 249 |
250 | 250 |
251 // A Spot describes a single occurence of a word. | 251 // A Spot describes a single occurrence of a word. |
252 type Spot struct { | 252 type Spot struct { |
253 File *File | 253 File *File |
254 Info SpotInfo | 254 Info SpotInfo |
255 } | 255 } |
256 | 256 |
257 | 257 |
258 // A FileRun is a list of KindRuns belonging to the same file. | 258 // A FileRun is a list of KindRuns belonging to the same file. |
259 type FileRun struct { | 259 type FileRun struct { |
260 File *File | 260 File *File |
261 Groups []*KindRun | 261 Groups []*KindRun |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 // ---------------------------------------------------------------------------- | 429 // ---------------------------------------------------------------------------- |
430 // Indexer | 430 // Indexer |
431 | 431 |
432 // Adjust these flags as seems best. | 432 // Adjust these flags as seems best. |
433 const excludeMainPackages = false | 433 const excludeMainPackages = false |
434 const excludeTestFiles = false | 434 const excludeTestFiles = false |
435 | 435 |
436 | 436 |
437 type IndexResult struct { | 437 type IndexResult struct { |
438 Decls RunList // package-level declarations (with snippets) | 438 Decls RunList // package-level declarations (with snippets) |
439 » Others RunList // all other occurences | 439 » Others RunList // all other occurrences |
440 } | 440 } |
441 | 441 |
442 | 442 |
443 // Statistics provides statistics information for an index. | 443 // Statistics provides statistics information for an index. |
444 type Statistics struct { | 444 type Statistics struct { |
445 Bytes int // total size of indexed source files | 445 Bytes int // total size of indexed source files |
446 Files int // number of indexed source files | 446 Files int // number of indexed source files |
447 Lines int // number of lines (all files) | 447 Lines int // number of lines (all files) |
448 Words int // number of different identifiers | 448 Words int // number of different identifiers |
449 » Spots int // number of identifier occurences | 449 » Spots int // number of identifier occurrences |
450 } | 450 } |
451 | 451 |
452 | 452 |
453 // An Indexer maintains the data structures and provides the machinery | 453 // An Indexer maintains the data structures and provides the machinery |
454 // for indexing .go files under a file tree. It implements the path.Visitor | 454 // for indexing .go files under a file tree. It implements the path.Visitor |
455 // interface for walking file trees, and the ast.Visitor interface for | 455 // interface for walking file trees, and the ast.Visitor interface for |
456 // walking Go ASTs. | 456 // walking Go ASTs. |
457 type Indexer struct { | 457 type Indexer struct { |
458 fset *token.FileSet // file set for all indexed files | 458 fset *token.FileSet // file set for all indexed files |
459 sources bytes.Buffer // concatenated sources | 459 sources bytes.Buffer // concatenated sources |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 x.stats.Files++ | 703 x.stats.Files++ |
704 x.stats.Lines += x.current.LineCount() | 704 x.stats.Lines += x.current.LineCount() |
705 } | 705 } |
706 | 706 |
707 | 707 |
708 // ---------------------------------------------------------------------------- | 708 // ---------------------------------------------------------------------------- |
709 // Index | 709 // Index |
710 | 710 |
711 type LookupResult struct { | 711 type LookupResult struct { |
712 Decls HitList // package-level declarations (with snippets) | 712 Decls HitList // package-level declarations (with snippets) |
713 » Others HitList // all other occurences | 713 » Others HitList // all other occurrences |
714 } | 714 } |
715 | 715 |
716 | 716 |
717 type Index struct { | 717 type Index struct { |
718 fset *token.FileSet // file set used during indexing; nil
if no textindex | 718 fset *token.FileSet // file set used during indexing; nil
if no textindex |
719 suffixes *suffixarray.Index // suffixes for concatenated sources;
nil if no textindex | 719 suffixes *suffixarray.Index // suffixes for concatenated sources;
nil if no textindex |
720 words map[string]*LookupResult // maps words to hit lists | 720 words map[string]*LookupResult // maps words to hit lists |
721 alts map[string]*AltWords // maps canonical(words) to lists of a
lternative spellings | 721 alts map[string]*AltWords // maps canonical(words) to lists of a
lternative spellings |
722 snippets []*Snippet // all snippets, indexed by snippet in
dex | 722 snippets []*Snippet // all snippets, indexed by snippet in
dex |
723 stats Statistics | 723 stats Statistics |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 } | 903 } |
904 | 904 |
905 | 905 |
906 // A FileLines value specifies a file and line numbers within that file. | 906 // A FileLines value specifies a file and line numbers within that file. |
907 type FileLines struct { | 907 type FileLines struct { |
908 Filename string | 908 Filename string |
909 Lines []int | 909 Lines []int |
910 } | 910 } |
911 | 911 |
912 | 912 |
913 // LookupRegexp returns the number and list of matches where a regular | 913 // LookupRegexp returns the number of matches and the matches where a regular |
914 // expression r is found in the full text index. At most n matches are | 914 // expression r is found in the full text index. At most n matches are |
915 // returned (thus found <= n). | 915 // returned (thus found <= n). |
916 // | 916 // |
917 func (x *Index) LookupRegexp(r *regexp.Regexp, n int) (found int, result []FileL
ines) { | 917 func (x *Index) LookupRegexp(r *regexp.Regexp, n int) (found int, result []FileL
ines) { |
918 if x.suffixes == nil || n <= 0 { | 918 if x.suffixes == nil || n <= 0 { |
919 return | 919 return |
920 } | 920 } |
921 // n > 0 | 921 // n > 0 |
922 | 922 |
923 var list positionList | 923 var list positionList |
924 » // FindAllIndex returns matches that may span across file boundaries. | 924 » // FindAllIndex may returns matches that span across file boundaries. |
925 » // This is unlikely, buf after eliminating them we may end up with | 925 » // Such matches are unlikely, buf after eliminating them we may end up |
926 » // fewer than n matches. If we don't have enough at the end, redo | 926 » // with fewer than n matches. If we don't have enough at the end, redo |
927 // the search with an increased value n1, but only if FindAllIndex | 927 // the search with an increased value n1, but only if FindAllIndex |
928 // returned all the requested matches in the first place (if it | 928 // returned all the requested matches in the first place (if it |
929 » // returned fewer than that then there cannot be more). | 929 » // returned fewer than that there cannot be more). |
930 for n1 := n; found < n; n1 += n - found { | 930 for n1 := n; found < n; n1 += n - found { |
931 found = 0 | 931 found = 0 |
932 matches := x.suffixes.FindAllIndex(r, n1) | 932 matches := x.suffixes.FindAllIndex(r, n1) |
933 // compute files, exclude matches that span file boundaries, | 933 // compute files, exclude matches that span file boundaries, |
934 // and map offsets to file-local offsets | 934 // and map offsets to file-local offsets |
935 list = make(positionList, len(matches)) | 935 list = make(positionList, len(matches)) |
936 for _, m := range matches { | 936 for _, m := range matches { |
937 // by construction, an offset corresponds to the Pos val
ue | 937 // by construction, an offset corresponds to the Pos val
ue |
938 // for the file set - use it to get the file and line | 938 // for the file set - use it to get the file and line |
939 p := token.Pos(m[0]) | 939 p := token.Pos(m[0]) |
(...skipping 28 matching lines...) Expand all Loading... |
968 if m.filename != last { | 968 if m.filename != last { |
969 addLines() | 969 addLines() |
970 last = m.filename | 970 last = m.filename |
971 } | 971 } |
972 lines = append(lines, m.line) | 972 lines = append(lines, m.line) |
973 } | 973 } |
974 addLines() | 974 addLines() |
975 | 975 |
976 return | 976 return |
977 } | 977 } |
LEFT | RIGHT |