ruby-lsp 0.19.1 → 0.20.1
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/exe/ruby-lsp +7 -1
- data/lib/core_ext/uri.rb +2 -2
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +63 -12
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +85 -36
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +5 -1
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +39 -98
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +12 -19
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +22 -0
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +2 -7
- data/lib/ruby_indexer/test/enhancements_test.rb +5 -7
- data/lib/ruby_indexer/test/global_variable_test.rb +49 -0
- data/lib/ruby_indexer/test/index_test.rb +89 -0
- data/lib/ruby_lsp/erb_document.rb +15 -2
- data/lib/ruby_lsp/listeners/definition.rb +20 -0
- data/lib/ruby_lsp/listeners/folding_ranges.rb +3 -3
- data/lib/ruby_lsp/requests/code_action_resolve.rb +8 -2
- data/lib/ruby_lsp/requests/completion.rb +1 -1
- data/lib/ruby_lsp/requests/definition.rb +2 -1
- data/lib/ruby_lsp/requests/document_highlight.rb +5 -1
- data/lib/ruby_lsp/requests/hover.rb +1 -1
- data/lib/ruby_lsp/requests/range_formatting.rb +4 -2
- data/lib/ruby_lsp/requests/references.rb +3 -1
- data/lib/ruby_lsp/requests/rename.rb +3 -1
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +1 -1
- data/lib/ruby_lsp/requests/signature_help.rb +1 -1
- data/lib/ruby_lsp/requests/support/common.rb +1 -1
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +6 -6
- data/lib/ruby_lsp/response_builders/document_symbol.rb +2 -2
- data/lib/ruby_lsp/response_builders/hover.rb +2 -2
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +14 -8
- data/lib/ruby_lsp/response_builders/signature_help.rb +2 -2
- data/lib/ruby_lsp/ruby_document.rb +33 -12
- data/lib/ruby_lsp/setup_bundler.rb +30 -8
- data/lib/ruby_lsp/type_inferrer.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58327a9f9a3d85375cbbf81e3e170a948d5c8dfbdcdcac0a1fdef5f685d20c95
|
4
|
+
data.tar.gz: 45572eb6645bce73d2079bed65f0d92c98921517926b968bba96788769a3aada
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c506eeff4d24060e3afdb4ad9da319c12b725050c8f25a9348ec7dea9082f8adced7671b7b1eb8f7f09412942139e47a2df5059b5672d2b6a75f0ffc5a59885d
|
7
|
+
data.tar.gz: d9a89ce24946e5f9cc47b5a48086f6fd977176d31332a0b634950dc00a41fc9a36e4753eae2896e2da0129e92bff4278265eaa970252a5292c783e5bc82258e9
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.20.1
|
data/exe/ruby-lsp
CHANGED
@@ -63,7 +63,13 @@ if ENV["BUNDLE_GEMFILE"].nil?
|
|
63
63
|
exit(78)
|
64
64
|
end
|
65
65
|
|
66
|
-
|
66
|
+
base_bundle = if env["BUNDLER_VERSION"]
|
67
|
+
"bundle _#{env["BUNDLER_VERSION"]}_"
|
68
|
+
else
|
69
|
+
"bundle"
|
70
|
+
end
|
71
|
+
|
72
|
+
exit exec(env, "#{base_bundle} exec ruby-lsp #{original_args.join(" ")}")
|
67
73
|
end
|
68
74
|
|
69
75
|
require "ruby_lsp/load_sorbet"
|
data/lib/core_ext/uri.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
|
4
4
|
module URI
|
5
5
|
class Generic
|
6
|
+
extend T::Sig
|
7
|
+
|
6
8
|
# Avoid a deprecation warning with Ruby 3.4 where the default parser was changed to RFC3986.
|
7
9
|
# This condition must remain even after support for 3.4 has been dropped for users that have
|
8
10
|
# `uri` in their lockfile, decoupling it from the ruby version.
|
@@ -27,8 +29,6 @@ module URI
|
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
30
|
-
extend T::Sig
|
31
|
-
|
32
32
|
sig { returns(T.nilable(String)) }
|
33
33
|
def to_standardized_path
|
34
34
|
parsed_path = path
|
@@ -28,7 +28,17 @@ module RubyIndexer
|
|
28
28
|
@encoding = T.let(Encoding::UTF_8, Encoding)
|
29
29
|
@excluded_gems = T.let(initial_excluded_gems, T::Array[String])
|
30
30
|
@included_gems = T.let([], T::Array[String])
|
31
|
-
|
31
|
+
|
32
|
+
@excluded_patterns = T.let(
|
33
|
+
[
|
34
|
+
File.join("**", "*_test.rb"),
|
35
|
+
File.join("node_modules", "**", "*"),
|
36
|
+
File.join("spec", "**", "*"),
|
37
|
+
File.join("test", "**", "*"),
|
38
|
+
File.join("tmp", "**", "*"),
|
39
|
+
],
|
40
|
+
T::Array[String],
|
41
|
+
)
|
32
42
|
|
33
43
|
path = Bundler.settings["path"]
|
34
44
|
if path
|
@@ -56,6 +66,21 @@ module RubyIndexer
|
|
56
66
|
)
|
57
67
|
end
|
58
68
|
|
69
|
+
sig { returns(String) }
|
70
|
+
def merged_excluded_file_pattern
|
71
|
+
# This regex looks for @excluded_patterns that follow the format of "something/**/*", where
|
72
|
+
# "something" is one or more non-"/"
|
73
|
+
#
|
74
|
+
# Returns "/path/to/workspace/{tmp,node_modules}/**/*"
|
75
|
+
@excluded_patterns
|
76
|
+
.filter_map do |pattern|
|
77
|
+
next if File.absolute_path?(pattern)
|
78
|
+
|
79
|
+
pattern.match(%r{\A([^/]+)/\*\*/\*\z})&.captures&.first
|
80
|
+
end
|
81
|
+
.then { |dirs| File.join(@workspace_path, "{#{dirs.join(",")}}/**/*") }
|
82
|
+
end
|
83
|
+
|
59
84
|
sig { returns(T::Array[IndexablePath]) }
|
60
85
|
def indexables
|
61
86
|
excluded_gems = @excluded_gems - @included_gems
|
@@ -64,21 +89,47 @@ module RubyIndexer
|
|
64
89
|
# NOTE: indexing the patterns (both included and excluded) needs to happen before indexing gems, otherwise we risk
|
65
90
|
# having duplicates if BUNDLE_PATH is set to a folder inside the project structure
|
66
91
|
|
92
|
+
flags = File::FNM_PATHNAME | File::FNM_EXTGLOB
|
93
|
+
|
94
|
+
# In order to speed up indexing, only traverse into top-level directories that are not entirely excluded.
|
95
|
+
# For example, if "tmp/**/*" is excluded, we don't need to traverse into "tmp" at all. However, if
|
96
|
+
# "vendor/bundle/**/*" is excluded, we will traverse all of "vendor" and `reject!` out all "vendor/bundle" entries
|
97
|
+
# later.
|
98
|
+
excluded_pattern = merged_excluded_file_pattern
|
99
|
+
included_paths = Dir.glob(File.join(@workspace_path, "*/"), flags)
|
100
|
+
.filter_map do |included_path|
|
101
|
+
next if File.fnmatch?(excluded_pattern, included_path, flags)
|
102
|
+
|
103
|
+
relative_path = included_path
|
104
|
+
.delete_prefix(@workspace_path)
|
105
|
+
.tap { |path| path.delete_prefix!("/") }
|
106
|
+
|
107
|
+
[included_path, relative_path]
|
108
|
+
end
|
109
|
+
|
110
|
+
indexables = T.let([], T::Array[IndexablePath])
|
111
|
+
|
67
112
|
# Add user specified patterns
|
68
|
-
|
113
|
+
@included_patterns.each do |pattern|
|
69
114
|
load_path_entry = T.let(nil, T.nilable(String))
|
70
115
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
# on repositories that define multiple gems, like Rails. All frameworks are defined inside the current
|
76
|
-
# workspace directory, but each one of them belongs to a different $LOAD_PATH entry
|
77
|
-
if load_path_entry.nil? || !path.start_with?(load_path_entry)
|
78
|
-
load_path_entry = $LOAD_PATH.find { |load_path| path.start_with?(load_path) }
|
79
|
-
end
|
116
|
+
included_paths.each do |included_path, relative_path|
|
117
|
+
relative_pattern = pattern.delete_prefix(File.join(relative_path, "/"))
|
118
|
+
|
119
|
+
next unless pattern.start_with?("**") || pattern.start_with?(relative_path)
|
80
120
|
|
81
|
-
|
121
|
+
Dir.glob(File.join(included_path, relative_pattern), flags).each do |path|
|
122
|
+
path = File.expand_path(path)
|
123
|
+
# All entries for the same pattern match the same $LOAD_PATH entry. Since searching the $LOAD_PATH for every
|
124
|
+
# entry is expensive, we memoize it until we find a path that doesn't belong to that $LOAD_PATH. This
|
125
|
+
# happens on repositories that define multiple gems, like Rails. All frameworks are defined inside the
|
126
|
+
# current workspace directory, but each one of them belongs to a different $LOAD_PATH entry
|
127
|
+
if load_path_entry.nil? || !path.start_with?(load_path_entry)
|
128
|
+
load_path_entry = $LOAD_PATH.find { |load_path| path.start_with?(load_path) }
|
129
|
+
end
|
130
|
+
|
131
|
+
indexables << IndexablePath.new(load_path_entry, path)
|
132
|
+
end
|
82
133
|
end
|
83
134
|
end
|
84
135
|
|
@@ -33,6 +33,10 @@ module RubyIndexer
|
|
33
33
|
T::Hash[Integer, Prism::Comment],
|
34
34
|
)
|
35
35
|
@inside_def = T.let(false, T::Boolean)
|
36
|
+
@code_units_cache = T.let(
|
37
|
+
parse_result.code_units_cache(@index.configuration.encoding),
|
38
|
+
T.any(T.proc.params(arg0: Integer).returns(Integer), Prism::CodeUnitsCache),
|
39
|
+
)
|
36
40
|
|
37
41
|
# The nesting stack we're currently inside. Used to determine the fully qualified name of constants, but only
|
38
42
|
# stored by unresolved aliases which need the original nesting to be lazily resolved
|
@@ -65,6 +69,11 @@ module RubyIndexer
|
|
65
69
|
:on_constant_or_write_node_enter,
|
66
70
|
:on_constant_and_write_node_enter,
|
67
71
|
:on_constant_operator_write_node_enter,
|
72
|
+
:on_global_variable_and_write_node_enter,
|
73
|
+
:on_global_variable_operator_write_node_enter,
|
74
|
+
:on_global_variable_or_write_node_enter,
|
75
|
+
:on_global_variable_target_node_enter,
|
76
|
+
:on_global_variable_write_node_enter,
|
68
77
|
:on_instance_variable_write_node_enter,
|
69
78
|
:on_instance_variable_and_write_node_enter,
|
70
79
|
:on_instance_variable_operator_write_node_enter,
|
@@ -106,10 +115,9 @@ module RubyIndexer
|
|
106
115
|
entry = Entry::Class.new(
|
107
116
|
nesting,
|
108
117
|
@file_path,
|
109
|
-
node.location,
|
110
|
-
constant_path.location,
|
118
|
+
Location.from_prism_location(node.location, @code_units_cache),
|
119
|
+
Location.from_prism_location(constant_path.location, @code_units_cache),
|
111
120
|
comments,
|
112
|
-
@index.configuration.encoding,
|
113
121
|
parent_class,
|
114
122
|
)
|
115
123
|
|
@@ -136,10 +144,9 @@ module RubyIndexer
|
|
136
144
|
entry = Entry::Module.new(
|
137
145
|
actual_nesting(name),
|
138
146
|
@file_path,
|
139
|
-
node.location,
|
140
|
-
constant_path.location,
|
147
|
+
Location.from_prism_location(node.location, @code_units_cache),
|
148
|
+
Location.from_prism_location(constant_path.location, @code_units_cache),
|
141
149
|
comments,
|
142
|
-
@index.configuration.encoding,
|
143
150
|
)
|
144
151
|
|
145
152
|
@owner_stack << entry
|
@@ -170,19 +177,17 @@ module RubyIndexer
|
|
170
177
|
if existing_entries
|
171
178
|
entry = T.must(existing_entries.first)
|
172
179
|
entry.update_singleton_information(
|
173
|
-
node.location,
|
174
|
-
expression.location,
|
180
|
+
Location.from_prism_location(node.location, @code_units_cache),
|
181
|
+
Location.from_prism_location(expression.location, @code_units_cache),
|
175
182
|
collect_comments(node),
|
176
|
-
@index.configuration.encoding,
|
177
183
|
)
|
178
184
|
else
|
179
185
|
entry = Entry::SingletonClass.new(
|
180
186
|
real_nesting,
|
181
187
|
@file_path,
|
182
|
-
node.location,
|
183
|
-
expression.location,
|
188
|
+
Location.from_prism_location(node.location, @code_units_cache),
|
189
|
+
Location.from_prism_location(expression.location, @code_units_cache),
|
184
190
|
collect_comments(node),
|
185
|
-
@index.configuration.encoding,
|
186
191
|
nil,
|
187
192
|
)
|
188
193
|
@index.add(entry, skip_prefix_tree: true)
|
@@ -310,7 +315,7 @@ module RubyIndexer
|
|
310
315
|
end
|
311
316
|
|
312
317
|
@enhancements.each do |enhancement|
|
313
|
-
enhancement.on_call_node(@index, @owner_stack.last, node, @file_path)
|
318
|
+
enhancement.on_call_node(@index, @owner_stack.last, node, @file_path, @code_units_cache)
|
314
319
|
rescue StandardError => e
|
315
320
|
@indexing_errors << "Indexing error in #{@file_path} with '#{enhancement.class.name}' enhancement: #{e.message}"
|
316
321
|
end
|
@@ -340,10 +345,9 @@ module RubyIndexer
|
|
340
345
|
@index.add(Entry::Method.new(
|
341
346
|
method_name,
|
342
347
|
@file_path,
|
343
|
-
node.location,
|
344
|
-
node.name_loc,
|
348
|
+
Location.from_prism_location(node.location, @code_units_cache),
|
349
|
+
Location.from_prism_location(node.name_loc, @code_units_cache),
|
345
350
|
comments,
|
346
|
-
@index.configuration.encoding,
|
347
351
|
[Entry::Signature.new(list_params(node.parameters))],
|
348
352
|
current_visibility,
|
349
353
|
@owner_stack.last,
|
@@ -357,10 +361,9 @@ module RubyIndexer
|
|
357
361
|
@index.add(Entry::Method.new(
|
358
362
|
method_name,
|
359
363
|
@file_path,
|
360
|
-
node.location,
|
361
|
-
node.name_loc,
|
364
|
+
Location.from_prism_location(node.location, @code_units_cache),
|
365
|
+
Location.from_prism_location(node.name_loc, @code_units_cache),
|
362
366
|
comments,
|
363
|
-
@index.configuration.encoding,
|
364
367
|
[Entry::Signature.new(list_params(node.parameters))],
|
365
368
|
current_visibility,
|
366
369
|
singleton,
|
@@ -382,6 +385,31 @@ module RubyIndexer
|
|
382
385
|
end
|
383
386
|
end
|
384
387
|
|
388
|
+
sig { params(node: Prism::GlobalVariableAndWriteNode).void }
|
389
|
+
def on_global_variable_and_write_node_enter(node)
|
390
|
+
handle_global_variable(node, node.name_loc)
|
391
|
+
end
|
392
|
+
|
393
|
+
sig { params(node: Prism::GlobalVariableOperatorWriteNode).void }
|
394
|
+
def on_global_variable_operator_write_node_enter(node)
|
395
|
+
handle_global_variable(node, node.name_loc)
|
396
|
+
end
|
397
|
+
|
398
|
+
sig { params(node: Prism::GlobalVariableOrWriteNode).void }
|
399
|
+
def on_global_variable_or_write_node_enter(node)
|
400
|
+
handle_global_variable(node, node.name_loc)
|
401
|
+
end
|
402
|
+
|
403
|
+
sig { params(node: Prism::GlobalVariableTargetNode).void }
|
404
|
+
def on_global_variable_target_node_enter(node)
|
405
|
+
handle_global_variable(node, node.location)
|
406
|
+
end
|
407
|
+
|
408
|
+
sig { params(node: Prism::GlobalVariableWriteNode).void }
|
409
|
+
def on_global_variable_write_node_enter(node)
|
410
|
+
handle_global_variable(node, node.name_loc)
|
411
|
+
end
|
412
|
+
|
385
413
|
sig { params(node: Prism::InstanceVariableWriteNode).void }
|
386
414
|
def on_instance_variable_write_node_enter(node)
|
387
415
|
handle_instance_variable(node, node.name_loc)
|
@@ -417,15 +445,38 @@ module RubyIndexer
|
|
417
445
|
node.old_name.slice,
|
418
446
|
@owner_stack.last,
|
419
447
|
@file_path,
|
420
|
-
node.new_name.location,
|
448
|
+
Location.from_prism_location(node.new_name.location, @code_units_cache),
|
421
449
|
comments,
|
422
|
-
@index.configuration.encoding,
|
423
450
|
),
|
424
451
|
)
|
425
452
|
end
|
426
453
|
|
427
454
|
private
|
428
455
|
|
456
|
+
sig do
|
457
|
+
params(
|
458
|
+
node: T.any(
|
459
|
+
Prism::GlobalVariableAndWriteNode,
|
460
|
+
Prism::GlobalVariableOperatorWriteNode,
|
461
|
+
Prism::GlobalVariableOrWriteNode,
|
462
|
+
Prism::GlobalVariableTargetNode,
|
463
|
+
Prism::GlobalVariableWriteNode,
|
464
|
+
),
|
465
|
+
loc: Prism::Location,
|
466
|
+
).void
|
467
|
+
end
|
468
|
+
def handle_global_variable(node, loc)
|
469
|
+
name = node.name.to_s
|
470
|
+
comments = collect_comments(node)
|
471
|
+
|
472
|
+
@index.add(Entry::GlobalVariable.new(
|
473
|
+
name,
|
474
|
+
@file_path,
|
475
|
+
Location.from_prism_location(loc, @code_units_cache),
|
476
|
+
comments,
|
477
|
+
))
|
478
|
+
end
|
479
|
+
|
429
480
|
sig do
|
430
481
|
params(
|
431
482
|
node: T.any(
|
@@ -453,9 +504,8 @@ module RubyIndexer
|
|
453
504
|
@index.add(Entry::InstanceVariable.new(
|
454
505
|
name,
|
455
506
|
@file_path,
|
456
|
-
loc,
|
507
|
+
Location.from_prism_location(loc, @code_units_cache),
|
457
508
|
collect_comments(node),
|
458
|
-
@index.configuration.encoding,
|
459
509
|
owner,
|
460
510
|
))
|
461
511
|
end
|
@@ -518,9 +568,8 @@ module RubyIndexer
|
|
518
568
|
old_name_value,
|
519
569
|
@owner_stack.last,
|
520
570
|
@file_path,
|
521
|
-
new_name.location,
|
571
|
+
Location.from_prism_location(new_name.location, @code_units_cache),
|
522
572
|
comments,
|
523
|
-
@index.configuration.encoding,
|
524
573
|
),
|
525
574
|
)
|
526
575
|
end
|
@@ -555,9 +604,8 @@ module RubyIndexer
|
|
555
604
|
@stack.dup,
|
556
605
|
name,
|
557
606
|
@file_path,
|
558
|
-
node.location,
|
607
|
+
Location.from_prism_location(node.location, @code_units_cache),
|
559
608
|
comments,
|
560
|
-
@index.configuration.encoding,
|
561
609
|
)
|
562
610
|
when Prism::ConstantWriteNode, Prism::ConstantAndWriteNode, Prism::ConstantOrWriteNode,
|
563
611
|
Prism::ConstantOperatorWriteNode
|
@@ -569,9 +617,8 @@ module RubyIndexer
|
|
569
617
|
@stack.dup,
|
570
618
|
name,
|
571
619
|
@file_path,
|
572
|
-
node.location,
|
620
|
+
Location.from_prism_location(node.location, @code_units_cache),
|
573
621
|
comments,
|
574
|
-
@index.configuration.encoding,
|
575
622
|
)
|
576
623
|
when Prism::ConstantPathWriteNode, Prism::ConstantPathOrWriteNode, Prism::ConstantPathOperatorWriteNode,
|
577
624
|
Prism::ConstantPathAndWriteNode
|
@@ -581,12 +628,16 @@ module RubyIndexer
|
|
581
628
|
@stack.dup,
|
582
629
|
name,
|
583
630
|
@file_path,
|
584
|
-
node.location,
|
631
|
+
Location.from_prism_location(node.location, @code_units_cache),
|
585
632
|
comments,
|
586
|
-
@index.configuration.encoding,
|
587
633
|
)
|
588
634
|
else
|
589
|
-
Entry::Constant.new(
|
635
|
+
Entry::Constant.new(
|
636
|
+
name,
|
637
|
+
@file_path,
|
638
|
+
Location.from_prism_location(node.location, @code_units_cache),
|
639
|
+
comments,
|
640
|
+
)
|
590
641
|
end,
|
591
642
|
)
|
592
643
|
end
|
@@ -652,9 +703,8 @@ module RubyIndexer
|
|
652
703
|
@index.add(Entry::Accessor.new(
|
653
704
|
name,
|
654
705
|
@file_path,
|
655
|
-
loc,
|
706
|
+
Location.from_prism_location(loc, @code_units_cache),
|
656
707
|
comments,
|
657
|
-
@index.configuration.encoding,
|
658
708
|
current_visibility,
|
659
709
|
@owner_stack.last,
|
660
710
|
))
|
@@ -665,9 +715,8 @@ module RubyIndexer
|
|
665
715
|
@index.add(Entry::Accessor.new(
|
666
716
|
"#{name}=",
|
667
717
|
@file_path,
|
668
|
-
loc,
|
718
|
+
Location.from_prism_location(loc, @code_units_cache),
|
669
719
|
comments,
|
670
|
-
@index.configuration.encoding,
|
671
720
|
current_visibility,
|
672
721
|
@owner_stack.last,
|
673
722
|
))
|
@@ -19,8 +19,12 @@ module RubyIndexer
|
|
19
19
|
owner: T.nilable(Entry::Namespace),
|
20
20
|
node: Prism::CallNode,
|
21
21
|
file_path: String,
|
22
|
+
code_units_cache: T.any(
|
23
|
+
T.proc.params(arg0: Integer).returns(Integer),
|
24
|
+
Prism::CodeUnitsCache,
|
25
|
+
),
|
22
26
|
).void
|
23
27
|
end
|
24
|
-
def on_call_node(index, owner, node, file_path); end
|
28
|
+
def on_call_node(index, owner, node, file_path, code_units_cache); end
|
25
29
|
end
|
26
30
|
end
|