ruby-lsp 0.14.6 → 0.16.4

Sign up to get free protection for your applications and to get access to all the features.
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