ruby-lsp 0.26.5 → 0.26.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c0285974bdf15d052431c1401f320645f57d8bd186ce9899dafc53f11da269a
4
- data.tar.gz: d17e63e0b0db476033d2dfcaec8e40b4131f97cde55c7ade2cd2977ead23dc15
3
+ metadata.gz: a2fb06df12b49f414c218bd2cb6a1ef5b817dff076894fa6e2ae6585a370f172
4
+ data.tar.gz: b9fef2a34f9361b8f4b3f74ecb3c64d53226964293bb01f4b7400ce1688746e9
5
5
  SHA512:
6
- metadata.gz: 26f63dc15bacf617c683dbb7b55fbf1eee1d2f8051b207a27cead0479b475c16d9cb31fbee3fc180f3c054cfd6754c2e5427ec1fa7d4330a17ff3a0ccd9c5f92
7
- data.tar.gz: 1717199121bee0e9e72dc7bac4ba1779cbed7d4480f7f58bf046b9a3ac8c752c34fe4584eadcf45f98437bbdfb5a3ebcad36cf6951318cf4c63ae6fb84e5b41e
6
+ metadata.gz: 5e2c4674e72af204f3b4c78b6053e205c9a4c7ffd5b99642cf78db3c469c0334f3952e3326c7b091b54974e2cd523716dcb8c0b1c17d861b9f80f87bbedd4056
7
+ data.tar.gz: d3aaba57e7f33f5a46bdd12a69f7c965e50bcb95049032e1ee12c21d538f4d3ffc6220e798abd0fa6488085f9cb45fea468e7a9318097b16ba9d73923e2ea9a5
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.26.5
1
+ 0.26.7
@@ -101,7 +101,7 @@ begin
101
101
  Bundler.setup
102
102
  $stderr.puts("Composed Bundle set up successfully")
103
103
  end
104
- rescue Bundler::GemNotFound, Bundler::GitError
104
+ rescue Bundler::GemNotFound, Bundler::GitError => e
105
105
  # Sometimes, we successfully set up the bundle, but users either change their Gemfile or uninstall gems from an
106
106
  # external process. If there's no install error, but the gem is still not found, then we need to attempt to start from
107
107
  # scratch
@@ -113,6 +113,10 @@ rescue Bundler::GemNotFound, Bundler::GitError
113
113
  exec(Gem.ruby, __FILE__, *ARGV, "--retry")
114
114
  end
115
115
  end
116
+
117
+ setup_error = e
118
+ $stderr.puts("Failed to set up composed Bundle\n#{e.full_message}")
119
+ $LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
116
120
  rescue StandardError => e
117
121
  setup_error = e
118
122
  $stderr.puts("Failed to set up composed Bundle\n#{e.full_message}")
@@ -227,7 +227,7 @@ module RubyIndexer
227
227
  others.uniq!
228
228
  others.map!(&:name)
229
229
 
230
- excluded.each do |dependency|
230
+ transitive_excluded = excluded.each_with_object([]) do |dependency, acc|
231
231
  next unless dependency.runtime?
232
232
 
233
233
  spec = dependency.to_spec
@@ -236,7 +236,7 @@ module RubyIndexer
236
236
  spec.dependencies.each do |transitive_dependency|
237
237
  next if others.include?(transitive_dependency.name)
238
238
 
239
- excluded << transitive_dependency
239
+ acc << transitive_dependency
240
240
  end
241
241
  rescue Gem::MissingSpecError
242
242
  # If a gem is scoped only to some specific platform, then its dependencies may not be installed either, but they
@@ -244,6 +244,7 @@ module RubyIndexer
244
244
  # just ignore if they're missing
245
245
  end
246
246
 
247
+ excluded.concat(transitive_excluded)
247
248
  excluded.uniq!
248
249
  excluded.map(&:name)
249
250
  rescue Bundler::GemfileNotFound
@@ -14,6 +14,12 @@ module RubyLsp
14
14
  fatal: Constant::DiagnosticSeverity::ERROR,
15
15
  }.freeze #: Hash[Symbol, Integer]
16
16
 
17
+ # Cops where adding a `rubocop:disable` inline comment would itself resolve the offense,
18
+ # causing Lint/RedundantCopDisableDirective to flag the disable as unnecessary.
19
+ SELF_RESOLVING_DISABLE_COPS = Set.new([
20
+ "Layout/EmptyComment",
21
+ ]).freeze #: Set[String]
22
+
17
23
  ENHANCED_DOC_URL = begin
18
24
  gem("rubocop", ">= 1.64.0")
19
25
  true
@@ -35,7 +41,7 @@ module RubyLsp
35
41
  code_actions = []
36
42
 
37
43
  code_actions << autocorrect_action if correctable?
38
- code_actions << disable_line_action
44
+ code_actions << disable_line_action unless SELF_RESOLVING_DISABLE_COPS.include?(@offense.cop_name)
39
45
 
