ruby-lsp 0.23.20 → 0.26.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 +10 -4
- data/exe/ruby-lsp-check +0 -4
- data/exe/ruby-lsp-launcher +25 -11
- data/exe/ruby-lsp-test-exec +6 -0
- 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 +29 -7
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +2 -2
- 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 +39 -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 +126 -67
- data/lib/ruby_lsp/listeners/test_discovery.rb +18 -15
- data/lib/ruby_lsp/listeners/test_style.rb +56 -23
- data/lib/ruby_lsp/requests/code_action_resolve.rb +3 -3
- data/lib/ruby_lsp/requests/code_lens.rb +14 -5
- 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 +95 -110
- 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 +18 -7
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +54 -7
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +0 -1
- data/lib/ruby_lsp/utils.rb +47 -11
- data/static_docs/break.md +103 -0
- metadata +7 -19
- 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: c80f549675508ffbb28d649de04506adabec01eac9aa4c6eee057ec848adf858
|
4
|
+
data.tar.gz: 71ea1a4d628444b98bc1173748f5aecf0d71bdc8d3dc80f33b2779c9c78d9de0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7261bf15c095154ff36152492aa252cbd84b84f6e83eb458623c7bb9790a57957885a855c2ee10683b7035267177e323c013988befc02e96f3fdf0274d2312ca
|
7
|
+
data.tar.gz: 74bcea4844e876230713400776bf7def1db44492bcf913526195b5d01919efd24ac69b517594ce2499e332184bf7ef4881e17e7694574bf4d35afabeda25b8c4
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.26.1
|
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
|
@@ -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,19 @@ 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.select! 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
|
+
|
302
|
+
definitions.any?
|
303
|
+
end
|
304
|
+
|
294
305
|
entries.uniq!
|
295
|
-
entries #: as Array[Array[Entry::Constant | Entry::ConstantAlias | Entry::Namespace | Entry::UnresolvedConstantAlias]]
|
306
|
+
entries #: as Array[Array[Entry::Constant | Entry::ConstantAlias | Entry::Namespace | Entry::UnresolvedConstantAlias]]
|
296
307
|
end
|
297
308
|
|
298
309
|
# Resolve a constant to its declaration based on its name and the nesting where the reference was found. Parameter
|
@@ -818,11 +829,22 @@ module RubyIndexer
|
|
818
829
|
)
|
819
830
|
# Find the first class entry that has a parent class. Notice that if the developer makes a mistake and inherits
|
820
831
|
# from two different classes in different files, we simply ignore it
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
832
|
+
possible_parents = singleton_levels > 0 ? self[attached_class_name] : namespace_entries
|
833
|
+
superclass = nil #: Entry::Class?
|
834
|
+
|
835
|
+
possible_parents&.each do |n|
|
836
|
+
# Ignore non class entries
|
837
|
+
next unless n.is_a?(Entry::Class)
|
838
|
+
|
839
|
+
parent_class = n.parent_class
|
840
|
+
next unless parent_class
|
841
|
+
|
842
|
+
# Always set the superclass, but break early if we found one that isn't `::Object` (meaning we found an explicit
|
843
|
+
# parent class and not the implicit default). Note that when setting different parents to the same class, which
|
844
|
+
# is invalid, we pick whatever is the first one we find
|
845
|
+
superclass = n
|
846
|
+
break if parent_class != "::Object"
|
847
|
+
end
|
826
848
|
|
827
849
|
if superclass
|
828
850
|
# If the user makes a mistake and creates a class that inherits from itself, this method would throw a stack
|
@@ -103,7 +103,7 @@ module RubyIndexer
|
|
103
103
|
#: (RBS::AST::Members::MethodDefinition member, Entry::Namespace owner) -> void
|
104
104
|
def handle_method(member, owner)
|
105
105
|
name = member.name.name
|
106
|
-
uri = URI::Generic.from_path(path: member.location.buffer.name)
|
106
|
+
uri = URI::Generic.from_path(path: member.location.buffer.name.to_s)
|
107
107
|
location = to_ruby_indexer_location(member.location)
|
108
108
|
comments = comments_to_string(member)
|
109
109
|
|
@@ -267,7 +267,7 @@ module RubyIndexer
|
|
267
267
|
|
268
268
|
#: (RBS::AST::Members::Alias member, Entry::Namespace owner_entry) -> void
|
269
269
|
def handle_signature_alias(member, owner_entry)
|
270
|
-
uri = URI::Generic.from_path(path: member.location.buffer.name)
|
270
|
+
uri = URI::Generic.from_path(path: member.location.buffer.name.to_s)
|
271
271
|
comments = comments_to_string(member)
|
272
272
|
|
273
273
|
entry = Entry::UnresolvedMethodAlias.new(
|
@@ -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,21 @@ 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
|
+
|
1997
|
+
candidates = @index.constant_completion_candidates("Qux", [])
|
1998
|
+
assert_equal(0, candidates.length)
|
1999
|
+
end
|
2000
|
+
|
1962
2001
|
def test_constant_completion_candidates_for_empty_name
|
1963
2002
|
index(<<~RUBY)
|
1964
2003
|
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))
|