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.
@@ -13,10 +13,6 @@ module Hind
13
13
  @result_sets = {} # {qualified_name => result_set_id}
14
14
  @ranges = {} # {file_path => [range_ids]}
15
15
  @project_id = nil
16
-
17
- # Method visibility tracking
18
- @visibility_stack = [] # Stack of method visibility states per scope
19
- @current_visibility = :public
20
16
  end
21
17
 
22
18
  def add_declaration(qualified_name, data)
@@ -24,12 +20,12 @@ module Hind
24
20
  @result_sets[qualified_name] = data[:result_set_id] if data[:result_set_id]
25
21
  end
26
22
 
27
- def add_reference(qualified_name, file_path, range_id, type = :reference)
23
+ def add_reference(qualified_name, file_path, range_id, document_id)
28
24
  @references[qualified_name] ||= []
29
25
  @references[qualified_name] << {
30
26
  file: file_path,
31
27
  range_id: range_id,
32
- type: type
28
+ document_id: document_id
33
29
  }
34
30
  end
35
31
 
@@ -58,98 +54,31 @@ module Hind
58
54
  @ranges[file_path] || []
59
55
  end
60
56
 
61
- def push_visibility_scope(visibility = :public)
62
- @visibility_stack.push(@current_visibility)
63
- @current_visibility = visibility
64
- end
65
-
66
- def pop_visibility_scope
67
- @current_visibility = @visibility_stack.pop || :public
68
- end
69
-
70
- def current_visibility
71
- @current_visibility
72
- end
73
-
74
- def get_declaration_in_scope(name, scope)
75
- # Try exact scope first
76
- qualified_name = scope.empty? ? name : "#{scope}::#{name}"
77
- return qualified_name if has_declaration?(qualified_name)
78
-
79
- # Try parent scopes
80
- scope_parts = scope.split('::')
81
- while scope_parts.any?
82
- scope_parts.pop
83
- qualified_name = scope_parts.empty? ? name : "#{scope_parts.join('::')}::#{name}"
84
- return qualified_name if has_declaration?(qualified_name)
85
- end
86
-
87
- # Try top level
88
- has_declaration?(name) ? name : nil
89
- end
90
-
91
- def get_method_declaration(method_name, scope, instance_method = true)
92
- separator = instance_method ? '#' : '.'
93
- qualified_name = scope.empty? ? method_name : "#{scope}#{separator}#{method_name}"
94
-
95
- return qualified_name if has_declaration?(qualified_name)
96
-
97
- # For instance methods, try to find in superclass chain
98
- if instance_method && !scope.empty?
99
- current_scope = scope
100
- while (class_data = @declarations[current_scope])
101
- break unless class_data[:type] == :class && class_data[:superclass]
102
-
103
- superclass = class_data[:superclass]
104
- superclass_method = "#{superclass}#{separator}#{method_name}"
105
- return superclass_method if has_declaration?(superclass_method)
106
-
107
- current_scope = superclass
108
- end
109
- end
110
-
111
- nil
112
- end
113
-
114
57
  def find_constant_declaration(name, current_scope)
115
58
  return name if has_declaration?(name)
116
59
 
117
- # Try with current scope
118
60
  if current_scope && !current_scope.empty?
119
61
  qualified_name = "#{current_scope}::#{name}"
120
62
  return qualified_name if has_declaration?(qualified_name)
121
63
 
122
- # Try parent scopes
123
64
  scope_parts = current_scope.split('::')
124
65
  while scope_parts.any?
125
66
  scope_parts.pop
126
- qualified_name = scope_parts.empty? ? name : "#{scope_parts.join('::')}::#{name}"
67
+ qualified_name = scope_parts.empty? ? name : "#{scope_parts.join("::")}::#{name}"
127
68
  return qualified_name if has_declaration?(qualified_name)
128
69
  end
129
70
  end
130
71
 
131
- # Try top level
132
72
  has_declaration?(name) ? name : nil
133
73
  end
134
74
 
135
- def get_instance_variable_scope(var_name, current_scope)
136
- return nil unless current_scope
137
- "#{current_scope}##{var_name}"
138
- end
139
-
140
- def get_class_variable_scope(var_name, current_scope)
141
- return nil unless current_scope
142
- "#{current_scope}::#{var_name}"
143
- end
144
-
145
75
  def debug_info