40
46
  code_actions
41
47
  end
@@ -31,6 +31,10 @@ 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
@@ -122,6 +126,7 @@ module RubyLsp
122
126
  return run_bundle_install(@custom_gemfile)
123
127
  end
124
128
 
129
+ @needs_update_path.delete if @needs_update_path.exist?
125
130
  FileUtils.cp(@lockfile.to_s, @custom_lockfile.to_s)
126
131
  correct_relative_remote_paths
127
132
  @lockfile_hash_path.write(@lockfile_hash)
@@ -331,26 +336,26 @@ module RubyLsp
331
336
  def update(env)
332
337
  # Try to auto upgrade the gems we depend on, unless they are in the Gemfile as that would result in undesired
333
338
  # source control changes
334
- gems = ["ruby-lsp", "debug", "prism"].reject { |dep| @dependencies[dep] }
339
+ gems = GEMS_TO_UPDATE.reject { |dep| @dependencies[dep] }
335
340
  gems << "ruby-lsp-rails" if @rails_app && !@dependencies["ruby-lsp-rails"]
336
341
 
337
342
  Bundler::CLI::Update.new({ conservative: true }, gems).run
338
343
  correct_relative_remote_paths if @custom_lockfile.exist?
339
- @needs_update_path.delete
344
+ @needs_update_path.delete if @needs_update_path.exist?
340
345
  @last_updated_path.write(Time.now.iso8601)
341
346
  env
342
347
  end
343
348
 
344
349
  #: (Hash[String, String] env) -> Hash[String, String]
345
350
  def run_bundle_install_through_command(env)
346
- # If `ruby-lsp` and `debug` (and potentially `ruby-lsp-rails`) are already in the Gemfile, then we shouldn't try
347
- # to upgrade them or else we'll produce undesired source control changes. If the composed bundle was just created
348
- # and any of `ruby-lsp`, `ruby-lsp-rails` or `debug` weren't a part of the Gemfile, then we need to run `bundle
349
- # install` for the first time to generate the Gemfile.lock with them included or else Bundler will complain that
350
- # they're missing. We can only update if the custom `.ruby-lsp/Gemfile.lock` already exists and includes all gems
351
+ # If the gems in GEMS_TO_UPDATE (and potentially `ruby-lsp-rails`) are already in the Gemfile, then we shouldn't
352
+ # try to upgrade them or else we'll produce undesired source control changes. If the composed bundle was just
353
+ # created and any of those gems weren't a part of the Gemfile, then we need to run `bundle install` for the first
354
+ # time to generate the Gemfile.lock with them included or else Bundler will complain that they're missing. We can
355
+ # only update if the custom `.ruby-lsp/Gemfile.lock` already exists and includes all gems
351
356
 
352
357
  # When not updating, we run `(bundle check || bundle install)`
353
- # When updating, we run `((bundle check && bundle update ruby-lsp debug) || bundle install)`
358
+ # When updating, we run `((bundle check && bundle update <GEMS_TO_UPDATE>) || bundle install)`
354
359
  bundler_path = File.join(Gem.default_bindir, "bundle")
355
360
  base_command = (!Gem.win_platform? && File.exist?(bundler_path) ? "#{Gem.ruby} #{bundler_path}" : "bundle").dup
356
361
 
@@ -361,12 +366,11 @@ module RubyLsp
361
366
  command = +"(#{base_command} check"
362
367
 
363
368
  if should_bundle_update?
364
- # If any of `ruby-lsp`, `ruby-lsp-rails` or `debug` are not in the Gemfile, try to update them to the latest
365
- # version
369
+ # If any of the gems in GEMS_TO_UPDATE (or `ruby-lsp-rails` for Rails apps) are not in the Gemfile, try to
370
+ # update them to the latest version
366
371
  command.prepend("(")
367
372
  command << " && #{base_command} update "
368
- command << "ruby-lsp " unless @dependencies["ruby-lsp"]
369
- command << "debug " unless @dependencies["debug"]
373
+ GEMS_TO_UPDATE.each { |gem| command << "#{gem} " unless @dependencies[gem] }
370
374
  command << "ruby-lsp-rails " if @rails_app && !@dependencies["ruby-lsp-rails"]
371
375
  command.delete_suffix!(" ")
372
376
  command << ")"
@@ -4,13 +4,40 @@
4
4
  require "English"
5
5
  require "json"
6
6
  require "socket"
7
- require "singleton"
8
7
  require "tmpdir"
9
8
  require_relative "../../ruby_indexer/lib/ruby_indexer/uri"
10
9
 
11
10
  module RubyLsp
12
11
  class LspReporter
