ruby-lsp 0.23.21 → 0.25.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/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 +9 -19
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +18 -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 -1
- data/lib/ruby_indexer/test/index_test.rb +24 -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 +29 -15
- data/lib/ruby_lsp/base_server.rb +14 -12
- data/lib/ruby_lsp/document.rb +158 -46
- 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 +9 -1
- 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 +63 -20
- data/lib/ruby_lsp/listeners/test_discovery.rb +18 -15
- data/lib/ruby_lsp/listeners/test_style.rb +21 -10
- 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 +9 -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 +50 -49
- data/lib/ruby_lsp/setup_bundler.rb +51 -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 -5
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +43 -4
- data/lib/ruby_lsp/utils.rb +47 -11
- data/static_docs/break.md +103 -0
- metadata +4 -18
- 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: 7637d6f68616069c2f8c0d870f3daf31808a1cccd8ab32d2bdaf1f67274f9b59
|
4
|
+
data.tar.gz: 7ea1d75ad921adbf01f69a0f5d2fba905673311c13b0999d44c08bdf54737053
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a354535a3853b0826635408fc46dc85cb7cee97c4993012dd983af11b8917121962d97bddf0853406b54f619faa8c2383cccca9638b4a0624309fb1e4c838249
|
7
|
+
data.tar.gz: 9e49e2436c63d90fc373b52ac9f6b65e83964fe108abd0a18fd46b655cd99bd55c471dd198624bb8701890f62175af2c9fcb50fcfa2bbf69e706406b9fa1e472
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.25.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
|
@@ -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
|
@@ -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
|
@@ -292,7 +292,7 @@ module RubyIndexer
|
|
292
292
|
# Top level constants
|
293
293
|
entries.concat(@entries_tree.search(name))
|
294
294
|
entries.uniq!
|
295
|
-
entries #: as Array[Array[Entry::Constant | Entry::ConstantAlias | Entry::Namespace | Entry::UnresolvedConstantAlias]]
|
295
|
+
entries #: as Array[Array[Entry::Constant | Entry::ConstantAlias | Entry::Namespace | Entry::UnresolvedConstantAlias]]
|
296
296
|
end
|
297
297
|
|
298
298
|
# Resolve a constant to its declaration based on its name and the nesting where the reference was found. Parameter
|
@@ -818,11 +818,22 @@ module RubyIndexer
|
|
818
818
|
)
|
819
819
|
# Find the first class entry that has a parent class. Notice that if the developer makes a mistake and inherits
|
820
820
|
# from two different classes in different files, we simply ignore it
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
821
|
+
possible_parents = singleton_levels > 0 ? self[attached_class_name] : namespace_entries
|
822
|
+
superclass = nil #: Entry::Class?
|
823
|
+
|
824
|
+
possible_parents&.each do |n|
|
825
|
+
# Ignore non class entries
|
826
|
+
next unless n.is_a?(Entry::Class)
|
827
|
+
|
828
|
+
parent_class = n.parent_class
|
829
|
+
next unless parent_class
|
830
|
+
|
831
|
+
# Always set the superclass, but break early if we found one that isn't `::Object` (meaning we found an explicit
|
832
|
+
# parent class and not the implicit default). Note that when setting different parents to the same class, which
|
833
|
+
# is invalid, we pick whatever is the first one we find
|
834
|
+
superclass = n
|
835
|
+
break if parent_class != "::Object"
|
836
|
+
end
|
826
837
|
|
827
838
|
if superclass
|
828
839
|
# 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
|
|
@@ -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
|
@@ -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
|
|