146
76
  {
147
77
  declarations_count: @declarations.size,
148
78
  references_count: @references.values.sum(&:size),
149
79
  result_sets_count: @result_sets.size,
150
80
  ranges_count: @ranges.values.sum(&:size),
151
- declaration_types: declaration_types_count,
152
- reference_types: reference_types_count
81
+ declaration_types: declaration_types_count
153
82
  }
154
83
  end
155
84
 
@@ -160,12 +89,6 @@ module Hind
160
89
  counts[decl[:type]] += 1
161
90
  end
162
91
  end
163
-
164
- def reference_types_count
165
- @references.values.flatten.each_with_object(Hash.new(0)) do |ref, counts|
166
- counts[ref[:type]] += 1
167
- end
168
- end
169
92
  end
170
93
  end
171
94
  end
@@ -10,16 +10,12 @@ module Hind
10
10
  @generator = generator
11
11
  @file_path = file_path
12
12
  @current_scope = []
13
- @current_visibility = :public
14
- @visibility_stack = []
15
- @in_singleton_class = false
16
13
  end
17
14
 
18
15
  def visit_class_node(node)
19
16
  @current_scope.push(node.constant_path.slice)
20
17
  class_name = current_scope_name
21
18
 
22
- # Register class declaration
23
19
  @generator.register_declaration({
24
20
  type: :class,
25
21
  name: class_name,
@@ -28,10 +24,7 @@ module Hind
28
24
  superclass: node.superclass&.slice
29
25
  })
30
26
 
31
- # Process the class body with proper scope and visibility
32
- push_visibility(:public)
33
27
  super
34
- pop_visibility
35
28
  @current_scope.pop
36
29
  end
37
30
 
@@ -46,32 +39,10 @@ module Hind
46
39
  scope: @current_scope[0..-2].join('::')
47
40
  })
48
41
 
49
- push_visibility(:public)
50
42
  super
51
- pop_visibility
52
43
  @current_scope.pop
53
44
  end
54
45
 
55
- def visit_def_node(node)
56
- method_name = node.name.to_s
57
- # Use '#' for instance methods
58
- qualified_name = @in_singleton_class ?
59
- "#{current_scope_name}.#{method_name}" :
60
- "#{current_scope_name}##{method_name}"
61
-
62
- @generator.register_declaration({
63
- type: :method,
64
- name: qualified_name,
65
- node: node,
66
- scope: current_scope_name,
67
- visibility: current_visibility,
68
- params: node.parameters&.slice,
69
- instance_method: !@in_singleton_class
70
- })
71
-
72
- super
73
- end
74
-
75
46
  def visit_constant_write_node(node)
76
47
  return unless node.name
77
48
 
@@ -88,152 +59,11 @@ module Hind
88
59
  super
89
60
  end
90
61
 
91
- def visit_singleton_class_node(node)
92
- if node.expression.is_a?(Prism::SelfNode)
93
- # class << self
94
- @in_singleton_class = true
95
- super
96
- @in_singleton_class = false
97
- else
98
- # Process regular singleton class
99
- super
100
- end
101
- end
102
-
103
- def visit_call_node(node)
104
- method_name = node.name.to_s
105
- case method_name
106
- when 'private', 'protected', 'public'
107
- handle_visibility_method(node)
108
- when 'attr_reader', 'attr_writer', 'attr_accessor'
109
- handle_attribute_method(node)
110
- end
111
-
112
- super
113
- end
114
-
115
- def visit_class_variable_write_node(node)
116
- return unless node.name
117
-
118
- var_name = node.name.to_s
119
- qualified_name = "#{current_scope_name}::#{var_name}"
120
-
121
- @generator.register_declaration({
122
- type: :class_variable,
123
- name: qualified_name,
124
- node: node,
125
- scope: current_scope_name
126
- })
127
-
128
- super
129
- end
130
-
131
- def visit_instance_variable_write_node(node)
132
- return unless node.name && current_scope_name
133
-
134
- var_name = node.name.to_s
135
- qualified_name = "#{current_scope_name}##{var_name}"
136
-
137
- @generator.register_declaration({
138
- type: :instance_variable,
139
- name: qualified_name,
140
- node: node,
141
- scope: current_scope_name
142
- })
143
-
144
- super
145
- end
146
-
147
62
  private
148
63
 
149
64
  def current_scope_name
150
65
  @current_scope.join('::')
151
66
  end
