ruby-lsp 0.14.6 → 0.16.4

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/VERSION +1 -1
  4. data/exe/ruby-lsp +1 -16
  5. data/exe/ruby-lsp-check +13 -22
  6. data/exe/ruby-lsp-doctor +9 -0
  7. data/lib/ruby_indexer/lib/ruby_indexer/collector.rb +14 -1
  8. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +11 -23
  9. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +4 -0
  10. data/lib/ruby_indexer/test/classes_and_modules_test.rb +46 -0
  11. data/lib/ruby_indexer/test/configuration_test.rb +2 -11
  12. data/lib/ruby_lsp/addon.rb +18 -9
  13. data/lib/ruby_lsp/base_server.rb +149 -0
  14. data/lib/ruby_lsp/document.rb +6 -11
  15. data/lib/ruby_lsp/global_state.rb +169 -0
  16. data/lib/ruby_lsp/internal.rb +4 -1
  17. data/lib/ruby_lsp/listeners/code_lens.rb +22 -13
  18. data/lib/ruby_lsp/listeners/completion.rb +13 -14
  19. data/lib/ruby_lsp/listeners/definition.rb +4 -3
  20. data/lib/ruby_lsp/listeners/document_symbol.rb +91 -3
  21. data/lib/ruby_lsp/listeners/hover.rb +6 -5
  22. data/lib/ruby_lsp/listeners/signature_help.rb +7 -4
  23. data/lib/ruby_lsp/load_sorbet.rb +62 -0
  24. data/lib/ruby_lsp/requests/code_lens.rb +3 -2
  25. data/lib/ruby_lsp/requests/completion.rb +15 -4
  26. data/lib/ruby_lsp/requests/completion_resolve.rb +56 -0
  27. data/lib/ruby_lsp/requests/definition.rb +11 -4
  28. data/lib/ruby_lsp/requests/diagnostics.rb +6 -12
  29. data/lib/ruby_lsp/requests/document_symbol.rb +3 -3
  30. data/lib/ruby_lsp/requests/formatting.rb +7 -43
  31. data/lib/ruby_lsp/requests/hover.rb +4 -4
  32. data/lib/ruby_lsp/requests/request.rb +2 -0
  33. data/lib/ruby_lsp/requests/semantic_highlighting.rb +1 -1
  34. data/lib/ruby_lsp/requests/signature_help.rb +4 -3
  35. data/lib/ruby_lsp/requests/support/common.rb +16 -5
  36. data/lib/ruby_lsp/requests/support/formatter.rb +26 -0
  37. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +1 -1
  38. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +47 -0
  39. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +4 -0
  40. data/lib/ruby_lsp/requests/support/{syntax_tree_formatting_runner.rb → syntax_tree_formatter.rb} +13 -6
  41. data/lib/ruby_lsp/requests/workspace_symbol.rb +5 -4
  42. data/lib/ruby_lsp/requests.rb +3 -1
  43. data/lib/ruby_lsp/server.rb +763 -142
  44. data/lib/ruby_lsp/setup_bundler.rb +13 -1
  45. data/lib/ruby_lsp/store.rb +3 -15
  46. data/lib/ruby_lsp/test_helper.rb +52 -0
  47. data/lib/ruby_lsp/utils.rb +68 -33
  48. metadata +11 -9
  49. data/lib/ruby_lsp/executor.rb +0 -614
  50. data/lib/ruby_lsp/requests/support/dependency_detector.rb +0 -93
  51. data/lib/ruby_lsp/requests/support/formatter_runner.rb +0 -18
  52. data/lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb +0 -34
  53. data/lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb +0 -35
@@ -19,6 +19,7 @@ module RubyLsp
19
19
  extend T::Sig
20
20
 
21
21
  class BundleNotLocked < StandardError; end
22
+ class BundleInstallFailure < StandardError; end
22
23
 
23
24
  FOUR_HOURS = T.let(4 * 60 * 60, Integer)
24
25
 
@@ -49,6 +50,7 @@ module RubyLsp
49
50
  @last_updated_path = T.let(@custom_dir + "last_updated", Pathname)
50
51
 
51
52
  @dependencies = T.let(load_dependencies, T::Hash[String, T.untyped])
53
+ @retry = T.let(false, T::Boolean)
52
54
  end
53
55
 
54
56
  # Sets up the custom bundle and returns the `BUNDLE_GEMFILE`, `BUNDLE_PATH` and `BUNDLE_APP_CONFIG` that should be
@@ -224,7 +226,17 @@ module RubyLsp
224
226
  # Add bundle update
225
227
  $stderr.puts("Ruby LSP> Running bundle install for the custom bundle. This may take a while...")
