Class: CallMap::SourceIndex

Inherits:
Object
  • Object
show all
Defined in:
lib/call_map/source_index.rb

Overview

Indexes class / module / method definitions found under a directory.

AST handling is delegated to DefinitionCollector; this class only stores the resulting Definitions and answers lookups against them.

Constant Summary collapse

DEFAULT_GLOB =
"app/**/*.rb"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSourceIndex

Returns a new instance of SourceIndex.



18
19
20
# File 'lib/call_map/source_index.rb', line 18

def initialize
  @definitions = []
end

Instance Attribute Details

#definitionsObject (readonly)

Returns the value of attribute definitions.



22
23
24
# File 'lib/call_map/source_index.rb', line 22

def definitions
  @definitions
end

Class Method Details

.build(root:, glob: DEFAULT_GLOB) ⇒ Object

Build a SourceIndex by indexing every Ruby file under root.



14
15
16
# File 'lib/call_map/source_index.rb', line 14

def self.build(root:, glob: DEFAULT_GLOB)
  new.index_directory(root, glob: glob)
end

Instance Method Details

#ancestor_chain(owner) ⇒ Object

The class plus its superclasses (innermost first), resolved against the index. Stops at classes not present in the index or on a cycle.



52
53
54
55
56
57
58
59
60
# File 'lib/call_map/source_index.rb', line 52

def ancestor_chain(owner)
  chain = []
  current = owner
  while current && !chain.include?(current)
    chain << current
    current = superclass_of(current)
  end
  chain
end

#find_class_definitions(qualified_name) ⇒ Object

All :class definitions matching the qualified name (a class may be reopened across files), in indexing order.



46
47
48
# File 'lib/call_map/source_index.rb', line 46

def find_class_definitions(qualified_name)
  definitions.select { |d| d.kind == :class && d.name == qualified_name }
end

#find_class_method(owner, name) ⇒ Object



40
41
42
# File 'lib/call_map/source_index.rb', line 40

def find_class_method(owner, name)
  find_method(:class_method, owner, name)
end

#find_instance_method(owner, name) ⇒ Object



36
37
38
# File 'lib/call_map/source_index.rb', line 36

def find_instance_method(owner, name)
  find_method(:instance_method, owner, name)
end

#index_directory(root, glob: DEFAULT_GLOB) ⇒ Object

Parameters:

  • root (String)

    directory to search from

  • glob (String) (defaults to: DEFAULT_GLOB)

    glob pattern relative to root



26
27
28
29
# File 'lib/call_map/source_index.rb', line 26

def index_directory(root, glob: DEFAULT_GLOB)
  Dir.glob(File.join(root, glob)).each { |path| index_file(path) }
  self
end

#index_file(path) ⇒ Object



31
32
33
34
# File 'lib/call_map/source_index.rb', line 31

def index_file(path)
  @definitions.concat(DefinitionCollector.collect(File.read(path), path: path))
  self
end

#superclass_of(owner) ⇒ Object



62
63
64
65
66
67
68
69
70
71
# File 'lib/call_map/source_index.rb', line 62

def superclass_of(owner)
  definition = find_class_definitions(owner).find(&:superclass)
  return nil unless definition

  superclass = definition.superclass
  # A "::"-prefixed superclass is an absolute path — no namespace fallback.
  return superclass.delete_prefix("::") if superclass.start_with?("::")

  resolve_class_name(superclass, definition.lexical_nesting)
end