Class: Hind::LSIF::ReferenceVisitor

Inherits:
Prism::Visitor
  • Object
show all
Defined in:
lib/hind/lsif/visitors/reference_visitor.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(generator, file_path) ⇒ ReferenceVisitor

Returns a new instance of ReferenceVisitor.



8
9
10
11
12
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 8

def initialize(generator, file_path)
  @generator = generator
  @file_path = file_path
  @current_scope = []
end

Instance Attribute Details

#current_scopeObject (readonly)

Returns the value of attribute current_scope.



6
7
8
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 6

def current_scope
  @current_scope
end

Instance Method Details

#visit_call_and_write_node(node) ⇒ Object



82
83
84
85
86
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 82

def visit_call_and_write_node(node)
  register_method_call_reference(node, name_override: node.read_name.to_s)
  register_method_call_reference(node, name_override: node.write_name.to_s)
  super
end

#visit_call_node(node) ⇒ Object



68
69
70
71
72
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 68

def visit_call_node(node)
  # Speculative resolution for method calls
  register_method_call_reference(node)
  super
end

#visit_call_operator_write_node(node) ⇒ Object



74
75
76
77
78
79
80
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 74

def visit_call_operator_write_node(node)
  # Handle self.age += 1
  # This involves both a getter (age) and a setter (age=)
  register_method_call_reference(node, name_override: node.read_name.to_s)
  register_method_call_reference(node, name_override: node.write_name.to_s)
  super
end

#visit_call_or_write_node(node) ⇒ Object



88
89
90
91
92
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 88

def visit_call_or_write_node(node)
  register_method_call_reference(node, name_override: node.read_name.to_s)
  register_method_call_reference(node, name_override: node.write_name.to_s)
  super
end

#visit_class_node(node) ⇒ Object



48
49
50
51
52
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 48

def visit_class_node(node)
  @current_scope.push(scip_name(node.constant_path.slice))
  super
  @current_scope.pop
end

#visit_constant_path_node(node) ⇒ Object



42
43
44
45
46
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 42

def visit_constant_path_node(node)
  # Skip creating a range for the whole path to avoid overlaps with parts.
  # Instead, just visit the components (parent and child).
  super
end

#visit_constant_read_node(node) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 14

def visit_constant_read_node(node)
  return unless node.name
  constant_name = node.name.to_s
  qualified_name = @current_scope.empty? ? constant_name : "#{current_scope_name}::#{constant_name}"

  # Try to find the correct declaration considering the scope
  found_name = GlobalState.instance.find_constant_declaration(constant_name, current_scope_name)

  if found_name
    @generator.register_reference({
      type: :constant,
      name: found_name,
      node: node,
      scope: current_scope_name
    })
  else
    # Register with the qualified name if not found - it might be defined later
    @generator.register_reference({
      type: :constant,
      name: qualified_name,
      node: node,
      scope: current_scope_name
    })
  end

  super
end

#visit_def_node(node) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 60

def visit_def_node(node)
  # We don't push def to current_scope because methods are usually inside classes/modules
  # and we use #method notation. Pushing 'method' to scope would result in A::B#method#submethod
  # which is not standard for Ruby normally unless we handle nested blocks.
  # But for now, let's just visit.
  super
end

#visit_index_and_write_node(node) ⇒ Object



101
102
103
104
105
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 101

def visit_index_and_write_node(node)
  register_method_call_reference(node, name_override: "[]")
  register_method_call_reference(node, name_override: "[]=")
  super
end

#visit_index_operator_write_node(node) ⇒ Object



94
95
96
97
98
99
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 94

def visit_index_operator_write_node(node)
  # Handle obj[key] += val
  register_method_call_reference(node, name_override: "[]")
  register_method_call_reference(node, name_override: "[]=")
  super
end

#visit_index_or_write_node(node) ⇒ Object



107
108
109
110
111
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 107

def visit_index_or_write_node(node)
  register_method_call_reference(node, name_override: "[]")
  register_method_call_reference(node, name_override: "[]=")
  super
end

#visit_module_node(node) ⇒ Object



54
55
56
57
58
# File 'lib/hind/lsif/visitors/reference_visitor.rb', line 54

def visit_module_node(node)
  @current_scope.push(scip_name(node.constant_path.slice))
  super
  @current_scope.pop
end