ruby-lsp 0.22.0 → 0.23.0

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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/exe/ruby-lsp +10 -9
  4. data/exe/ruby-lsp-check +5 -5
  5. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +26 -20
  6. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +131 -23
  7. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +60 -30
  8. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +73 -55
  9. data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +16 -14
  10. data/lib/{core_ext → ruby_indexer/lib/ruby_indexer}/uri.rb +29 -3
  11. data/lib/ruby_indexer/ruby_indexer.rb +1 -1
  12. data/lib/ruby_indexer/test/class_variables_test.rb +140 -0
  13. data/lib/ruby_indexer/test/classes_and_modules_test.rb +11 -6
  14. data/lib/ruby_indexer/test/configuration_test.rb +116 -51
  15. data/lib/ruby_indexer/test/enhancements_test.rb +2 -2
  16. data/lib/ruby_indexer/test/index_test.rb +72 -43
  17. data/lib/ruby_indexer/test/method_test.rb +80 -0
  18. data/lib/ruby_indexer/test/rbs_indexer_test.rb +1 -1
  19. data/lib/ruby_indexer/test/reference_finder_test.rb +1 -1
  20. data/lib/ruby_indexer/test/test_case.rb +2 -2
  21. data/lib/ruby_indexer/test/uri_test.rb +72 -0
  22. data/lib/ruby_lsp/addon.rb +9 -0
  23. data/lib/ruby_lsp/base_server.rb +15 -6
  24. data/lib/ruby_lsp/document.rb +10 -1
  25. data/lib/ruby_lsp/global_state.rb +1 -1
  26. data/lib/ruby_lsp/internal.rb +1 -1
  27. data/lib/ruby_lsp/listeners/code_lens.rb +8 -4
  28. data/lib/ruby_lsp/listeners/completion.rb +73 -4
  29. data/lib/ruby_lsp/listeners/definition.rb +73 -17
  30. data/lib/ruby_lsp/listeners/document_symbol.rb +49 -5
  31. data/lib/ruby_lsp/listeners/folding_ranges.rb +1 -1
  32. data/lib/ruby_lsp/listeners/hover.rb +57 -0
  33. data/lib/ruby_lsp/requests/completion.rb +6 -0
  34. data/lib/ruby_lsp/requests/completion_resolve.rb +2 -1
  35. data/lib/ruby_lsp/requests/definition.rb +6 -0
  36. data/lib/ruby_lsp/requests/prepare_rename.rb +51 -0
  37. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +1 -1
  38. data/lib/ruby_lsp/requests/rename.rb +14 -4
  39. data/lib/ruby_lsp/requests/support/common.rb +1 -5
  40. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +1 -1
  41. data/lib/ruby_lsp/requests/workspace_symbol.rb +3 -2
  42. data/lib/ruby_lsp/scripts/compose_bundle.rb +1 -1
  43. data/lib/ruby_lsp/server.rb +42 -7
  44. data/lib/ruby_lsp/setup_bundler.rb +54 -46
  45. data/lib/ruby_lsp/test_helper.rb +45 -11
  46. data/lib/ruby_lsp/type_inferrer.rb +22 -0
  47. data/lib/ruby_lsp/utils.rb +3 -0
  48. metadata +7 -8
  49. data/lib/ruby_indexer/lib/ruby_indexer/indexable_path.rb +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e48cef95e466e2a75943921fc08ede1a449e07096e44078ca063bdbee6d3c54b
4
- data.tar.gz: c0ce6a0636645674e9e9a87219124b622b1280420c14c4bd12f8f0f0aafc3f32
3
+ metadata.gz: 3792653083ea45143ce56ff51f68ced5217a52e9172c2cb33e03d012eda30ee8
4
+ data.tar.gz: 7d798218889b1add42189e08013a3503d9140a6504144fd0edfd8de00827c7f0
5
5
  SHA512:
