ruby-lsp 0.14.6 → 0.16.5

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 (56) 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 +32 -8
  10. data/lib/ruby_indexer/lib/ruby_indexer/location.rb +26 -0
  11. data/lib/ruby_indexer/ruby_indexer.rb +1 -0
  12. data/lib/ruby_indexer/test/classes_and_modules_test.rb +46 -0
  13. data/lib/ruby_indexer/test/configuration_test.rb +2 -11
  14. data/lib/ruby_lsp/addon.rb +18 -9
  15. data/lib/ruby_lsp/base_server.rb +149 -0
  16. data/lib/ruby_lsp/document.rb +6 -11
  17. data/lib/ruby_lsp/global_state.rb +180 -0
  18. data/lib/ruby_lsp/internal.rb +4 -1
  19. data/lib/ruby_lsp/listeners/code_lens.rb +22 -13
  20. data/lib/ruby_lsp/listeners/completion.rb +13 -14
  21. data/lib/ruby_lsp/listeners/definition.rb +14 -6
  22. data/lib/ruby_lsp/listeners/document_symbol.rb +91 -3
  23. data/lib/ruby_lsp/listeners/hover.rb +6 -5
  24. data/lib/ruby_lsp/listeners/signature_help.rb +7 -4
  25. data/lib/ruby_lsp/load_sorbet.rb +62 -0
  26. data/lib/ruby_lsp/requests/code_lens.rb +3 -2
  27. data/lib/ruby_lsp/requests/completion.rb +15 -4
  28. data/lib/ruby_lsp/requests/completion_resolve.rb +56 -0
  29. data/lib/ruby_lsp/requests/definition.rb +11 -4
  30. data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
  31. data/lib/ruby_lsp/requests/document_symbol.rb +3 -3
  32. data/lib/ruby_lsp/requests/formatting.rb +7 -43
  33. data/lib/ruby_lsp/requests/hover.rb +4 -4
  34. data/lib/ruby_lsp/requests/request.rb +2 -0
  35. data/lib/ruby_lsp/requests/semantic_highlighting.rb +7 -4
  36. data/lib/ruby_lsp/requests/signature_help.rb +4 -3
  37. data/lib/ruby_lsp/requests/support/common.rb +16 -5
  38. data/lib/ruby_lsp/requests/support/formatter.rb +26 -0
  39. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +1 -1
  40. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +47 -0
  41. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +4 -0
  42. data/lib/ruby_lsp/requests/support/{syntax_tree_formatting_runner.rb → syntax_tree_formatter.rb} +13 -6
  43. data/lib/ruby_lsp/requests/workspace_symbol.rb +5 -4
  44. data/lib/ruby_lsp/requests.rb +3 -1
  45. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +36 -13
  46. data/lib/ruby_lsp/server.rb +763 -142
  47. data/lib/ruby_lsp/setup_bundler.rb +13 -1
  48. data/lib/ruby_lsp/store.rb +3 -15
  49. data/lib/ruby_lsp/test_helper.rb +52 -0
  50. data/lib/ruby_lsp/utils.rb +68 -33
  51. metadata +16 -13
  52. data/lib/ruby_lsp/executor.rb +0 -614
  53. data/lib/ruby_lsp/requests/support/dependency_detector.rb +0 -93
  54. data/lib/ruby_lsp/requests/support/formatter_runner.rb +0 -18
  55. data/lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb +0 -34
  56. 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: T.any(Integer, String), 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.5
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-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: language_server-protocol
@@ -30,20 +30,20 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.22.0
33
+ version: 0.23.0
34
34
  - - "<"
35
35
  - !ruby/object:Gem::Version
36
- version: '0.25'
36
+ version: '0.28'
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
- version: 0.22.0
43
+ version: 0.23.0
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
- version: '0.25'
46
+ version: '0.28'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: sorbet-runtime
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -83,6 +83,7 @@ files:
83
83
  - lib/ruby_indexer/lib/ruby_indexer/entry.rb
84
84
  - lib/ruby_indexer/lib/ruby_indexer/index.rb
