ruby-lsp 0.23.23 → 0.26.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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/exe/ruby-lsp +10 -4
- data/exe/ruby-lsp-check +0 -4
- data/exe/ruby-lsp-launcher +25 -11
- data/exe/ruby-lsp-test-exec +3 -15
- data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +0 -1
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +0 -1
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +7 -1
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +1 -4
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +10 -19
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +27 -7
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +12 -8
- data/lib/ruby_indexer/test/configuration_test.rb +1 -2
- data/lib/ruby_indexer/test/index_test.rb +36 -0
- data/lib/ruby_indexer/test/instance_variables_test.rb +24 -0
- data/lib/ruby_indexer/test/method_test.rb +17 -0
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +2 -2
- data/lib/ruby_indexer/test/reference_finder_test.rb +79 -14
- data/lib/ruby_lsp/addon.rb +44 -15
- data/lib/ruby_lsp/base_server.rb +34 -26
- data/lib/ruby_lsp/document.rb +162 -52
- data/lib/ruby_lsp/erb_document.rb +8 -3
- data/lib/ruby_lsp/global_state.rb +21 -0
- data/lib/ruby_lsp/internal.rb +0 -2
- data/lib/ruby_lsp/listeners/completion.rb +14 -3
- data/lib/ruby_lsp/listeners/hover.rb +7 -0
- data/lib/ruby_lsp/listeners/inlay_hints.rb +5 -3
- data/lib/ruby_lsp/listeners/spec_style.rb +7 -8
- data/lib/ruby_lsp/listeners/test_discovery.rb +18 -15
- data/lib/ruby_lsp/listeners/test_style.rb +14 -13
- data/lib/ruby_lsp/requests/code_action_resolve.rb +3 -3
- data/lib/ruby_lsp/requests/code_lens.rb +9 -3
- data/lib/ruby_lsp/requests/completion.rb +1 -1
- data/lib/ruby_lsp/requests/definition.rb +1 -1
- data/lib/ruby_lsp/requests/discover_tests.rb +2 -2
- data/lib/ruby_lsp/requests/document_highlight.rb +1 -1
- data/lib/ruby_lsp/requests/hover.rb +1 -1
- data/lib/ruby_lsp/requests/inlay_hints.rb +3 -3
- data/lib/ruby_lsp/requests/on_type_formatting.rb +1 -1
- data/lib/ruby_lsp/requests/prepare_rename.rb +1 -1
- data/lib/ruby_lsp/requests/references.rb +10 -6
- data/lib/ruby_lsp/requests/rename.rb +8 -6
- data/lib/ruby_lsp/requests/request.rb +6 -7
- data/lib/ruby_lsp/requests/selection_ranges.rb +1 -1
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +1 -1
- data/lib/ruby_lsp/requests/signature_help.rb +1 -1
- data/lib/ruby_lsp/requests/support/common.rb +1 -3
- data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +2 -2
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +13 -3
- data/lib/ruby_lsp/response_builders/response_builder.rb +6 -8
- data/lib/ruby_lsp/ruby_document.rb +10 -5
- data/lib/ruby_lsp/server.rb +89 -108
- data/lib/ruby_lsp/setup_bundler.rb +59 -25
- data/lib/ruby_lsp/static_docs.rb +1 -0
- data/lib/ruby_lsp/store.rb +0 -10
- data/lib/ruby_lsp/test_helper.rb +1 -4
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +13 -8
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +17 -4
- data/lib/ruby_lsp/utils.rb +47 -11
- data/static_docs/break.md +103 -0
- metadata +2 -16
- data/lib/ruby_lsp/load_sorbet.rb +0 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e8b51ca9a97aa0e855fbf1109f07733aae195eb25dba844f79840665b36ac9a
|
4
|
+
data.tar.gz: 79d5c3af7ba9fb03c2da197b4213a861e366b7be5a60e677ac6ca9ae8269dbea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8cb30f7427f02460320becb1b883c502ea0fbfd48f5148192e1339350e94836ed6ba825df4b4b0fe0ff8d32325d6196af6a26ef94d566e4e32ecd235d66ed821
|
7
|
+
data.tar.gz: 68d5712e3ae16ecaa602eeccadcab5108d89cce1f1a282b82bd3244b3111131442ee6feda63b1e7049027624c07be25e5f3ae39a00b9df25130f12f43c2dac80
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.26.0
|
data/exe/ruby-lsp
CHANGED
@@ -88,13 +88,17 @@ if ENV["BUNDLE_GEMFILE"].nil?
|
|
88
88
|
exit exec(env, "#{base_command} exec ruby-lsp #{original_args.join(" ")}".strip)
|
89
89
|
end
|
90
90
|
|
91
|
+
$stdin.sync = true
|
92
|
+
$stdout.sync = true
|
93
|
+
$stderr.sync = true
|
94
|
+
$stdin.binmode
|
95
|
+
$stdout.binmode
|
96
|
+
$stderr.binmode
|
97
|
+
|
91
98
|
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
92
99
|
|
93
|
-
require "ruby_lsp/load_sorbet"
|
94
100
|
require "ruby_lsp/internal"
|
95
101
|
|
96
|
-
T::Utils.run_all_sig_blocks
|
97
|
-
|
98
102
|
if options[:debug]
|
99
103
|
if ["x64-mingw-ucrt", "x64-mingw32"].include?(RUBY_PLATFORM)
|
100
104
|
$stderr.puts "Debugging is not supported on Windows"
|
@@ -147,8 +151,10 @@ if options[:doctor]
|
|
147
151
|
return
|
148
152
|
end
|
149
153
|
|
154
|
+
server = RubyLsp::Server.new
|
155
|
+
|
150
156
|
# Ensure all output goes out stderr by default to allow puts/p/pp to work
|
151
157
|
# without specifying output device.
|
152
158
|
$> = $stderr
|
153
159
|
|
154
|
-
|
160
|
+
server.start
|
data/exe/ruby-lsp-check
CHANGED
@@ -3,13 +3,9 @@
|
|
3
3
|
|
4
4
|
# This executable checks if all automatic LSP requests run successfully on every Ruby file under the current directory
|
5
5
|
|
6
|
-
require "ruby_lsp/load_sorbet"
|
7
|
-
|
8
6
|
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
9
7
|
require "ruby_lsp/internal"
|
10
8
|
|
11
|
-
T::Utils.run_all_sig_blocks
|
12
|
-
|
13
9
|
files = Dir.glob("#{Dir.pwd}/**/*.rb")
|
14
10
|
|
15
11
|
puts "Verifying that all automatic LSP requests execute successfully. This may take a while..."
|
data/exe/ruby-lsp-launcher
CHANGED
@@ -6,6 +6,13 @@
|
|
6
6
|
# composed bundle
|
7
7
|
# !!!!!!!
|
8
8
|
|
9
|
+
$stdin.sync = true
|
10
|
+
$stdout.sync = true
|
11
|
+
$stderr.sync = true
|
12
|
+
$stdin.binmode
|
13
|
+
$stdout.binmode
|
14
|
+
$stderr.binmode
|
15
|
+
|
9
16
|
setup_error = nil
|
10
17
|
install_error = nil
|
11
18
|
reboot = false
|
@@ -28,7 +35,6 @@ else
|
|
28
35
|
# Read the initialize request before even starting the server. We need to do this to figure out the workspace URI.
|
29
36
|
# Editors are not required to spawn the language server process on the same directory as the workspace URI, so we need
|
30
37
|
# to ensure that we're setting up the bundle in the right place
|
31
|
-
$stdin.binmode
|
32
38
|
headers = $stdin.gets("\r\n\r\n")
|
33
39
|
content_length = headers[/Content-Length: (\d+)/i, 1].to_i
|
34
40
|
$stdin.read(content_length)
|
@@ -83,8 +89,13 @@ begin
|
|
83
89
|
# This Marshal load can only happen after requiring Bundler because it will load a custom error class from Bundler
|
84
90
|
# itself. If we try to load before requiring, the class will not be defined and loading will fail
|
85
91
|
error_path = File.join(".ruby-lsp", "install_error")
|
86
|
-
install_error =
|
87
|
-
Marshal.load(File.read(error_path))
|
92
|
+
install_error = begin
|
93
|
+
Marshal.load(File.read(error_path)) if File.exist?(error_path)
|
94
|
+
rescue ArgumentError
|
95
|
+
# The class we tried to load is not defined. This might happen when the user upgrades Bundler and new error
|
96
|
+
# classes are introduced or removed
|
97
|
+
File.delete(error_path)
|
98
|
+
nil
|
88
99
|
end
|
89
100
|
|
90
101
|
Bundler.setup
|
@@ -120,11 +131,8 @@ end
|
|
120
131
|
# Now that the bundle is set up, we can begin actually launching the server. Note that `Bundler.setup` will have already
|
121
132
|
# configured the load path using the version of the Ruby LSP present in the composed bundle. Do not push any Ruby LSP
|
122
133
|
# paths into the load path manually or we may end up requiring the wrong version of the gem
|
123
|
-
require "ruby_lsp/load_sorbet"
|
124
134
|
require "ruby_lsp/internal"
|
125
135
|
|
126
|
-
T::Utils.run_all_sig_blocks
|
127
|
-
|
128
136
|
if ARGV.include?("--debug")
|
129
137
|
if ["x64-mingw-ucrt", "x64-mingw32"].include?(RUBY_PLATFORM)
|
130
138
|
$stderr.puts "Debugging is not supported on Windows"
|
@@ -138,22 +146,28 @@ if ARGV.include?("--debug")
|
|
138
146
|
end
|
139
147
|
end
|
140
148
|
|
141
|
-
# Ensure all output goes out stderr by default to allow puts/p/pp to work without specifying output device.
|
142
|
-
$> = $stderr
|
143
|
-
|
144
149
|
initialize_request = JSON.parse(raw_initialize, symbolize_names: true) if raw_initialize
|
145
150
|
|
146
151
|
begin
|
147
|
-
RubyLsp::Server.new(
|
152
|
+
server = RubyLsp::Server.new(
|
148
153
|
install_error: install_error,
|
149
154
|
setup_error: setup_error,
|
150
155
|
initialize_request: initialize_request,
|
151
|
-
)
|
156
|
+
)
|
157
|
+
|
158
|
+
# Ensure all output goes out stderr by default to allow puts/p/pp to work without specifying output device.
|
159
|
+
$> = $stderr
|
160
|
+
|
161
|
+
server.start
|
152
162
|
rescue ArgumentError
|
153
163
|
# If the launcher is booting an outdated version of the server, then the initializer doesn't accept a keyword splat
|
154
164
|
# and we already read the initialize request from the stdin pipe. In this case, we need to process the initialize
|
155
165
|
# request manually and then start the main loop
|
156
166
|
server = RubyLsp::Server.new
|
167
|
+
|
168
|
+
# Ensure all output goes out stderr by default to allow puts/p/pp to work without specifying output device.
|
169
|
+
$> = $stderr
|
170
|
+
|
157
171
|
server.process_message(initialize_request)
|
158
172
|
server.start
|
159
173
|
end
|
data/exe/ruby-lsp-test-exec
CHANGED
@@ -1,18 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
#
|
5
|
-
#
|
6
|
-
|
7
|
-
*ENV["RUBYOPT"],
|
8
|
-
"-rbundler/setup",
|
9
|
-
"-r#{File.expand_path("../lib/ruby_lsp/test_reporters/minitest_reporter", __dir__)}",
|
10
|
-
"-r#{File.expand_path("../lib/ruby_lsp/test_reporters/test_unit_reporter", __dir__)}",
|
11
|
-
].join(" ")
|
12
|
-
|
13
|
-
# Replace this process with whatever command was passed. We only want to set RUBYOPT.
|
14
|
-
# The way you use this executable is by prefixing your test command with `ruby-lsp-test-exec`, like so:
|
15
|
-
# ruby-lsp-test-exec bundle exec ruby -Itest test/example_test.rb
|
16
|
-
# ruby-lsp-test-exec bundle exec ruby -Ispec spec/example_spec.rb
|
17
|
-
# ruby-lsp-test-exec bundle exec rspec spec/example_spec.rb
|
18
|
-
exec({ "RUBYOPT" => rubyopt }, *ARGV)
|
4
|
+
# This executable will be removed thanks to the changes in https://github.com/Shopify/ruby-lsp/pull/3661.
|
5
|
+
# Remove this a few months after extension updates have rolled out
|
6
|
+
exec(*ARGV)
|
@@ -9,7 +9,7 @@ module RubyIndexer
|
|
9
9
|
#: Array[String]
|
10
10
|
attr_reader :indexing_errors
|
11
11
|
|
12
|
-
#: (Index index, Prism::Dispatcher dispatcher, Prism::ParseResult parse_result, URI::Generic uri, ?collect_comments: bool) -> void
|
12
|
+
#: (Index index, Prism::Dispatcher dispatcher, Prism::ParseLexResult | Prism::ParseResult parse_result, URI::Generic uri, ?collect_comments: bool) -> void
|
13
13
|
def initialize(index, dispatcher, parse_result, uri, collect_comments: false)
|
14
14
|
@index = index
|
15
15
|
@uri = uri
|
@@ -260,6 +260,9 @@ module RubyIndexer
|
|
260
260
|
handle_attribute(node, reader: false, writer: true)
|
261
261
|
when :attr_accessor
|
262
262
|
handle_attribute(node, reader: true, writer: true)
|
263
|
+
when :attr
|
264
|
+
has_writer = node.arguments&.arguments&.last&.is_a?(Prism::TrueNode) || false
|
265
|
+
handle_attribute(node, reader: true, writer: has_writer)
|
263
266
|
when :alias_method
|
264
267
|
handle_alias_method(node)
|
265
268
|
when :include, :prepend, :extend
|
@@ -726,6 +729,9 @@ module RubyIndexer
|
|
726
729
|
comment = @comments_by_line[line]
|
727
730
|
break unless comment
|
728
731
|
|
732
|
+
# a trailing comment from a previous line is not a comment for this node
|
733
|
+
break if comment.trailing?
|
734
|
+
|
729
735
|
comment_content = comment.location.slice
|
730
736
|
|
731
737
|
# invalid encodings would raise an "invalid byte sequence" exception
|
@@ -98,11 +98,8 @@ module RubyIndexer
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
+
# @abstract
|
101
102
|
class ModuleOperation
|
102
|
-
extend T::Helpers
|
103
|
-
|
104
|
-
abstract!
|
105
|
-
|
106
103
|
#: String
|
107
104
|
attr_reader :module_name
|
108
105
|
|
@@ -115,11 +112,8 @@ module RubyIndexer
|
|
115
112
|
class Include < ModuleOperation; end
|
116
113
|
class Prepend < ModuleOperation; end
|
117
114
|
|
115
|
+
# @abstract
|
118
116
|
class Namespace < Entry
|
119
|
-
extend T::Helpers
|
120
|
-
|
121
|
-
abstract!
|
122
|
-
|
123
117
|
#: Array[String]
|
124
118
|
attr_reader :nesting
|
125
119
|
|
@@ -191,11 +185,8 @@ module RubyIndexer
|
|
191
185
|
class Constant < Entry
|
192
186
|
end
|
193
187
|
|
188
|
+
# @abstract
|
194
189
|
class Parameter
|
195
|
-
extend T::Helpers
|
196
|
-
|
197
|
-
abstract!
|
198
|
-
|
199
190
|
# Name includes just the name of the parameter, excluding symbols like splats
|
200
191
|
#: Symbol
|
201
192
|
attr_reader :name
|
@@ -289,12 +280,8 @@ module RubyIndexer
|
|
289
280
|
end
|
290
281
|
end
|
291
282
|
|
283
|
+
# @abstract
|
292
284
|
class Member < Entry
|
293
|
-
extend T::Sig
|
294
|
-
extend T::Helpers
|
295
|
-
|
296
|
-
abstract!
|
297
|
-
|
298
285
|
#: Entry::Namespace?
|
299
286
|
attr_reader :owner
|
300
287
|
|
@@ -305,8 +292,11 @@ module RubyIndexer
|
|
305
292
|
@owner = owner
|
306
293
|
end
|
307
294
|
|
308
|
-
|
309
|
-
|
295
|
+
# @abstract
|
296
|
+
#: -> Array[Signature]
|
297
|
+
def signatures
|
298
|
+
raise AbstractMethodInvokedError
|
299
|
+
end
|
310
300
|
|
311
301
|
#: -> String
|
312
302
|
def decorated_parameters
|
@@ -343,6 +333,7 @@ module RubyIndexer
|
|
343
333
|
end
|
344
334
|
|
345
335
|
class Method < Member
|
336
|
+
# @override
|
346
337
|
#: Array[Signature]
|
347
338
|
attr_reader :signatures
|
348
339
|
|
@@ -266,7 +266,7 @@ module RubyIndexer
|
|
266
266
|
def constant_completion_candidates(name, nesting)
|
267
267
|
# If we have a top level reference, then we don't need to include completions inside the current nesting
|
268
268
|
if name.start_with?("::")
|
269
|
-
return @entries_tree.search(name.delete_prefix("::")) #: as Array[Array[Entry::Constant | Entry::ConstantAlias | Entry::Namespace | Entry::UnresolvedConstantAlias]]
|
269
|
+
return @entries_tree.search(name.delete_prefix("::")) #: as Array[Array[Entry::Constant | Entry::ConstantAlias | Entry::Namespace | Entry::UnresolvedConstantAlias]]
|
270
270
|
end
|
271
271
|
|
272
272
|
# Otherwise, we have to include every possible constant the user might be referring to. This is essentially the
|
@@ -291,8 +291,17 @@ module RubyIndexer
|
|
291
291
|
|
292
292
|
# Top level constants
|
293
293
|
entries.concat(@entries_tree.search(name))
|
294
|
+
|
295
|
+
# Filter only constants since methods may have names that look like constants
|
296
|
+
entries.each do |definitions|
|
297
|
+
definitions.select! do |entry|
|
298
|
+
entry.is_a?(Entry::Constant) || entry.is_a?(Entry::ConstantAlias) ||
|
299
|
+
entry.is_a?(Entry::Namespace) || entry.is_a?(Entry::UnresolvedConstantAlias)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
294
303
|
entries.uniq!
|
295
|
-
entries #: as Array[Array[Entry::Constant | Entry::ConstantAlias | Entry::Namespace | Entry::UnresolvedConstantAlias]]
|
304
|
+
entries #: as Array[Array[Entry::Constant | Entry::ConstantAlias | Entry::Namespace | Entry::UnresolvedConstantAlias]]
|
296
305
|
end
|
297
306
|
|
298
307
|
# Resolve a constant to its declaration based on its name and the nesting where the reference was found. Parameter
|
@@ -818,11 +827,22 @@ module RubyIndexer
|
|
818
827
|
)
|
819
828
|
# Find the first class entry that has a parent class. Notice that if the developer makes a mistake and inherits
|
820
829
|
# from two different classes in different files, we simply ignore it
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
830
|
+
possible_parents = singleton_levels > 0 ? self[attached_class_name] : namespace_entries
|
831
|
+
superclass = nil #: Entry::Class?
|
832
|
+
|
833
|
+
possible_parents&.each do |n|
|
834
|
+
# Ignore non class entries
|
835
|
+
next unless n.is_a?(Entry::Class)
|
836
|
+
|
837
|
+
parent_class = n.parent_class
|
838
|
+
next unless parent_class
|
839
|
+
|
840
|
+
# Always set the superclass, but break early if we found one that isn't `::Object` (meaning we found an explicit
|
841
|
+
# parent class and not the implicit default). Note that when setting different parents to the same class, which
|
842
|
+
# is invalid, we pick whatever is the first one we find
|
843
|
+
superclass = n
|
844
|
+
break if parent_class != "::Object"
|
845
|
+
end
|
826
846
|
|
827
847
|
if superclass
|
828
848
|
# If the user makes a mistake and creates a class that inherits from itself, this method would throw a stack
|
@@ -3,11 +3,8 @@
|
|
3
3
|
|
4
4
|
module RubyIndexer
|
5
5
|
class ReferenceFinder
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
abstract!
|
10
|
-
end
|
6
|
+
# @abstract
|
7
|
+
class Target; end
|
11
8
|
|
12
9
|
class ConstTarget < Target
|
13
10
|
#: String
|
@@ -35,10 +32,14 @@ module RubyIndexer
|
|
35
32
|
#: String
|
36
33
|
attr_reader :name
|
37
34
|
|
38
|
-
#:
|
39
|
-
|
35
|
+
#: Array[String]
|
36
|
+
attr_reader :owner_ancestors
|
37
|
+
|
38
|
+
#: (String name, Array[String] owner_ancestors) -> void
|
39
|
+
def initialize(name, owner_ancestors)
|
40
40
|
super()
|
41
41
|
@name = name
|
42
|
+
@owner_ancestors = owner_ancestors
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
@@ -325,7 +326,10 @@ module RubyIndexer
|
|
325
326
|
def collect_instance_variable_references(name, location, declaration)
|
326
327
|
return unless @target.is_a?(InstanceVariableTarget) && name == @target.name
|
327
328
|
|
328
|
-
|
329
|
+
receiver_type = Index.actual_nesting(@stack, nil).join("::")
|
330
|
+
if @target.owner_ancestors.include?(receiver_type)
|
331
|
+
@references << Reference.new(name, location, declaration: declaration)
|
332
|
+
end
|
329
333
|
end
|
330
334
|
end
|
331
335
|
end
|
@@ -20,7 +20,7 @@ module RubyIndexer
|
|
20
20
|
assert(uris.none? { |uri| uri.full_path.include?("test/fixtures") })
|
21
21
|
assert(uris.none? { |uri| uri.full_path.include?(bundle_path.join("minitest-reporters").to_s) })
|
22
22
|
assert(uris.none? { |uri| uri.full_path.include?(bundle_path.join("ansi").to_s) })
|
23
|
-
assert(uris.any? { |uri| uri.full_path.include?(bundle_path.join("
|
23
|
+
assert(uris.any? { |uri| uri.full_path.include?(bundle_path.join("prism").to_s) })
|
24
24
|
assert(uris.none? { |uri| uri.full_path == __FILE__ })
|
25
25
|
end
|
26
26
|
|
@@ -59,7 +59,6 @@ module RubyIndexer
|
|
59
59
|
|
60
60
|
assert_includes(paths, "#{RbConfig::CONFIG["rubylibdir"]}/pathname.rb")
|
61
61
|
assert_includes(paths, "#{RbConfig::CONFIG["rubylibdir"]}/ipaddr.rb")
|
62
|
-
assert_includes(paths, "#{RbConfig::CONFIG["rubylibdir"]}/erb.rb")
|
63
62
|
end
|
64
63
|
|
65
64
|
def test_indexable_uris_includes_project_files
|
@@ -728,6 +728,30 @@ module RubyIndexer
|
|
728
728
|
assert_equal(["A", "ALIAS"], @index.linearized_ancestors_of("A"))
|
729
729
|
end
|
730
730
|
|
731
|
+
def test_linearizing_ancestors_for_classes_with_overridden_parents
|
732
|
+
index(<<~RUBY)
|
733
|
+
# Find the re-open of a class first, without specifying a parent
|
734
|
+
class Child
|
735
|
+
end
|
736
|
+
|
737
|
+
# Now, find the actual definition of the class, which includes a parent
|
738
|
+
class Parent; end
|
739
|
+
class Child < Parent
|
740
|
+
end
|
741
|
+
RUBY
|
742
|
+
|
743
|
+
assert_equal(
|
744
|
+
[
|
745
|
+
"Child",
|
746
|
+
"Parent",
|
747
|
+
"Object",
|
748
|
+
"Kernel",
|
749
|
+
"BasicObject",
|
750
|
+
],
|
751
|
+
@index.linearized_ancestors_of("Child"),
|
752
|
+
)
|
753
|
+
end
|
754
|
+
|
731
755
|
def test_resolving_an_inherited_method
|
732
756
|
index(<<~RUBY)
|
733
757
|
module Foo
|
@@ -1959,6 +1983,18 @@ module RubyIndexer
|
|
1959
1983
|
assert_equal(["XQRK"], result.map { |entries| entries.first&.name })
|
1960
1984
|
end
|
1961
1985
|
|
1986
|
+
def test_constant_completion_does_not_confuse_uppercase_methods
|
1987
|
+
index(<<~RUBY)
|
1988
|
+
class Foo
|
1989
|
+
def Qux
|
1990
|
+
end
|
1991
|
+
end
|
1992
|
+
RUBY
|
1993
|
+
|
1994
|
+
candidates = @index.constant_completion_candidates("Q", [])
|
1995
|
+
refute_includes(candidates.flat_map { |entries| entries.map(&:name) }, "Qux")
|
1996
|
+
end
|
1997
|
+
|
1962
1998
|
def test_constant_completion_candidates_for_empty_name
|
1963
1999
|
index(<<~RUBY)
|
1964
2000
|
module Foo
|
@@ -236,5 +236,29 @@ module RubyIndexer
|
|
236
236
|
assert_instance_of(Entry::SingletonClass, owner)
|
237
237
|
assert_equal("Foo::<Class:Foo>", owner&.name)
|
238
238
|
end
|
239
|
+
|
240
|
+
def test_class_instance_variable_comments
|
241
|
+
index(<<~RUBY)
|
242
|
+
class Foo
|
243
|
+
# Documentation for @a
|
244
|
+
@a = "Hello" #: String
|
245
|
+
@b = "World" # trailing comment
|
246
|
+
@c = "!"
|
247
|
+
end
|
248
|
+
end
|
249
|
+
RUBY
|
250
|
+
|
251
|
+
assert_entry("@a", Entry::InstanceVariable, "/fake/path/foo.rb:2-4:2-6")
|
252
|
+
entry = @index["@a"]&.first #: as Entry::InstanceVariable
|
253
|
+
assert_equal("Documentation for @a", entry.comments)
|
254
|
+
|
255
|
+
assert_entry("@b", Entry::InstanceVariable, "/fake/path/foo.rb:3-4:3-6")
|
256
|
+
entry = @index["@b"]&.first #: as Entry::InstanceVariable
|
257
|
+
assert_empty(entry.comments)
|
258
|
+
|
259
|
+
assert_entry("@c", Entry::InstanceVariable, "/fake/path/foo.rb:4-4:4-6")
|
260
|
+
entry = @index["@c"]&.first #: as Entry::InstanceVariable
|
261
|
+
assert_empty(entry.comments)
|
262
|
+
end
|
239
263
|
end
|
240
264
|
end
|
@@ -950,6 +950,23 @@ module RubyIndexer
|
|
950
950
|
assert_predicate(entry, :public?)
|
951
951
|
end
|
952
952
|
|
953
|
+
def test_handling_attr
|
954
|
+
index(<<~RUBY)
|
955
|
+
class Foo
|
956
|
+
attr :bar
|
957
|
+
attr :baz, true
|
958
|
+
attr :qux, false
|
959
|
+
end
|
960
|
+
RUBY
|
961
|
+
|
962
|
+
assert_entry("bar", Entry::Accessor, "/fake/path/foo.rb:1-8:1-11")
|
963
|
+
assert_no_entry("bar=")
|
964
|
+
assert_entry("baz", Entry::Accessor, "/fake/path/foo.rb:2-8:2-11")
|
965
|
+
assert_entry("baz=", Entry::Accessor, "/fake/path/foo.rb:2-8:2-11")
|
966
|
+
assert_entry("qux", Entry::Accessor, "/fake/path/foo.rb:3-8:3-11")
|
967
|
+
assert_no_entry("qux=")
|
968
|
+
end
|
969
|
+
|
953
970
|
private
|
954
971
|
|
955
972
|
#: (Entry::Method entry, String call_string) -> void
|
@@ -232,8 +232,8 @@ module RubyIndexer
|
|
232
232
|
signatures = entry.signatures
|
233
233
|
assert_equal(2, signatures.length)
|
234
234
|
|
235
|
-
# def self.select: [X, Y, Z] (::Array[X & io]? read_array, ?::Array[Y & io]? write_array, ?::Array[Z & io]? error_array) -> [ Array[X], Array[Y], Array[Z] ]
|
236
|
-
# | [X, Y, Z] (::Array[X & io]? read_array, ?::Array[Y & io]? write_array, ?::Array[Z & io]? error_array, Time::_Timeout? timeout) -> [ Array[X], Array[Y], Array[Z] ]?
|
235
|
+
# def self.select: [X, Y, Z] (::Array[X & io]? read_array, ?::Array[Y & io]? write_array, ?::Array[Z & io]? error_array) -> [ Array[X], Array[Y], Array[Z] ]
|
236
|
+
# | [X, Y, Z] (::Array[X & io]? read_array, ?::Array[Y & io]? write_array, ?::Array[Z & io]? error_array, Time::_Timeout? timeout) -> [ Array[X], Array[Y], Array[Z] ]?
|
237
237
|
|
238
238
|
parameters = signatures[0]&.parameters #: as !nil
|
239
239
|
assert_equal([:read_array, :write_array, :error_array], parameters.map(&:name))
|
@@ -216,22 +216,43 @@ module RubyIndexer
|
|
216
216
|
assert_equal(11, refs[2].location.start_line)
|
217
217
|
end
|
218
218
|
|
219
|
-
def
|
220
|
-
refs = find_instance_variable_references("@
|
219
|
+
def test_finds_instance_variable_references
|
220
|
+
refs = find_instance_variable_references("@name", ["Foo"], <<~RUBY)
|
221
221
|
class Foo
|
222
|
-
def
|
223
|
-
@foo
|
222
|
+
def initialize
|
223
|
+
@name = "foo"
|
224
|
+
end
|
225
|
+
def name
|
226
|
+
@name
|
227
|
+
end
|
228
|
+
def name_capital
|
229
|
+
@name[0]
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
class Bar
|
234
|
+
def initialize
|
235
|
+
@name = "foo"
|
236
|
+
end
|
237
|
+
def name
|
238
|
+
@name
|
224
239
|
end
|
225
240
|
end
|
226
241
|
RUBY
|
227
|
-
assert_equal(
|
242
|
+
assert_equal(3, refs.size)
|
228
243
|
|
229
|
-
assert_equal("@
|
244
|
+
assert_equal("@name", refs[0].name)
|
230
245
|
assert_equal(3, refs[0].location.start_line)
|
246
|
+
|
247
|
+
assert_equal("@name", refs[1].name)
|
248
|
+
assert_equal(6, refs[1].location.start_line)
|
249
|
+
|
250
|
+
assert_equal("@name", refs[2].name)
|
251
|
+
assert_equal(9, refs[2].location.start_line)
|
231
252
|
end
|
232
253
|
|
233
254
|
def test_finds_instance_variable_write_references
|
234
|
-
refs = find_instance_variable_references("@foo", <<~RUBY)
|
255
|
+
refs = find_instance_variable_references("@foo", ["Foo"], <<~RUBY)
|
235
256
|
class Foo
|
236
257
|
def write
|
237
258
|
@foo = 1
|
@@ -252,26 +273,70 @@ module RubyIndexer
|
|
252
273
|
assert_equal(7, refs[4].location.start_line)
|
253
274
|
end
|
254
275
|
|
255
|
-
def
|
256
|
-
refs = find_instance_variable_references("@name", <<~RUBY)
|
257
|
-
|
276
|
+
def test_finds_instance_variable_references_in_owner_ancestors
|
277
|
+
refs = find_instance_variable_references("@name", ["Foo", "Base", "Top", "Parent"], <<~RUBY)
|
278
|
+
module Base
|
279
|
+
def change_name(name)
|
280
|
+
@name = name
|
281
|
+
end
|
258
282
|
def name
|
283
|
+
@name
|
284
|
+
end
|
285
|
+
|
286
|
+
module ::Top
|
287
|
+
def name
|
288
|
+
@name
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
class Parent
|
294
|
+
def initialize
|
295
|
+
@name = "parent"
|
296
|
+
end
|
297
|
+
def name_capital
|
298
|
+
@name[0]
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
class Foo < Parent
|
303
|
+
include Base
|
304
|
+
def initialize
|
259
305
|
@name = "foo"
|
260
306
|
end
|
307
|
+
def name
|
308
|
+
@name
|
309
|
+
end
|
261
310
|
end
|
311
|
+
|
262
312
|
class Bar
|
263
313
|
def name
|
264
314
|
@name = "bar"
|
265
315
|
end
|
266
316
|
end
|
267
317
|
RUBY
|
268
|
-
assert_equal(
|
318
|
+
assert_equal(7, refs.size)
|
269
319
|
|
270
320
|
assert_equal("@name", refs[0].name)
|
271
321
|
assert_equal(3, refs[0].location.start_line)
|
272
322
|
|
273
323
|
assert_equal("@name", refs[1].name)
|
274
|
-
assert_equal(
|
324
|
+
assert_equal(6, refs[1].location.start_line)
|
325
|
+
|
326
|
+
assert_equal("@name", refs[2].name)
|
327
|
+
assert_equal(11, refs[2].location.start_line)
|
328
|
+
|
329
|
+
assert_equal("@name", refs[3].name)
|
330
|
+
assert_equal(18, refs[3].location.start_line)
|
331
|
+
|
332
|
+
assert_equal("@name", refs[4].name)
|
333
|
+
assert_equal(21, refs[4].location.start_line)
|
334
|
+
|
335
|
+
assert_equal("@name", refs[5].name)
|
336
|
+
assert_equal(28, refs[5].location.start_line)
|
337
|
+
|
338
|
+
assert_equal("@name", refs[6].name)
|
339
|
+
assert_equal(31, refs[6].location.start_line)
|
275
340
|
end
|
276
341
|
|
277
342
|
def test_accounts_for_reopened_classes
|
@@ -310,8 +375,8 @@ module RubyIndexer
|
|
310
375
|
find_references(target, source)
|
311
376
|
end
|
312
377
|
|
313
|
-
def find_instance_variable_references(instance_variable_name, source)
|
314
|
-
target = ReferenceFinder::InstanceVariableTarget.new(instance_variable_name)
|
378
|
+
def find_instance_variable_references(instance_variable_name, owner_ancestors, source)
|
379
|
+
target = ReferenceFinder::InstanceVariableTarget.new(instance_variable_name, owner_ancestors)
|
315
380
|
find_references(target, source)
|
316
381
|
end
|
317
382
|
|