ruby-lsp 0.23.11 → 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.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/VERSION +1 -1
  4. data/exe/ruby-lsp +10 -4
  5. data/exe/ruby-lsp-check +0 -4
  6. data/exe/ruby-lsp-launcher +46 -22
  7. data/exe/ruby-lsp-test-exec +6 -0
  8. data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -2
  9. data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -6
  10. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +85 -118
  11. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +159 -183
  12. data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +10 -14
  13. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +130 -253
  14. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +189 -285
  15. data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
  16. data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +23 -27
  17. data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +31 -59
  18. data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +58 -68
  19. data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +17 -19
  20. data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +7 -11
  21. data/lib/ruby_lsp/addon.rb +88 -86
  22. data/lib/ruby_lsp/base_server.rb +79 -65
  23. data/lib/ruby_lsp/client_capabilities.rb +16 -13
  24. data/lib/ruby_lsp/document.rb +205 -104
  25. data/lib/ruby_lsp/erb_document.rb +45 -47
  26. data/lib/ruby_lsp/global_state.rb +134 -86
  27. data/lib/ruby_lsp/internal.rb +8 -3
  28. data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
  29. data/lib/ruby_lsp/listeners/completion.rb +81 -76
  30. data/lib/ruby_lsp/listeners/definition.rb +78 -72
  31. data/lib/ruby_lsp/listeners/document_highlight.rb +149 -151
  32. data/lib/ruby_lsp/listeners/document_link.rb +93 -86
  33. data/lib/ruby_lsp/listeners/document_symbol.rb +38 -52
  34. data/lib/ruby_lsp/listeners/folding_ranges.rb +40 -43
  35. data/lib/ruby_lsp/listeners/hover.rb +109 -117
  36. data/lib/ruby_lsp/listeners/inlay_hints.rb +8 -13
  37. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
  38. data/lib/ruby_lsp/listeners/signature_help.rb +12 -27
  39. data/lib/ruby_lsp/listeners/spec_style.rb +231 -0
  40. data/lib/ruby_lsp/listeners/test_discovery.rb +107 -0
  41. data/lib/ruby_lsp/listeners/test_style.rb +207 -95
  42. data/lib/ruby_lsp/node_context.rb +12 -39
  43. data/lib/ruby_lsp/rbs_document.rb +10 -11
  44. data/lib/ruby_lsp/requests/code_action_resolve.rb +92 -66
  45. data/lib/ruby_lsp/requests/code_actions.rb +34 -31
  46. data/lib/ruby_lsp/requests/code_lens.rb +31 -21
  47. data/lib/ruby_lsp/requests/completion.rb +8 -21
  48. data/lib/ruby_lsp/requests/completion_resolve.rb +14 -12
  49. data/lib/ruby_lsp/requests/definition.rb +8 -20
  50. data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
  51. data/lib/ruby_lsp/requests/discover_tests.rb +20 -7
  52. data/lib/ruby_lsp/requests/document_highlight.rb +6 -16
  53. data/lib/ruby_lsp/requests/document_link.rb +6 -17
  54. data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
  55. data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
  56. data/lib/ruby_lsp/requests/formatting.rb +6 -9
  57. data/lib/ruby_lsp/requests/go_to_relevant_file.rb +139 -0
  58. data/lib/ruby_lsp/requests/hover.rb +12 -25
  59. data/lib/ruby_lsp/requests/inlay_hints.rb +8 -19
  60. data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
  61. data/lib/ruby_lsp/requests/prepare_rename.rb +5 -10
  62. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +5 -15
  63. data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
  64. data/lib/ruby_lsp/requests/references.rb +17 -57
  65. data/lib/ruby_lsp/requests/rename.rb +27 -51
  66. data/lib/ruby_lsp/requests/request.rb +13 -25
  67. data/lib/ruby_lsp/requests/selection_ranges.rb +7 -7
  68. data/lib/ruby_lsp/requests/semantic_highlighting.rb +16 -35
  69. data/lib/ruby_lsp/requests/show_syntax_tree.rb +7 -8
  70. data/lib/ruby_lsp/requests/signature_help.rb +9 -27
  71. data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
  72. data/lib/ruby_lsp/requests/support/common.rb +23 -61
  73. data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
  74. data/lib/ruby_lsp/requests/support/package_url.rb +414 -0
  75. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
  76. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +13 -16
  77. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +34 -36
  78. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  79. data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
  80. data/lib/ruby_lsp/requests/support/source_uri.rb +22 -33
  81. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
  82. data/lib/ruby_lsp/requests/support/test_item.rb +16 -14
  83. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
  84. data/lib/ruby_lsp/requests/workspace_symbol.rb +24 -16
  85. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +6 -9
  86. data/lib/ruby_lsp/response_builders/document_symbol.rb +15 -21
  87. data/lib/ruby_lsp/response_builders/hover.rb +12 -18
  88. data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
  89. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +62 -91
  90. data/lib/ruby_lsp/response_builders/signature_help.rb +6 -8
  91. data/lib/ruby_lsp/response_builders/test_collection.rb +35 -13
  92. data/lib/ruby_lsp/ruby_document.rb +32 -98
  93. data/lib/ruby_lsp/scope.rb +7 -11
  94. data/lib/ruby_lsp/scripts/compose_bundle.rb +7 -5
  95. data/lib/ruby_lsp/server.rb +305 -198
  96. data/lib/ruby_lsp/setup_bundler.rb +160 -97
  97. data/lib/ruby_lsp/static_docs.rb +12 -7
  98. data/lib/ruby_lsp/store.rb +21 -49
  99. data/lib/ruby_lsp/test_helper.rb +3 -16
  100. data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +241 -0
  101. data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +145 -0
  102. data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +92 -0
  103. data/lib/ruby_lsp/type_inferrer.rb +13 -14
  104. data/lib/ruby_lsp/utils.rb +138 -93
  105. data/static_docs/break.md +103 -0
  106. metadata +15 -34
  107. data/lib/ruby_indexer/test/class_variables_test.rb +0 -140
  108. data/lib/ruby_indexer/test/classes_and_modules_test.rb +0 -745
  109. data/lib/ruby_indexer/test/configuration_test.rb +0 -239
  110. data/lib/ruby_indexer/test/constant_test.rb +0 -402
  111. data/lib/ruby_indexer/test/enhancements_test.rb +0 -325
  112. data/lib/ruby_indexer/test/global_variable_test.rb +0 -49
  113. data/lib/ruby_indexer/test/index_test.rb +0 -2186
  114. data/lib/ruby_indexer/test/instance_variables_test.rb +0 -240
  115. data/lib/ruby_indexer/test/method_test.rb +0 -947
  116. data/lib/ruby_indexer/test/prefix_tree_test.rb +0 -150
  117. data/lib/ruby_indexer/test/rbs_indexer_test.rb +0 -386
  118. data/lib/ruby_indexer/test/reference_finder_test.rb +0 -330
  119. data/lib/ruby_indexer/test/test_case.rb +0 -51
  120. data/lib/ruby_indexer/test/uri_test.rb +0 -72
  121. data/lib/ruby_lsp/load_sorbet.rb +0 -62
