ruby-lsp 0.18.3 → 0.18.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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +15 -5
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +8 -0
- data/lib/ruby_lsp/addon.rb +10 -10
- data/lib/ruby_lsp/base_server.rb +6 -0
- data/lib/ruby_lsp/internal.rb +1 -1
- data/lib/ruby_lsp/listeners/hover.rb +38 -0
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +24 -21
- data/lib/ruby_lsp/requests/on_type_formatting.rb +1 -1
- data/lib/ruby_lsp/requests/support/common.rb +2 -2
- data/lib/ruby_lsp/scope.rb +47 -0
- data/lib/ruby_lsp/server.rb +29 -24
- data/lib/ruby_lsp/utils.rb +3 -6
- metadata +3 -3
- data/lib/ruby_lsp/parameter_scope.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd64a8dbd26620a032266729f488c5ace69ead93e1cd8ae2677333d128bd72d4
|
4
|
+
data.tar.gz: a7489c2405509d8764750c5946036d19106db75b6609524117f763b6279f45d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dba4de24eca9cd3db51c94a2aef71c0b77e041172a5827d24b2a4b4079c41d955e0e990972258a6fd223766eedc20490f9af809da80ff46eb289a31d2fe2dbb7
|
7
|
+
data.tar.gz: 49922ea026fe43cd23bfece5b5e1f6c10838dfe6e80a24c1dc5bd184d359361459af94083f773c86ce45f392ab4750f242a512136d367b8ccd95125ff13d42a9
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.18.
|
1
|
+
0.18.4
|
@@ -139,13 +139,23 @@ module RubyIndexer
|
|
139
139
|
|
140
140
|
sig { params(overload: RBS::AST::Members::MethodDefinition::Overload).returns(T::Array[Entry::Parameter]) }
|
141
141
|
def process_overload(overload)
|
142
|
-
function =
|
143
|
-
parameters = parse_arguments(function)
|
142
|
+
function = overload.method_type.type
|
144
143
|
|
145
|
-
|
146
|
-
|
144
|
+
if function.is_a?(RBS::Types::Function)
|
145
|
+
parameters = parse_arguments(function)
|
147
146
|
|
148
|
-
|
147
|
+
block = overload.method_type.block
|
148
|
+
parameters << Entry::BlockParameter.anonymous if block&.required
|
149
|
+
return parameters
|
150
|
+
end
|
151
|
+
|
152
|
+
# Untyped functions are a new RBS feature (since v3.6.0) to declare methods that accept any parameters. For our
|
153
|
+
# purposes, accepting any argument is equivalent to `...`
|
154
|
+
if defined?(RBS::Types::UntypedFunction) && function.is_a?(RBS::Types::UntypedFunction)
|
155
|
+
[Entry::ForwardingParameter.new]
|
156
|
+
else
|
157
|
+
[]
|
158
|
+
end
|
149
159
|
end
|
150
160
|
|
151
161
|
sig { params(function: RBS::Types::Function).returns(T::Array[Entry::Parameter]) }
|
@@ -348,6 +348,14 @@ module RubyIndexer
|
|
348
348
|
assert_includes(entry.comments, "Returns `true` if any element of `self` meets a given criterion.")
|
349
349
|
end
|
350
350
|
|
351
|
+
def test_indexing_untyped_functions
|
352
|
+
entries = @index.resolve_method("call", "Method")
|
353
|
+
|
354
|
+
parameters = entries.first.signatures.first.parameters
|
355
|
+
assert_equal(1, parameters.length)
|
356
|
+
assert_instance_of(Entry::ForwardingParameter, parameters.first)
|
357
|
+
end
|
358
|
+
|
351
359
|
private
|
352
360
|
|
353
361
|
def parse_rbs_methods(rbs, method_name)
|
data/lib/ruby_lsp/addon.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
5
|
-
# To register an
|
5
|
+
# To register an add-on, inherit from this class and implement both `name` and `activate`
|
6
6
|
#
|
7
7
|
# # Example
|
8
8
|
#
|
@@ -14,7 +14,7 @@ module RubyLsp
|
|
14
14
|
# end
|
15
15
|
#
|
16
16
|
# def name
|
17
|
-
# "My
|
17
|
+
# "My add-on name"
|
18
18
|
# end
|
19
19
|
# end
|
20
20
|
# end
|
@@ -27,7 +27,7 @@ module RubyLsp
|
|
27
27
|
|
28
28
|
@addons = T.let([], T::Array[Addon])
|
29
29
|
@addon_classes = T.let([], T::Array[T.class_of(Addon)])
|
30
|
-
#
|
30
|
+
# Add-on instances that have declared a handler to accept file watcher events
|
31
31
|
@file_watcher_addons = T.let([], T::Array[Addon])
|
32
32
|
|
33
33
|
AddonNotFoundError = Class.new(StandardError)
|
@@ -51,12 +51,12 @@ module RubyLsp
|
|
51
51
|
super
|
52
52
|
end
|
53
53
|
|
54
|
-
# Discovers and loads all
|
54
|
+
# Discovers and loads all add-ons. Returns a list of errors when trying to require add-ons
|
55
55
|
sig do
|
56
56
|
params(global_state: GlobalState, outgoing_queue: Thread::Queue).returns(T::Array[StandardError])
|
57
57
|
end
|
58
58
|
def load_addons(global_state, outgoing_queue)
|
59
|
-
# Require all
|
59
|
+
# Require all add-ons entry points, which should be placed under
|
60
60
|
# `some_gem/lib/ruby_lsp/your_gem_name/addon.rb`
|
61
61
|
errors = Gem.find_files("ruby_lsp/**/addon.rb").filter_map do |addon|
|
62
62
|
require File.expand_path(addon)
|
@@ -69,7 +69,7 @@ module RubyLsp
|
|
69
69
|
self.addons = addon_classes.map(&:new)
|
70
70
|
self.file_watcher_addons = addons.select { |addon| addon.respond_to?(:workspace_did_change_watched_files) }
|
71
71
|
|
72
|
-
# Activate each one of the discovered
|
72
|
+
# Activate each one of the discovered add-ons. If any problems occur in the add-ons, we don't want to
|
73
73
|
# fail to boot the server
|
74
74
|
addons.each do |addon|
|
75
75
|
addon.activate(global_state, outgoing_queue)
|
@@ -83,7 +83,7 @@ module RubyLsp
|
|
83
83
|
sig { params(addon_name: String).returns(Addon) }
|
84
84
|
def get(addon_name)
|
85
85
|
addon = addons.find { |addon| addon.name == addon_name }
|
86
|
-
raise AddonNotFoundError, "Could not find
|
86
|
+
raise AddonNotFoundError, "Could not find add-on '#{addon_name}'" unless addon
|
87
87
|
|
88
88
|
addon
|
89
89
|
end
|
@@ -118,17 +118,17 @@ module RubyLsp
|
|
118
118
|
@errors.map(&:full_message).join("\n\n")
|
119
119
|
end
|
120
120
|
|
121
|
-
# Each
|
121
|
+
# Each add-on should implement `MyAddon#activate` and use to perform any sort of initialization, such as
|
122
122
|
# reading information into memory or even spawning a separate process
|
123
123
|
sig { abstract.params(global_state: GlobalState, outgoing_queue: Thread::Queue).void }
|
124
124
|
def activate(global_state, outgoing_queue); end
|
125
125
|
|
126
|
-
# Each
|
126
|
+
# Each add-on should implement `MyAddon#deactivate` and use to perform any clean up, like shutting down a
|
127
127
|
# child process
|
128
128
|
sig { abstract.void }
|
129
129
|
def deactivate; end
|
130
130
|
|
131
|
-
#
|
131
|
+
# Add-ons should override the `name` method to return the add-on name
|
132
132
|
sig { abstract.returns(String) }
|
133
133
|
def name; end
|
134
134
|
|
data/lib/ruby_lsp/base_server.rb
CHANGED
@@ -130,6 +130,12 @@ module RubyLsp
|
|
130
130
|
sig { abstract.void }
|
131
131
|
def shutdown; end
|
132
132
|
|
133
|
+
sig { params(id: Integer, message: String, type: Integer).void }
|
134
|
+
def fail_request_and_notify(id, message, type: Constant::MessageType::INFO)
|
135
|
+
send_message(Error.new(id: id, code: Constant::ErrorCodes::REQUEST_FAILED, message: message))
|
136
|
+
send_message(Notification.window_show_message(message, type: type))
|
137
|
+
end
|
138
|
+
|
133
139
|
sig { returns(Thread) }
|
134
140
|
def new_worker
|
135
141
|
Thread.new do
|
data/lib/ruby_lsp/internal.rb
CHANGED
@@ -26,7 +26,7 @@ require "ruby_lsp/base_server"
|
|
26
26
|
require "ruby_indexer/ruby_indexer"
|
27
27
|
require "core_ext/uri"
|
28
28
|
require "ruby_lsp/utils"
|
29
|
-
require "ruby_lsp/
|
29
|
+
require "ruby_lsp/scope"
|
30
30
|
require "ruby_lsp/global_state"
|
31
31
|
require "ruby_lsp/server"
|
32
32
|
require "ruby_lsp/type_inferrer"
|
@@ -21,6 +21,7 @@ module RubyLsp
|
|
21
21
|
Prism::InstanceVariableWriteNode,
|
22
22
|
Prism::SymbolNode,
|
23
23
|
Prism::StringNode,
|
24
|
+
Prism::InterpolatedStringNode,
|
24
25
|
Prism::SuperNode,
|
25
26
|
Prism::ForwardingSuperNode,
|
26
27
|
],
|
@@ -68,9 +69,21 @@ module RubyLsp
|
|
68
69
|
:on_instance_variable_target_node_enter,
|
69
70
|
:on_super_node_enter,
|
70
71
|
:on_forwarding_super_node_enter,
|
72
|
+
:on_string_node_enter,
|
73
|
+
:on_interpolated_string_node_enter,
|
71
74
|
)
|
72
75
|
end
|
73
76
|
|
77
|
+
sig { params(node: Prism::StringNode).void }
|
78
|
+
def on_string_node_enter(node)
|
79
|
+
generate_heredoc_hover(node)
|
80
|
+
end
|
81
|
+
|
82
|
+
sig { params(node: Prism::InterpolatedStringNode).void }
|
83
|
+
def on_interpolated_string_node_enter(node)
|
84
|
+
generate_heredoc_hover(node)
|
85
|
+
end
|
86
|
+
|
74
87
|
sig { params(node: Prism::ConstantReadNode).void }
|
75
88
|
def on_constant_read_node_enter(node)
|
76
89
|
return if @sorbet_level != RubyDocument::SorbetLevel::Ignore
|
@@ -155,6 +168,31 @@ module RubyLsp
|
|
155
168
|
|
156
169
|
private
|
157
170
|
|
171
|
+
sig { params(node: T.any(Prism::InterpolatedStringNode, Prism::StringNode)).void }
|
172
|
+
def generate_heredoc_hover(node)
|
173
|
+
return unless node.heredoc?
|
174
|
+
|
175
|
+
opening_content = node.opening_loc&.slice
|
176
|
+
return unless opening_content
|
177
|
+
|
178
|
+
match = /(<<(?<type>(-|~)?))(?<quote>['"`]?)(?<delimiter>\w+)\k<quote>/.match(opening_content)
|
179
|
+
return unless match
|
180
|
+
|
181
|
+
heredoc_delimiter = match.named_captures["delimiter"]
|
182
|
+
|
183
|
+
if heredoc_delimiter
|
184
|
+
message = if match["type"] == "~"
|
185
|
+
"This is a squiggly heredoc definition using the `#{heredoc_delimiter}` delimiter. " \
|
186
|
+
"Indentation will be ignored in the resulting string."
|
187
|
+
else
|
188
|
+
"This is a heredoc definition using the `#{heredoc_delimiter}` delimiter. " \
|
189
|
+
"Indentation will be considered part of the string."
|
190
|
+
end
|
191
|
+
|
192
|
+
@response_builder.push(message, category: :documentation)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
158
196
|
sig { void }
|
159
197
|
def handle_super_node_hover
|
160
198
|
# Sorbet can handle super hover on typed true or higher
|
@@ -27,7 +27,7 @@ module RubyLsp
|
|
27
27
|
def initialize(dispatcher, response_builder)
|
28
28
|
@response_builder = response_builder
|
29
29
|
@special_methods = T.let(nil, T.nilable(T::Array[String]))
|
30
|
-
@current_scope = T.let(
|
30
|
+
@current_scope = T.let(Scope.new, Scope)
|
31
31
|
@inside_regex_capture = T.let(false, T::Boolean)
|
32
32
|
@inside_implicit_node = T.let(false, T::Boolean)
|
33
33
|
|
@@ -102,7 +102,7 @@ module RubyLsp
|
|
102
102
|
|
103
103
|
sig { params(node: Prism::DefNode).void }
|
104
104
|
def on_def_node_enter(node)
|
105
|
-
@current_scope =
|
105
|
+
@current_scope = Scope.new(@current_scope)
|
106
106
|
end
|
107
107
|
|
108
108
|
sig { params(node: Prism::DefNode).void }
|
@@ -112,7 +112,7 @@ module RubyLsp
|
|
112
112
|
|
113
113
|
sig { params(node: Prism::BlockNode).void }
|
114
114
|
def on_block_node_enter(node)
|
115
|
-
@current_scope =
|
115
|
+
@current_scope = Scope.new(@current_scope)
|
116
116
|
end
|
117
117
|
|
118
118
|
sig { params(node: Prism::BlockNode).void }
|
@@ -128,39 +128,39 @@ module RubyLsp
|
|
128
128
|
sig { params(node: Prism::BlockParameterNode).void }
|
129
129
|
def on_block_parameter_node_enter(node)
|
130
130
|
name = node.name
|
131
|
-
@current_scope
|
131
|
+
@current_scope.add(name.to_sym, :parameter) if name
|
132
132
|
end
|
133
133
|
|
134
134
|
sig { params(node: Prism::RequiredKeywordParameterNode).void }
|
135
135
|
def on_required_keyword_parameter_node_enter(node)
|
136
|
-
@current_scope
|
136
|
+
@current_scope.add(node.name, :parameter)
|
137
137
|
end
|
138
138
|
|
139
139
|
sig { params(node: Prism::OptionalKeywordParameterNode).void }
|
140
140
|
def on_optional_keyword_parameter_node_enter(node)
|
141
|
-
@current_scope
|
141
|
+
@current_scope.add(node.name, :parameter)
|
142
142
|
end
|
143
143
|
|
144
144
|
sig { params(node: Prism::KeywordRestParameterNode).void }
|
145
145
|
def on_keyword_rest_parameter_node_enter(node)
|
146
146
|
name = node.name
|
147
|
-
@current_scope
|
147
|
+
@current_scope.add(name.to_sym, :parameter) if name
|
148
148
|
end
|
149
149
|
|
150
150
|
sig { params(node: Prism::OptionalParameterNode).void }
|
151
151
|
def on_optional_parameter_node_enter(node)
|
152
|
-
@current_scope
|
152
|
+
@current_scope.add(node.name, :parameter)
|
153
153
|
end
|
154
154
|
|
155
155
|
sig { params(node: Prism::RequiredParameterNode).void }
|
156
156
|
def on_required_parameter_node_enter(node)
|
157
|
-
@current_scope
|
157
|
+
@current_scope.add(node.name, :parameter)
|
158
158
|
end
|
159
159
|
|
160
160
|
sig { params(node: Prism::RestParameterNode).void }
|
161
161
|
def on_rest_parameter_node_enter(node)
|
162
162
|
name = node.name
|
163
|
-
@current_scope
|
163
|
+
@current_scope.add(name.to_sym, :parameter) if name
|
164
164
|
end
|
165
165
|
|
166
166
|
sig { params(node: Prism::SelfNode).void }
|
@@ -170,8 +170,8 @@ module RubyLsp
|
|
170
170
|
|
171
171
|
sig { params(node: Prism::LocalVariableWriteNode).void }
|
172
172
|
def on_local_variable_write_node_enter(node)
|
173
|
-
|
174
|
-
@response_builder.add_token(node.name_loc,
|
173
|
+
local = @current_scope.lookup(node.name)
|
174
|
+
@response_builder.add_token(node.name_loc, :parameter) if local&.type == :parameter
|
175
175
|
end
|
176
176
|
|
177
177
|
sig { params(node: Prism::LocalVariableReadNode).void }
|
@@ -184,25 +184,26 @@ module RubyLsp
|
|
184
184
|
return
|
185
185
|
end
|
186
186
|
|
187
|
-
|
187
|
+
local = @current_scope.lookup(node.name)
|
188
|
+
@response_builder.add_token(node.location, local&.type || :variable)
|
188
189
|
end
|
189
190
|
|
190
191
|
sig { params(node: Prism::LocalVariableAndWriteNode).void }
|
191
192
|
def on_local_variable_and_write_node_enter(node)
|
192
|
-
|
193
|
-
@response_builder.add_token(node.name_loc,
|
193
|
+
local = @current_scope.lookup(node.name)
|
194
|
+
@response_builder.add_token(node.name_loc, :parameter) if local&.type == :parameter
|
194
195
|
end
|
195
196
|
|
196
197
|
sig { params(node: Prism::LocalVariableOperatorWriteNode).void }
|
197
198
|
def on_local_variable_operator_write_node_enter(node)
|
198
|
-
|
199
|
-
@response_builder.add_token(node.name_loc,
|
199
|
+
local = @current_scope.lookup(node.name)
|
200
|
+
@response_builder.add_token(node.name_loc, :parameter) if local&.type == :parameter
|
200
201
|
end
|
201
202
|
|
202
203
|
sig { params(node: Prism::LocalVariableOrWriteNode).void }
|
203
204
|
def on_local_variable_or_write_node_enter(node)
|
204
|
-
|
205
|
-
@response_builder.add_token(node.name_loc,
|
205
|
+
local = @current_scope.lookup(node.name)
|
206
|
+
@response_builder.add_token(node.name_loc, :parameter) if local&.type == :parameter
|
206
207
|
end
|
207
208
|
|
208
209
|
sig { params(node: Prism::LocalVariableTargetNode).void }
|
@@ -213,7 +214,8 @@ module RubyLsp
|
|
213
214
|
# prevent pushing local variable target tokens. See https://github.com/ruby/prism/issues/1912
|
214
215
|
return if @inside_regex_capture
|
215
216
|
|
216
|
-
|
217
|
+
local = @current_scope.lookup(node.name)
|
218
|
+
@response_builder.add_token(node.location, local&.type || :variable)
|
217
219
|
end
|
218
220
|
|
219
221
|
sig { params(node: Prism::ClassNode).void }
|
@@ -311,7 +313,8 @@ module RubyLsp
|
|
311
313
|
capture_name_offset = T.must(content.index("(?<#{name}>")) + 3
|
312
314
|
local_var_loc = loc.copy(start_offset: loc.start_offset + capture_name_offset, length: name.length)
|
313
315
|
|
314
|
-
|
316
|
+
local = @current_scope.lookup(name)
|
317
|
+
@response_builder.add_token(local_var_loc, local&.type || :variable)
|
315
318
|
end
|
316
319
|
end
|
317
320
|
end
|
@@ -63,7 +63,7 @@ module RubyLsp
|
|
63
63
|
if (comment_match = @previous_line.match(/^#(\s*)/))
|
64
64
|
handle_comment_line(T.must(comment_match[1]))
|
65
65
|
elsif @document.syntax_error?
|
66
|
-
match = /(
|
66
|
+
match = /(<<((-|~)?))(?<quote>['"`]?)(?<delimiter>\w+)\k<quote>/.match(@previous_line)
|
67
67
|
heredoc_delimiter = match && match.named_captures["delimiter"]
|
68
68
|
|
69
69
|
if heredoc_delimiter
|
@@ -5,8 +5,8 @@ module RubyLsp
|
|
5
5
|
module Requests
|
6
6
|
module Support
|
7
7
|
module Common
|
8
|
-
# WARNING: Methods in this class may be used by Ruby LSP
|
9
|
-
# https://github.com/Shopify/ruby-lsp-rails, or
|
8
|
+
# WARNING: Methods in this class may be used by Ruby LSP add-ons such as
|
9
|
+
# https://github.com/Shopify/ruby-lsp-rails, or add-ons by created by developers outside of Shopify, so be
|
10
10
|
# cautious of changing anything.
|
11
11
|
extend T::Sig
|
12
12
|
extend T::Helpers
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RubyLsp
|
5
|
+
class Scope
|
6
|
+
extend T::Sig
|
7
|
+
|
8
|
+
sig { returns(T.nilable(Scope)) }
|
9
|
+
attr_reader :parent
|
10
|
+
|
11
|
+
sig { params(parent: T.nilable(Scope)).void }
|
12
|
+
def initialize(parent = nil)
|
13
|
+
@parent = parent
|
14
|
+
|
15
|
+
# A hash of name => type
|
16
|
+
@locals = T.let({}, T::Hash[Symbol, Local])
|
17
|
+
end
|
18
|
+
|
19
|
+
# Add a new local to this scope. The types should only be `:parameter` or `:variable`
|
20
|
+
sig { params(name: T.any(String, Symbol), type: Symbol).void }
|
21
|
+
def add(name, type)
|
22
|
+
@locals[name.to_sym] = Local.new(type)
|
23
|
+
end
|
24
|
+
|
25
|
+
sig { params(name: T.any(String, Symbol)).returns(T.nilable(Local)) }
|
26
|
+
def lookup(name)
|
27
|
+
sym = name.to_sym
|
28
|
+
entry = @locals[sym]
|
29
|
+
return entry if entry
|
30
|
+
return unless @parent
|
31
|
+
|
32
|
+
@parent.lookup(sym)
|
33
|
+
end
|
34
|
+
|
35
|
+
class Local
|
36
|
+
extend T::Sig
|
37
|
+
|
38
|
+
sig { returns(Symbol) }
|
39
|
+
attr_reader :type
|
40
|
+
|
41
|
+
sig { params(type: Symbol).void }
|
42
|
+
def initialize(type)
|
43
|
+
@type = type
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/ruby_lsp/server.rb
CHANGED
@@ -142,7 +142,7 @@ module RubyLsp
|
|
142
142
|
method: "window/showMessage",
|
143
143
|
params: Interface::ShowMessageParams.new(
|
144
144
|
type: Constant::MessageType::WARNING,
|
145
|
-
message: "Error loading
|
145
|
+
message: "Error loading add-ons:\n\n#{errored_addons.map(&:formatted_errors).join("\n\n")}",
|
146
146
|
),
|
147
147
|
),
|
148
148
|
)
|
@@ -285,8 +285,9 @@ module RubyLsp
|
|
285
285
|
rescue RuboCop::Error => e
|
286
286
|
# The user may have provided unknown config switches in .rubocop or
|
287
287
|
# is trying to load a non-existant config file.
|
288
|
-
send_message(Notification.
|
288
|
+
send_message(Notification.window_show_message(
|
289
289
|
"RuboCop configuration error: #{e.message}. Formatting will not be available.",
|
290
|
+
type: Constant::MessageType::ERROR,
|
290
291
|
))
|
291
292
|
end
|
292
293
|
end
|
@@ -531,10 +532,16 @@ module RubyLsp
|
|
531
532
|
response = Requests::Formatting.new(@global_state, document).perform
|
532
533
|
send_message(Result.new(id: message[:id], response: response))
|
533
534
|
rescue Requests::Request::InvalidFormatter => error
|
534
|
-
send_message(Notification.
|
535
|
+
send_message(Notification.window_show_message(
|
536
|
+
"Configuration error: #{error.message}",
|
537
|
+
type: Constant::MessageType::ERROR,
|
538
|
+
))
|
535
539
|
send_empty_response(message[:id])
|
536
540
|
rescue StandardError, LoadError => error
|
537
|
-
send_message(Notification.
|
541
|
+
send_message(Notification.window_show_message(
|
542
|
+
"Formatting error: #{error.message}",
|
543
|
+
type: Constant::MessageType::ERROR,
|
544
|
+
))
|
538
545
|
send_empty_response(message[:id])
|
539
546
|
end
|
540
547
|
|
@@ -673,30 +680,19 @@ module RubyLsp
|
|
673
680
|
document = @store.get(uri)
|
674
681
|
|
675
682
|
unless document.is_a?(RubyDocument)
|
676
|
-
|
677
|
-
|
683
|
+
fail_request_and_notify(message[:id], "Code actions are currently only available for Ruby documents")
|
684
|
+
return
|
678
685
|
end
|
679
686
|
|
680
687
|
result = Requests::CodeActionResolve.new(document, params).perform
|
681
688
|
|
682
689
|
case result
|
683
690
|
when Requests::CodeActionResolve::Error::EmptySelection
|
684
|
-
|
685
|
-
raise Requests::CodeActionResolve::CodeActionError
|
691
|
+
fail_request_and_notify(message[:id], "Invalid selection for extract variable refactor")
|
686
692
|
when Requests::CodeActionResolve::Error::InvalidTargetRange
|
687
|
-
|
688
|
-
Notification.window_show_error(
|
689
|
-
"Couldn't find an appropriate location to place extracted refactor",
|
690
|
-
),
|
691
|
-
)
|
692
|
-
raise Requests::CodeActionResolve::CodeActionError
|
693
|
+
fail_request_and_notify(message[:id], "Couldn't find an appropriate location to place extracted refactor")
|
693
694
|
when Requests::CodeActionResolve::Error::UnknownCodeAction
|
694
|
-
|
695
|
-
Notification.window_show_error(
|
696
|
-
"Unknown code action",
|
697
|
-
),
|
698
|
-
)
|
699
|
-
raise Requests::CodeActionResolve::CodeActionError
|
695
|
+
fail_request_and_notify(message[:id], "Unknown code action")
|
700
696
|
else
|
701
697
|
send_message(Result.new(id: message[:id], response: result))
|
702
698
|
end
|
@@ -729,10 +725,16 @@ module RubyLsp
|
|
729
725
|
),
|
730
726
|
)
|
731
727
|
rescue Requests::Request::InvalidFormatter => error
|
732
|
-
send_message(Notification.
|
728
|
+
send_message(Notification.window_show_message(
|
729
|
+
"Configuration error: #{error.message}",
|
730
|
+
type: Constant::MessageType::ERROR,
|
731
|
+
))
|
733
732
|
send_empty_response(message[:id])
|
734
733
|
rescue StandardError, LoadError => error
|
735
|
-
send_message(Notification.
|
734
|
+
send_message(Notification.window_show_message(
|
735
|
+
"Error running diagnostics: #{error.message}",
|
736
|
+
type: Constant::MessageType::ERROR,
|
737
|
+
))
|
736
738
|
send_empty_response(message[:id])
|
737
739
|
end
|
738
740
|
|
@@ -969,7 +971,9 @@ module RubyLsp
|
|
969
971
|
false
|
970
972
|
end
|
971
973
|
rescue StandardError => error
|
972
|
-
|
974
|
+
message = "Error while indexing (see [troubleshooting steps]" \
|
975
|
+
"(https://shopify.github.io/ruby-lsp/troubleshooting#indexing)): #{error.message}"
|
976
|
+
send_message(Notification.window_show_message(message, type: Constant::MessageType::ERROR))
|
973
977
|
end
|
974
978
|
|
975
979
|
# Indexing produces a high number of short lived object allocations. That might lead to some fragmentation and
|
@@ -1054,8 +1058,9 @@ module RubyLsp
|
|
1054
1058
|
@global_state.formatter = "none"
|
1055
1059
|
|
1056
1060
|
send_message(
|
1057
|
-
Notification.
|
1061
|
+
Notification.window_show_message(
|
1058
1062
|
"Ruby LSP formatter is set to `rubocop` but RuboCop was not found in the Gemfile or gemspec.",
|
1063
|
+
type: Constant::MessageType::ERROR,
|
1059
1064
|
),
|
1060
1065
|
)
|
1061
1066
|
end
|
data/lib/ruby_lsp/utils.rb
CHANGED
@@ -64,14 +64,11 @@ module RubyLsp
|
|
64
64
|
class << self
|
65
65
|
extend T::Sig
|
66
66
|
|
67
|
-
sig { params(message: String).returns(Notification) }
|
68
|
-
def
|
67
|
+
sig { params(message: String, type: Integer).returns(Notification) }
|
68
|
+
def window_show_message(message, type: Constant::MessageType::INFO)
|
69
69
|
new(
|
70
70
|
method: "window/showMessage",
|
71
|
-
params: Interface::ShowMessageParams.new(
|
72
|
-
type: Constant::MessageType::ERROR,
|
73
|
-
message: message,
|
74
|
-
),
|
71
|
+
params: Interface::ShowMessageParams.new(type: type, message: message),
|
75
72
|
)
|
76
73
|
end
|
77
74
|
|
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.18.
|
4
|
+
version: 0.18.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-09-
|
11
|
+
date: 2024-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: language_server-protocol
|
@@ -129,7 +129,6 @@ files:
|
|
129
129
|
- lib/ruby_lsp/listeners/signature_help.rb
|
130
130
|
- lib/ruby_lsp/load_sorbet.rb
|
131
131
|
- lib/ruby_lsp/node_context.rb
|
132
|
-
- lib/ruby_lsp/parameter_scope.rb
|
133
132
|
- lib/ruby_lsp/rbs_document.rb
|
134
133
|
- lib/ruby_lsp/requests/code_action_resolve.rb
|
135
134
|
- lib/ruby_lsp/requests/code_actions.rb
|
@@ -171,6 +170,7 @@ files:
|
|
171
170
|
- lib/ruby_lsp/response_builders/semantic_highlighting.rb
|
172
171
|
- lib/ruby_lsp/response_builders/signature_help.rb
|
173
172
|
- lib/ruby_lsp/ruby_document.rb
|
173
|
+
- lib/ruby_lsp/scope.rb
|
174
174
|
- lib/ruby_lsp/server.rb
|
175
175
|
- lib/ruby_lsp/setup_bundler.rb
|
176
176
|
- lib/ruby_lsp/store.rb
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
module RubyLsp
|
5
|
-
class ParameterScope
|
6
|
-
extend T::Sig
|
7
|
-
|
8
|
-
sig { returns(T.nilable(ParameterScope)) }
|
9
|
-
attr_reader :parent
|
10
|
-
|
11
|
-
sig { params(parent: T.nilable(ParameterScope)).void }
|
12
|
-
def initialize(parent = nil)
|
13
|
-
@parent = parent
|
14
|
-
@parameters = T.let(Set.new, T::Set[Symbol])
|
15
|
-
end
|
16
|
-
|
17
|
-
sig { params(name: T.any(String, Symbol)).void }
|
18
|
-
def <<(name)
|
19
|
-
@parameters << name.to_sym
|
20
|
-
end
|
21
|
-
|
22
|
-
sig { params(name: T.any(Symbol, String)).returns(Symbol) }
|
23
|
-
def type_for(name)
|
24
|
-
parameter?(name) ? :parameter : :variable
|
25
|
-
end
|
26
|
-
|
27
|
-
sig { params(name: T.any(Symbol, String)).returns(T::Boolean) }
|
28
|
-
def parameter?(name)
|
29
|
-
sym = name.to_sym
|
30
|
-
@parameters.include?(sym) || (!@parent.nil? && @parent.parameter?(sym))
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|