hind 0.1.6 → 0.1.8

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.
@@ -1,255 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Hind
4
- module LSIF
5
- class Visitor < Prism::Visitor
6
- def initialize(generator)
7
- @generator = generator
8
- @current_scope = []
9
- end
10
-
11
- def visit_def_node(node)
12
- method_name = node.name.to_s
13
- qualified_name = current_scope_name.empty? ? method_name : "#{current_scope_name}##{method_name}"
14
-
15
- range_id = @generator.create_range(node.location, node.location)
16
- result_set_id = @generator.emit_vertex('resultSet')
17
- @generator.emit_edge('next', range_id, result_set_id)
18
-
19
- def_result_id = @generator.emit_vertex('definitionResult')
20
- @generator.emit_edge('textDocument/definition', result_set_id, def_result_id)
21
- @generator.emit_edge('item', def_result_id, [range_id], 'definitions')
22
-
23
- # Generate method signature for hover
24
- sig = []
25
- sig << "def #{qualified_name}"
26
- sig << "(#{node.parameters.slice})" if node.parameters
27
-
28
- hover_id = @generator.emit_vertex('hoverResult', {
29
- contents: [{
30
- language: 'ruby',
31
- value: sig.join
32
- }]
33
- })
34
- @generator.emit_edge('textDocument/hover', result_set_id, hover_id)
35
-
36
- @generator.add_to_global_state(qualified_name, result_set_id, range_id)
37
-
38
- super
39
- end
40
-
41
- def visit_class_node(node)
42
- @current_scope.push(node.constant_path.slice)
43
- class_name = current_scope_name
44
-
45
- range_id = @generator.create_range(node.location, node.location)
46
- result_set_id = @generator.emit_vertex('resultSet')
47
- @generator.emit_edge('next', range_id, result_set_id)
48
-
49
- def_result_id = @generator.emit_vertex('definitionResult')
50
- @generator.emit_edge('textDocument/definition', result_set_id, def_result_id)
51
- @generator.emit_edge('item', def_result_id, [range_id], 'definitions')
52
-
53
- # Generate hover with inheritance info
54
- hover = []
55
- class_def = "class #{class_name}"
56
- class_def += " < #{node.superclass.slice}" if node.superclass
57
-
58
- hover << if node.superclass
59
- "#{class_def}\n\nInherits from: #{node.superclass.slice}"
60
- else
61
- class_def
62
- end
63
-
64
- hover_id = @generator.emit_vertex('hoverResult', {
65
- contents: [{
66
- language: 'ruby',
67
- value: hover.join("\n")
68
- }]
69
- })
70
- @generator.emit_edge('textDocument/hover', result_set_id, hover_id)
71
-
72
- @generator.add_to_global_state(class_name, result_set_id, range_id)
73
-
74
- # Handle inheritance
75
- visit_inheritance(node.superclass) if node.superclass
76
-
77
- super
78
- @current_scope.pop
79
- end
80
-
81
- def visit_module_node(node)
82
- @current_scope.push(node.constant_path.slice)
83
- module_name = current_scope_name
84
-
85
- range_id = @generator.create_range(node.location, node.location)
86
- result_set_id = @generator.emit_vertex('resultSet')
87
- @generator.emit_edge('next', range_id, result_set_id)
88
-
89
- def_result_id = @generator.emit_vertex('definitionResult')
90
- @generator.emit_edge('textDocument/definition', result_set_id, def_result_id)
91
- @generator.emit_edge('item', def_result_id, [range_id], 'definitions')
92
-
93
- hover_id = @generator.emit_vertex('hoverResult', {
94
- contents: [{
95
- language: 'ruby',
96
- value: "module #{module_name}"
97
- }]
98
- })
99
- @generator.emit_edge('textDocument/hover', result_set_id, hover_id)
100
-
101
- @generator.add_to_global_state(module_name, result_set_id, range_id)
102
-
103
- super
104
- @current_scope.pop
105
- end
106
-
107
- def visit_call_node(node)
108
- return unless node.name && node.location
109
-
110
- method_name = node.name.to_s
111
- qualified_names = []
112
-
113
- # Try with current scope first
114
- qualified_names << "#{current_scope_name}##{method_name}" unless current_scope_name.empty?
115
-
116
- # Try with receiver's type if available
117
- if node.receiver
118
- case node.receiver.type
119
- when :constant_read
120
- qualified_names << "#{node.receiver.name}##{method_name}"
121
- when :call
122
- # Handle method chaining
123
- qualified_names << "#{node.receiver.name}##{method_name}" if node.receiver.name
124
- when :instance_variable_read
125
- # Handle instance variable calls
126
- qualified_names << "#{current_scope_name}##{method_name}" if current_scope_name
127
- end
128
- end
129
-
130
- # Try as a standalone method
131
- qualified_names << method_name
132
-
133
- # Add references for matching qualified names
134
- qualified_names.each do |qualified_name|
135
- next unless @generator.global_state.result_sets[qualified_name]
136
-
137
- range_id = @generator.create_range(node.location, node.location)
138
- @generator.global_state.add_reference(qualified_name, @generator.metadata[:uri], range_id)
139
- @generator.emit_edge('next', range_id, @generator.global_state.result_sets[qualified_name])
140
- break # Stop after finding first match
141
- end
142
-
143
- super
144
- end
145
-
146
- def visit_constant_read_node(node)
147
- return unless node.name
148
-
149
- constant_name = node.name.to_s
150
- qualified_name = @current_scope.empty? ? constant_name : "#{current_scope_name}::#{constant_name}"
151
-
152
- return unless @generator.global_state.result_sets[qualified_name]
153
-
154
- range_id = @generator.create_range(node.location, node.location)
155
- @generator.global_state.add_reference(qualified_name, @generator.metadata[:uri], range_id)
156
- @generator.emit_edge('next', range_id, @generator.global_state.result_sets[qualified_name])
157
-
158
- super
159
- end
160
-
161
- def visit_constant_write_node(node)
162
- return unless node.name
163
-
164
- constant_name = node.name.to_s
165
- qualified_name = @current_scope.empty? ? constant_name : "#{current_scope_name}::#{constant_name}"
166
-
167
- range_id = @generator.create_range(node.location, node.location)
168
- result_set_id = @generator.emit_vertex('resultSet')
169
- @generator.emit_edge('next', range_id, result_set_id)
170
-
171
- def_result_id = @generator.emit_vertex('definitionResult')
172
- @generator.emit_edge('textDocument/definition', result_set_id, def_result_id)
173
- @generator.emit_edge('item', def_result_id, [range_id], 'definitions')
174
-
175
- hover_id = @generator.emit_vertex('hoverResult', {
176
- contents: [{
177
- language: 'ruby',
178
- value: "#{qualified_name} = ..."
179
- }]
180
- })
181
- @generator.emit_edge('textDocument/hover', result_set_id, hover_id)
182
-
183
- @generator.add_to_global_state(qualified_name, result_set_id, range_id)
184
-
185
- super
186
- end
187
-
188
- def visit_instance_variable_read_node(node)
189
- return unless node.name && current_scope_name
190
-
191
- var_name = node.name.to_s
192
- qualified_name = "#{current_scope_name}##{var_name}"
193
-
194
- return unless @generator.global_state.result_sets[qualified_name]
195
-
196
- range_id = @generator.create_range(node.location, node.location)
197
- @generator.global_state.add_reference(qualified_name, @generator.metadata[:uri], range_id)
198
- @generator.emit_edge('next', range_id, @generator.global_state.result_sets[qualified_name])
199
-
200
- super
201
- end
202
-
203
- def visit_instance_variable_write_node(node)
204
- return unless node.name && current_scope_name
205
-
206
- var_name = node.name.to_s
207
- qualified_name = "#{current_scope_name}##{var_name}"
208
-
209
- range_id = @generator.create_range(node.location, node.location)
210
- result_set_id = @generator.emit_vertex('resultSet')
211
- @generator.emit_edge('next', range_id, result_set_id)
212
-
213
- def_result_id = @generator.emit_vertex('definitionResult')
214
- @generator.emit_edge('textDocument/definition', result_set_id, def_result_id)
215
- @generator.emit_edge('item', def_result_id, [range_id], 'definitions')
216
-
217
- hover_id = @generator.emit_vertex('hoverResult', {
218
- contents: [{
219
- language: 'ruby',
220
- value: "Instance variable #{var_name} in #{current_scope_name}"
221
- }]
222
- })
223
- @generator.emit_edge('textDocument/hover', result_set_id, hover_id)
224
-
225
- @generator.add_to_global_state(qualified_name, result_set_id, range_id)
226
-
227
- super
228
- end
229
-
230
- private
231
-
232
- def current_scope_name
233
- @current_scope.join('::')
234
- end
235
-
236
- def visit_inheritance(node)
237
- case node.type
238
- when :constant_read_node, :constant_path_node
239
- range_id = @generator.create_range(node.location, node.location)
240
- qualified_name = case node.type
241
- when :constant_read_node
242
- node.name.to_s
243
- when :constant_path_node
244
- node.slice
245
- end
246
-
247
- return unless @generator.global_state.result_sets[qualified_name]
248
-
249
- @generator.global_state.add_reference(qualified_name, @generator.metadata[:uri], range_id)
250
- @generator.emit_edge('next', range_id, @generator.global_state.result_sets[qualified_name])
251
- end
252
- end
253
- end
254
- end
255
- end