hind 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,221 @@
1
+ # lib/hind/lsif/visitors/reference_visitor.rb
2
+ # frozen_string_literal: true
3
+
4
+ module Hind
5
+ module LSIF
6
+ class ReferenceVisitor < Prism::Visitor
7
+ attr_reader :current_scope
8
+
9
+ def initialize(generator, file_path)
10
+ @generator = generator
11
+ @file_path = file_path
12
+ @current_scope = []
13
+ end
14
+
15
+ # Method calls
16
+ def visit_call_node(node)
17
+ return unless node.name && node.location
18
+
19
+ method_name = node.name.to_s
20
+ qualified_names = generate_qualified_names_for_call(node)
21
+
22
+ qualified_names.each do |qualified_name|
23
+ @generator.register_reference({
24
+ type: :method,
25
+ name: qualified_name,
26
+ node: node,
27
+ scope: current_scope_name,
28
+ call_type: :instance_method
29
+ })
30
+ end
31
+
32
+ super
33
+ end
34
+
35
+ # Class/module references
36
+ def visit_constant_read_node(node)
37
+ return unless node.name
38
+
39
+ constant_name = node.name.to_s
40
+ qualified_name = @current_scope.empty? ? constant_name : "#{current_scope_name}::#{constant_name}"
41
+
42
+ @generator.register_reference({
43
+ type: :constant,
44
+ name: qualified_name,
45
+ node: node,
46
+ scope: current_scope_name
47
+ })
48
+
49
+ super
50
+ end
51
+
52
+ # Constant path references (e.g., A::B::C)
53
+ def visit_constant_path_node(node)
54
+ qualified_name = node.slice
55
+
56
+ @generator.register_reference({
57
+ type: :constant,
58
+ name: qualified_name,
59
+ node: node,
60
+ scope: current_scope_name
61
+ })
62
+
63
+ super
64
+ end
65
+
66
+ # Instance variable references
67
+ def visit_instance_variable_read_node(node)
68
+ return unless node.name && current_scope_name
69
+
70
+ var_name = node.name.to_s
71
+ qualified_name = "#{current_scope_name}##{var_name}"
72
+
73
+ @generator.register_reference({
74
+ type: :instance_variable,
75
+ name: qualified_name,
76
+ node: node,
77
+ scope: current_scope_name
78
+ })
79
+
80
+ super
81
+ end
82
+
83
+ # Class variable references
84
+ def visit_class_variable_read_node(node)
85
+ return unless node.name && current_scope_name
86
+
87
+ var_name = node.name.to_s
88
+ qualified_name = "#{current_scope_name}::#{var_name}"
89
+
90
+ @generator.register_reference({
91
+ type: :class_variable,
92
+ name: qualified_name,
93
+ node: node,
94
+ scope: current_scope_name
95
+ })
96
+
97
+ super
98
+ end
99
+
100
+ # Singleton method calls (class methods)
101
+ def visit_constant_path_call_node(node)
102
+ return unless node.name
103
+
104
+ method_name = node.name.to_s
105
+ receiver_name = node.receiver.slice
106
+ qualified_name = "#{receiver_name}.#{method_name}"
107
+
108
+ @generator.register_reference({
109
+ type: :method,
110
+ name: qualified_name,
111
+ node: node,
112
+ scope: current_scope_name,
113
+ call_type: :class_method
114
+ })
115
+
116
+ super
117
+ end
118
+
119
+ # Super method calls
120
+ def visit_super_node(node)
121
+ return unless current_scope_name
122
+
123
+ # Extract current method name from scope
124
+ current_method = current_method_name
125
+ return unless current_method
126
+
127
+ # Try to find the superclass method
128
+ if in_class_scope?
129
+ superclass = find_superclass
130
+ if superclass
131
+ qualified_name = "#{superclass}##{current_method}"
132
+
133
+ @generator.register_reference({
134
+ type: :method,
135
+ name: qualified_name,
136
+ node: node,
137
+ scope: current_scope_name,
138
+ call_type: :super
139
+ })
140
+ end
141
+ end
142
+
143
+ super
144
+ end
145
+
146
+ # Track class/module scope
147
+ def visit_class_node(node)
148
+ @current_scope.push(node.constant_path.slice)
149
+ super
150
+ @current_scope.pop
151
+ end
152
+
153
+ def visit_module_node(node)
154
+ @current_scope.push(node.constant_path.slice)
155
+ super
156
+ @current_scope.pop
157
+ end
158
+
159
+ private
160
+
161
+ def current_scope_name
162
+ @current_scope.join('::')
163
+ end
164
+
165
+ def generate_qualified_names_for_call(node)
166
+ qualified_names = []
167
+ method_name = node.name.to_s
168
+
169
+ # Try with current scope first
170
+ qualified_names << "#{current_scope_name}##{method_name}" unless current_scope_name.empty?
171
+
172
+ # Try with receiver's type if available
173
+ if node.receiver
174
+ case node.receiver
175
+ when Prism::ConstantReadNode
176
+ qualified_names << "#{node.receiver.name}##{method_name}"
177
+ when Prism::ConstantPathNode
178
+ qualified_names << "#{node.receiver.slice}##{method_name}"
179
+ when Prism::CallNode
180
+ # Method chaining - try both instance and class methods
181
+ if node.receiver.name
182
+ qualified_names << "#{node.receiver.name}##{method_name}"
183
+ qualified_names << "#{node.receiver.name}.#{method_name}"
184
+ end
185
+ when Prism::InstanceVariableReadNode
186
+ # Instance variable calls - try current class context
187
+ qualified_names << "#{current_scope_name}##{method_name}" if current_scope_name
188
+ end
189
+ end
190
+
191
+ # Try as a standalone method
192
+ qualified_names << method_name
193
+
194
+ # Add potential class method variant
195
+ qualified_names << "#{current_scope_name}.#{method_name}" unless current_scope_name.empty?
196
+
197
+ qualified_names.uniq
198
+ end
199
+
200
+ def current_method_name
201
+ # Try to find the nearest method node in the AST
202
+ # This is a simplified version - you might need to enhance this
203
+ # based on your specific needs
204
+ "current_method"
205
+ end
206
+
207
+ def in_class_scope?
208
+ # Check if we're currently in a class definition
209
+ !@current_scope.empty? && @generator.global_state.declarations[@current_scope.last]&.[](:type) == :class
210
+ end
211
+
212
+ def find_superclass
213
+ return unless in_class_scope?
214
+
215
+ current_class = @current_scope.last
216
+ class_declaration = @generator.global_state.declarations[current_class]
217
+ class_declaration&.[](:superclass)
218
+ end
219
+ end
220
+ end
221
+ end
data/lib/hind/lsif.rb CHANGED
@@ -1,9 +1,10 @@
1
- require_relative "lsif/global_state"
2
- require_relative "lsif/edge"
3
- require_relative "lsif/generator"
4
- require_relative "lsif/vertex"
5
- require_relative "lsif/visitor"
1
+ # frozen_string_literal: true
6
2
 
