hind 0.1.4 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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