226
228
  $stderr.puts("Ruby LSP> Command: #{command}")
227
- system(env, command)
229
+
230
+ # Try to run the bundle install or update command. If that fails, it normally means that the custom lockfile is in
231
+ # a bad state that no longer reflects the top level one. In that case, we can remove the whole directory, try
232
+ # another time and give up if it fails again
233
+ if !system(env, command) && !@retry && @custom_dir.exist?
234
+ @retry = true
235
+ @custom_dir.rmtree
236
+ $stderr.puts("Ruby LSP> Running bundle install failed. Trying to re-generate the custom bundle from scratch")
237
+ return setup!
238
+ end
239
+
228
240
  [bundle_gemfile.to_s, expanded_path, env["BUNDLE_APP_CONFIG"]]
229
241
  end
230
242
 
@@ -5,21 +5,12 @@ module RubyLsp
5
5
  class Store
6
6
  extend T::Sig
7
7
 
8
- sig { returns(String) }
9
- attr_accessor :encoding
10
-
11
- sig { returns(String) }
12
- attr_accessor :formatter
13
-
14
8
  sig { returns(T::Boolean) }
15
9
  attr_accessor :supports_progress
16
10
 
17
11
  sig { returns(T::Boolean) }
18
12
  attr_accessor :experimental_features
19
13
 
20
- sig { returns(URI::Generic) }
21
- attr_accessor :workspace_uri
22
-
23
14
  sig { returns(T::Hash[Symbol, RequestConfig]) }
24
15
  attr_accessor :features_configuration
25
16
 
@@ -29,11 +20,8 @@ module RubyLsp
29
20
  sig { void }
30
21
  def initialize
31
22
  @state = T.let({}, T::Hash[String, Document])
32
- @encoding = T.let(Constant::PositionEncodingKind::UTF8, String)
33
- @formatter = T.let("auto", String)
34
23
  @supports_progress = T.let(true, T::Boolean)
35
24
  @experimental_features = T.let(false, T::Boolean)