6
- metadata.gz: 89d02237ecce7e784bb5275ba4d5fc30b64981ea337b078f3117037b98d8f734e0d7e6266078e76023125dd52bbcb6ded8d04fdac1c29eb8292fd29e401cece4
7
- data.tar.gz: 7245d82a481bd9e6a56d0cce9ad03796bd1a6d9e770beb5632fcaf7669ab0af9e9c0c95f0b671d844231af718add21b98011665ac3355fab5647ab12378b60bf
6
+ metadata.gz: ec313c0971ed544bfb14904105345d8a4843e8aa4eeefaccbcbdb69e40ff2da2f618b4d95f89cf86ed51a90a9e3f2cb7aca93d56dca352de6f1ac2b4aff29dfe
7
+ data.tar.gz: 1fb2034291a4ca052d91c03095dcea32165dd2deaeafdbda59dfd67142d6380fcf9f1306879b9b516c8ba14605223042625fca5ecc1b7b9eb2137c0777ebc32f
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.22.0
1
+ 0.23.0
data/exe/ruby-lsp CHANGED
@@ -64,7 +64,7 @@ if ENV["BUNDLE_GEMFILE"].nil?
64
64
  # which gives us the opportunity to control which specs are activated and enter degraded mode if any gems failed to
65
65
  # install rather than failing to boot the server completely
66
66
  if options[:launcher]
67
- command = +File.expand_path("ruby-lsp-launcher", __dir__)
67
+ command = +"#{Gem.ruby} #{File.expand_path("ruby-lsp-launcher", __dir__)}"
68
68
  command << " --debug" if options[:debug]
69
69
  exit exec(command)
70
70
  end
@@ -78,13 +78,14 @@ if ENV["BUNDLE_GEMFILE"].nil?
78
78
  exit(78)
79
79
  end
80
80
 
81
- base_bundle = if env["BUNDLER_VERSION"]
82
- "bundle _#{env["BUNDLER_VERSION"]}_"
83
- else
84
- "bundle"
81
+ bundler_path = File.join(Gem.default_bindir, "bundle")
82
+ base_command = (File.exist?(bundler_path) ? "#{Gem.ruby} #{bundler_path}" : "bundle").dup
83
+
84
+ if env["BUNDLER_VERSION"]
85
+ base_command << " _#{env["BUNDLER_VERSION"]}_"
85
86
  end
86
87
 
87
- exit exec(env, "#{base_bundle} exec ruby-lsp #{original_args.join(" ")}".strip)
88
+ exit exec(env, "#{base_command} exec ruby-lsp #{original_args.join(" ")}".strip)
88
89
  end
89
90
 
90
91
  $LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
@@ -139,9 +140,9 @@ if options[:doctor]
139
140
 
140
141
  puts "Globbing for indexable files"
141
142
 
142
- index.configuration.indexables.each do |indexable|
143
- puts "indexing: #{indexable.full_path}"
144
- index.index_single(indexable)
143
+ index.configuration.indexable_uris.each do |uri|
144
+ puts "indexing: #{uri}"
145
+ index.index_file(uri)
145
146
  end
146
147
  return
147
148
  end
data/exe/ruby-lsp-check CHANGED
@@ -44,14 +44,14 @@ puts "\n"
44
44
  puts "Verifying that indexing executes successfully. This may take a while..."
45
45
 
46
46
  index = RubyIndexer::Index.new
47
- indexables = index.configuration.indexables
47
+ uris = index.configuration.indexable_uris
48
48
 
49
- indexables.each_with_index do |indexable, i|
50
- index.index_single(indexable)
49
+ uris.each_with_index do |uri, i|
50
+ index.index_file(uri)
51
51
  rescue => e
52
- errors[indexable.full_path] = e
52
+ errors[uri.full_path] = e
53
53
  ensure
54
- print("\033[M\033[0KIndexed #{i + 1}/#{indexables.length}") unless ENV["CI"]
54
+ print("\033[M\033[0KIndexed #{i + 1}/#{uris.length}") unless ENV["CI"]
55
55
  end
56
56
  puts "\n"
57
57
 
@@ -81,8 +81,8 @@ module RubyIndexer
81
81
  .then { |dirs| File.join(@workspace_path, "{#{dirs.join(",")}}/**/*") }
82
82
  end
83
83
 
84
- sig { returns(T::Array[IndexablePath]) }
85
- def indexables
84
+ sig { returns(T::Array[URI::Generic]) }
85
+ def indexable_uris
86
86
  excluded_gems = @excluded_gems - @included_gems
87
87
  locked_gems = Bundler.locked_gems&.specs
88
88
 
@@ -107,12 +107,12 @@ module RubyIndexer
107
107
  [included_path, relative_path]
108
108
  end
109
109
 
110
- indexables = T.let([], T::Array[IndexablePath])
110
+ uris = T.let([], T::Array[URI::Generic])
111
111
 
112
112
  # Handle top level files separately. The path below is an optimization to prevent descending down directories that
113
113
  # are going to be excluded anyway, so we need to handle top level scripts separately
