ruby-lsp 0.26.4 → 0.26.6
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-launcher +4 -3
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +3 -2
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +19 -0
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +33 -27
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +1 -0
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +6 -2
- data/lib/ruby_lsp/global_state.rb +65 -33
- data/lib/ruby_lsp/listeners/definition.rb +34 -14
- data/lib/ruby_lsp/listeners/document_link.rb +1 -6
- data/lib/ruby_lsp/listeners/hover.rb +2 -2
- data/lib/ruby_lsp/requests/code_action_resolve.rb +33 -11
- data/lib/ruby_lsp/requests/code_actions.rb +20 -5
- data/lib/ruby_lsp/requests/completion_resolve.rb +8 -6
- data/lib/ruby_lsp/requests/support/source_uri.rb +7 -6
- data/lib/ruby_lsp/scripts/compose_bundle.rb +1 -1
- data/lib/ruby_lsp/setup_bundler.rb +39 -25
- metadata +2 -16
- data/lib/ruby_indexer/test/class_variables_test.rb +0 -140
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +0 -770
- data/lib/ruby_indexer/test/configuration_test.rb +0 -279
- data/lib/ruby_indexer/test/constant_test.rb +0 -402
- data/lib/ruby_indexer/test/enhancements_test.rb +0 -325
- data/lib/ruby_indexer/test/global_variable_test.rb +0 -49
- data/lib/ruby_indexer/test/index_test.rb +0 -2276
- data/lib/ruby_indexer/test/instance_variables_test.rb +0 -264
- data/lib/ruby_indexer/test/method_test.rb +0 -990
- data/lib/ruby_indexer/test/prefix_tree_test.rb +0 -150
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +0 -381
- data/lib/ruby_indexer/test/reference_finder_test.rb +0 -395
- data/lib/ruby_indexer/test/test_case.rb +0 -57
- data/lib/ruby_indexer/test/uri_test.rb +0 -85
|
@@ -283,10 +283,10 @@ module RubyLsp
|
|
|
283
283
|
content = KEYWORD_DOCS[keyword]
|
|
284
284
|
return unless content
|
|
285
285
|
|
|
286
|
-
|
|
286
|
+
doc_uri = URI::Generic.from_path(path: File.join(STATIC_DOCS_PATH, "#{keyword}.md"))
|
|
287
287
|
|
|
288
288
|
@response_builder.push("```ruby\n#{keyword}\n```", category: :title)
|
|
289
|
-
@response_builder.push("[Read more](#{
|
|
289
|
+
@response_builder.push("[Read more](#{doc_uri})", category: :links)
|
|
290
290
|
@response_builder.push(content, category: :documentation)
|
|
291
291
|
end
|
|
292
292
|
|
|
@@ -51,20 +51,42 @@ module RubyLsp
|
|
|
51
51
|
#: -> (Interface::CodeAction)
|
|
52
52
|
def switch_block_style
|
|
53
53
|
source_range = @code_action.dig(:data, :range)
|
|
54
|
-
|
|
54
|
+
if source_range[:start] == source_range[:end]
|
|
55
|
+
block_context = @document.locate_node(
|
|
56
|
+
source_range[:start],
|
|
57
|
+
node_types: [Prism::BlockNode],
|
|
58
|
+
)
|
|
59
|
+
node = block_context.node
|
|
60
|
+
unless node.is_a?(Prism::BlockNode)
|
|
61
|
+
raise InvalidTargetRangeError, "Cursor is not inside a block"
|
|
62
|
+
end
|
|
55
63
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
# Find the call node at the block node's start position.
|
|
65
|
+
# This should be the call node whose block the cursor is inside of.
|
|
66
|
+
call_context = RubyDocument.locate(
|
|
67
|
+
@document.ast,
|
|
68
|
+
node.location.cached_start_code_units_offset(@document.code_units_cache),
|
|
69
|
+
node_types: [Prism::CallNode],
|
|
70
|
+
code_units_cache: @document.code_units_cache,
|
|
71
|
+
)
|
|
72
|
+
target = call_context.node
|
|
73
|
+
unless target.is_a?(Prism::CallNode) && target.block == node
|
|
74
|
+
raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
|
|
75
|
+
end
|
|
76
|
+
else
|
|
77
|
+
target = @document.locate_first_within_range(
|
|
78
|
+
@code_action.dig(:data, :range),
|
|
79
|
+
node_types: [Prism::CallNode],
|
|
80
|
+
)
|
|
60
81
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
82
|
+
unless target.is_a?(Prism::CallNode)
|
|
83
|
+
raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
|
|
84
|
+
end
|
|
64
85
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
86
|
+
node = target.block
|
|
87
|
+
unless node.is_a?(Prism::BlockNode)
|
|
88
|
+
raise InvalidTargetRangeError, "Couldn't find an appropriate location to place extracted refactor"
|
|
89
|
+
end
|
|
68
90
|
end
|
|
69
91
|
|
|
70
92
|
indentation = " " * target.location.start_column unless node.opening_loc.slice == "do"
|
|
@@ -63,12 +63,8 @@ module RubyLsp
|
|
|
63
63
|
kind: Constant::CodeActionKind::REFACTOR_EXTRACT,
|
|
64
64
|
data: { range: @range, uri: @uri.to_s },
|
|
65
65
|
)
|
|
66
|
-
code_actions << Interface::CodeAction.new(
|
|
67
|
-
title: TOGGLE_BLOCK_STYLE_TITLE,
|
|
68
|
-
kind: Constant::CodeActionKind::REFACTOR_REWRITE,
|
|
69
|
-
data: { range: @range, uri: @uri.to_s },
|
|
70
|
-
)
|
|
71
66
|
end
|
|
67
|
+
code_actions.concat(toggle_block_style_action)
|
|
72
68
|
code_actions.concat(attribute_actions)
|
|
73
69
|
|
|
74
70
|
code_actions
|
|
@@ -113,6 +109,25 @@ module RubyLsp
|
|
|
113
109
|
),
|
|
114
110
|
]
|
|
115
111
|
end
|
|
112
|
+
|
|
113
|
+
#: -> Array[Interface::CodeAction]
|
|
114
|
+
def toggle_block_style_action
|
|
115
|
+
if @range[:start] == @range[:end]
|
|
116
|
+
block_context = @document.locate_node(
|
|
117
|
+
@range[:start],
|
|
118
|
+
node_types: [Prism::BlockNode],
|
|
119
|
+
)
|
|
120
|
+
return [] unless block_context.node.is_a?(Prism::BlockNode)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
[
|
|
124
|
+
Interface::CodeAction.new(
|
|
125
|
+
title: TOGGLE_BLOCK_STYLE_TITLE,
|
|
126
|
+
kind: Constant::CodeActionKind::REFACTOR_REWRITE,
|
|
127
|
+
data: { range: @range, uri: @uri.to_s },
|
|
128
|
+
),
|
|
129
|
+
]
|
|
130
|
+
end
|
|
116
131
|
end
|
|
117
132
|
end
|
|
118
133
|
end
|
|
@@ -68,10 +68,12 @@ module RubyLsp
|
|
|
68
68
|
"[Learn more about guessed types](#{GUESSED_TYPES_URL})"
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
@item[:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
unless @item[:kind] == Constant::CompletionItemKind::FILE
|
|
72
|
+
@item[:documentation] = Interface::MarkupContent.new(
|
|
73
|
+
kind: "markdown",
|
|
74
|
+
value: markdown_from_index_entries(label, entries, MAX_DOCUMENTATION_ENTRIES, extra_links: extra_links),
|
|
75
|
+
)
|
|
76
|
+
end
|
|
75
77
|
|
|
76
78
|
@item
|
|
77
79
|
end
|
|
@@ -84,7 +86,7 @@ module RubyLsp
|
|
|
84
86
|
content = KEYWORD_DOCS[keyword]
|
|
85
87
|
|
|
86
88
|
if content
|
|
87
|
-
|
|
89
|
+
doc_uri = URI::Generic.from_path(path: File.join(STATIC_DOCS_PATH, "#{keyword}.md"))
|
|
88
90
|
|
|
89
91
|
@item[:documentation] = Interface::MarkupContent.new(
|
|
90
92
|
kind: "markdown",
|
|
@@ -93,7 +95,7 @@ module RubyLsp
|
|
|
93
95
|
#{keyword}
|
|
94
96
|
```
|
|
95
97
|
|
|
96
|
-
[Read more](#{
|
|
98
|
+
[Read more](#{doc_uri})
|
|
97
99
|
|
|
98
100
|
#{content}
|
|
99
101
|
MARKDOWN
|
|
@@ -5,6 +5,7 @@ require "uri/file"
|
|
|
5
5
|
|
|
6
6
|
module URI
|
|
7
7
|
# Must be kept in sync with the one in Tapioca
|
|
8
|
+
# https://github.com/Shopify/tapioca/blob/main/lib/tapioca/helpers/source_uri.rb
|
|
8
9
|
class Source < URI::File
|
|
9
10
|
COMPONENT = [
|
|
10
11
|
:scheme,
|
|
@@ -21,16 +22,14 @@ module URI
|
|
|
21
22
|
# have the uri gem in their own bundle and thus not use a compatible version.
|
|
22
23
|
PARSER = const_defined?(:RFC2396_PARSER) ? RFC2396_PARSER : DEFAULT_PARSER #: RFC2396_Parser
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
self #: as untyped # rubocop:disable Style/RedundantSelf
|
|
27
|
-
.alias_method(:line_number, :fragment)
|
|
25
|
+
alias_method(:gem_name, :host)
|
|
26
|
+
alias_method(:line_number, :fragment)
|
|
28
27
|
|
|
29
28
|
#: String?
|
|
30
29
|
attr_reader :gem_version
|
|
31
30
|
|
|
32
31
|
class << self
|
|
33
|
-
#: (gem_name: String, gem_version: String?, path: String, line_number: String?) ->
|
|
32
|
+
#: (gem_name: String, gem_version: String?, path: String, line_number: String?) -> instance
|
|
34
33
|
def build(gem_name:, gem_version:, path:, line_number:)
|
|
35
34
|
super(
|
|
36
35
|
{
|
|
@@ -67,12 +66,14 @@ module URI
|
|
|
67
66
|
|
|
68
67
|
#: -> String
|
|
69
68
|
def to_s
|
|
70
|
-
"source://#{gem_name}/#{gem_version}
|
|
69
|
+
"source://#{gem_name}/#{gem_version}/#{path}##{line_number}"
|
|
71
70
|
end
|
|
72
71
|
|
|
73
72
|
if URI.respond_to?(:register_scheme)
|
|
73
|
+
# Handle URI 0.11.0 and newer https://github.com/ruby/uri/pull/26
|
|
74
74
|
URI.register_scheme("SOURCE", self)
|
|
75
75
|
else
|
|
76
|
+
# Fallback for URI <0.11.0
|
|
76
77
|
@@schemes = @@schemes #: Hash[String, untyped] # rubocop:disable Style/ClassVars
|
|
77
78
|
@@schemes["SOURCE"] = self
|
|
78
79
|
end
|
|
@@ -5,7 +5,7 @@ def compose(raw_initialize)
|
|
|
5
5
|
require_relative "../setup_bundler"
|
|
6
6
|
require "json"
|
|
7
7
|
require "uri"
|
|
8
|
-
|
|
8
|
+
require_relative "../../ruby_indexer/lib/ruby_indexer/uri"
|
|
9
9
|
|
|
10
10
|
initialize_request = JSON.parse(raw_initialize, symbolize_names: true)
|
|
11
11
|
workspace_uri = initialize_request.dig(:params, :workspaceFolders, 0, :uri)
|
|
@@ -31,12 +31,16 @@ module RubyLsp
|
|
|
31
31
|
|
|
32
32
|
FOUR_HOURS = 4 * 60 * 60 #: Integer
|
|
33
33
|
|
|
34
|
+
# Gems that should be kept up to date in the composed bundle. When updating, any of these gems that are not
|
|
35
|
+
# already in the user's Gemfile will be updated together.
|
|
36
|
+
GEMS_TO_UPDATE = ["ruby-lsp", "debug", "prism", "rbs"].freeze #: Array[String]
|
|
37
|
+
|
|
34
38
|
#: (String project_path, **untyped options) -> void
|
|
35
39
|
def initialize(project_path, **options)
|
|
36
40
|
@project_path = project_path
|
|
37
41
|
@branch = options[:branch] #: String?
|
|
38
42
|
@launcher = options[:launcher] #: bool?
|
|
39
|
-
|
|
43
|
+
force_output_to_stderr! if @launcher
|
|
40
44
|
|
|
41
45
|
# Regular bundle paths
|
|
42
46
|
@gemfile = begin
|
|
@@ -282,14 +286,25 @@ module RubyLsp
|
|
|
282
286
|
|
|
283
287
|
return update(env) if @needs_update_path.exist?
|
|
284
288
|
|
|
285
|
-
# The ENV can only be merged after checking if an update is required because we depend on the original value of
|
|
286
|
-
# ENV["BUNDLE_GEMFILE"], which gets overridden after the merge
|
|
287
289
|
FileUtils.touch(@needs_update_path) if needs_update
|
|
288
290
|
|
|
289
291
|
$stderr.puts("Ruby LSP> Checking if the composed bundle is satisfied...")
|
|
290
|
-
missing_gems = bundle_check
|
|
291
292
|
|
|
292
|
-
|
|
293
|
+
begin
|
|
294
|
+
missing_gems = bundle_check
|
|
295
|
+
rescue Errno::EPIPE, Bundler::HTTPError
|
|
296
|
+
# These are errors cases where we cannot recover
|
|
297
|
+
raise
|
|
298
|
+
rescue => e
|
|
299
|
+
# If anything fails with bundle check, try to bundle install
|
|
300
|
+
$stderr.puts("Ruby LSP> Running bundle install because #{e.message}")
|
|
301
|
+
bundle_install
|
|
302
|
+
return env
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
if missing_gems.empty?
|
|
306
|
+
$stderr.puts("Ruby LSP> Bundle already satisfied")
|
|
307
|
+
else
|
|
293
308
|
$stderr.puts(<<~MESSAGE)
|
|
294
309
|
Ruby LSP> Running bundle install because the following gems are not installed:
|
|
295
310
|
#{missing_gems.map { |g| "#{g.name}: #{g.version}" }.join("\n")}
|
|
@@ -298,11 +313,6 @@ module RubyLsp
|
|
|
298
313
|
bundle_install
|
|
299
314
|
end
|
|
300
315
|
|
|
301
|
-
$stderr.puts("Ruby LSP> Bundle already satisfied")
|
|
302
|
-
env
|
|
303
|
-
rescue => e
|
|
304
|
-
$stderr.puts("Ruby LSP> Running bundle install because #{e.message}")
|
|
305
|
-
bundle_install
|
|
306
316
|
env
|
|
307
317
|
end
|
|
308
318
|
|
|
@@ -325,7 +335,7 @@ module RubyLsp
|
|
|
325
335
|
def update(env)
|
|
326
336
|
# Try to auto upgrade the gems we depend on, unless they are in the Gemfile as that would result in undesired
|
|
327
337
|
# source control changes
|
|
328
|
-
gems =
|
|
338
|
+
gems = GEMS_TO_UPDATE.reject { |dep| @dependencies[dep] }
|
|
329
339
|
gems << "ruby-lsp-rails" if @rails_app && !@dependencies["ruby-lsp-rails"]
|
|
330
340
|
|
|
331
341
|
Bundler::CLI::Update.new({ conservative: true }, gems).run
|
|
@@ -337,14 +347,14 @@ module RubyLsp
|
|
|
337
347
|
|
|
338
348
|
#: (Hash[String, String] env) -> Hash[String, String]
|
|
339
349
|
def run_bundle_install_through_command(env)
|
|
340
|
-
# If
|
|
341
|
-
# to upgrade them or else we'll produce undesired source control changes. If the composed bundle was just
|
|
342
|
-
# and any of
|
|
343
|
-
#
|
|
344
|
-
#
|
|
350
|
+
# If the gems in GEMS_TO_UPDATE (and potentially `ruby-lsp-rails`) are already in the Gemfile, then we shouldn't
|
|
351
|
+
# try to upgrade them or else we'll produce undesired source control changes. If the composed bundle was just
|
|
352
|
+
# created and any of those gems weren't a part of the Gemfile, then we need to run `bundle install` for the first
|
|
353
|
+
# time to generate the Gemfile.lock with them included or else Bundler will complain that they're missing. We can
|
|
354
|
+
# only update if the custom `.ruby-lsp/Gemfile.lock` already exists and includes all gems
|
|
345
355
|
|
|
346
356
|
# When not updating, we run `(bundle check || bundle install)`
|
|
347
|
-
# When updating, we run `((bundle check && bundle update
|
|
357
|
+
# When updating, we run `((bundle check && bundle update <GEMS_TO_UPDATE>) || bundle install)`
|
|
348
358
|
bundler_path = File.join(Gem.default_bindir, "bundle")
|
|
349
359
|
base_command = (!Gem.win_platform? && File.exist?(bundler_path) ? "#{Gem.ruby} #{bundler_path}" : "bundle").dup
|
|
350
360
|
|
|
@@ -355,12 +365,11 @@ module RubyLsp
|
|
|
355
365
|
command = +"(#{base_command} check"
|
|
356
366
|
|
|
357
367
|
if should_bundle_update?
|
|
358
|
-
# If any of
|
|
359
|
-
# version
|
|
368
|
+
# If any of the gems in GEMS_TO_UPDATE (or `ruby-lsp-rails` for Rails apps) are not in the Gemfile, try to
|
|
369
|
+
# update them to the latest version
|
|
360
370
|
command.prepend("(")
|
|
361
371
|
command << " && #{base_command} update "
|
|
362
|
-
command << "
|
|
363
|
-
command << "debug " unless @dependencies["debug"]
|
|
372
|
+
GEMS_TO_UPDATE.each { |gem| command << "#{gem} " unless @dependencies[gem] }
|
|
364
373
|
command << "ruby-lsp-rails " if @rails_app && !@dependencies["ruby-lsp-rails"]
|
|
365
374
|
command.delete_suffix!(" ")
|
|
366
375
|
command << ")"
|
|
@@ -489,11 +498,16 @@ module RubyLsp
|
|
|
489
498
|
end
|
|
490
499
|
|
|
491
500
|
#: -> void
|
|
492
|
-
def
|
|
493
|
-
|
|
501
|
+
def force_output_to_stderr!
|
|
502
|
+
# Bundler and RubyGems have different UI objects used for printing. We need to ensure that both are configured to
|
|
503
|
+
# print only to stderr or else they'll break the connection with the editor
|
|
504
|
+
Gem::DefaultUserInteraction.ui = Gem::StreamUI.new($stdin, $stderr, $stderr, false)
|
|
505
|
+
|
|
506
|
+
ui = Bundler.ui
|
|
507
|
+
ui.output_stream = :stderr if ui.respond_to?(:output_stream=)
|
|
508
|
+
ui.level = :info
|
|
494
509
|
|
|
495
|
-
Bundler::Thor::Shell::Basic.prepend(ThorPatch)
|
|
496
|
-
Bundler.ui.level = :info
|
|
510
|
+
Bundler::Thor::Shell::Basic.prepend(ThorPatch) if defined?(Bundler::Thor::Shell::Basic)
|
|
497
511
|
end
|
|
498
512
|
end
|
|
499
513
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-lsp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.26.
|
|
4
|
+
version: 0.26.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shopify
|
|
@@ -96,20 +96,6 @@ files:
|
|
|
96
96
|
- lib/ruby_indexer/lib/ruby_indexer/uri.rb
|
|
97
97
|
- lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb
|
|
98
98
|
- lib/ruby_indexer/ruby_indexer.rb
|
|
99
|
-
- lib/ruby_indexer/test/class_variables_test.rb
|
|
100
|
-
- lib/ruby_indexer/test/classes_and_modules_test.rb
|
|
101
|
-
- lib/ruby_indexer/test/configuration_test.rb
|
|
102
|
-
- lib/ruby_indexer/test/constant_test.rb
|
|
103
|
-
- lib/ruby_indexer/test/enhancements_test.rb
|
|
104
|
-
- lib/ruby_indexer/test/global_variable_test.rb
|
|
105
|
-
- lib/ruby_indexer/test/index_test.rb
|
|
106
|
-
- lib/ruby_indexer/test/instance_variables_test.rb
|
|
107
|
-
- lib/ruby_indexer/test/method_test.rb
|
|
108
|
-
- lib/ruby_indexer/test/prefix_tree_test.rb
|
|
109
|
-
- lib/ruby_indexer/test/rbs_indexer_test.rb
|
|
110
|
-
- lib/ruby_indexer/test/reference_finder_test.rb
|
|
111
|
-
- lib/ruby_indexer/test/test_case.rb
|
|
112
|
-
- lib/ruby_indexer/test/uri_test.rb
|
|
113
99
|
- lib/ruby_lsp/addon.rb
|
|
114
100
|
- lib/ruby_lsp/base_server.rb
|
|
115
101
|
- lib/ruby_lsp/client_capabilities.rb
|
|
@@ -217,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
217
203
|
- !ruby/object:Gem::Version
|
|
218
204
|
version: '0'
|
|
219
205
|
requirements: []
|
|
220
|
-
rubygems_version:
|
|
206
|
+
rubygems_version: 4.0.3
|
|
221
207
|
specification_version: 4
|
|
222
208
|
summary: An opinionated language server for Ruby
|
|
223
209
|
test_files: []
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# typed: true
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require_relative "test_case"
|
|
5
|
-
|
|
6
|
-
module RubyIndexer
|
|
7
|
-
class ClassVariableTest < TestCase
|
|
8
|
-
def test_class_variable_and_write
|
|
9
|
-
index(<<~RUBY)
|
|
10
|
-
class Foo
|
|
11
|
-
@@bar &&= 1
|
|
12
|
-
end
|
|
13
|
-
RUBY
|
|
14
|
-
|
|
15
|
-
assert_entry("@@bar", Entry::ClassVariable, "/fake/path/foo.rb:1-2:1-7")
|
|
16
|
-
|
|
17
|
-
entry = @index["@@bar"]&.first #: as Entry::ClassVariable
|
|
18
|
-
owner = entry.owner #: as !nil
|
|
19
|
-
assert_instance_of(Entry::Class, owner)
|
|
20
|
-
assert_equal("Foo", owner.name)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def test_class_variable_operator_write
|
|
24
|
-
index(<<~RUBY)
|
|
25
|
-
class Foo
|
|
26
|
-
@@bar += 1
|
|
27
|
-
end
|
|
28
|
-
RUBY
|
|
29
|
-
|
|
30
|
-
assert_entry("@@bar", Entry::ClassVariable, "/fake/path/foo.rb:1-2:1-7")
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def test_class_variable_or_write
|
|
34
|
-
index(<<~RUBY)
|
|
35
|
-
class Foo
|
|
36
|
-
@@bar ||= 1
|
|
37
|
-
end
|
|
38
|
-
RUBY
|
|
39
|
-
|
|
40
|
-
assert_entry("@@bar", Entry::ClassVariable, "/fake/path/foo.rb:1-2:1-7")
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def test_class_variable_target_node
|
|
44
|
-
index(<<~RUBY)
|
|
45
|
-
class Foo
|
|
46
|
-
@@foo, @@bar = 1
|
|
47
|
-
end
|
|
48
|
-
RUBY
|
|
49
|
-
|
|
50
|
-
assert_entry("@@foo", Entry::ClassVariable, "/fake/path/foo.rb:1-2:1-7")
|
|
51
|
-
assert_entry("@@bar", Entry::ClassVariable, "/fake/path/foo.rb:1-9:1-14")
|
|
52
|
-
|
|
53
|
-
entry = @index["@@foo"]&.first #: as Entry::ClassVariable
|
|
54
|
-
owner = entry.owner #: as !nil
|
|
55
|
-
assert_instance_of(Entry::Class, owner)
|
|
56
|
-
assert_equal("Foo", owner.name)
|
|
57
|
-
|
|
58
|
-
entry = @index["@@bar"]&.first #: as Entry::ClassVariable
|
|
59
|
-
owner = entry.owner #: as !nil
|
|
60
|
-
assert_instance_of(Entry::Class, owner)
|
|
61
|
-
assert_equal("Foo", owner.name)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def test_class_variable_write
|
|
65
|
-
index(<<~RUBY)
|
|
66
|
-
class Foo
|
|
67
|
-
@@bar = 1
|
|
68
|
-
end
|
|
69
|
-
RUBY
|
|
70
|
-
|
|
71
|
-
assert_entry("@@bar", Entry::ClassVariable, "/fake/path/foo.rb:1-2:1-7")
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def test_empty_name_class_variable
|
|
75
|
-
index(<<~RUBY)
|
|
76
|
-
module Foo
|
|
77
|
-
@@ = 1
|
|
78
|
-
end
|
|
79
|
-
RUBY
|
|
80
|
-
|
|
81
|
-
refute_entry("@@")
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def test_top_level_class_variable
|
|
85
|
-
index(<<~RUBY)
|
|
86
|
-
@@foo = 123
|
|
87
|
-
RUBY
|
|
88
|
-
|
|
89
|
-
entry = @index["@@foo"]&.first #: as Entry::ClassVariable
|
|
90
|
-
assert_nil(entry.owner)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def test_class_variable_inside_self_method
|
|
94
|
-
index(<<~RUBY)
|
|
95
|
-
class Foo
|
|
96
|
-
def self.bar
|
|
97
|
-
@@bar = 123
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
RUBY
|
|
101
|
-
|
|
102
|
-
entry = @index["@@bar"]&.first #: as Entry::ClassVariable
|
|
103
|
-
owner = entry.owner #: as !nil
|
|
104
|
-
assert_instance_of(Entry::Class, owner)
|
|
105
|
-
assert_equal("Foo", owner.name)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def test_class_variable_inside_singleton_class
|
|
109
|
-
index(<<~RUBY)
|
|
110
|
-
class Foo
|
|
111
|
-
class << self
|
|
112
|
-
@@bar = 123
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
RUBY
|
|
116
|
-
|
|
117
|
-
entry = @index["@@bar"]&.first #: as Entry::ClassVariable
|
|
118
|
-
owner = entry.owner #: as !nil
|
|
119
|
-
assert_instance_of(Entry::Class, owner)
|
|
120
|
-
assert_equal("Foo", owner.name)
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def test_class_variable_in_singleton_class_method
|
|
124
|
-
index(<<~RUBY)
|
|
125
|
-
class Foo
|
|
126
|
-
class << self
|
|
127
|
-
def self.bar
|
|
128
|
-
@@bar = 123
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
RUBY
|
|
133
|
-
|
|
134
|
-
entry = @index["@@bar"]&.first #: as Entry::ClassVariable
|
|
135
|
-
owner = entry.owner #: as !nil
|
|
136
|
-
assert_instance_of(Entry::Class, owner)
|
|
137
|
-
assert_equal("Foo", owner.name)
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
end
|