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