@@ -1,239 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- require "test_helper"
5
-
6
- module RubyIndexer
7
- class ConfigurationTest < Minitest::Test
8
- def setup
9
- @config = Configuration.new
10
- @workspace_path = File.expand_path(File.join("..", "..", ".."), __dir__)
11
- @config.workspace_path = @workspace_path
12
- end
13
-
14
- def test_load_configuration_executes_configure_block
15
- @config.apply_config({ "excluded_patterns" => ["**/fixtures/**/*.rb"] })
16
- uris = @config.indexable_uris
17
-
18
- bundle_path = Bundler.bundle_path.join("gems")
19
-
20
- assert(uris.none? { |uri| uri.full_path.include?("test/fixtures") })
21
- assert(uris.none? { |uri| uri.full_path.include?(bundle_path.join("minitest-reporters").to_s) })
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("sorbet-runtime").to_s) })
24
- assert(uris.none? { |uri| uri.full_path == __FILE__ })
25
- end
26
-
27
- def test_indexable_uris_have_expanded_full_paths
28
- @config.apply_config({ "included_patterns" => ["**/*.rb"] })
29
- uris = @config.indexable_uris
30
-
31
- # All paths should be expanded
32
- assert(uris.all? { |uri| File.absolute_path?(uri.full_path) })
33
- end
34
-
35
- def test_indexable_uris_only_includes_gem_require_paths
36
- uris = @config.indexable_uris
37
-
38
- Bundler.locked_gems.specs.each do |lazy_spec|
39
- next if lazy_spec.name == "ruby-lsp"
40
-
41
- spec = Gem::Specification.find_by_name(lazy_spec.name)
42
- assert(uris.none? { |uri| uri.full_path.start_with?("#{spec.full_gem_path}/test/") })
43
- rescue Gem::MissingSpecError
44
- # Transitive dependencies might be missing when running tests on Windows
45
- end
46
- end
47
-
48
- def test_indexable_uris_does_not_include_default_gem_path_when_in_bundle
49
- uris = @config.indexable_uris
50
- assert(uris.none? { |uri| uri.full_path.start_with?("#{RbConfig::CONFIG["rubylibdir"]}/psych") })
51
- end
52
-
53
- def test_indexable_uris_includes_default_gems
54
- paths = @config.indexable_uris.map(&:full_path)
55
-
56
- assert_includes(paths, "#{RbConfig::CONFIG["rubylibdir"]}/pathname.rb")
57
- assert_includes(paths, "#{RbConfig::CONFIG["rubylibdir"]}/ipaddr.rb")
58
- assert_includes(paths, "#{RbConfig::CONFIG["rubylibdir"]}/erb.rb")
59
- end
60
-
61
- def test_indexable_uris_includes_project_files
62
- paths = @config.indexable_uris.map(&:full_path)
63
-
64
- Dir.glob("#{Dir.pwd}/lib/**/*.rb").each do |path|
65
- next if path.end_with?("_test.rb")
66
-
67
- assert_includes(paths, path)
68
- end
69
- end
70
-
71
- def test_indexable_uris_avoids_duplicates_if_bundle_path_is_inside_project
72
- Bundler.settings.temporary(path: "vendor/bundle") do
73
- config = Configuration.new
74
-
75
- assert_includes(config.instance_variable_get(:@excluded_patterns), "vendor/bundle/**/*.rb")
76
- end
77
- end
78
-
79
- def test_indexable_uris_does_not_include_gems_own_installed_files
80
- uris = @config.indexable_uris
81
- uris_inside_bundled_lsp = uris.select do |uri|
82
- uri.full_path.start_with?(Bundler.bundle_path.join("gems", "ruby-lsp").to_s)
83
- end
84
-
85
- assert_empty(
86
- uris_inside_bundled_lsp,
87
- "Indexable URIs should not include files from the gem currently being worked on. " \
88
- "Included: #{uris_inside_bundled_lsp.map(&:full_path)}",
89
- )
90
- end
91
-
92
- def test_indexable_uris_does_not_include_non_ruby_files_inside_rubylibdir
93
- path = Pathname.new(RbConfig::CONFIG["rubylibdir"]).join("extra_file.txt").to_s
94
- FileUtils.touch(path)
95
-
96
- uris = @config.indexable_uris
97
- assert(uris.none? { |uri| uri.full_path == path })
98
- ensure
99
- FileUtils.rm(T.must(path))
100
- end
101
-
102
- def test_paths_are_unique
103
- uris = @config.indexable_uris
104
- assert_equal(uris.uniq.length, uris.length)
105
- end
106
-
107
- def test_configuration_raises_for_unknown_keys
108
- assert_raises(ArgumentError) do
109
- @config.apply_config({ "unknown_config" => 123 })
110
- end
111
- end
112
-
113
- def test_magic_comments_regex
114
- regex = @config.magic_comment_regex
115
-
116
- [
117
- "# frozen_string_literal:",
118
- "# typed:",
119
- "# compiled:",
120
- "# encoding:",
121
- "# shareable_constant_value:",
122
- "# warn_indent:",
123
- "# rubocop:",
124
- "# nodoc:",
125
- "# doc:",
126
- "# coding:",
127
- "# warn_past_scope:",
128
- ].each do |comment|
129
- assert_match(regex, comment)
130
- end
131
- end
132
-
133
- def test_indexable_uris_respect_given_workspace_path
134
- Dir.mktmpdir do |dir|
135
- FileUtils.mkdir(File.join(dir, "ignore"))
136
- FileUtils.touch(File.join(dir, "ignore", "file0.rb"))
137
- FileUtils.touch(File.join(dir, "file1.rb"))
138
- FileUtils.touch(File.join(dir, "file2.rb"))
139
-
140
- @config.apply_config({ "excluded_patterns" => ["ignore/**/*.rb"] })
141
- @config.workspace_path = dir
142
-
143
- uris = @config.indexable_uris
144
- assert(uris.none? { |uri| uri.full_path.start_with?(File.join(dir, "ignore")) })
145
-
146
- # After switching the workspace path, all indexable URIs will be found in one of these places:
147
- # - The new workspace path
148
- # - The Ruby LSP's own code (because Bundler is requiring the dependency from source)
149
- # - Bundled gems
150
- # - Default gems
151
- assert(
152
- uris.all? do |u|
153
- u.full_path.start_with?(dir) ||
154
- u.full_path.start_with?(File.join(Dir.pwd, "lib")) ||
155
- u.full_path.start_with?(Bundler.bundle_path.to_s) ||
156
- u.full_path.start_with?(RbConfig::CONFIG["rubylibdir"])
157
- end,
158
- )
159
- end
160
- end
161
-
162
- def test_includes_top_level_files
163
- Dir.mktmpdir do |dir|
164
- FileUtils.touch(File.join(dir, "find_me.rb"))
165
- @config.workspace_path = dir
166
-
167
- uris = @config.indexable_uris
168
- assert(uris.find { |u| File.basename(u.full_path) == "find_me.rb" })
169
- end
170
- end
171
-
172
- def test_transitive_dependencies_for_non_dev_gems_are_not_excluded
173
- Dir.mktmpdir do |dir|
174
- Dir.chdir(dir) do
175
- # Both IRB and debug depend on reline. Since IRB is in the default group, reline should not be excluded
176
- File.write(File.join(dir, "Gemfile"), <<~RUBY)
177
- source "https://rubygems.org"
178
- gem "irb"
179
- gem "ruby-lsp", path: "#{Bundler.root}"
180
-
181
- group :development do
182
- gem "debug"
183
- end
184
- RUBY
185
-
186
- Bundler.with_unbundled_env do
187
- capture_subprocess_io do
188
- system("bundle install")
189
- end
190
-
191
- stdout, _stderr = capture_subprocess_io do
192
- script = [
193
- "require \"ruby_lsp/internal\"",
194
- "print RubyIndexer::Configuration.new.instance_variable_get(:@excluded_gems).join(\",\")",
195
- ].join(";")
196
- system("bundle exec ruby -e '#{script}'")
197
- end
198
-
199
- excluded_gems = stdout.split(",")
200
- assert_includes(excluded_gems, "debug")
201
- refute_includes(excluded_gems, "reline")
202
- refute_includes(excluded_gems, "irb")
203
- end
204
- end
205
- end
206
- end
207
-
208
- def test_does_not_fail_if_there_are_missing_specs_due_to_platform_constraints
209
- Dir.mktmpdir do |dir|
210
- Dir.chdir(dir) do
211
- File.write(File.join(dir, "Gemfile"), <<~RUBY)
212
- source "https://rubygems.org"
213
- gem "ruby-lsp", path: "#{Bundler.root}"
214
-
215
- platforms :windows do
216
- gem "tzinfo"
217
- gem "tzinfo-data"
218
- end
219
- RUBY
220
-
221
- Bundler.with_unbundled_env do
222
- capture_subprocess_io { system("bundle install") }
223
-
224
- _stdout, stderr = capture_subprocess_io do
225
- script = [
226
- "require \"ruby_lsp/internal\"",
227
- "RubyIndexer::Configuration.new.indexable_uris",
228
- ].join(";")
229
-
230
- system("bundle exec ruby -e '#{script}'")
231
- end
232
-
233
- assert_empty(stderr)
234
- end
235
- end
236
- end
237
- end
238
- end
239
- end
@@ -1,402 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- require_relative "test_case"
5
-
6
- module RubyIndexer
7
- class ConstantTest < TestCase
8
- def test_constant_writes
9
- index(<<~RUBY)
10
- FOO = 1
11
-
12
- class ::Bar
13
- FOO = 2
14
- end
15
-
16
- BAR = 3 if condition
17
- RUBY
18
-
19
- assert_entry("FOO", Entry::Constant, "/fake/path/foo.rb:0-0:0-7")
20
- assert_entry("Bar::FOO", Entry::Constant, "/fake/path/foo.rb:3-2:3-9")
21
- assert_entry("BAR", Entry::Constant, "/fake/path/foo.rb:6-0:6-7")
22
- end
23
-
24
- def test_constant_with_multibyte_characters
25
- index(<<~RUBY)
26
- CONST_💎 = "Ruby"
27
- RUBY
28
-
29
- assert_entry("CONST_💎", Entry::Constant, "/fake/path/foo.rb:0-0:0-16")
30
- end
31
-
32
- def test_constant_or_writes
33
- index(<<~RUBY)
34
- FOO ||= 1
35
-
36
- class ::Bar
37
- FOO ||= 2
38
- end
39
- RUBY
40
-
41
- assert_entry("FOO", Entry::Constant, "/fake/path/foo.rb:0-0:0-9")
42
- assert_entry("Bar::FOO", Entry::Constant, "/fake/path/foo.rb:3-2:3-11")
43
- end
44
-
45
- def test_constant_path_writes
46
- index(<<~RUBY)
47
- class A
48
- FOO = 1
49
- ::BAR = 1
50
-
51
- module B
52
- FOO = 1
53
- end
54
- end
55
-
56
- A::BAZ = 1
57
- RUBY
58
-
59
- assert_entry("A::FOO", Entry::Constant, "/fake/path/foo.rb:1-2:1-9")
60
- assert_entry("BAR", Entry::Constant, "/fake/path/foo.rb:2-2:2-11")
61
- assert_entry("A::B::FOO", Entry::Constant, "/fake/path/foo.rb:5-4:5-11")
62
- assert_entry("A::BAZ", Entry::Constant, "/fake/path/foo.rb:9-0:9-10")
63
- end
64
-
65
- def test_constant_path_or_writes
66
- index(<<~RUBY)
67
- class A
68
- FOO ||= 1
69
- ::BAR ||= 1
70
- end
71
-
72
- A::BAZ ||= 1
73
- RUBY
74
-
75
- assert_entry("A::FOO", Entry::Constant, "/fake/path/foo.rb:1-2:1-11")
76
- assert_entry("BAR", Entry::Constant, "/fake/path/foo.rb:2-2:2-13")
77
- assert_entry("A::BAZ", Entry::Constant, "/fake/path/foo.rb:5-0:5-12")
78
- end
79
-
80
- def test_comments_for_constants
81
- index(<<~RUBY)
82
- # FOO comment
83
- FOO = 1
84
-
85
- class A
86
- # A::FOO comment
87
- FOO = 1
88
-
89
- # ::BAR comment
90
- ::BAR = 1
91
- end
92
-
93
- # A::BAZ comment
94
- A::BAZ = 1
95
- RUBY
96
-
97
- foo_comment = @index["FOO"].first.comments
98
- assert_equal("FOO comment", foo_comment)
99
-
100
- a_foo_comment = @index["A::FOO"].first.comments
101
- assert_equal("A::FOO comment", a_foo_comment)
102
-
103
- bar_comment = @index["BAR"].first.comments
104
- assert_equal("::BAR comment", bar_comment)
105
-
106
- a_baz_comment = @index["A::BAZ"].first.comments
107
- assert_equal("A::BAZ comment", a_baz_comment)
108
- end
109
-
110
- def test_variable_path_constants_are_ignored
111
- index(<<~RUBY)
112
- var::FOO = 1
113
- self.class::FOO = 1
114
- RUBY
115
-
116
- assert_no_indexed_entries
117
- end
118
-
119
- def test_private_constant_indexing
120
- index(<<~RUBY)
121
- class A
122
- B = 1
123
- private_constant(:B)
124
-
125
- C = 2
126
- private_constant("C")
127
-
128
- D = 1
129
- end
130
- RUBY
131
-
132
- b_const = @index["A::B"].first
133
- assert_predicate(b_const, :private?)
134
-
135
- c_const = @index["A::C"].first
136
- assert_predicate(c_const, :private?)
137
-
138
- d_const = @index["A::D"].first
139
- assert_predicate(d_const, :public?)
140
- end
141
-
142
- def test_marking_constants_as_private_reopening_namespaces
143
- index(<<~RUBY)
144
- module A
145
- module B
146
- CONST_A = 1
147
- private_constant(:CONST_A)
148
-
149
- CONST_B = 2
150
- CONST_C = 3
151
- end
152
-
153
- module B
154
- private_constant(:CONST_B)
155
- end
156
- end
157
-
158
- module A
159
- module B
160
- private_constant(:CONST_C)
161
- end
162
- end
163
- RUBY
164
-
165
- a_const = @index["A::B::CONST_A"].first
166
- assert_predicate(a_const, :private?)
167
-
168
- b_const = @index["A::B::CONST_B"].first
169
- assert_predicate(b_const, :private?)
170
-
171
- c_const = @index["A::B::CONST_C"].first
172
- assert_predicate(c_const, :private?)
173
- end
174
-
175
- def test_marking_constants_as_private_with_receiver
176
- index(<<~RUBY)
177
- module A
178
- module B
179
- CONST_A = 1
180
- CONST_B = 2
181
- end
182
-
183
- B.private_constant(:CONST_A)
184
- end
185
-
186
- A::B.private_constant(:CONST_B)
187
- RUBY
188
-
189
- a_const = @index["A::B::CONST_A"].first
190
- assert_predicate(a_const, :private?)
191
-
192
- b_const = @index["A::B::CONST_B"].first
193
- assert_predicate(b_const, :private?)
194
- end
195
-
196
- def test_indexing_constant_aliases
197
- index(<<~RUBY)
198
- module A
199
- module B
200
- module C
201
- end
202
- end
203
-
204
- FIRST = B::C
205
- end
206
-
207
- SECOND = A::FIRST
208
- RUBY
209
-
210
- unresolve_entry = @index["A::FIRST"].first
211
- assert_instance_of(Entry::UnresolvedConstantAlias, unresolve_entry)
212
- assert_equal(["A"], unresolve_entry.nesting)
213
- assert_equal("B::C", unresolve_entry.target)
214
-
215
- resolved_entry = @index.resolve("A::FIRST", []).first
216
- assert_instance_of(Entry::ConstantAlias, resolved_entry)
217
- assert_equal("A::B::C", resolved_entry.target)
218
- end
219
-
220
- def test_aliasing_namespaces
221
- index(<<~RUBY)
222
- module A
223
- module B
224
- module C
225
- end
226
- end
227
-
228
- ALIAS = B
229
- end
230
-
231
- module Other
232
- ONE_MORE = A::ALIAS
233
- end
234
- RUBY
235
-
236
- unresolve_entry = @index["A::ALIAS"].first
237
- assert_instance_of(Entry::UnresolvedConstantAlias, unresolve_entry)
238
- assert_equal(["A"], unresolve_entry.nesting)
239
- assert_equal("B", unresolve_entry.target)
240
-
241
- resolved_entry = @index.resolve("ALIAS", ["A"]).first
242
- assert_instance_of(Entry::ConstantAlias, resolved_entry)
243
- assert_equal("A::B", resolved_entry.target)
244
-
245
- resolved_entry = @index.resolve("ALIAS::C", ["A"]).first
246
- assert_instance_of(Entry::Module, resolved_entry)
247
- assert_equal("A::B::C", resolved_entry.name)
248
-
249
- unresolve_entry = @index["Other::ONE_MORE"].first
250
- assert_instance_of(Entry::UnresolvedConstantAlias, unresolve_entry)
251
- assert_equal(["Other"], unresolve_entry.nesting)
252
- assert_equal("A::ALIAS", unresolve_entry.target)
253
-
254
- resolved_entry = @index.resolve("Other::ONE_MORE::C", []).first
255
- assert_instance_of(Entry::Module, resolved_entry)
256
- end
257
-
258
- def test_indexing_same_line_constant_aliases
259
- index(<<~RUBY)
260
- module A
261
- B = C = 1
262
- D = E ||= 1
263
- F = G::H &&= 1
264
- I::J = K::L = M = 1
265
- end
266
- RUBY
267
-
268
- # B and C
269
- unresolve_entry = @index["A::B"].first
270
- assert_instance_of(Entry::UnresolvedConstantAlias, unresolve_entry)
271
- assert_equal(["A"], unresolve_entry.nesting)
272
- assert_equal("C", unresolve_entry.target)
273
-
274
- resolved_entry = @index.resolve("A::B", []).first
275
- assert_instance_of(Entry::ConstantAlias, resolved_entry)
276
- assert_equal("A::C", resolved_entry.target)
277
-
278
- constant = @index["A::C"].first
279
- assert_instance_of(Entry::Constant, constant)
280
-
281
- # D and E
282
- unresolve_entry = @index["A::D"].first
283
- assert_instance_of(Entry::UnresolvedConstantAlias, unresolve_entry)
284
- assert_equal(["A"], unresolve_entry.nesting)
285
- assert_equal("E", unresolve_entry.target)
286
-
287
- resolved_entry = @index.resolve("A::D", []).first
288
- assert_instance_of(Entry::ConstantAlias, resolved_entry)
289
- assert_equal("A::E", resolved_entry.target)
290
-
291
- # F and G::H
292
- unresolve_entry = @index["A::F"].first
293
- assert_instance_of(Entry::UnresolvedConstantAlias, unresolve_entry)
294
- assert_equal(["A"], unresolve_entry.nesting)
295
- assert_equal("G::H", unresolve_entry.target)
296
-
297
- resolved_entry = @index.resolve("A::F", []).first
298
- assert_instance_of(Entry::ConstantAlias, resolved_entry)
299
- assert_equal("A::G::H", resolved_entry.target)
300
-
301
- # I::J, K::L and M
302
- unresolve_entry = @index["A::I::J"].first
303
- assert_instance_of(Entry::UnresolvedConstantAlias, unresolve_entry)
304
- assert_equal(["A"], unresolve_entry.nesting)
305
- assert_equal("K::L", unresolve_entry.target)
306
-
307
- resolved_entry = @index.resolve("A::I::J", []).first
308
- assert_instance_of(Entry::ConstantAlias, resolved_entry)
309
- assert_equal("A::K::L", resolved_entry.target)
310
-
311
- # When we are resolving A::I::J, we invoke `resolve("K::L", ["A"])`, which recursively resolves A::K::L too.
312
- # Therefore, both A::I::J and A::K::L point to A::M by the end of the previous resolve invocation
313
- resolved_entry = @index["A::K::L"].first
314
- assert_instance_of(Entry::ConstantAlias, resolved_entry)
315
- assert_equal("A::M", resolved_entry.target)
316
-
317
- constant = @index["A::M"].first
318
- assert_instance_of(Entry::Constant, constant)
319
- end
320
-
321
- def test_indexing_or_and_operator_nodes
322
- index(<<~RUBY)
323
- A ||= 1
324
- B &&= 2
325
- C &= 3
326
- D::E ||= 4
327
- F::G &&= 5
328
- H::I &= 6
329
- RUBY
330
-
331
- assert_entry("A", Entry::Constant, "/fake/path/foo.rb:0-0:0-7")
332
- assert_entry("B", Entry::Constant, "/fake/path/foo.rb:1-0:1-7")
333
- assert_entry("C", Entry::Constant, "/fake/path/foo.rb:2-0:2-6")
334
- assert_entry("D::E", Entry::Constant, "/fake/path/foo.rb:3-0:3-10")
335
- assert_entry("F::G", Entry::Constant, "/fake/path/foo.rb:4-0:4-10")
336
- assert_entry("H::I", Entry::Constant, "/fake/path/foo.rb:5-0:5-9")
337
- end
338
-
339
- def test_indexing_constant_targets
340
- index(<<~RUBY)
341
- module A
342
- B, C = [1, Y]
343
- D::E, F::G = [Z, 4]
344
- H, I::J = [5, B]
345
- K, L = C
346
- end
347
-
348
- module Real
349
- Z = 1
350
- Y = 2
351
- end
352
- RUBY
353
-
354
- assert_entry("A::B", Entry::Constant, "/fake/path/foo.rb:1-2:1-3")
355
- assert_entry("A::C", Entry::UnresolvedConstantAlias, "/fake/path/foo.rb:1-5:1-6")
356
- assert_entry("A::D::E", Entry::UnresolvedConstantAlias, "/fake/path/foo.rb:2-2:2-6")
357
- assert_entry("A::F::G", Entry::Constant, "/fake/path/foo.rb:2-8:2-12")
358
- assert_entry("A::H", Entry::Constant, "/fake/path/foo.rb:3-2:3-3")
359
- assert_entry("A::I::J", Entry::UnresolvedConstantAlias, "/fake/path/foo.rb:3-5:3-9")
360
- assert_entry("A::K", Entry::Constant, "/fake/path/foo.rb:4-2:4-3")
361
- assert_entry("A::L", Entry::Constant, "/fake/path/foo.rb:4-5:4-6")
362
- end
363
-
364
- def test_indexing_constant_targets_with_splats
365
- index(<<~RUBY)
366
- A, *, B = baz
367
- C, = bar
368
- (D, E) = baz
369
- F, G = *baz, qux
370
- H, I = [baz, *qux]
371
- J, L = [*something, String]
372
- M = [String]
373
- RUBY
374
-
375
- assert_entry("A", Entry::Constant, "/fake/path/foo.rb:0-0:0-1")
376
- assert_entry("B", Entry::Constant, "/fake/path/foo.rb:0-6:0-7")
377
- assert_entry("D", Entry::Constant, "/fake/path/foo.rb:2-1:2-2")
378
- assert_entry("E", Entry::Constant, "/fake/path/foo.rb:2-4:2-5")
379
- assert_entry("F", Entry::Constant, "/fake/path/foo.rb:3-0:3-1")
380
- assert_entry("G", Entry::Constant, "/fake/path/foo.rb:3-3:3-4")
381
- assert_entry("H", Entry::Constant, "/fake/path/foo.rb:4-0:4-1")
382
- assert_entry("I", Entry::Constant, "/fake/path/foo.rb:4-3:4-4")
383
- assert_entry("J", Entry::Constant, "/fake/path/foo.rb:5-0:5-1")
384
- assert_entry("L", Entry::Constant, "/fake/path/foo.rb:5-3:5-4")
385
- assert_entry("M", Entry::Constant, "/fake/path/foo.rb:6-0:6-12")
386
- end
387
-
388
- def test_indexing_destructuring_an_array
389
- index(<<~RUBY)
390
- Baz = [1, 2]
391
- Foo, Bar = Baz
392
- This, That = foo, bar
393
- RUBY
394
-
395
- assert_entry("Baz", Entry::Constant, "/fake/path/foo.rb:0-0:0-12")
396
- assert_entry("Foo", Entry::Constant, "/fake/path/foo.rb:1-0:1-3")
397
- assert_entry("Bar", Entry::Constant, "/fake/path/foo.rb:1-5:1-8")
398
- assert_entry("This", Entry::Constant, "/fake/path/foo.rb:2-0:2-4")
399
- assert_entry("That", Entry::Constant, "/fake/path/foo.rb:2-6:2-10")
400
- end
401
- end
402
- end