Class: Decode::Index

Inherits:
Object
  • Object
show all
Defined in:
lib/decode/index.rb

Overview

A list of definitions organised for quick lookup and lexical enumeration.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(languages = Languages.all) ⇒ Index

Initialize an empty index.



30
31
32
33
34
35
36
37
38
# File 'lib/decode/index.rb', line 30

def initialize(languages = Languages.all)
  @languages = languages
  
  @sources = {}
  @definitions = {}
  
  # This is essentially a prefix tree:
  @trie = Trie.new
end

Instance Attribute Details

#definitionsObject (readonly)

All definitions which have been parsed.



50
51
52
# File 'lib/decode/index.rb', line 50

def definitions
  @definitions
end

#languagesObject

All supported languages for this index.



42
43
44
# File 'lib/decode/index.rb', line 42

def languages
  @languages
end

#sourcesObject (readonly)

All source files that have been parsed.



46
47
48
# File 'lib/decode/index.rb', line 46

def sources
  @sources
end

#trieObject (readonly)

A (prefix) trie of lexically scoped definitions.



55
56
57
# File 'lib/decode/index.rb', line 55

def trie
  @trie
end

Instance Method Details

#lookup(reference, relative_to: nil) ⇒ Object

Lookup the specified reference and return matching definitions.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/decode/index.rb', line 80

def lookup(reference, relative_to: nil)
  if reference.absolute? || relative_to.nil?
    lexical_path = []
  else
    lexical_path = relative_to.path.dup
  end
  
  path = reference.path
  
  while true
    node = @trie.lookup(lexical_path)
    
    if node.children[path.first]
      if target = node.lookup(path)
        return reference.best(target.values)
      else
        return nil
      end
    end
    
    break if lexical_path.empty?
    lexical_path.pop
  end
end

#update(paths) ⇒ Object

Updates the index by parsing the specified files. All extracted definitions are merged into the existing index.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/decode/index.rb', line 61

def update(paths)
  paths.each do |path|
    if source = @languages.source_for(path)
      @sources[path] = source
      
      source.definitions do |symbol|
        # $stderr.puts "Adding #{symbol.qualified_name} to #{symbol.lexical_path.join(' -> ')}"
        
        @definitions[symbol.qualified_name] = symbol
        @trie.insert(symbol.path, symbol)
      end
    end
  end
end