ruby-lsp 0.23.11 → 0.26.1
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 +4 -4
- data/README.md +2 -2
- data/VERSION +1 -1
- data/exe/ruby-lsp +10 -4
- data/exe/ruby-lsp-check +0 -4
- data/exe/ruby-lsp-launcher +45 -22
- data/exe/ruby-lsp-test-exec +6 -0
- data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -2
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -6
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +82 -116
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +140 -183
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +10 -14
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +107 -236
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +166 -281
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +23 -27
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +25 -57
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +58 -68
- data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +17 -19
- data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +7 -11
- data/lib/ruby_indexer/test/class_variables_test.rb +14 -14
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +65 -40
- data/lib/ruby_indexer/test/configuration_test.rb +49 -9
- data/lib/ruby_indexer/test/constant_test.rb +34 -34
- data/lib/ruby_indexer/test/enhancements_test.rb +1 -1
- data/lib/ruby_indexer/test/index_test.rb +185 -135
- data/lib/ruby_indexer/test/instance_variables_test.rb +61 -37
- data/lib/ruby_indexer/test/method_test.rb +166 -123
- data/lib/ruby_indexer/test/prefix_tree_test.rb +21 -21
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +70 -75
- data/lib/ruby_indexer/test/reference_finder_test.rb +79 -14
- data/lib/ruby_indexer/test/test_case.rb +9 -3
- data/lib/ruby_indexer/test/uri_test.rb +15 -2
- data/lib/ruby_lsp/addon.rb +88 -86
- data/lib/ruby_lsp/base_server.rb +59 -54
- data/lib/ruby_lsp/client_capabilities.rb +16 -13
- data/lib/ruby_lsp/document.rb +205 -104
- data/lib/ruby_lsp/erb_document.rb +45 -47
- data/lib/ruby_lsp/global_state.rb +73 -57
- data/lib/ruby_lsp/internal.rb +8 -3
- data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
- data/lib/ruby_lsp/listeners/completion.rb +81 -76
- data/lib/ruby_lsp/listeners/definition.rb +44 -58
- data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
- data/lib/ruby_lsp/listeners/document_link.rb +50 -70
- data/lib/ruby_lsp/listeners/document_symbol.rb +38 -52
- data/lib/ruby_lsp/listeners/folding_ranges.rb +40 -43
- data/lib/ruby_lsp/listeners/hover.rb +107 -115
- data/lib/ruby_lsp/listeners/inlay_hints.rb +8 -13
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
- data/lib/ruby_lsp/listeners/signature_help.rb +12 -27
- data/lib/ruby_lsp/listeners/spec_style.rb +214 -0
- data/lib/ruby_lsp/listeners/test_discovery.rb +92 -0
- data/lib/ruby_lsp/listeners/test_style.rb +205 -95
- data/lib/ruby_lsp/node_context.rb +12 -39
- data/lib/ruby_lsp/rbs_document.rb +10 -11
- data/lib/ruby_lsp/requests/code_action_resolve.rb +65 -61
- data/lib/ruby_lsp/requests/code_actions.rb +14 -26
- data/lib/ruby_lsp/requests/code_lens.rb +31 -21
- data/lib/ruby_lsp/requests/completion.rb +8 -21
- data/lib/ruby_lsp/requests/completion_resolve.rb +6 -6
- data/lib/ruby_lsp/requests/definition.rb +8 -20
- data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
- data/lib/ruby_lsp/requests/discover_tests.rb +20 -7
- data/lib/ruby_lsp/requests/document_highlight.rb +6 -16
- data/lib/ruby_lsp/requests/document_link.rb +6 -17
- data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
- data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
- data/lib/ruby_lsp/requests/formatting.rb +6 -9
- data/lib/ruby_lsp/requests/go_to_relevant_file.rb +85 -0
- data/lib/ruby_lsp/requests/hover.rb +12 -25
- data/lib/ruby_lsp/requests/inlay_hints.rb +8 -19
- data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
- data/lib/ruby_lsp/requests/prepare_rename.rb +5 -10
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +5 -15
- data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
- data/lib/ruby_lsp/requests/references.rb +17 -57
- data/lib/ruby_lsp/requests/rename.rb +27 -51
- data/lib/ruby_lsp/requests/request.rb +13 -25
- data/lib/ruby_lsp/requests/selection_ranges.rb +7 -7
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +16 -35
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +7 -8
- data/lib/ruby_lsp/requests/signature_help.rb +9 -27
- data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
- data/lib/ruby_lsp/requests/support/common.rb +16 -58
- data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +13 -16
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +34 -36
- data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
- data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
- data/lib/ruby_lsp/requests/support/source_uri.rb +20 -32
- data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
- data/lib/ruby_lsp/requests/support/test_item.rb +16 -14
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
- data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
- data/lib/ruby_lsp/response_builders/collection_response_builder.rb +6 -9
- data/lib/ruby_lsp/response_builders/document_symbol.rb +15 -21
- data/lib/ruby_lsp/response_builders/hover.rb +12 -18
- data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +62 -91
- data/lib/ruby_lsp/response_builders/signature_help.rb +6 -8
- data/lib/ruby_lsp/response_builders/test_collection.rb +35 -13
- data/lib/ruby_lsp/ruby_document.rb +32 -98
- data/lib/ruby_lsp/scope.rb +7 -11
- data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
- data/lib/ruby_lsp/server.rb +303 -196
- data/lib/ruby_lsp/setup_bundler.rb +121 -82
- data/lib/ruby_lsp/static_docs.rb +12 -7
- data/lib/ruby_lsp/store.rb +21 -49
- data/lib/ruby_lsp/test_helper.rb +3 -16
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +233 -0
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +145 -0
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +92 -0
- data/lib/ruby_lsp/type_inferrer.rb +13 -14
- data/lib/ruby_lsp/utils.rb +138 -93
- data/static_docs/break.md +103 -0
- metadata +14 -20
- data/lib/ruby_lsp/load_sorbet.rb +0 -62
data/lib/ruby_lsp/utils.rb
CHANGED
@@ -5,27 +5,21 @@ module RubyLsp
|
|
5
5
|
# rubocop:disable RubyLsp/UseLanguageServerAliases
|
6
6
|
Interface = LanguageServer::Protocol::Interface
|
7
7
|
Constant = LanguageServer::Protocol::Constant
|
8
|
-
Transport = LanguageServer::Protocol::Transport
|
9
8
|
# rubocop:enable RubyLsp/UseLanguageServerAliases
|
10
9
|
|
11
10
|
# Used to indicate that a request shouldn't return a response
|
12
|
-
BUNDLE_PATH =
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
Bundler.with_original_env { Bundler.default_gemfile.basename.to_s }
|
23
|
-
rescue Bundler::GemfileNotFound
|
24
|
-
"Gemfile"
|
25
|
-
end,
|
26
|
-
String,
|
27
|
-
)
|
11
|
+
BUNDLE_PATH = begin
|
12
|
+
Bundler.bundle_path.to_s
|
13
|
+
rescue Bundler::GemfileNotFound
|
14
|
+
nil
|
15
|
+
end #: String?
|
16
|
+
GEMFILE_NAME = begin
|
17
|
+
Bundler.with_original_env { Bundler.default_gemfile.basename.to_s }
|
18
|
+
rescue Bundler::GemfileNotFound
|
19
|
+
"Gemfile"
|
20
|
+
end #: String
|
28
21
|
GUESSED_TYPES_URL = "https://shopify.github.io/ruby-lsp/#guessed-types"
|
22
|
+
TEST_PATH_PATTERN = "**/{test,spec,features}/**/{*_test.rb,test_*.rb,*_spec.rb,*.feature}"
|
29
23
|
|
30
24
|
# Request delegation for embedded languages is not yet standardized into the language server specification. Here we
|
31
25
|
# use this custom error class as a way to return a signal to the client that the request should be delegated to the
|
@@ -37,36 +31,35 @@ module RubyLsp
|
|
37
31
|
CODE = -32900
|
38
32
|
end
|
39
33
|
|
34
|
+
class AbstractMethodInvokedError < StandardError; end
|
35
|
+
|
40
36
|
BUNDLE_COMPOSE_FAILED_CODE = -33000
|
41
37
|
|
42
38
|
# A notification to be sent to the client
|
39
|
+
# @abstract
|
43
40
|
class Message
|
44
|
-
|
45
|
-
extend T::Helpers
|
46
|
-
|
47
|
-
sig { returns(String) }
|
41
|
+
#: String
|
48
42
|
attr_reader :method
|
49
43
|
|
50
|
-
|
44
|
+
#: Object
|
51
45
|
attr_reader :params
|
52
46
|
|
53
|
-
|
54
|
-
|
55
|
-
sig { params(method: String, params: Object).void }
|
47
|
+
#: (method: String, params: Object) -> void
|
56
48
|
def initialize(method:, params:)
|
57
49
|
@method = method
|
58
50
|
@params = params
|
59
51
|
end
|
60
52
|
|
61
|
-
|
62
|
-
|
53
|
+
# @abstract
|
54
|
+
#: -> Hash[Symbol, untyped]
|
55
|
+
def to_hash
|
56
|
+
raise AbstractMethodInvokedError
|
57
|
+
end
|
63
58
|
end
|
64
59
|
|
65
60
|
class Notification < Message
|
66
61
|
class << self
|
67
|
-
|
68
|
-
|
69
|
-
sig { params(message: String, type: Integer).returns(Notification) }
|
62
|
+
#: (String message, ?type: Integer) -> Notification
|
70
63
|
def window_show_message(message, type: Constant::MessageType::INFO)
|
71
64
|
new(
|
72
65
|
method: "window/showMessage",
|
@@ -74,7 +67,7 @@ module RubyLsp
|
|
74
67
|
)
|
75
68
|
end
|
76
69
|
|
77
|
-
|
70
|
+
#: (String message, ?type: Integer) -> Notification
|
78
71
|
def window_log_message(message, type: Constant::MessageType::LOG)
|
79
72
|
new(
|
80
73
|
method: "window/logMessage",
|
@@ -82,7 +75,7 @@ module RubyLsp
|
|
82
75
|
)
|
83
76
|
end
|
84
77
|
|
85
|
-
|
78
|
+
#: (Hash[Symbol, untyped] data) -> Notification
|
86
79
|
def telemetry(data)
|
87
80
|
new(
|
88
81
|
method: "telemetry/event",
|
@@ -90,14 +83,7 @@ module RubyLsp
|
|
90
83
|
)
|
91
84
|
end
|
92
85
|
|
93
|
-
|
94
|
-
params(
|
95
|
-
id: String,
|
96
|
-
title: String,
|
97
|
-
percentage: T.nilable(Integer),
|
98
|
-
message: T.nilable(String),
|
99
|
-
).returns(Notification)
|
100
|
-
end
|
86
|
+
#: (String id, String title, ?percentage: Integer?, ?message: String?) -> Notification
|
101
87
|
def progress_begin(id, title, percentage: nil, message: nil)
|
102
88
|
new(
|
103
89
|
method: "$/progress",
|
@@ -113,13 +99,7 @@ module RubyLsp
|
|
113
99
|
)
|
114
100
|
end
|
115
101
|
|
116
|
-
|
117
|
-
params(
|
118
|
-
id: String,
|
119
|
-
percentage: T.nilable(Integer),
|
120
|
-
message: T.nilable(String),
|
121
|
-
).returns(Notification)
|
122
|
-
end
|
102
|
+
#: (String id, ?percentage: Integer?, ?message: String?) -> Notification
|
123
103
|
def progress_report(id, percentage: nil, message: nil)
|
124
104
|
new(
|
125
105
|
method: "$/progress",
|
@@ -134,7 +114,7 @@ module RubyLsp
|
|
134
114
|
)
|
135
115
|
end
|
136
116
|
|
137
|
-
|
117
|
+
#: (String id) -> Notification
|
138
118
|
def progress_end(id)
|
139
119
|
Notification.new(
|
140
120
|
method: "$/progress",
|
@@ -145,13 +125,7 @@ module RubyLsp
|
|
145
125
|
)
|
146
126
|
end
|
147
127
|
|
148
|
-
|
149
|
-
params(
|
150
|
-
uri: String,
|
151
|
-
diagnostics: T::Array[Interface::Diagnostic],
|
152
|
-
version: T.nilable(Integer),
|
153
|
-
).returns(Notification)
|
154
|
-
end
|
128
|
+
#: (String uri, Array[Interface::Diagnostic] diagnostics, ?version: Integer?) -> Notification
|
155
129
|
def publish_diagnostics(uri, diagnostics, version: nil)
|
156
130
|
new(
|
157
131
|
method: "textDocument/publishDiagnostics",
|
@@ -160,30 +134,23 @@ module RubyLsp
|
|
160
134
|
end
|
161
135
|
end
|
162
136
|
|
163
|
-
|
164
|
-
|
165
|
-
sig { override.returns(T::Hash[Symbol, T.untyped]) }
|
137
|
+
# @override
|
138
|
+
#: -> Hash[Symbol, untyped]
|
166
139
|
def to_hash
|
167
140
|
hash = { method: @method }
|
168
|
-
|
141
|
+
|
142
|
+
if @params
|
143
|
+
hash[:params] = @params #: as untyped
|
144
|
+
.to_hash
|
145
|
+
end
|
146
|
+
|
169
147
|
hash
|
170
148
|
end
|
171
149
|
end
|
172
150
|
|
173
151
|
class Request < Message
|
174
|
-
extend T::Sig
|
175
|
-
|
176
152
|
class << self
|
177
|
-
|
178
|
-
|
179
|
-
sig do
|
180
|
-
params(
|
181
|
-
id: Integer,
|
182
|
-
pattern: T.any(Interface::RelativePattern, String),
|
183
|
-
kind: Integer,
|
184
|
-
registration_id: T.nilable(String),
|
185
|
-
).returns(Request)
|
186
|
-
end
|
153
|
+
#: (Integer id, (Interface::RelativePattern | String) pattern, ?kind: Integer, ?registration_id: String?) -> Request
|
187
154
|
def register_watched_files(
|
188
155
|
id,
|
189
156
|
pattern,
|
@@ -210,30 +177,34 @@ module RubyLsp
|
|
210
177
|
end
|
211
178
|
end
|
212
179
|
|
213
|
-
|
180
|
+
#: (id: (Integer | String), method: String, params: Object) -> void
|
214
181
|
def initialize(id:, method:, params:)
|
215
182
|
@id = id
|
216
183
|
super(method: method, params: params)
|
217
184
|
end
|
218
185
|
|
219
|
-
|
186
|
+
# @override
|
187
|
+
#: -> Hash[Symbol, untyped]
|
220
188
|
def to_hash
|
221
189
|
hash = { id: @id, method: @method }
|
222
|
-
|
190
|
+
|
191
|
+
if @params
|
192
|
+
hash[:params] = @params #: as untyped
|
193
|
+
.to_hash
|
194
|
+
end
|
195
|
+
|
223
196
|
hash
|
224
197
|
end
|
225
198
|
end
|
226
199
|
|
227
200
|
class Error
|
228
|
-
|
229
|
-
|
230
|
-
sig { returns(String) }
|
201
|
+
#: String
|
231
202
|
attr_reader :message
|
232
203
|
|
233
|
-
|
204
|
+
#: Integer
|
234
205
|
attr_reader :code
|
235
206
|
|
236
|
-
|
207
|
+
#: (id: Integer, code: Integer, message: String, ?data: Hash[Symbol, untyped]?) -> void
|
237
208
|
def initialize(id:, code:, message:, data: nil)
|
238
209
|
@id = id
|
239
210
|
@code = code
|
@@ -241,7 +212,7 @@ module RubyLsp
|
|
241
212
|
@data = data
|
242
213
|
end
|
243
214
|
|
244
|
-
|
215
|
+
#: -> Hash[Symbol, untyped]
|
245
216
|
def to_hash
|
246
217
|
{
|
247
218
|
id: @id,
|
@@ -256,21 +227,19 @@ module RubyLsp
|
|
256
227
|
|
257
228
|
# The final result of running a request before its IO is finalized
|
258
229
|
class Result
|
259
|
-
|
260
|
-
|
261
|
-
sig { returns(T.untyped) }
|
230
|
+
#: untyped
|
262
231
|
attr_reader :response
|
263
232
|
|
264
|
-
|
233
|
+
#: Integer
|
265
234
|
attr_reader :id
|
266
235
|
|
267
|
-
|
236
|
+
#: (id: Integer, response: untyped) -> void
|
268
237
|
def initialize(id:, response:)
|
269
238
|
@id = id
|
270
239
|
@response = response
|
271
240
|
end
|
272
241
|
|
273
|
-
|
242
|
+
#: -> Hash[Symbol, untyped]
|
274
243
|
def to_hash
|
275
244
|
{ id: @id, result: @response }
|
276
245
|
end
|
@@ -278,19 +247,95 @@ module RubyLsp
|
|
278
247
|
|
279
248
|
# A request configuration, to turn on/off features
|
280
249
|
class RequestConfig
|
281
|
-
|
282
|
-
|
283
|
-
sig { returns(T::Hash[Symbol, T::Boolean]) }
|
284
|
-
attr_accessor :configuration
|
285
|
-
|
286
|
-
sig { params(configuration: T::Hash[Symbol, T::Boolean]).void }
|
250
|
+
#: (Hash[Symbol, bool] configuration) -> void
|
287
251
|
def initialize(configuration)
|
288
252
|
@configuration = configuration
|
289
253
|
end
|
290
254
|
|
291
|
-
|
255
|
+
#: (Symbol feature) -> bool?
|
292
256
|
def enabled?(feature)
|
293
257
|
@configuration[:enableAll] || @configuration[feature]
|
294
258
|
end
|
259
|
+
|
260
|
+
#: (Hash[Symbol, bool]) -> void
|
261
|
+
def merge!(hash)
|
262
|
+
@configuration.merge!(hash)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
class SorbetLevel
|
267
|
+
class << self
|
268
|
+
#: -> SorbetLevel
|
269
|
+
def ignore
|
270
|
+
new("ignore")
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
#: (String?) -> void
|
275
|
+
def initialize(sigil)
|
276
|
+
@level = case sigil
|
277
|
+
when "ignore"
|
278
|
+
:ignore
|
279
|
+
when "false"
|
280
|
+
:false
|
281
|
+
when "true"
|
282
|
+
:true
|
283
|
+
when "strict", "strong"
|
284
|
+
:strict
|
285
|
+
else
|
286
|
+
:none
|
287
|
+
end #: Symbol
|
288
|
+
end
|
289
|
+
|
290
|
+
#: -> bool
|
291
|
+
def ignore? = @level == :ignore
|
292
|
+
|
293
|
+
#: -> bool
|
294
|
+
def false? = @level == :false
|
295
|
+
|
296
|
+
#: -> bool
|
297
|
+
def true? = @level == :true
|
298
|
+
|
299
|
+
#: -> bool
|
300
|
+
def strict? = @level == :strict
|
301
|
+
|
302
|
+
#: -> bool
|
303
|
+
def none? = @level == :none
|
304
|
+
|
305
|
+
#: -> bool
|
306
|
+
def true_or_higher? = @level == :true || @level == :strict
|
307
|
+
end
|
308
|
+
|
309
|
+
# Reads JSON RPC messages from the given IO in a loop
|
310
|
+
class MessageReader
|
311
|
+
#: (IO) -> void
|
312
|
+
def initialize(io)
|
313
|
+
@io = io
|
314
|
+
end
|
315
|
+
|
316
|
+
#: () { (Hash[Symbol, untyped]) -> void } -> void
|
317
|
+
def each_message(&block)
|
318
|
+
while (headers = @io.gets("\r\n\r\n"))
|
319
|
+
raw_message = @io.read(headers[/Content-Length: (\d+)/i, 1].to_i) #: as !nil
|
320
|
+
block.call(JSON.parse(raw_message, symbolize_names: true))
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
# Writes JSON RPC messages to the given IO
|
326
|
+
class MessageWriter
|
327
|
+
#: (IO) -> void
|
328
|
+
def initialize(io)
|
329
|
+
@io = io
|
330
|
+
end
|
331
|
+
|
332
|
+
#: (Hash[Symbol, untyped]) -> void
|
333
|
+
def write(message)
|
334
|
+
message[:jsonrpc] = "2.0"
|
335
|
+
json_message = message.to_json
|
336
|
+
|
337
|
+
@io.write("Content-Length: #{json_message.bytesize}\r\n\r\n#{json_message}")
|
338
|
+
@io.flush
|
339
|
+
end
|
295
340
|
end
|
296
341
|
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# Break
|
2
|
+
|
3
|
+
In Ruby, the `break` keyword is used to exit a loop or block prematurely. Unlike `next` which skips to the next iteration, `break` terminates the loop entirely and continues with the code after the loop.
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
# Basic break usage in a loop
|
7
|
+
5.times do |i|
|
8
|
+
break if i == 3
|
9
|
+
|
10
|
+
puts i
|
11
|
+
end
|
12
|
+
# Output:
|
13
|
+
# 0
|
14
|
+
# 1
|
15
|
+
# 2
|
16
|
+
```
|
17
|
+
|
18
|
+
The `break` statement can be used with any of Ruby's iteration methods or loops.
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
array = [1, 2, 3, 4, 5]
|
22
|
+
|
23
|
+
# Break in each iteration
|
24
|
+
array.each do |num|
|
25
|
+
break if num > 3
|
26
|
+
|
27
|
+
puts "Number: #{num}"
|
28
|
+
end
|
29
|
+
# Output:
|
30
|
+
# Number: 1
|
31
|
+
# Number: 2
|
32
|
+
# Number: 3
|
33
|
+
|
34
|
+
# Break in an infinite loop
|
35
|
+
count = 0
|
36
|
+
loop do
|
37
|
+
count += 1
|
38
|
+
break if count >= 3
|
39
|
+
|
40
|
+
puts "Count: #{count}"
|
41
|
+
end
|
42
|
+
# Output:
|
43
|
+
# Count: 1
|
44
|
+
# Count: 2
|
45
|
+
```
|
46
|
+
|
47
|
+
## Break with a Value
|
48
|
+
|
49
|
+
When used inside a block, `break` can return a value that becomes the result of the method call.
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
# Break with a return value in map
|
53
|
+
result = [1, 2, 3, 4, 5].map do |num|
|
54
|
+
break "Too large!" if num > 3
|
55
|
+
|
56
|
+
num * 2
|
57
|
+
end
|
58
|
+
puts result # Output: "Too large!"
|
59
|
+
|
60
|
+
# Break with a value in find
|
61
|
+
number = (1..10).find do |n|
|
62
|
+
break n if n > 5 && n.even?
|
63
|
+
end
|
64
|
+
puts number # Output: 6
|
65
|
+
```
|
66
|
+
|
67
|
+
## Break in Nested Loops
|
68
|
+
|
69
|
+
When using `break` in nested loops, it only exits the innermost loop. To break from nested loops, you typically need to use a flag or return.
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
# Break in nested iteration
|
73
|
+
(1..3).each do |i|
|
74
|
+
puts "Outer: #{i}"
|
75
|
+
|
76
|
+
(1..3).each do |j|
|
77
|
+
break if j == 2
|
78
|
+
|
79
|
+
puts " Inner: #{j}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
# Output:
|
83
|
+
# Outer: 1
|
84
|
+
# Inner: 1
|
85
|
+
# Outer: 2
|
86
|
+
# Inner: 1
|
87
|
+
# Outer: 3
|
88
|
+
# Inner: 1
|
89
|
+
|
90
|
+
# Breaking from nested loops with a flag
|
91
|
+
found = false
|
92
|
+
(1..3).each do |i|
|
93
|
+
(1..3).each do |j|
|
94
|
+
if i * j == 4
|
95
|
+
found = true
|
96
|
+
break
|
97
|
+
end
|
98
|
+
end
|
99
|
+
break if found
|
100
|
+
end
|
101
|
+
```
|
102
|
+
|
103
|
+
The `break` keyword is essential for controlling loop execution and implementing early exit conditions. It's particularly useful when you've found what you're looking for and don't need to continue iterating.
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lsp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.26.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: language_server-protocol
|
@@ -52,7 +52,7 @@ dependencies:
|
|
52
52
|
version: '3'
|
53
53
|
- - "<"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
55
|
+
version: '5'
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
58
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -62,21 +62,7 @@ dependencies:
|
|
62
62
|
version: '3'
|
63
63
|
- - "<"
|
64
64
|
- !ruby/object:Gem::Version
|
65
|
-
version: '
|
66
|
-
- !ruby/object:Gem::Dependency
|
67
|
-
name: sorbet-runtime
|
68
|
-
requirement: !ruby/object:Gem::Requirement
|
69
|
-
requirements:
|
70
|
-
- - ">="
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
version: 0.5.10782
|
73
|
-
type: :runtime
|
74
|
-
prerelease: false
|
75
|
-
version_requirements: !ruby/object:Gem::Requirement
|
76
|
-
requirements:
|
77
|
-
- - ">="
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
version: 0.5.10782
|
65
|
+
version: '5'
|
80
66
|
description: An opinionated language server for Ruby
|
81
67
|
email:
|
82
68
|
- ruby@shopify.com
|
@@ -84,6 +70,7 @@ executables:
|
|
84
70
|
- ruby-lsp
|
85
71
|
- ruby-lsp-check
|
86
72
|
- ruby-lsp-launcher
|
73
|
+
- ruby-lsp-test-exec
|
87
74
|
extensions: []
|
88
75
|
extra_rdoc_files: []
|
89
76
|
files:
|
@@ -93,6 +80,7 @@ files:
|
|
93
80
|
- exe/ruby-lsp
|
94
81
|
- exe/ruby-lsp-check
|
95
82
|
- exe/ruby-lsp-launcher
|
83
|
+
- exe/ruby-lsp-test-exec
|
96
84
|
- lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb
|
97
85
|
- lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb
|
98
86
|
- lib/ruby-lsp.rb
|
@@ -140,8 +128,9 @@ files:
|
|
140
128
|
- lib/ruby_lsp/listeners/inlay_hints.rb
|
141
129
|
- lib/ruby_lsp/listeners/semantic_highlighting.rb
|
142
130
|
- lib/ruby_lsp/listeners/signature_help.rb
|
131
|
+
- lib/ruby_lsp/listeners/spec_style.rb
|
132
|
+
- lib/ruby_lsp/listeners/test_discovery.rb
|
143
133
|
- lib/ruby_lsp/listeners/test_style.rb
|
144
|
-
- lib/ruby_lsp/load_sorbet.rb
|
145
134
|
- lib/ruby_lsp/node_context.rb
|
146
135
|
- lib/ruby_lsp/rbs_document.rb
|
147
136
|
- lib/ruby_lsp/requests/code_action_resolve.rb
|
@@ -157,6 +146,7 @@ files:
|
|
157
146
|
- lib/ruby_lsp/requests/document_symbol.rb
|
158
147
|
- lib/ruby_lsp/requests/folding_ranges.rb
|
159
148
|
- lib/ruby_lsp/requests/formatting.rb
|
149
|
+
- lib/ruby_lsp/requests/go_to_relevant_file.rb
|
160
150
|
- lib/ruby_lsp/requests/hover.rb
|
161
151
|
- lib/ruby_lsp/requests/inlay_hints.rb
|
162
152
|
- lib/ruby_lsp/requests/on_type_formatting.rb
|
@@ -199,8 +189,12 @@ files:
|
|
199
189
|
- lib/ruby_lsp/static_docs.rb
|
200
190
|
- lib/ruby_lsp/store.rb
|
201
191
|
- lib/ruby_lsp/test_helper.rb
|
192
|
+
- lib/ruby_lsp/test_reporters/lsp_reporter.rb
|
193
|
+
- lib/ruby_lsp/test_reporters/minitest_reporter.rb
|
194
|
+
- lib/ruby_lsp/test_reporters/test_unit_reporter.rb
|
202
195
|
- lib/ruby_lsp/type_inferrer.rb
|
203
196
|
- lib/ruby_lsp/utils.rb
|
197
|
+
- static_docs/break.md
|
204
198
|
- static_docs/yield.md
|
205
199
|
homepage: https://github.com/Shopify/ruby-lsp
|
206
200
|
licenses:
|
@@ -222,7 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
216
|
- !ruby/object:Gem::Version
|
223
217
|
version: '0'
|
224
218
|
requirements: []
|
225
|
-
rubygems_version: 3.6.
|
219
|
+
rubygems_version: 3.6.9
|
226
220
|
specification_version: 4
|
227
221
|
summary: An opinionated language server for Ruby
|
228
222
|
test_files: []
|
data/lib/ruby_lsp/load_sorbet.rb
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
# typed: true
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "sorbet-runtime"
|
5
|
-
|
6
|
-
begin
|
7
|
-
T::Configuration.default_checked_level = :never
|
8
|
-
# Suppresses call validation errors
|
9
|
-
T::Configuration.call_validation_error_handler = ->(*arg) {}
|
10
|
-
# Suppresses errors caused by T.cast, T.let, T.must, etc.
|
11
|
-
T::Configuration.inline_type_error_handler = ->(*arg) {}
|
12
|
-
# Suppresses errors caused by incorrect parameter ordering
|
13
|
-
T::Configuration.sig_validation_error_handler = ->(*arg) {}
|
14
|
-
rescue
|
15
|
-
# Need this rescue so that if another gem has
|
16
|
-
# already set the checked level by the time we
|
17
|
-
# get to it, we don't fail outright.
|
18
|
-
nil
|
19
|
-
end
|
20
|
-
|
21
|
-
module RubyLsp
|
22
|
-
# No-op all inline type assertions defined in T
|
23
|
-
module InlineTypeAssertions
|
24
|
-
def absurd(value)
|
25
|
-
value
|
26
|
-
end
|
27
|
-
|
28
|
-
def any(type_a, type_b, *types)
|
29
|
-
T::Types::Union.new([type_a, type_b, *types])
|
30
|
-
end
|
31
|
-
|
32
|
-
def assert_type!(value, type, checked: true)
|
33
|
-
value
|
34
|
-
end
|
35
|
-
|
36
|
-
def bind(value, type, checked: true)
|
37
|
-
value
|
38
|
-
end
|
39
|
-
|
40
|
-
def cast(value, type, checked: true)
|
41
|
-
value
|
42
|
-
end
|
43
|
-
|
44
|
-
def let(value, type, checked: true)
|
45
|
-
value
|
46
|
-
end
|
47
|
-
|
48
|
-
def must(arg)
|
49
|
-
arg
|
50
|
-
end
|
51
|
-
|
52
|
-
def nilable(type)
|
53
|
-
T::Types::Union.new([type, T::Utils::Nilable::NIL_TYPE])
|
54
|
-
end
|
55
|
-
|
56
|
-
def unsafe(value)
|
57
|
-
value
|
58
|
-
end
|
59
|
-
|
60
|
-
T.singleton_class.prepend(self)
|
61
|
-
end
|
62
|
-
end
|