85
85
  - lib/ruby_indexer/lib/ruby_indexer/indexable_path.rb
86
+ - lib/ruby_indexer/lib/ruby_indexer/location.rb
86
87
  - lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb
87
88
  - lib/ruby_indexer/ruby_indexer.rb
88
89
  - lib/ruby_indexer/test/classes_and_modules_test.rb
@@ -93,9 +94,10 @@ files:
93
94
  - lib/ruby_indexer/test/prefix_tree_test.rb
94
95
  - lib/ruby_indexer/test/test_case.rb
95
96
  - lib/ruby_lsp/addon.rb
97
+ - lib/ruby_lsp/base_server.rb
96
98
  - lib/ruby_lsp/check_docs.rb
97
99
  - lib/ruby_lsp/document.rb
98
- - lib/ruby_lsp/executor.rb
100
+ - lib/ruby_lsp/global_state.rb
99
101
  - lib/ruby_lsp/internal.rb
100
102
  - lib/ruby_lsp/listeners/code_lens.rb
101
103
  - lib/ruby_lsp/listeners/completion.rb
@@ -108,12 +110,14 @@ files:
108
110
  - lib/ruby_lsp/listeners/inlay_hints.rb
109
111
  - lib/ruby_lsp/listeners/semantic_highlighting.rb
110
112
  - lib/ruby_lsp/listeners/signature_help.rb
113
+ - lib/ruby_lsp/load_sorbet.rb
111
114
  - lib/ruby_lsp/parameter_scope.rb
112
115
  - lib/ruby_lsp/requests.rb
113
116
  - lib/ruby_lsp/requests/code_action_resolve.rb
114
117
  - lib/ruby_lsp/requests/code_actions.rb
115
118
  - lib/ruby_lsp/requests/code_lens.rb
116
119
  - lib/ruby_lsp/requests/completion.rb
120
+ - lib/ruby_lsp/requests/completion_resolve.rb
117
121
  - lib/ruby_lsp/requests/definition.rb
118
122
  - lib/ruby_lsp/requests/diagnostics.rb
119
123
  - lib/ruby_lsp/requests/document_highlight.rb
@@ -131,16 +135,14 @@ files:
131
135
  - lib/ruby_lsp/requests/signature_help.rb
132
136
  - lib/ruby_lsp/requests/support/annotation.rb
133
137
  - 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
138
+ - lib/ruby_lsp/requests/support/formatter.rb
136
139
  - 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
140
+ - lib/ruby_lsp/requests/support/rubocop_formatter.rb
139
141
  - lib/ruby_lsp/requests/support/rubocop_runner.rb
140
142
  - lib/ruby_lsp/requests/support/selection_range.rb
141
143
  - lib/ruby_lsp/requests/support/sorbet.rb
142
144
  - lib/ruby_lsp/requests/support/source_uri.rb
143
- - lib/ruby_lsp/requests/support/syntax_tree_formatting_runner.rb
145
+ - lib/ruby_lsp/requests/support/syntax_tree_formatter.rb
144
146
  - lib/ruby_lsp/requests/workspace_symbol.rb
145
147
  - lib/ruby_lsp/response_builders.rb
146
148
  - lib/ruby_lsp/response_builders/collection_response_builder.rb
@@ -153,6 +155,7 @@ files:
153
155
  - lib/ruby_lsp/server.rb
154
156
  - lib/ruby_lsp/setup_bundler.rb
155
157
  - lib/ruby_lsp/store.rb
158
+ - lib/ruby_lsp/test_helper.rb
156
159
  - lib/ruby_lsp/utils.rb
157
160
  homepage: https://github.com/Shopify/ruby-lsp
158
161
  licenses:
@@ -175,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
178
  - !ruby/object:Gem::Version
176
179
  version: '0'
177
180
  requirements: []
178
- rubygems_version: 3.5.6
181
+ rubygems_version: 3.5.9
179
182
  signing_key:
180
183
  specification_version: 4
181
184
  summary: An opinionated language server for Ruby