ruby-lsp 0.21.3 → 0.22.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/exe/ruby-lsp +1 -1
- data/exe/ruby-lsp-launcher +0 -3
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +6 -0
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +179 -59
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +31 -28
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +10 -10
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +2 -2
- data/lib/ruby_indexer/test/configuration_test.rb +10 -0
- data/lib/ruby_indexer/test/constant_test.rb +8 -8
- data/lib/ruby_indexer/test/enhancements_test.rb +134 -38
- data/lib/ruby_indexer/test/index_test.rb +39 -0
- data/lib/ruby_indexer/test/method_test.rb +114 -1
- data/lib/ruby_lsp/global_state.rb +2 -4
- data/lib/ruby_lsp/internal.rb +1 -0
- data/lib/ruby_lsp/listeners/document_symbol.rb +37 -4
- data/lib/ruby_lsp/requests/definition.rb +2 -0
- data/lib/ruby_lsp/requests/hover.rb +2 -0
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +1 -0
- data/lib/ruby_lsp/server.rb +13 -0
- data/lib/ruby_lsp/setup_bundler.rb +43 -25
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: efd5671eae595026a17c3114a00de1053865ac828726dd7ac5a66548f6b1ad56
|
4
|
+
data.tar.gz: ccf5b7af12a6e1e327cc2d458be11f39a9ac7319ab9049863ed5a74e333e8a6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fbcdfaac508788a17fb3b7e939ce290e33049a0080ff6260abfaeb609ee76a033234ccc2efa5724587e9c4cbf4552e2cd5d2cb0af1186971b8ed06fec290cb3
|
7
|
+
data.tar.gz: 3e37acf250618e60df2addbce7f9acf86df4bf3e771b7b49c4cd8f4ad326ea82e3d41ad80c5ce71e3b0429dab98385df51f4645824cd419e32dac5ea13778760
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.22.1
|
data/exe/ruby-lsp
CHANGED
@@ -54,7 +54,7 @@ rescue OptionParser::InvalidOption => e
|
|
54
54
|
exit(1)
|
55
55
|
end
|
56
56
|
|
57
|
-
# When we're running without bundler, then we need to make sure the
|
57
|
+
# When we're running without bundler, then we need to make sure the composed bundle is fully configured and re-execute
|
58
58
|
# using `BUNDLE_GEMFILE=.ruby-lsp/Gemfile bundle exec ruby-lsp` so that we have access to the gems that are a part of
|
59
59
|
# the application's bundle
|
60
60
|
if ENV["BUNDLE_GEMFILE"].nil?
|
data/exe/ruby-lsp-launcher
CHANGED
@@ -74,9 +74,6 @@ rescue StandardError => e
|
|
74
74
|
# If Bundler.setup fails, we need to restore the original $LOAD_PATH so that we can still require the Ruby LSP server
|
75
75
|
# in degraded mode
|
76
76
|
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
77
|
-
ensure
|
78
|
-
require "fileutils"
|
79
|
-
FileUtils.rm(bundle_env_path) if File.exist?(bundle_env_path)
|
80
77
|
end
|
81
78
|
|
82
79
|
error_path = File.join(".ruby-lsp", "install_error")
|
@@ -109,6 +109,12 @@ module RubyIndexer
|
|
109
109
|
|
110
110
|
indexables = T.let([], T::Array[IndexablePath])
|
111
111
|
|
112
|
+
# Handle top level files separately. The path below is an optimization to prevent descending down directories that
|
113
|
+
# are going to be excluded anyway, so we need to handle top level scripts separately
|
114
|
+
Dir.glob(File.join(@workspace_path, "*.rb"), flags).each do |path|
|
115
|
+
indexables << IndexablePath.new(nil, path)
|
116
|
+
end
|
117
|
+
|
112
118
|
# Add user specified patterns
|
113
119
|
@included_patterns.each do |pattern|
|
114
120
|
load_path_entry = T.let(nil, T.nilable(String))
|
@@ -18,13 +18,12 @@ module RubyIndexer
|
|
18
18
|
parse_result: Prism::ParseResult,
|
19
19
|
file_path: String,
|
20
20
|
collect_comments: T::Boolean,
|
21
|
-
enhancements: T::Array[Enhancement],
|
22
21
|
).void
|
23
22
|
end
|
24
|
-
def initialize(index, dispatcher, parse_result, file_path, collect_comments: false
|
23
|
+
def initialize(index, dispatcher, parse_result, file_path, collect_comments: false)
|
25
24
|
@index = index
|
26
25
|
@file_path = file_path
|
27
|
-
@enhancements =
|
26
|
+
@enhancements = T.let(Enhancement.all(self), T::Array[Enhancement])
|
28
27
|
@visibility_stack = T.let([Entry::Visibility::PUBLIC], T::Array[Entry::Visibility])
|
29
28
|
@comments_by_line = T.let(
|
30
29
|
parse_result.comments.to_h do |c|
|
@@ -37,6 +36,7 @@ module RubyIndexer
|
|
37
36
|
parse_result.code_units_cache(@index.configuration.encoding),
|
38
37
|
T.any(T.proc.params(arg0: Integer).returns(Integer), Prism::CodeUnitsCache),
|
39
38
|
)
|
39
|
+
@source_lines = T.let(parse_result.source.lines, T::Array[String])
|
40
40
|
|
41
41
|
# The nesting stack we're currently inside. Used to determine the fully qualified name of constants, but only
|
42
42
|
# stored by unresolved aliases which need the original nesting to be lazily resolved
|
@@ -85,15 +85,9 @@ module RubyIndexer
|
|
85
85
|
|
86
86
|
sig { params(node: Prism::ClassNode).void }
|
87
87
|
def on_class_node_enter(node)
|
88
|
-
@visibility_stack.push(Entry::Visibility::PUBLIC)
|
89
88
|
constant_path = node.constant_path
|
90
|
-
name = constant_path.slice
|
91
|
-
|
92
|
-
comments = collect_comments(node)
|
93
|
-
|
94
89
|
superclass = node.superclass
|
95
|
-
|
96
|
-
nesting = actual_nesting(name)
|
90
|
+
nesting = actual_nesting(constant_path.slice)
|
97
91
|
|
98
92
|
parent_class = case superclass
|
99
93
|
when Prism::ConstantReadNode, Prism::ConstantPathNode
|
@@ -112,53 +106,29 @@ module RubyIndexer
|
|
112
106
|
end
|
113
107
|
end
|
114
108
|
|
115
|
-
|
109
|
+
add_class(
|
116
110
|
nesting,
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
comments,
|
121
|
-
parent_class,
|
111
|
+
node.location,
|
112
|
+
constant_path.location,
|
113
|
+
parent_class_name: parent_class,
|
114
|
+
comments: collect_comments(node),
|
122
115
|
)
|
123
|
-
|
124
|
-
@owner_stack << entry
|
125
|
-
@index.add(entry)
|
126
|
-
@stack << name
|
127
116
|
end
|
128
117
|
|
129
118
|
sig { params(node: Prism::ClassNode).void }
|
130
119
|
def on_class_node_leave(node)
|
131
|
-
|
132
|
-
@owner_stack.pop
|
133
|
-
@visibility_stack.pop
|
120
|
+
pop_namespace_stack
|
134
121
|
end
|
135
122
|
|
136
123
|
sig { params(node: Prism::ModuleNode).void }
|
137
124
|
def on_module_node_enter(node)
|
138
|
-
@visibility_stack.push(Entry::Visibility::PUBLIC)
|
139
125
|
constant_path = node.constant_path
|
140
|
-
|
141
|
-
|
142
|
-
comments = collect_comments(node)
|
143
|
-
|
144
|
-
entry = Entry::Module.new(
|
145
|
-
actual_nesting(name),
|
146
|
-
@file_path,
|
147
|
-
Location.from_prism_location(node.location, @code_units_cache),
|
148
|
-
Location.from_prism_location(constant_path.location, @code_units_cache),
|
149
|
-
comments,
|
150
|
-
)
|
151
|
-
|
152
|
-
@owner_stack << entry
|
153
|
-
@index.add(entry)
|
154
|
-
@stack << name
|
126
|
+
add_module(constant_path.slice, node.location, constant_path.location, comments: collect_comments(node))
|
155
127
|
end
|
156
128
|
|
157
129
|
sig { params(node: Prism::ModuleNode).void }
|
158
130
|
def on_module_node_leave(node)
|
159
|
-
|
160
|
-
@owner_stack.pop
|
161
|
-
@visibility_stack.pop
|
131
|
+
pop_namespace_stack
|
162
132
|
end
|
163
133
|
|
164
134
|
sig { params(node: Prism::SingletonClassNode).void }
|
@@ -200,9 +170,7 @@ module RubyIndexer
|
|
200
170
|
|
201
171
|
sig { params(node: Prism::SingletonClassNode).void }
|
202
172
|
def on_singleton_class_node_leave(node)
|
203
|
-
|
204
|
-
@owner_stack.pop
|
205
|
-
@visibility_stack.pop
|
173
|
+
pop_namespace_stack
|
206
174
|
end
|
207
175
|
|
208
176
|
sig { params(node: Prism::MultiWriteNode).void }
|
@@ -314,10 +282,13 @@ module RubyIndexer
|
|
314
282
|
@visibility_stack.push(Entry::Visibility::PRIVATE)
|
315
283
|
when :module_function
|
316
284
|
handle_module_function(node)
|
285
|
+
when :private_class_method
|
286
|
+
@visibility_stack.push(Entry::Visibility::PRIVATE)
|
287
|
+
handle_private_class_method(node)
|
317
288
|
end
|
318
289
|
|
319
290
|
@enhancements.each do |enhancement|
|
320
|
-
enhancement.on_call_node_enter(
|
291
|
+
enhancement.on_call_node_enter(node)
|
321
292
|
rescue StandardError => e
|
322
293
|
@indexing_errors << <<~MSG
|
323
294
|
Indexing error in #{@file_path} with '#{enhancement.class.name}' on call node enter enhancement: #{e.message}
|
@@ -329,7 +300,7 @@ module RubyIndexer
|
|
329
300
|
def on_call_node_leave(node)
|
330
301
|
message = node.name
|
331
302
|
case message
|
332
|
-
when :public, :protected, :private
|
303
|
+
when :public, :protected, :private, :private_class_method
|
333
304
|
# We want to restore the visibility stack when we leave a method definition with a visibility modifier
|
334
305
|
# e.g. `private def foo; end`
|
335
306
|
if node.arguments&.arguments&.first&.is_a?(Prism::DefNode)
|
@@ -338,7 +309,7 @@ module RubyIndexer
|
|
338
309
|
end
|
339
310
|
|
340
311
|
@enhancements.each do |enhancement|
|
341
|
-
enhancement.on_call_node_leave(
|
312
|
+
enhancement.on_call_node_leave(node)
|
342
313
|
rescue StandardError => e
|
343
314
|
@indexing_errors << <<~MSG
|
344
315
|
Indexing error in #{@file_path} with '#{enhancement.class.name}' on call node leave enhancement: #{e.message}
|
@@ -463,6 +434,98 @@ module RubyIndexer
|
|
463
434
|
)
|
464
435
|
end
|
465
436
|
|
437
|
+
sig do
|
438
|
+
params(
|
439
|
+
name: String,
|
440
|
+
node_location: Prism::Location,
|
441
|
+
signatures: T::Array[Entry::Signature],
|
442
|
+
visibility: Entry::Visibility,
|
443
|
+
comments: T.nilable(String),
|
444
|
+
).void
|
445
|
+
end
|
446
|
+
def add_method(name, node_location, signatures, visibility: Entry::Visibility::PUBLIC, comments: nil)
|
447
|
+
location = Location.from_prism_location(node_location, @code_units_cache)
|
448
|
+
|
449
|
+
@index.add(Entry::Method.new(
|
450
|
+
name,
|
451
|
+
@file_path,
|
452
|
+
location,
|
453
|
+
location,
|
454
|
+
comments,
|
455
|
+
signatures,
|
456
|
+
visibility,
|
457
|
+
@owner_stack.last,
|
458
|
+
))
|
459
|
+
end
|
460
|
+
|
461
|
+
sig do
|
462
|
+
params(
|
463
|
+
name: String,
|
464
|
+
full_location: Prism::Location,
|
465
|
+
name_location: Prism::Location,
|
466
|
+
comments: T.nilable(String),
|
467
|
+
).void
|
468
|
+
end
|
469
|
+
def add_module(name, full_location, name_location, comments: nil)
|
470
|
+
location = Location.from_prism_location(full_location, @code_units_cache)
|
471
|
+
name_loc = Location.from_prism_location(name_location, @code_units_cache)
|
472
|
+
|
473
|
+
entry = Entry::Module.new(
|
474
|
+
actual_nesting(name),
|
475
|
+
@file_path,
|
476
|
+
location,
|
477
|
+
name_loc,
|
478
|
+
comments,
|
479
|
+
)
|
480
|
+
|
481
|
+
advance_namespace_stack(name, entry)
|
482
|
+
end
|
483
|
+
|
484
|
+
sig do
|
485
|
+
params(
|
486
|
+
name_or_nesting: T.any(String, T::Array[String]),
|
487
|
+
full_location: Prism::Location,
|
488
|
+
name_location: Prism::Location,
|
489
|
+
parent_class_name: T.nilable(String),
|
490
|
+
comments: T.nilable(String),
|
491
|
+
).void
|
492
|
+
end
|
493
|
+
def add_class(name_or_nesting, full_location, name_location, parent_class_name: nil, comments: nil)
|
494
|
+
nesting = name_or_nesting.is_a?(Array) ? name_or_nesting : actual_nesting(name_or_nesting)
|
495
|
+
entry = Entry::Class.new(
|
496
|
+
nesting,
|
497
|
+
@file_path,
|
498
|
+
Location.from_prism_location(full_location, @code_units_cache),
|
499
|
+
Location.from_prism_location(name_location, @code_units_cache),
|
500
|
+
comments,
|
501
|
+
parent_class_name,
|
502
|
+
)
|
503
|
+
|
504
|
+
advance_namespace_stack(T.must(nesting.last), entry)
|
505
|
+
end
|
506
|
+
|
507
|
+
sig { params(block: T.proc.params(index: Index, base: Entry::Namespace).void).void }
|
508
|
+
def register_included_hook(&block)
|
509
|
+
owner = @owner_stack.last
|
510
|
+
return unless owner
|
511
|
+
|
512
|
+
@index.register_included_hook(owner.name) do |index, base|
|
513
|
+
block.call(index, base)
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
sig { void }
|
518
|
+
def pop_namespace_stack
|
519
|
+
@stack.pop
|
520
|
+
@owner_stack.pop
|
521
|
+
@visibility_stack.pop
|
522
|
+
end
|
523
|
+
|
524
|
+
sig { returns(T.nilable(Entry::Namespace)) }
|
525
|
+
def current_owner
|
526
|
+
@owner_stack.last
|
527
|
+
end
|
528
|
+
|
466
529
|
private
|
467
530
|
|
468
531
|
sig do
|
@@ -661,8 +724,7 @@ module RubyIndexer
|
|
661
724
|
comments = +""
|
662
725
|
|
663
726
|
start_line = node.location.start_line - 1
|
664
|
-
start_line -= 1 unless
|
665
|
-
|
727
|
+
start_line -= 1 unless comment_exists_at?(start_line)
|
666
728
|
start_line.downto(1) do |line|
|
667
729
|
comment = @comments_by_line[line]
|
668
730
|
break unless comment
|
@@ -683,6 +745,11 @@ module RubyIndexer
|
|
683
745
|
comments
|
684
746
|
end
|
685
747
|
|
748
|
+
sig { params(line: Integer).returns(T::Boolean) }
|
749
|
+
def comment_exists_at?(line)
|
750
|
+
@comments_by_line.key?(line) || !@source_lines[line - 1].to_s.strip.empty?
|
751
|
+
end
|
752
|
+
|
686
753
|
sig { params(name: String).returns(String) }
|
687
754
|
def fully_qualify_name(name)
|
688
755
|
if @stack.empty? || name.start_with?("::")
|
@@ -746,16 +813,22 @@ module RubyIndexer
|
|
746
813
|
return unless arguments
|
747
814
|
|
748
815
|
arguments.each do |node|
|
749
|
-
next unless node.is_a?(Prism::ConstantReadNode) || node.is_a?(Prism::ConstantPathNode)
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
owner.mixin_operations << Entry::Include.new(node.full_name)
|
754
|
-
when :prepend
|
755
|
-
owner.mixin_operations << Entry::Prepend.new(node.full_name)
|
756
|
-
when :extend
|
816
|
+
next unless node.is_a?(Prism::ConstantReadNode) || node.is_a?(Prism::ConstantPathNode) ||
|
817
|
+
(node.is_a?(Prism::SelfNode) && operation == :extend)
|
818
|
+
|
819
|
+
if node.is_a?(Prism::SelfNode)
|
757
820
|
singleton = @index.existing_or_new_singleton_class(owner.name)
|
758
|
-
singleton.mixin_operations << Entry::Include.new(
|
821
|
+
singleton.mixin_operations << Entry::Include.new(owner.name)
|
822
|
+
else
|
823
|
+
case operation
|
824
|
+
when :include
|
825
|
+
owner.mixin_operations << Entry::Include.new(node.full_name)
|
826
|
+
when :prepend
|
827
|
+
owner.mixin_operations << Entry::Prepend.new(node.full_name)
|
828
|
+
when :extend
|
829
|
+
singleton = @index.existing_or_new_singleton_class(owner.name)
|
830
|
+
singleton.mixin_operations << Entry::Include.new(node.full_name)
|
831
|
+
end
|
759
832
|
end
|
760
833
|
rescue Prism::ConstantPathNode::DynamicPartsInConstantPathError,
|
761
834
|
Prism::ConstantPathNode::MissingNodesInConstantPathError
|
@@ -805,6 +878,45 @@ module RubyIndexer
|
|
805
878
|
end
|
806
879
|
end
|
807
880
|
|
881
|
+
sig { params(node: Prism::CallNode).void }
|
882
|
+
def handle_private_class_method(node)
|
883
|
+
node.arguments&.arguments&.each do |argument|
|
884
|
+
string_or_symbol_nodes = case argument
|
885
|
+
when Prism::StringNode, Prism::SymbolNode
|
886
|
+
[argument]
|
887
|
+
when Prism::ArrayNode
|
888
|
+
argument.elements
|
889
|
+
else
|
890
|
+
[]
|
891
|
+
end
|
892
|
+
|
893
|
+
unless string_or_symbol_nodes.empty?
|
894
|
+
# pop the visibility off since there isn't a method definition following `private_class_method`
|
895
|
+
@visibility_stack.pop
|
896
|
+
end
|
897
|
+
|
898
|
+
string_or_symbol_nodes.each do |string_or_symbol_node|
|
899
|
+
method_name = case string_or_symbol_node
|
900
|
+
when Prism::StringNode
|
901
|
+
string_or_symbol_node.content
|
902
|
+
when Prism::SymbolNode
|
903
|
+
string_or_symbol_node.value
|
904
|
+
end
|
905
|
+
next unless method_name
|
906
|
+
|
907
|
+
owner_name = @owner_stack.last&.name
|
908
|
+
next unless owner_name
|
909
|
+
|
910
|
+
entries = @index.resolve_method(method_name, @index.existing_or_new_singleton_class(owner_name).name)
|
911
|
+
next unless entries
|
912
|
+
|
913
|
+
entries.each do |entry|
|
914
|
+
entry.visibility = Entry::Visibility::PRIVATE
|
915
|
+
end
|
916
|
+
end
|
917
|
+
end
|
918
|
+
end
|
919
|
+
|
808
920
|
sig { returns(Entry::Visibility) }
|
809
921
|
def current_visibility
|
810
922
|
T.must(@visibility_stack.last)
|
@@ -910,5 +1022,13 @@ module RubyIndexer
|
|
910
1022
|
|
911
1023
|
corrected_nesting
|
912
1024
|
end
|
1025
|
+
|
1026
|
+
sig { params(short_name: String, entry: Entry::Namespace).void }
|
1027
|
+
def advance_namespace_stack(short_name, entry)
|
1028
|
+
@visibility_stack.push(Entry::Visibility::PUBLIC)
|
1029
|
+
@owner_stack << entry
|
1030
|
+
@index.add(entry)
|
1031
|
+
@stack << short_name
|
1032
|
+
end
|
913
1033
|
end
|
914
1034
|
end
|
@@ -8,38 +8,41 @@ module RubyIndexer
|
|
8
8
|
|
9
9
|
abstract!
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
@enhancements = T.let([], T::Array[T::Class[Enhancement]])
|
12
|
+
|
13
|
+
class << self
|
14
|
+
extend T::Sig
|
15
|
+
|
16
|
+
sig { params(child: T::Class[Enhancement]).void }
|
17
|
+
def inherited(child)
|
18
|
+
@enhancements << child
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
sig { params(listener: DeclarationListener).returns(T::Array[Enhancement]) }
|
23
|
+
def all(listener)
|
24
|
+
@enhancements.map { |enhancement| enhancement.new(listener) }
|
25
|
+
end
|
26
|
+
|
27
|
+
# Only available for testing purposes
|
28
|
+
sig { void }
|
29
|
+
def clear
|
30
|
+
@enhancements.clear
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
sig { params(listener: DeclarationListener).void }
|
35
|
+
def initialize(listener)
|
36
|
+
@listener = listener
|
14
37
|
end
|
15
38
|
|
16
39
|
# The `on_extend` indexing enhancement is invoked whenever an extend is encountered in the code. It can be used to
|
17
40
|
# register for an included callback, similar to what `ActiveSupport::Concern` does in order to auto-extend the
|
18
41
|
# `ClassMethods` modules
|
19
|
-
sig
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
code_units_cache: T.any(
|
25
|
-
T.proc.params(arg0: Integer).returns(Integer),
|
26
|
-
Prism::CodeUnitsCache,
|
27
|
-
),
|
28
|
-
).void
|
29
|
-
end
|
30
|
-
def on_call_node_enter(owner, node, file_path, code_units_cache); end
|
31
|
-
|
32
|
-
sig do
|
33
|
-
overridable.params(
|
34
|
-
owner: T.nilable(Entry::Namespace),
|
35
|
-
node: Prism::CallNode,
|
36
|
-
file_path: String,
|
37
|
-
code_units_cache: T.any(
|
38
|
-
T.proc.params(arg0: Integer).returns(Integer),
|
39
|
-
Prism::CodeUnitsCache,
|
40
|
-
),
|
41
|
-
).void
|
42
|
-
end
|
43
|
-
def on_call_node_leave(owner, node, file_path, code_units_cache); end
|
42
|
+
sig { overridable.params(node: Prism::CallNode).void }
|
43
|
+
def on_call_node_enter(node); end # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
44
|
+
|
45
|
+
sig { overridable.params(node: Prism::CallNode).void }
|
46
|
+
def on_call_node_leave(node); end # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
44
47
|
end
|
45
48
|
end
|
@@ -7,6 +7,7 @@ module RubyIndexer
|
|
7
7
|
|
8
8
|
class UnresolvableAliasError < StandardError; end
|
9
9
|
class NonExistingNamespaceError < StandardError; end
|
10
|
+
class IndexNotEmptyError < StandardError; end
|
10
11
|
|
11
12
|
# The minimum Jaro-Winkler similarity score for an entry to be considered a match for a given fuzzy search query
|
12
13
|
ENTRY_SIMILARITY_THRESHOLD = 0.7
|
@@ -39,9 +40,6 @@ module RubyIndexer
|
|
39
40
|
# Holds the linearized ancestors list for every namespace
|
40
41
|
@ancestors = T.let({}, T::Hash[String, T::Array[String]])
|
41
42
|
|
42
|
-
# List of classes that are enhancing the index
|
43
|
-
@enhancements = T.let([], T::Array[Enhancement])
|
44
|
-
|
45
43
|
# Map of module name to included hooks that have to be executed when we include the given module
|
46
44
|
@included_hooks = T.let(
|
47
45
|
{},
|
@@ -51,12 +49,6 @@ module RubyIndexer
|
|
51
49
|
@configuration = T.let(RubyIndexer::Configuration.new, Configuration)
|
52
50
|
end
|
53
51
|
|
54
|
-
# Register an enhancement to the index. Enhancements must conform to the `Enhancement` interface
|
55
|
-
sig { params(enhancement: Enhancement).void }
|
56
|
-
def register_enhancement(enhancement)
|
57
|
-
@enhancements << enhancement
|
58
|
-
end
|
59
|
-
|
60
52
|
# Register an included `hook` that will be executed when `module_name` is included into any namespace
|
61
53
|
sig { params(module_name: String, hook: T.proc.params(index: Index, base: Entry::Namespace).void).void }
|
62
54
|
def register_included_hook(module_name, &hook)
|
@@ -360,6 +352,15 @@ module RubyIndexer
|
|
360
352
|
).void
|
361
353
|
end
|
362
354
|
def index_all(indexable_paths: @configuration.indexables, &block)
|
355
|
+
# When troubleshooting an indexing issue, e.g. through irb, it's not obvious that `index_all` will augment the
|
356
|
+
# existing index values, meaning it may contain 'stale' entries. This check ensures that the user is aware of this
|
357
|
+
# behavior and can take appropriate action.
|
358
|
+
# binding.break
|
359
|
+
if @entries.any?
|
360
|
+
raise IndexNotEmptyError,
|
361
|
+
"The index is not empty. To prevent invalid entries, `index_all` can only be called once."
|
362
|
+
end
|
363
|
+
|
363
364
|
RBSIndexer.new(self).index_ruby_core
|
364
365
|
# Calculate how many paths are worth 1% of progress
|
365
366
|
progress_step = (indexable_paths.length / 100.0).ceil
|
@@ -386,7 +387,6 @@ module RubyIndexer
|
|
386
387
|
result,
|
387
388
|
indexable_path.full_path,
|
388
389
|
collect_comments: collect_comments,
|
389
|
-
enhancements: @enhancements,
|
390
390
|
)
|
391
391
|
dispatcher.dispatch(result.value)
|
392
392
|
|
@@ -302,10 +302,10 @@ module RubyIndexer
|
|
302
302
|
RUBY
|
303
303
|
|
304
304
|
b_const = @index["A::B"].first
|
305
|
-
|
305
|
+
assert_predicate(b_const, :private?)
|
306
306
|
|
307
307
|
c_const = @index["A::C"].first
|
308
|
-
|
308
|
+
assert_predicate(c_const, :private?)
|
309
309
|
|
310
310
|
d_const = @index["A::D"].first
|
311
311
|
assert_equal(Entry::Visibility::PUBLIC, d_const.visibility)
|
@@ -160,5 +160,15 @@ module RubyIndexer
|
|
160
160
|
)
|
161
161
|
end
|
162
162
|
end
|
163
|
+
|
164
|
+
def test_includes_top_level_files
|
165
|
+
Dir.mktmpdir do |dir|
|
166
|
+
FileUtils.touch(File.join(dir, "find_me.rb"))
|
167
|
+
@config.workspace_path = dir
|
168
|
+
|
169
|
+
indexables = @config.indexables
|
170
|
+
assert(indexables.find { |i| File.basename(i.full_path) == "find_me.rb" })
|
171
|
+
end
|
172
|
+
end
|
163
173
|
end
|
164
174
|
end
|
@@ -130,13 +130,13 @@ module RubyIndexer
|
|
130
130
|
RUBY
|
131
131
|
|
132
132
|
b_const = @index["A::B"].first
|
133
|
-
|
133
|
+
assert_predicate(b_const, :private?)
|
134
134
|
|
135
135
|
c_const = @index["A::C"].first
|
136
|
-
|
136
|
+
assert_predicate(c_const, :private?)
|
137
137
|
|
138
138
|
d_const = @index["A::D"].first
|
139
|
-
|
139
|
+
assert_predicate(d_const, :public?)
|
140
140
|
end
|
141
141
|
|
142
142
|
def test_marking_constants_as_private_reopening_namespaces
|
@@ -163,13 +163,13 @@ module RubyIndexer
|
|
163
163
|
RUBY
|
164
164
|
|
165
165
|
a_const = @index["A::B::CONST_A"].first
|
166
|
-
|
166
|
+
assert_predicate(a_const, :private?)
|
167
167
|
|
168
168
|
b_const = @index["A::B::CONST_B"].first
|
169
|
-
|
169
|
+
assert_predicate(b_const, :private?)
|
170
170
|
|
171
171
|
c_const = @index["A::B::CONST_C"].first
|
172
|
-
|
172
|
+
assert_predicate(c_const, :private?)
|
173
173
|
end
|
174
174
|
|
175
175
|
def test_marking_constants_as_private_with_receiver
|
@@ -187,10 +187,10 @@ module RubyIndexer
|
|
187
187
|
RUBY
|
188
188
|
|
189
189
|
a_const = @index["A::B::CONST_A"].first
|
190
|
-
|
190
|
+
assert_predicate(a_const, :private?)
|
191
191
|
|
192
192
|
b_const = @index["A::B::CONST_B"].first
|
193
|
-
|
193
|
+
assert_predicate(b_const, :private?)
|
194
194
|
end
|
195
195
|
|
196
196
|
def test_indexing_constant_aliases
|