13
- include Singleton
12
+ @instance = nil #: LspReporter?
13
+
14
+ class << self
15
+ #: -> LspReporter
16
+ def instance
17
+ @instance ||= new
18
+ end
19
+
20
+ #: -> bool
21
+ def start_coverage?
22
+ ENV["RUBY_LSP_TEST_RUNNER"] == "coverage"
23
+ end
24
+
25
+ #: -> bool
26
+ def executed_under_test_runner?
27
+ !!(ENV["RUBY_LSP_TEST_RUNNER"] && ENV["RUBY_LSP_ENV"] != "test")
28
+ end
29
+
30
+ #: (Method | UnboundMethod) -> [URI::Generic, Integer?]?
31
+ def uri_and_line_for(method_object)
32
+ file_path, line = method_object.source_location
33
+ return unless file_path
34
+ return if file_path.start_with?("(eval at ")
35
+
36
+ uri = URI::Generic.from_path(path: File.expand_path(file_path))
37
+ zero_based_line = line ? line - 1 : nil
38
+ [uri, zero_based_line]
39
+ end
40
+ end
14
41
 
15
42
  # https://code.visualstudio.com/api/references/vscode-api#Position
16
43
  #: type position = { line: Integer, character: Integer }
@@ -50,6 +77,8 @@ module RubyLsp
50
77
  end #: IO | StringIO
51
78
 
52
79
  @invoked_shutdown = false #: bool
80
+ @message_queue = Thread::Queue.new #: Thread::Queue
81
+ @writer = Thread.new { write_loop } #: Thread
53
82
  end
54
83
 
55
84
  #: -> void
@@ -68,6 +97,8 @@ module RubyLsp
68
97
  @invoked_shutdown = true
69
98
 
70
99
  send_message("finish")
100
+ @message_queue.close
101
+ @writer.join
71
102
  @io.close
72
103
  end
73
104
 
@@ -96,17 +127,6 @@ module RubyLsp
96
127
  send_message("error", id: id, message: message, uri: uri.to_s)
97
128
  end
98
129
 
99
- #: (Method | UnboundMethod) -> [URI::Generic, Integer?]?
100
- def uri_and_line_for(method_object)
101
- file_path, line = method_object.source_location
102
- return unless file_path
103
- return if file_path.start_with?("(eval at ")
104
-
105
- uri = URI::Generic.from_path(path: File.expand_path(file_path))
106
- zero_based_line = line ? line - 1 : nil
107
- [uri, zero_based_line]
108
- end
109
-
110
130
  # Gather the results returned by Coverage.result and format like the VS Code test explorer expects
111
131
  #
112
132
  # Coverage result format:
@@ -195,23 +215,11 @@ module RubyLsp
195
215
  internal_shutdown unless @invoked_shutdown
196
216
  end
197
217
 
198
- class << self
199
- #: -> bool
200
- def start_coverage?
201
- ENV["RUBY_LSP_TEST_RUNNER"] == "coverage"
202
- end
203
-
204
- #: -> bool
205
- def executed_under_test_runner?
206
- !!(ENV["RUBY_LSP_TEST_RUNNER"] && ENV["RUBY_LSP_ENV"] != "test")
207
- end
208
- end
209
-
210
218
  private
211
219
 
212
- #: (String) -> TCPSocket
220
+ #: (String) -> Socket
213
221
  def socket(port)
214
- socket = TCPSocket.new("localhost", port)
222
+ socket = Socket.tcp("localhost", port)
215
223
  socket.binmode
216
224
  socket.sync = true
217
225
  socket
@@ -220,7 +228,14 @@ module RubyLsp
220
228
  #: (String?, **untyped) -> void
221
229
  def send_message(method_name, **params)
222
230
  json_message = { method: method_name, params: params }.to_json
223
- @io.write("Content-Length: #{json_message.bytesize}\r\n\r\n#{json_message}")
231
+ @message_queue << "Content-Length: #{json_message.bytesize}\r\n\r\n#{json_message}"
232
+ end
233
+
234
+ #: -> void
235
+ def write_loop
236
+ while (message = @message_queue.pop)
237
+ @io.write(message)
238
+ end
224
239
  end
225
240
  end
226
241
  end
@@ -89,7 +89,7 @@ module RubyLsp
89
89
  test_class_or_wrapper
90
90
  end
91
91
 
92
- uri, line = LspReporter.instance.uri_and_line_for(klass.instance_method(method_name))
92
+ uri, line = LspReporter.uri_and_line_for(klass.instance_method(method_name))
93
93
  return unless uri
94
94
 
95
95
  id = "#{name}##{handle_spec_test_id(method_name, line)}"
@@ -25,7 +25,7 @@ module RubyLsp
25
25
  def test_started(test)
26
26
  super
27
27
 
28
- uri, line = LspReporter.instance.uri_and_line_for(test.method(test.method_name))
28
+ uri, line = LspReporter.uri_and_line_for(test.method(test.method_name))
29
29
  return unless uri
30
30
 
31
31
  @current_uri = uri
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.5
4
+ version: 0.26.7
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
@@ -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