152
-
153
- def current_visibility
154
- @current_visibility
155
- end
156
-
157
- def push_visibility(visibility)
158
- @visibility_stack.push(@current_visibility)
159
- @current_visibility = visibility
160
- end
161
-
162
- def pop_visibility
163
- @current_visibility = @visibility_stack.pop || :public
164
- end
165
-
166
- def handle_visibility_method(node)
167
- visibility = node.name.to_sym
168
-
169
- if node.arguments&.arguments&.empty?
170
- # Global visibility change
171
- @current_visibility = visibility
172
- elsif node.arguments
173
- # Per-method visibility change
174
- node.arguments.arguments.each do |arg|
175
- next unless arg.is_a?(Prism::SymbolNode) || arg.is_a?(Prism::StringNode)
176
-
177
- method_name = arg.value.to_s
178
- qualified_name = "#{current_scope_name}##{method_name}"
179
-
180
- if @generator.global_state.has_declaration?(qualified_name)
181
- @generator.global_state.get_declaration(qualified_name)[:visibility] = visibility
182
- end
183
- end
184
- end
185
- end
186
-
187
- def handle_attribute_method(node)
188
- return unless node.arguments
189
-
190
- attr_type = node.name.to_s
191
- node.arguments.arguments.each do |arg|
192
- next unless arg.respond_to?(:value)
193
-
194
- attr_name = arg.value.to_s
195
- register_attribute(attr_name, attr_type)
196
- end
197
- end
198
-
199
- def register_attribute(attr_name, attr_type)
200
- base_name = "#{current_scope_name}##{attr_name}"
201
-
202
- # Register reader method if applicable
203
- if %w[attr_reader attr_accessor].include?(attr_type)
204
- @generator.register_declaration({
205
- type: :method,
206
- name: base_name,
207
- node: nil, # Synthetic node
208
- scope: current_scope_name,
209
- visibility: current_visibility,
210
- synthetic: true,
211
- kind: :reader
212
- })
213
- end
214
-
215
- # Register writer method if applicable
216
- if %w[attr_writer attr_accessor].include?(attr_type)
217
- @generator.register_declaration({
218
- type: :method,
219
- name: "#{base_name}=",
220
- node: nil, # Synthetic node
221
- scope: current_scope_name,
222
- visibility: current_visibility,
223
- synthetic: true,
224
- kind: :writer
225
- })
226
- end
227
-
228
- # Register the instance variable
229
- @generator.register_declaration({
230
- type: :instance_variable,
231
- name: "@#{attr_name}",
232
- node: nil, # Synthetic node
233
- scope: current_scope_name,
234
- synthetic: true
235
- })
236
- end
237
67
  end
238
68
  end
239
69
  end
@@ -1,4 +1,3 @@
1
- # lib/hind/lsif/visitors/reference_visitor.rb
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module Hind
@@ -12,27 +11,6 @@ module Hind
12
11
  @current_scope = []
13
12
  end
14
13
 
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
14
  def visit_constant_read_node(node)
37
15
  return unless node.name
38
16
 
@@ -49,7 +27,6 @@ module Hind
49
27
  super
50
28
  end
51
29
 
52
- # Constant path references (e.g., A::B::C)
53
30
  def visit_constant_path_node(node)
54
31
  qualified_name = node.slice
55
32
 
@@ -63,87 +40,6 @@ module Hind
63
40
  super
64
41
  end
65
42
 
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
43
  def visit_class_node(node)
148
44
  @current_scope.push(node.constant_path.slice)
149
45
  super
@@ -161,61 +57,6 @@ module Hind
161
57
  def current_scope_name
162
58
  @current_scope.join('::')
163
59
  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
60
  end
220
61
  end
221
62
  end
data/lib/hind/lsif.rb CHANGED
@@ -4,7 +4,6 @@ require_relative 'lsif/global_state'
4
4
  require_relative 'lsif/edge'
5
5
  require_relative 'lsif/generator'
6
6
  require_relative 'lsif/vertex'
7
- require_relative 'lsif/visitor'
8
7
 
9
8
  module Hind
10
9
  module LSIF
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.6'
4
+ VERSION = '0.1.8'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hind
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aboobacker MK
@@ -111,7 +111,6 @@ files:
111
111
  - lib/hind/lsif/generator.rb
112
112
  - lib/hind/lsif/global_state.rb
113
113
  - lib/hind/lsif/vertex.rb
114
- - lib/hind/lsif/visitor.rb
115
114
  - lib/hind/lsif/visitors/declaration_visitor.rb
116
115
  - lib/hind/lsif/visitors/reference_visitor.rb
117
116
  - lib/hind/parser.rb