114
114
  Dir.glob(File.join(@workspace_path, "*.rb"), flags).each do |path|
115
- indexables << IndexablePath.new(nil, path)
115
+ uris << URI::Generic.from_path(path: path)
116
116
  end
117
117
 
118
118
  # Add user specified patterns
@@ -134,7 +134,7 @@ module RubyIndexer
134
134
  load_path_entry = $LOAD_PATH.find { |load_path| path.start_with?(load_path) }
135
135
  end
136
136
 
137
- indexables << IndexablePath.new(load_path_entry, path)
137
+ uris << URI::Generic.from_path(path: path, load_path_entry: load_path_entry)
138
138
  end
139
139
  end
140
140
  end
@@ -150,9 +150,9 @@ module RubyIndexer
150
150
  end
151
151
 
152
152
  # Remove user specified patterns
153
- indexables.reject! do |indexable|
153
+ uris.reject! do |indexable|
154
154
  excluded_patterns.any? do |pattern|
155
- File.fnmatch?(pattern, indexable.full_path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
155
+ File.fnmatch?(pattern, T.must(indexable.full_path), File::FNM_PATHNAME | File::FNM_EXTGLOB)
156
156
  end
157
157
  end
158
158
 
@@ -182,14 +182,14 @@ module RubyIndexer
182
182
 
183
183
  if pathname.directory?
184
184
  # If the default_path is a directory, we index all the Ruby files in it
185
- indexables.concat(
185
+ uris.concat(
186
186
  Dir.glob(File.join(default_path, "**", "*.rb"), File::FNM_PATHNAME | File::FNM_EXTGLOB).map! do |path|
187
- IndexablePath.new(RbConfig::CONFIG["rubylibdir"], path)
187
+ URI::Generic.from_path(path: path, load_path_entry: RbConfig::CONFIG["rubylibdir"])
188
188
  end,
189
189
  )
190
190
  elsif pathname.extname == ".rb"
191
191
  # If the default_path is a Ruby file, we index it
192
- indexables << IndexablePath.new(RbConfig::CONFIG["rubylibdir"], default_path)
192
+ uris << URI::Generic.from_path(path: default_path, load_path_entry: RbConfig::CONFIG["rubylibdir"])
193
193
  end
194
194
  end
195
195
 
@@ -204,10 +204,12 @@ module RubyIndexer
204
204
  # duplicates or accidentally ignoring exclude patterns
205
205
  next if spec.full_gem_path == @workspace_path
206
206
 
207
- indexables.concat(
207
+ uris.concat(
208
208
  spec.require_paths.flat_map do |require_path|
209
209
  load_path_entry = File.join(spec.full_gem_path, require_path)
210
- Dir.glob(File.join(load_path_entry, "**", "*.rb")).map! { |path| IndexablePath.new(load_path_entry, path) }
210
+ Dir.glob(File.join(load_path_entry, "**", "*.rb")).map! do |path|
211
+ URI::Generic.from_path(path: path, load_path_entry: load_path_entry)
212
+ end
211
213
  end,
212
214
  )
213
215
  rescue Gem::MissingSpecError
@@ -216,8 +218,8 @@ module RubyIndexer
216
218
  # just ignore if they're missing
217
219
  end
218
220
 
219
- indexables.uniq!(&:full_path)
220
- indexables
221
+ uris.uniq!(&:to_s)
222
+ uris
221
223
  end
222
224
 
223
225
  sig { returns(Regexp) }
@@ -271,6 +273,15 @@ module RubyIndexer
271
273
  end
272
274
 
273
275
  others.concat(this_gem.to_spec.dependencies) if this_gem
276
+ others.concat(
277
+ others.filter_map do |d|
278
+ d.to_spec&.dependencies
279
+ rescue Gem::MissingSpecError
280
+ nil
281
+ end.flatten,
282
+ )
283
+ others.uniq!
284
+ others.map!(&:name)
274
285
 
275
286
  excluded.each do |dependency|
276
287
  next unless dependency.runtime?
@@ -279,12 +290,7 @@ module RubyIndexer
279
290
  next unless spec
280
291
 
281
292
  spec.dependencies.each do |transitive_dependency|
282
- # If the transitive dependency is included in other groups, skip it
283
- next if others.any? { |d| d.name == transitive_dependency.name }
284
-
285
- # If the transitive dependency is included as a transitive dependency of a gem outside of the development
286
- # group, skip it
287
- next if others.any? { |d| d.to_spec&.dependencies&.include?(transitive_dependency) }
293
+ next if others.include?(transitive_dependency.name)
288
294
 
289
295
  excluded << transitive_dependency
290
296
  end
@@ -16,13 +16,13 @@ module RubyIndexer
16
16
  index: Index,
17
17
  dispatcher: Prism::Dispatcher,
18
18
  parse_result: Prism::ParseResult,
19
- file_path: String,
19
+ uri: URI::Generic,
20
20
  collect_comments: T::Boolean,
21
21
  ).void
22
22
  end
23
- def initialize(index, dispatcher, parse_result, file_path, collect_comments: false)
23
+ def initialize(index, dispatcher, parse_result, uri, collect_comments: false)
24
24
  @index = index
25
- @file_path = file_path
25
+ @uri = uri
26
26
  @enhancements = T.let(Enhancement.all(self), T::Array[Enhancement])
27
27
  @visibility_stack = T.let([Entry::Visibility::PUBLIC], T::Array[Entry::Visibility])
28
28
  @comments_by_line = T.let(
@@ -80,6 +80,11 @@ module RubyIndexer
80
80
  :on_instance_variable_or_write_node_enter,
81
81
  :on_instance_variable_target_node_enter,
82
82
  :on_alias_method_node_enter,
83
+ :on_class_variable_and_write_node_enter,
84
+ :on_class_variable_operator_write_node_enter,
85
+ :on_class_variable_or_write_node_enter,
86
+ :on_class_variable_target_node_enter,
87
+ :on_class_variable_write_node_enter,
83
88
  )
84
89
  end
85
90
 
@@ -154,7 +159,7 @@ module RubyIndexer
154
159
  else
155
160
  entry = Entry::SingletonClass.new(
156
161
  real_nesting,
157
- @file_path,
162
+ @uri,
158
163
  Location.from_prism_location(node.location, @code_units_cache),
159
164
  Location.from_prism_location(expression.location, @code_units_cache),
160
165
  collect_comments(node),
@@ -282,13 +287,16 @@ module RubyIndexer
282
287
  @visibility_stack.push(Entry::Visibility::PRIVATE)
283
288
  when :module_function
284
289
  handle_module_function(node)
290
+ when :private_class_method
291
+ @visibility_stack.push(Entry::Visibility::PRIVATE)
292
+ handle_private_class_method(node)
285
293
  end
286
294
 
287
295
  @enhancements.each do |enhancement|
288
296
  enhancement.on_call_node_enter(node)
289
297
  rescue StandardError => e
290
298
  @indexing_errors << <<~MSG
291
- Indexing error in #{@file_path} with '#{enhancement.class.name}' on call node enter enhancement: #{e.message}
299
+ Indexing error in #{@uri} with '#{enhancement.class.name}' on call node enter enhancement: #{e.message}
292
300
  MSG
293
301
  end
294
302
  end
@@ -297,7 +305,7 @@ module RubyIndexer
297
305
  def on_call_node_leave(node)
298
306
  message = node.name
299
307
  case message
300
- when :public, :protected, :private
308
+ when :public, :protected, :private, :private_class_method
301
309
  # We want to restore the visibility stack when we leave a method definition with a visibility modifier
302
310
  # e.g. `private def foo; end`
303
311
  if node.arguments&.arguments&.first&.is_a?(Prism::DefNode)
@@ -309,7 +317,7 @@ module RubyIndexer
309
317
  enhancement.on_call_node_leave(node)
310
318
  rescue StandardError => e
311
319
  @indexing_errors << <<~MSG
312
- Indexing error in #{@file_path} with '#{enhancement.class.name}' on call node leave enhancement: #{e.message}
320
+ Indexing error in #{@uri} with '#{enhancement.class.name}' on call node leave enhancement: #{e.message}
313
321
  MSG
314
322
  end
315
323
  end
@@ -324,7 +332,7 @@ module RubyIndexer
324
332
  when nil
325
333
  @index.add(Entry::Method.new(
326
334
  method_name,
327
- @file_path,
335
+ @uri,
328
336
  Location.from_prism_location(node.location, @code_units_cache),
329
337
  Location.from_prism_location(node.name_loc, @code_units_cache),
330
338
  comments,
@@ -340,7 +348,7 @@ module RubyIndexer
340
348
 
341
349
  @index.add(Entry::Method.new(
342
350
  method_name,
343
- @file_path,
351
+ @uri,
344
352
  Location.from_prism_location(node.location, @code_units_cache),
345
353
  Location.from_prism_location(node.name_loc, @code_units_cache),
346
354
  comments,
@@ -424,13 +432,38 @@ module RubyIndexer
424
432
  method_name,
425
433
  node.old_name.slice,
426
434
  @owner_stack.last,
427
- @file_path,
435
+ @uri,
428
436
  Location.from_prism_location(node.new_name.location, @code_units_cache),
429
437
  comments,
430
438
  ),
431
439
  )
432
440
  end
433
441
 
442
+ sig { params(node: Prism::ClassVariableAndWriteNode).void }
443
+ def on_class_variable_and_write_node_enter(node)
444
+ handle_class_variable(node, node.name_loc)
445
+ end
446
+
447
+ sig { params(node: Prism::ClassVariableOperatorWriteNode).void }
448
+ def on_class_variable_operator_write_node_enter(node)
449
+ handle_class_variable(node, node.name_loc)
450
+ end
451
+
452
+ sig { params(node: Prism::ClassVariableOrWriteNode).void }
453
+ def on_class_variable_or_write_node_enter(node)
454
+ handle_class_variable(node, node.name_loc)
455
+ end
456
+
457
+ sig { params(node: Prism::ClassVariableTargetNode).void }
458
+ def on_class_variable_target_node_enter(node)
459
+ handle_class_variable(node, node.location)
460
+ end
461
+
462
+ sig { params(node: Prism::ClassVariableWriteNode).void }
463
+ def on_class_variable_write_node_enter(node)
464
+ handle_class_variable(node, node.name_loc)
465
+ end
466
+
434
467
  sig do
435
468
  params(
436
469
  name: String,
@@ -445,7 +478,7 @@ module RubyIndexer
445
478
 
446
479
  @index.add(Entry::Method.new(
447
480
  name,
448
- @file_path,
481
+ @uri,
449
482
  location,
450
483
  location,
451
484
  comments,
@@ -469,7 +502,7 @@ module RubyIndexer
469
502
 
470
503
  entry = Entry::Module.new(
471
504
  actual_nesting(name),
472
- @file_path,
505
+ @uri,
473
506
  location,
474
507
  name_loc,
475
508
  comments,
@@ -491,7 +524,7 @@ module RubyIndexer
491
524
  nesting = name_or_nesting.is_a?(Array) ? name_or_nesting : actual_nesting(name_or_nesting)
492
525
  entry = Entry::Class.new(
493
526
  nesting,
494
- @file_path,
527
+ @uri,
495
528
  Location.from_prism_location(full_location, @code_units_cache),
496
529
  Location.from_prism_location(name_location, @code_units_cache),
497
530
  comments,
@@ -543,12 +576,48 @@ module RubyIndexer
543
576
 
544
577
  @index.add(Entry::GlobalVariable.new(
545
578
  name,
546
- @file_path,
579
+ @uri,
547
580
  Location.from_prism_location(loc, @code_units_cache),
548
581
  comments,
549
582
  ))
550
583
  end
551
584
 
585
+ sig do
586
+ params(
587
+ node: T.any(
588
+ Prism::ClassVariableAndWriteNode,
589
+ Prism::ClassVariableOperatorWriteNode,
590
+ Prism::ClassVariableOrWriteNode,
591
+ Prism::ClassVariableTargetNode,
592
+ Prism::ClassVariableWriteNode,
593
+ ),
594
+ loc: Prism::Location,
595
+ ).void
596
+ end
597
+ def handle_class_variable(node, loc)
598
+ name = node.name.to_s
599
+ # Ignore incomplete class variable names, which aren't valid Ruby syntax.
600
+ # This could occur if the code is in an incomplete or temporary state.
601
+ return if name == "@@"
602
+
603
+ comments = collect_comments(node)
604
+
605
+ owner = @owner_stack.last
606
+
607
+ # set the class variable's owner to the attached context when defined within a singleton scope.
608
+ if owner.is_a?(Entry::SingletonClass)
609
+ owner = @owner_stack.reverse.find { |entry| !entry.name.include?("<Class:") }
610
+ end
611
+
612
+ @index.add(Entry::ClassVariable.new(
613
+ name,
614
+ @uri,
615
+ Location.from_prism_location(loc, @code_units_cache),
616
+ comments,
617
+ owner,
618
+ ))
619
+ end
620
+
552
621
  sig do
553
622
  params(
554
623
  node: T.any(
@@ -575,7 +644,7 @@ module RubyIndexer
575
644
 
576
645
  @index.add(Entry::InstanceVariable.new(
577
646
  name,
578
- @file_path,
647
+ @uri,
579
648
  Location.from_prism_location(loc, @code_units_cache),
580
649
  collect_comments(node),
581
650
  owner,
@@ -639,7 +708,7 @@ module RubyIndexer
639
708
  new_name_value,
640
709
  old_name_value,
641
710
  @owner_stack.last,
642
- @file_path,
711
+ @uri,
643
712
  Location.from_prism_location(new_name.location, @code_units_cache),
644
713
  comments,
645
714
  ),
@@ -675,7 +744,7 @@ module RubyIndexer
675
744
  value.slice,
676
745
  @stack.dup,
677
746
  name,
678
- @file_path,
747
+ @uri,
679
748
  Location.from_prism_location(node.location, @code_units_cache),
680
749
  comments,
681
750
  )
@@ -688,7 +757,7 @@ module RubyIndexer
688
757
  value.name.to_s,
689
758
  @stack.dup,
690
759
  name,
691
- @file_path,
760
+ @uri,
692
761
  Location.from_prism_location(node.location, @code_units_cache),
693
762
  comments,
694
763
  )
@@ -699,14 +768,14 @@ module RubyIndexer
699
768
  value.target.slice,
700
769
  @stack.dup,
701
770
  name,
702
- @file_path,
771
+ @uri,
703
772
  Location.from_prism_location(node.location, @code_units_cache),
704
773
  comments,
705
774
  )
706
775
  else
707
776
  Entry::Constant.new(
708
777
  name,
709
- @file_path,
778
+ @uri,
710
779
  Location.from_prism_location(node.location, @code_units_cache),
711
780
  comments,
712
781
  )
@@ -778,7 +847,7 @@ module RubyIndexer
778
847
  if reader
779
848
  @index.add(Entry::Accessor.new(
780
849
  name,
781
- @file_path,
850
+ @uri,
782
851
  Location.from_prism_location(loc, @code_units_cache),
783
852
  comments,
784
853
  current_visibility,
@@ -790,7 +859,7 @@ module RubyIndexer
790
859
 
791
860
  @index.add(Entry::Accessor.new(
792
861
  "#{name}=",
793
- @file_path,
862
+ @uri,
794
863
  Location.from_prism_location(loc, @code_units_cache),
795
864
  comments,
796
865
  current_visibility,
@@ -863,7 +932,7 @@ module RubyIndexer
863
932
  location = Location.from_prism_location(argument.location, @code_units_cache)
864
933
  @index.add(Entry::Method.new(
865
934
  method_name,
866
- @file_path,
935
+ @uri,
867
936
  location,
868
937
  location,
869
938
  collect_comments(node)&.concat(entry.comments),
@@ -875,6 +944,45 @@ module RubyIndexer
875
944
  end
876
945
  end
877
946
 
947
+ sig { params(node: Prism::CallNode).void }
948
+ def handle_private_class_method(node)
949
+ node.arguments&.arguments&.each do |argument|
950
+ string_or_symbol_nodes = case argument
951
+ when Prism::StringNode, Prism::SymbolNode
952
+ [argument]
953
+ when Prism::ArrayNode
954
+ argument.elements
955
+ else
956
+ []
957
+ end
958
+
959
+ unless string_or_symbol_nodes.empty?
960
+ # pop the visibility off since there isn't a method definition following `private_class_method`
961
+ @visibility_stack.pop
962
+ end
963
+
964
+ string_or_symbol_nodes.each do |string_or_symbol_node|
965
+ method_name = case string_or_symbol_node
966
+ when Prism::StringNode
967
+ string_or_symbol_node.content
968
+ when Prism::SymbolNode
969
+ string_or_symbol_node.value
970
+ end
971
+ next unless method_name
972
+
973
+ owner_name = @owner_stack.last&.name
974
+ next unless owner_name
975
+
976
+ entries = @index.resolve_method(method_name, @index.existing_or_new_singleton_class(owner_name).name)
977
+ next unless entries
978
+
979
+ entries.each do |entry|
980
+ entry.visibility = Entry::Visibility::PRIVATE
981
+ end
982
+ end
983
+ end
984
+ end
985
+
878
986
  sig { returns(Entry::Visibility) }
879
987
  def current_visibility
880
988
  T.must(@visibility_stack.last)