3
+ require_relative 'lsif/global_state'
4
+ require_relative 'lsif/edge'
5
+ require_relative 'lsif/generator'
6
+ require_relative 'lsif/vertex'
7
+ require_relative 'lsif/visitor'
7
8
 
8
9
  module Hind
9
10
  module LSIF
data/lib/hind/parser.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hind
2
4
  class Parser
3
5
  def initialize(code)
@@ -7,6 +9,7 @@ module Hind
7
9
  def parse
8
10
  result = Prism.parse(@code)
9
11
  raise "Parse error: #{result.errors}" unless result.success?
12
+
10
13
  result.value
11
14
  end
12
15
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hind
2
4
  module SCIP
3
5
  class Generator
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hind
2
4
  module SCIP
3
5
  class Visitor
data/lib/hind/scip.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hind
2
4
  module SCIP
3
5
  end
data/lib/hind/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hind
4
- VERSION = "0.1.4"
4
+ VERSION = '0.1.6'
5
5
  end
data/lib/hind.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "hind/version"
4
- require_relative "hind/lsif"
5
- require_relative "hind/scip"
6
- require_relative "hind/parser"
3
+ require_relative 'hind/version'
4
+ require_relative 'hind/lsif'
5
+ require_relative 'hind/scip'
6
+ require_relative 'hind/parser'
7
7
 
8
8
  module Hind
9
9
  class Error < StandardError; end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hind
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aboobacker MK
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-02-09 00:00:00.000000000 Z
10
+ date: 2025-02-10 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: prism
@@ -112,6 +112,8 @@ files:
112
112
  - lib/hind/lsif/global_state.rb
113
113
  - lib/hind/lsif/vertex.rb
114
114
  - lib/hind/lsif/visitor.rb
115
+ - lib/hind/lsif/visitors/declaration_visitor.rb
116
+ - lib/hind/lsif/visitors/reference_visitor.rb
115
117
  - lib/hind/parser.rb
116
118
  - lib/hind/scip.rb
117
119
  - lib/hind/scip/generator.rb