36
- @workspace_uri = T.let(URI::Generic.from_path(path: Dir.pwd), URI::Generic)
37
25
  @features_configuration = T.let(
38
26
  {
39
27
  inlayHint: RequestConfig.new({
@@ -57,9 +45,9 @@ module RubyLsp
57
45
  T.must(@state[uri.to_s])
58
46
  end
59
47
 
60
- sig { params(uri: URI::Generic, source: String, version: Integer).void }
61
- def set(uri:, source:, version:)
62
- document = RubyDocument.new(source: source, version: version, uri: uri, encoding: @encoding)
48
+ sig { params(uri: URI::Generic, source: String, version: Integer, encoding: Encoding).void }
49
+ def set(uri:, source:, version:, encoding: Encoding::UTF_8)
50
+ document = RubyDocument.new(source: source, version: version, uri: uri, encoding: encoding)
63
51
  @state[uri.to_s] = document
64
52
  end
65
53
 
@@ -0,0 +1,52 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ # NOTE: This module is intended to be used by addons for writing their own tests, so keep that in mind if changing.
5
+
6
+ module RubyLsp
7
+ module TestHelper
8
+ extend T::Sig
9
+
10
+ sig do
11
+ type_parameters(:T)
12
+ .params(
13
+ source: T.nilable(String),
14
+ uri: URI::Generic,
15
+ stub_no_typechecker: T::Boolean,
16
+ load_addons: T::Boolean,
17
+ block: T.proc.params(server: RubyLsp::Server, uri: URI::Generic).returns(T.type_parameter(:T)),
18
+ ).returns(T.type_parameter(:T))
19
+ end
20
+ def with_server(source = nil, uri = Kernel.URI("file:///fake.rb"), stub_no_typechecker: false, load_addons: true,
21
+ &block)
22
+ server = RubyLsp::Server.new(test_mode: true)
23
+ server.global_state.stubs(:typechecker).returns(false) if stub_no_typechecker
24
+
25
+ if source
26
+ server.process_message({
27
+ method: "textDocument/didOpen",
28
+ params: {
29
+ textDocument: {
30
+ uri: uri,
31
+ text: source,
32
+ version: 1,
33
+ },
34
+ },
35
+ })
36
+ end
37
+
38
+ server.global_state.index.index_single(
39
+ RubyIndexer::IndexablePath.new(nil, T.must(uri.to_standardized_path)),
40
+ source,
41
+ )
42
+ server.load_addons if load_addons
43
+ block.call(server, uri)
44
+ ensure
45
+ if load_addons
46
+ RubyLsp::Addon.addons.each(&:deactivate)
47
+ RubyLsp::Addon.addons.clear
48
+ end
49
+ T.must(server).run_shutdown
50
+ end
51
+ end
52
+ end
@@ -2,8 +2,13 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module RubyLsp
5
+ # rubocop:disable RubyLsp/UseLanguageServerAliases
6
+ Interface = LanguageServer::Protocol::Interface
7
+ Constant = LanguageServer::Protocol::Constant
8
+ Transport = LanguageServer::Protocol::Transport
9
+ # rubocop:enable RubyLsp/UseLanguageServerAliases
10
+
5
11
  # Used to indicate that a request shouldn't return a response
6
- VOID = T.let(Object.new.freeze, Object)
7
12
  BUNDLE_PATH = T.let(
8
13
  begin
9
14
  Bundler.bundle_path.to_s
@@ -26,19 +31,22 @@ module RubyLsp
26
31
  extend T::Sig
27
32
  extend T::Helpers
28
33
 
29
- abstract!
30
-
31
34
  sig { returns(String) }
32
- attr_reader :message
35
+ attr_reader :method
33
36
 
34
37
  sig { returns(Object) }
35
38
  attr_reader :params
36
39
 
37
- sig { params(message: String, params: Object).void }
38
- def initialize(message:, params:)
39
- @message = message
40
+ abstract!
41
+
42
+ sig { params(method: String, params: Object).void }
43
+ def initialize(method:, params:)
44
+ @method = method
40
45
  @params = params
41
46
  end
47
+
48
+ sig { abstract.returns(T::Hash[Symbol, T.untyped]) }
49
+ def to_hash; end
42
50
  end
43
51
 
44
52
  class Notification < Message
@@ -47,7 +55,7 @@ module RubyLsp
47
55
  sig { params(message: String).returns(Notification) }
48
56
  def window_show_error(message)
49
57
  new(
50
- message: "window/showMessage",
58
+ method: "window/showMessage",
51
59
  params: Interface::ShowMessageParams.new(
52
60
  type: Constant::MessageType::ERROR,
53
61
  message: message,
@@ -55,46 +63,73 @@ module RubyLsp
55
63
  )
56
64
  end
57
65
  end
58
- end
59
66
 
60
- class Request < Message; end
61
-
62
- # The final result of running a request before its IO is finalized
63
- class Result
64
67
  extend T::Sig
65
68
 
66
- sig { returns(T.untyped) }
67
- attr_reader :response
69
+ sig { override.returns(T::Hash[Symbol, T.untyped]) }
70
+ def to_hash
71
+ { method: @method, params: T.unsafe(@params).to_hash }
72
+ end
73
+ end
68
74
 
69
- sig { returns(T.nilable(Exception)) }
70
- attr_reader :error
75
+ class Request < Message
76
+ extend T::Sig
71
77
 
72
- sig { params(response: T.untyped, error: T.nilable(Exception)).void }
73
- def initialize(response:, error: nil)
74
- @response = response
75
- @error = error
78
+ sig { params(id: Integer, method: String, params: Object).void }
79
+ def initialize(id:, method:, params:)
80
+ @id = id
81
+ super(method: method, params: params)
82
+ end
83
+
84
+ sig { override.returns(T::Hash[Symbol, T.untyped]) }
85
+ def to_hash
86
+ { id: @id, method: @method, params: T.unsafe(@params).to_hash }
76
87
  end
77
88
  end
78
89
 
79
- # A request that will sit in the queue until it's executed
80
- class Job
90
+ class Error
81
91
  extend T::Sig
82
92
 
93
+ sig { returns(String) }
94
+ attr_reader :message
95
+
96
+ sig { params(id: Integer, code: Integer, message: String, data: T.nilable(T::Hash[Symbol, T.untyped])).void }
97
+ def initialize(id:, code:, message:, data: nil)
98
+ @id = id
99
+ @code = code
100
+ @message = message
101
+ @data = data
102
+ end
103
+
83
104
  sig { returns(T::Hash[Symbol, T.untyped]) }
84
- attr_reader :request
105
+ def to_hash
106
+ {
107
+ id: @id,
108
+ error: {
109
+ code: @code,
110
+ message: @message,
111
+ data: @data,
112
+ },
113
+ }
114
+ end
115
+ end
85
116
 
86
- sig { returns(T::Boolean) }
87
- attr_reader :cancelled
117
+ # The final result of running a request before its IO is finalized
118
+ class Result
119
+ extend T::Sig
88
120
 
89
- sig { params(request: T::Hash[Symbol, T.untyped], cancelled: T::Boolean).void }
90
- def initialize(request:, cancelled:)
91
- @request = request
92
- @cancelled = cancelled
121
+ sig { returns(T.untyped) }
122
+ attr_reader :response
123
+
124
+ sig { params(id: Integer, response: T.untyped).void }
125
+ def initialize(id:, response:)
126
+ @id = id
127
+ @response = response
93
128
  end
94
129
 
95
- sig { void }
96
- def cancel
97
- @cancelled = true
130
+ sig { returns(T::Hash[Symbol, T.untyped]) }
131
+ def to_hash
132
+ { id: @id, result: @response }
98
133
  end
99
134
  end
100
135
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-lsp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.6
4
+ version: 0.16.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-15 00:00:00.000000000 Z
11
+ date: 2024-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: language_server-protocol
@@ -93,9 +93,10 @@ files:
93
93
  - lib/ruby_indexer/test/prefix_tree_test.rb
94
94
  - lib/ruby_indexer/test/test_case.rb
95
95
  - lib/ruby_lsp/addon.rb
96
+ - lib/ruby_lsp/base_server.rb
96
97
  - lib/ruby_lsp/check_docs.rb
97
98
  - lib/ruby_lsp/document.rb
98
- - lib/ruby_lsp/executor.rb
99
+ - lib/ruby_lsp/global_state.rb
99
100
  - lib/ruby_lsp/internal.rb
100
101
  - lib/ruby_lsp/listeners/code_lens.rb
101
102
  - lib/ruby_lsp/listeners/completion.rb
@@ -108,12 +109,14 @@ files:
108
109
  - lib/ruby_lsp/listeners/inlay_hints.rb
109
110
  - lib/ruby_lsp/listeners/semantic_highlighting.rb
110
111
  - lib/ruby_lsp/listeners/signature_help.rb
112
+ - lib/ruby_lsp/load_sorbet.rb
111
113
  - lib/ruby_lsp/parameter_scope.rb
112
114
  - lib/ruby_lsp/requests.rb
113
115
  - lib/ruby_lsp/requests/code_action_resolve.rb
114
116
  - lib/ruby_lsp/requests/code_actions.rb
115
117
  - lib/ruby_lsp/requests/code_lens.rb
116
118
  - lib/ruby_lsp/requests/completion.rb
119
+ - lib/ruby_lsp/requests/completion_resolve.rb
117
120
  - lib/ruby_lsp/requests/definition.rb
118
121
  - lib/ruby_lsp/requests/diagnostics.rb
119
122
  - lib/ruby_lsp/requests/document_highlight.rb
@@ -131,16 +134,14 @@ files:
131
134
  - lib/ruby_lsp/requests/signature_help.rb
132
135
  - lib/ruby_lsp/requests/support/annotation.rb
133
136
  - lib/ruby_lsp/requests/support/common.rb
134
- - lib/ruby_lsp/requests/support/dependency_detector.rb
135
- - lib/ruby_lsp/requests/support/formatter_runner.rb
137
+ - lib/ruby_lsp/requests/support/formatter.rb
136
138
  - lib/ruby_lsp/requests/support/rubocop_diagnostic.rb
137
- - lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb
138
- - lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb
139
+ - lib/ruby_lsp/requests/support/rubocop_formatter.rb
139
140
  - lib/ruby_lsp/requests/support/rubocop_runner.rb
140
141
  - lib/ruby_lsp/requests/support/selection_range.rb
141
142
  - lib/ruby_lsp/requests/support/sorbet.rb
142
143
  - lib/ruby_lsp/requests/support/source_uri.rb
143
- - lib/ruby_lsp/requests/support/syntax_tree_formatting_runner.rb
144
+ - lib/ruby_lsp/requests/support/syntax_tree_formatter.rb
144
145
  - lib/ruby_lsp/requests/workspace_symbol.rb
145
146
  - lib/ruby_lsp/response_builders.rb
146
147
  - lib/ruby_lsp/response_builders/collection_response_builder.rb
@@ -153,6 +154,7 @@ files:
153
154
  - lib/ruby_lsp/server.rb
154
155
  - lib/ruby_lsp/setup_bundler.rb
155
156
  - lib/ruby_lsp/store.rb
157
+ - lib/ruby_lsp/test_helper.rb
156
158
  - lib/ruby_lsp/utils.rb
157
159
  homepage: https://github.com/Shopify/ruby-lsp
158
160
  licenses:
@@ -175,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
177
  - !ruby/object:Gem::Version
176
178
  version: '0'
177
179
  requirements: []
178
- rubygems_version: 3.5.6
180
+ rubygems_version: 3.5.7
179
181
  signing_key:
180
182
  specification_version: 4
181
183
  summary: An opinionated language server for Ruby