ruby-lsp 0.23.11 → 0.23.13
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-launcher +12 -11
- data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -1
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -5
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +81 -115
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +117 -166
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +9 -7
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +88 -200
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +56 -192
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +14 -16
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +22 -45
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +42 -60
- data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +9 -16
- data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +5 -9
- data/lib/ruby_indexer/test/configuration_test.rb +42 -3
- data/lib/ruby_indexer/test/method_test.rb +28 -2
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +1 -1
- data/lib/ruby_lsp/addon.rb +44 -71
- data/lib/ruby_lsp/base_server.rb +29 -32
- data/lib/ruby_lsp/client_capabilities.rb +10 -12
- data/lib/ruby_lsp/document.rb +34 -45
- data/lib/ruby_lsp/erb_document.rb +24 -36
- data/lib/ruby_lsp/global_state.rb +51 -56
- data/lib/ruby_lsp/internal.rb +2 -0
- data/lib/ruby_lsp/listeners/code_lens.rb +81 -88
- data/lib/ruby_lsp/listeners/completion.rb +36 -55
- data/lib/ruby_lsp/listeners/definition.rb +37 -51
- data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
- data/lib/ruby_lsp/listeners/document_link.rb +43 -62
- data/lib/ruby_lsp/listeners/document_symbol.rb +35 -49
- data/lib/ruby_lsp/listeners/folding_ranges.rb +32 -39
- data/lib/ruby_lsp/listeners/hover.rb +81 -100
- data/lib/ruby_lsp/listeners/inlay_hints.rb +4 -11
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +42 -51
- data/lib/ruby_lsp/listeners/signature_help.rb +6 -25
- data/lib/ruby_lsp/listeners/spec_style.rb +155 -0
- data/lib/ruby_lsp/listeners/test_discovery.rb +89 -0
- data/lib/ruby_lsp/listeners/test_style.rb +160 -88
- data/lib/ruby_lsp/node_context.rb +12 -39
- data/lib/ruby_lsp/rbs_document.rb +8 -6
- data/lib/ruby_lsp/requests/code_action_resolve.rb +10 -10
- data/lib/ruby_lsp/requests/code_actions.rb +14 -26
- data/lib/ruby_lsp/requests/code_lens.rb +6 -17
- data/lib/ruby_lsp/requests/completion.rb +7 -20
- data/lib/ruby_lsp/requests/completion_resolve.rb +5 -5
- data/lib/ruby_lsp/requests/definition.rb +8 -17
- data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
- data/lib/ruby_lsp/requests/discover_tests.rb +18 -5
- data/lib/ruby_lsp/requests/document_highlight.rb +5 -15
- 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 +87 -0
- data/lib/ruby_lsp/requests/hover.rb +8 -18
- data/lib/ruby_lsp/requests/inlay_hints.rb +6 -17
- data/lib/ruby_lsp/requests/on_type_formatting.rb +28 -38
- data/lib/ruby_lsp/requests/prepare_rename.rb +4 -9
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +4 -13
- data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
- data/lib/ruby_lsp/requests/references.rb +6 -36
- data/lib/ruby_lsp/requests/rename.rb +11 -37
- data/lib/ruby_lsp/requests/request.rb +7 -19
- data/lib/ruby_lsp/requests/selection_ranges.rb +5 -5
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +12 -31
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +5 -6
- data/lib/ruby_lsp/requests/signature_help.rb +8 -26
- data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
- data/lib/ruby_lsp/requests/support/common.rb +13 -50
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +9 -12
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +22 -34
- 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 +16 -30
- data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
- data/lib/ruby_lsp/requests/support/test_item.rb +10 -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 +5 -5
- data/lib/ruby_lsp/response_builders/document_symbol.rb +10 -16
- data/lib/ruby_lsp/response_builders/hover.rb +10 -13
- data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +59 -87
- data/lib/ruby_lsp/response_builders/signature_help.rb +5 -6
- data/lib/ruby_lsp/response_builders/test_collection.rb +6 -10
- data/lib/ruby_lsp/ruby_document.rb +22 -60
- data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +109 -0
- data/lib/ruby_lsp/scope.rb +7 -11
- data/lib/ruby_lsp/server.rb +133 -74
- data/lib/ruby_lsp/setup_bundler.rb +58 -57
- data/lib/ruby_lsp/static_docs.rb +4 -7
- data/lib/ruby_lsp/store.rb +21 -40
- data/lib/ruby_lsp/test_helper.rb +3 -12
- data/lib/ruby_lsp/test_reporter.rb +207 -0
- data/lib/ruby_lsp/test_unit_test_runner.rb +98 -0
- data/lib/ruby_lsp/type_inferrer.rb +9 -13
- data/lib/ruby_lsp/utils.rb +37 -81
- metadata +9 -3
@@ -3,93 +3,180 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Listeners
|
6
|
-
class TestStyle
|
7
|
-
|
6
|
+
class TestStyle < TestDiscovery
|
7
|
+
class << self
|
8
|
+
# Resolves the minimal set of commands required to execute the requested tests
|
9
|
+
#: (Array[Hash[Symbol, untyped]]) -> Array[String]
|
10
|
+
def resolve_test_commands(items)
|
11
|
+
# A nested hash of file_path => test_group => { tags: [], examples: [test_example] } to ensure we build the
|
12
|
+
# minimum amount of commands needed to execute the requested tests. This is only used for specific examples
|
13
|
+
# where we will need more complex regexes to execute it all at the same time
|
14
|
+
aggregated_tests = Hash.new do |hash, key|
|
15
|
+
hash[key] = Hash.new do |inner_h, inner_k|
|
16
|
+
inner_h[inner_k] = { tags: Set.new, examples: [] }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Full files are paths that should be executed as a whole e.g.: an entire test file or directory
|
21
|
+
full_files = []
|
22
|
+
queue = items.dup
|
23
|
+
|
24
|
+
until queue.empty?
|
25
|
+
item = T.must(queue.shift)
|
26
|
+
tags = Set.new(item[:tags])
|
27
|
+
next unless tags.include?("framework:minitest") || tags.include?("framework:test_unit")
|
28
|
+
|
29
|
+
children = item[:children]
|
30
|
+
uri = URI(item[:uri])
|
31
|
+
path = uri.full_path
|
32
|
+
next unless path
|
33
|
+
|
34
|
+
if tags.include?("test_dir")
|
35
|
+
if children.empty?
|
36
|
+
full_files.concat(Dir.glob(
|
37
|
+
"#{path}/**/{*_test,test_*}.rb",
|
38
|
+
File::Constants::FNM_EXTGLOB | File::Constants::FNM_PATHNAME,
|
39
|
+
))
|
40
|
+
end
|
41
|
+
elsif tags.include?("test_file")
|
42
|
+
full_files << path if children.empty?
|
43
|
+
elsif tags.include?("test_group")
|
44
|
+
# If all of the children of the current test group are other groups, then there's no need to add it to the
|
45
|
+
# aggregated examples
|
46
|
+
unless children.any? && children.all? { |child| child[:tags].include?("test_group") }
|
47
|
+
aggregated_tests[path][item[:label]] = { tags: tags, examples: [] }
|
48
|
+
end
|
49
|
+
else
|
50
|
+
class_name, method_name = item[:id].split("#")
|
51
|
+
aggregated_tests[path][class_name][:examples] << method_name
|
52
|
+
aggregated_tests[path][class_name][:tags].merge(tags)
|
53
|
+
end
|
54
|
+
|
55
|
+
queue.concat(children) unless children.empty?
|
56
|
+
end
|
57
|
+
|
58
|
+
commands = []
|
59
|
+
|
60
|
+
aggregated_tests.each do |file_path, groups_and_examples|
|
61
|
+
# Separate groups into Minitest and Test Unit. You can have both frameworks in the same file, but you cannot
|
62
|
+
# have a group belongs to both at the same time
|
63
|
+
minitest_groups, test_unit_groups = groups_and_examples.partition do |_, info|
|
64
|
+
info[:tags].include?("framework:minitest")
|
65
|
+
end
|
66
|
+
|
67
|
+
if minitest_groups.any?
|
68
|
+
commands << handle_minitest_groups(file_path, minitest_groups)
|
69
|
+
end
|
70
|
+
|
71
|
+
if test_unit_groups.any?
|
72
|
+
commands.concat(handle_test_unit_groups(file_path, test_unit_groups))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
unless full_files.empty?
|
77
|
+
commands << "#{BASE_COMMAND} -Itest -e \"ARGV.each { |f| require f }\" #{full_files.join(" ")}"
|
78
|
+
end
|
79
|
+
|
80
|
+
commands
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
#: (String, Hash[String, Hash[Symbol, untyped]]) -> String
|
86
|
+
def handle_minitest_groups(file_path, groups_and_examples)
|
87
|
+
regexes = groups_and_examples.flat_map do |group, info|
|
88
|
+
examples = info[:examples]
|
89
|
+
group_regex = Shellwords.escape(group).gsub(
|
90
|
+
Shellwords.escape(TestDiscovery::DYNAMIC_REFERENCE_MARKER),
|
91
|
+
".*",
|
92
|
+
)
|
93
|
+
if examples.empty?
|
94
|
+
"^#{group_regex}(#|::)"
|
95
|
+
elsif examples.length == 1
|
96
|
+
"^#{group_regex}##{examples[0]}$"
|
97
|
+
else
|
98
|
+
"^#{group_regex}#(#{examples.join("|")})$"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
regex = if regexes.length == 1
|
103
|
+
regexes[0]
|
104
|
+
else
|
105
|
+
"(#{regexes.join("|")})"
|
106
|
+
end
|
107
|
+
|
108
|
+
"#{BASE_COMMAND} -Itest #{file_path} --name \"/#{regex}/\""
|
109
|
+
end
|
110
|
+
|
111
|
+
#: (String, Hash[String, Hash[Symbol, untyped]]) -> Array[String]
|
112
|
+
def handle_test_unit_groups(file_path, groups_and_examples)
|
113
|
+
groups_and_examples.map do |group, info|
|
114
|
+
examples = info[:examples]
|
115
|
+
group_regex = Shellwords.escape(group).gsub(
|
116
|
+
Shellwords.escape(TestDiscovery::DYNAMIC_REFERENCE_MARKER),
|
117
|
+
".*",
|
118
|
+
)
|
119
|
+
command = +"#{BASE_COMMAND} -Itest #{file_path} --testcase \"/^#{group_regex}$/\""
|
120
|
+
|
121
|
+
unless examples.empty?
|
122
|
+
command << if examples.length == 1
|
123
|
+
" --name \"/#{examples[0]}$/\""
|
124
|
+
else
|
125
|
+
" --name \"/(#{examples.join("|")})$/\""
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
command
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
8
134
|
include Requests::Support::Common
|
9
135
|
|
136
|
+
MINITEST_REPORTER_PATH = File.expand_path("../ruby_lsp_reporter_plugin.rb", __dir__) #: String
|
137
|
+
TEST_UNIT_REPORTER_PATH = File.expand_path("../test_unit_test_runner.rb", __dir__) #: String
|
10
138
|
ACCESS_MODIFIERS = [:public, :private, :protected].freeze
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
).void
|
20
|
-
end
|
139
|
+
BASE_COMMAND = begin
|
140
|
+
Bundler.with_original_env { Bundler.default_lockfile }
|
141
|
+
"bundle exec ruby"
|
142
|
+
rescue Bundler::GemfileNotFound
|
143
|
+
"ruby"
|
144
|
+
end #: String
|
145
|
+
|
146
|
+
#: (ResponseBuilders::TestCollection response_builder, GlobalState global_state, Prism::Dispatcher dispatcher, URI::Generic uri) -> void
|
21
147
|
def initialize(response_builder, global_state, dispatcher, uri)
|
22
|
-
|
23
|
-
|
24
|
-
@
|
25
|
-
@visibility_stack = T.let([:public], T::Array[Symbol])
|
26
|
-
@nesting = T.let([], T::Array[String])
|
148
|
+
super
|
149
|
+
|
150
|
+
@framework = :minitest #: Symbol
|
27
151
|
|
28
152
|
dispatcher.register(
|
29
153
|
self,
|
154
|
+
# Common handlers registered in parent class
|
30
155
|
:on_class_node_enter,
|
31
|
-
:on_class_node_leave,
|
32
|
-
:on_module_node_enter,
|
33
|
-
:on_module_node_leave,
|
34
156
|
:on_def_node_enter,
|
35
157
|
:on_call_node_enter,
|
36
158
|
:on_call_node_leave,
|
37
159
|
)
|
38
160
|
end
|
39
161
|
|
40
|
-
|
162
|
+
#: (Prism::ClassNode node) -> void
|
41
163
|
def on_class_node_enter(node)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
if attached_ancestors.include?("Test::Unit::TestCase") ||
|
57
|
-
non_declarative_minitest?(attached_ancestors, fully_qualified_name)
|
58
|
-
|
59
|
-
@response_builder.add(Requests::Support::TestItem.new(
|
60
|
-
fully_qualified_name,
|
61
|
-
fully_qualified_name,
|
62
|
-
@uri,
|
63
|
-
range_from_node(node),
|
64
|
-
))
|
164
|
+
with_test_ancestor_tracking(node) do |name, ancestors|
|
165
|
+
@framework = :test_unit if ancestors.include?("Test::Unit::TestCase")
|
166
|
+
|
167
|
+
if @framework == :test_unit || non_declarative_minitest?(ancestors, name)
|
168
|
+
@response_builder.add(Requests::Support::TestItem.new(
|
169
|
+
name,
|
170
|
+
name,
|
171
|
+
@uri,
|
172
|
+
range_from_node(node),
|
173
|
+
framework: @framework,
|
174
|
+
))
|
175
|
+
end
|
65
176
|
end
|
66
|
-
|
67
|
-
@nesting << name
|
68
177
|
end
|
69
178
|
|
70
|
-
|
71
|
-
def on_module_node_enter(node)
|
72
|
-
@visibility_stack << :public
|
73
|
-
|
74
|
-
name = constant_name(node.constant_path)
|
75
|
-
name ||= name_with_dynamic_reference(node.constant_path)
|
76
|
-
|
77
|
-
@nesting << name
|
78
|
-
end
|
79
|
-
|
80
|
-
sig { params(node: Prism::ModuleNode).void }
|
81
|
-
def on_module_node_leave(node)
|
82
|
-
@visibility_stack.pop
|
83
|
-
@nesting.pop
|
84
|
-
end
|
85
|
-
|
86
|
-
sig { params(node: Prism::ClassNode).void }
|
87
|
-
def on_class_node_leave(node)
|
88
|
-
@visibility_stack.pop
|
89
|
-
@nesting.pop
|
90
|
-
end
|
91
|
-
|
92
|
-
sig { params(node: Prism::DefNode).void }
|
179
|
+
#: (Prism::DefNode node) -> void
|
93
180
|
def on_def_node_enter(node)
|
94
181
|
return if @visibility_stack.last != :public
|
95
182
|
|
@@ -109,10 +196,11 @@ module RubyLsp
|
|
109
196
|
name,
|
110
197
|
@uri,
|
111
198
|
range_from_node(node),
|
199
|
+
framework: @framework,
|
112
200
|
))
|
113
201
|
end
|
114
202
|
|
115
|
-
|
203
|
+
#: (Prism::CallNode node) -> void
|
116
204
|
def on_call_node_enter(node)
|
117
205
|
name = node.name
|
118
206
|
return unless ACCESS_MODIFIERS.include?(name)
|
@@ -120,7 +208,7 @@ module RubyLsp
|
|
120
208
|
@visibility_stack << name
|
121
209
|
end
|
122
210
|
|
123
|
-
|
211
|
+
#: (Prism::CallNode node) -> void
|
124
212
|
def on_call_node_leave(node)
|
125
213
|
name = node.name
|
126
214
|
return unless ACCESS_MODIFIERS.include?(name)
|
@@ -131,7 +219,7 @@ module RubyLsp
|
|
131
219
|
|
132
220
|
private
|
133
221
|
|
134
|
-
|
222
|
+
#: (Array[String] attached_ancestors, String fully_qualified_name) -> bool
|
135
223
|
def non_declarative_minitest?(attached_ancestors, fully_qualified_name)
|
136
224
|
return false unless attached_ancestors.include?("Minitest::Test")
|
137
225
|
|
@@ -143,22 +231,6 @@ module RubyLsp
|
|
143
231
|
rescue RubyIndexer::Index::NonExistingNamespaceError
|
144
232
|
true
|
145
233
|
end
|
146
|
-
|
147
|
-
sig do
|
148
|
-
params(
|
149
|
-
node: T.any(
|
150
|
-
Prism::ConstantPathNode,
|
151
|
-
Prism::ConstantReadNode,
|
152
|
-
Prism::ConstantPathTargetNode,
|
153
|
-
Prism::CallNode,
|
154
|
-
Prism::MissingNode,
|
155
|
-
),
|
156
|
-
).returns(String)
|
157
|
-
end
|
158
|
-
def name_with_dynamic_reference(node)
|
159
|
-
slice = node.slice
|
160
|
-
slice.gsub(/((?<=::)|^)[a-z]\w*/, DYNAMIC_REFERENCE_MARKER)
|
161
|
-
end
|
162
234
|
end
|
163
235
|
end
|
164
236
|
end
|
@@ -5,36 +5,19 @@ module RubyLsp
|
|
5
5
|
# This class allows listeners to access contextual information about a node in the AST, such as its parent,
|
6
6
|
# its namespace nesting, and the surrounding CallNode (e.g. a method call).
|
7
7
|
class NodeContext
|
8
|
-
|
9
|
-
|
10
|
-
sig { returns(T.nilable(Prism::Node)) }
|
8
|
+
#: Prism::Node?
|
11
9
|
attr_reader :node, :parent
|
12
10
|
|
13
|
-
|
11
|
+
#: Array[String]
|
14
12
|
attr_reader :nesting
|
15
13
|
|
16
|
-
|
14
|
+
#: Prism::CallNode?
|
17
15
|
attr_reader :call_node
|
18
16
|
|
19
|
-
|
17
|
+
#: String?
|
20
18
|
attr_reader :surrounding_method
|
21
19
|
|
22
|
-
|
23
|
-
params(
|
24
|
-
node: T.nilable(Prism::Node),
|
25
|
-
parent: T.nilable(Prism::Node),
|
26
|
-
nesting_nodes: T::Array[T.any(
|
27
|
-
Prism::ClassNode,
|
28
|
-
Prism::ModuleNode,
|
29
|
-
Prism::SingletonClassNode,
|
30
|
-
Prism::DefNode,
|
31
|
-
Prism::BlockNode,
|
32
|
-
Prism::LambdaNode,
|
33
|
-
Prism::ProgramNode,
|
34
|
-
)],
|
35
|
-
call_node: T.nilable(Prism::CallNode),
|
36
|
-
).void
|
37
|
-
end
|
20
|
+
#: (Prism::Node? node, Prism::Node? parent, Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)] nesting_nodes, Prism::CallNode? call_node) -> void
|
38
21
|
def initialize(node, parent, nesting_nodes, call_node)
|
39
22
|
@node = node
|
40
23
|
@parent = parent
|
@@ -42,16 +25,16 @@ module RubyLsp
|
|
42
25
|
@call_node = call_node
|
43
26
|
|
44
27
|
nesting, surrounding_method = handle_nesting_nodes(nesting_nodes)
|
45
|
-
@nesting =
|
46
|
-
@surrounding_method =
|
28
|
+
@nesting = nesting #: Array[String]
|
29
|
+
@surrounding_method = surrounding_method #: String?
|
47
30
|
end
|
48
31
|
|
49
|
-
|
32
|
+
#: -> String
|
50
33
|
def fully_qualified_name
|
51
|
-
@fully_qualified_name ||=
|
34
|
+
@fully_qualified_name ||= @nesting.join("::") #: String?
|
52
35
|
end
|
53
36
|
|
54
|
-
|
37
|
+
#: -> Array[Symbol]
|
55
38
|
def locals_for_scope
|
56
39
|
locals = []
|
57
40
|
|
@@ -69,20 +52,10 @@ module RubyLsp
|
|
69
52
|
|
70
53
|
private
|
71
54
|
|
72
|
-
|
73
|
-
params(nodes: T::Array[T.any(
|
74
|
-
Prism::ClassNode,
|
75
|
-
Prism::ModuleNode,
|
76
|
-
Prism::SingletonClassNode,
|
77
|
-
Prism::DefNode,
|
78
|
-
Prism::BlockNode,
|
79
|
-
Prism::LambdaNode,
|
80
|
-
Prism::ProgramNode,
|
81
|
-
)]).returns([T::Array[String], T.nilable(String)])
|
82
|
-
end
|
55
|
+
#: (Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)] nodes) -> [Array[String], String?]
|
83
56
|
def handle_nesting_nodes(nodes)
|
84
57
|
nesting = []
|
85
|
-
surrounding_method =
|
58
|
+
surrounding_method = nil #: String?
|
86
59
|
|
87
60
|
@nesting_nodes.each do |node|
|
88
61
|
case node
|
@@ -3,18 +3,18 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
class RBSDocument < Document
|
6
|
-
extend T::Sig
|
7
6
|
extend T::Generic
|
8
7
|
|
9
8
|
ParseResultType = type_member { { fixed: T::Array[RBS::AST::Declarations::Base] } }
|
10
9
|
|
11
|
-
|
10
|
+
#: (source: String, version: Integer, uri: URI::Generic, global_state: GlobalState) -> void
|
12
11
|
def initialize(source:, version:, uri:, global_state:)
|
13
|
-
@syntax_error =
|
12
|
+
@syntax_error = false #: bool
|
14
13
|
super
|
15
14
|
end
|
16
15
|
|
17
|
-
|
16
|
+
# @override
|
17
|
+
#: -> bool
|
18
18
|
def parse!
|
19
19
|
return false unless @needs_parsing
|
20
20
|
|
@@ -29,12 +29,14 @@ module RubyLsp
|
|
29
29
|
true
|
30
30
|
end
|
31
31
|
|
32
|
-
|
32
|
+
# @override
|
33
|
+
#: -> bool
|
33
34
|
def syntax_error?
|
34
35
|
@syntax_error
|
35
36
|
end
|
36
37
|
|
37
|
-
|
38
|
+
# @override
|
39
|
+
#: -> LanguageId
|
38
40
|
def language_id
|
39
41
|
LanguageId::RBS
|
40
42
|
end
|
@@ -7,7 +7,6 @@ module RubyLsp
|
|
7
7
|
# request is used to to resolve the edit field for a given code action, if it is not already provided in the
|
8
8
|
# textDocument/codeAction response. We can use it for scenarios that require more computation such as refactoring.
|
9
9
|
class CodeActionResolve < Request
|
10
|
-
extend T::Sig
|
11
10
|
include Support::Common
|
12
11
|
|
13
12
|
NEW_VARIABLE_NAME = "new_variable"
|
@@ -23,7 +22,7 @@ module RubyLsp
|
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
|
-
|
25
|
+
#: (RubyDocument document, GlobalState global_state, Hash[Symbol, untyped] code_action) -> void
|
27
26
|
def initialize(document, global_state, code_action)
|
28
27
|
super()
|
29
28
|
@document = document
|
@@ -31,7 +30,8 @@ module RubyLsp
|
|
31
30
|
@code_action = code_action
|
32
31
|
end
|
33
32
|
|
34
|
-
|
33
|
+
# @override
|
34
|
+
#: -> (Interface::CodeAction | Error)
|
35
35
|
def perform
|
36
36
|
return Error::EmptySelection if @document.source.empty?
|
37
37
|
|
@@ -53,7 +53,7 @@ module RubyLsp
|
|
53
53
|
|
54
54
|
private
|
55
55
|
|
56
|
-
|
56
|
+
#: -> (Interface::CodeAction | Error)
|
57
57
|
def switch_block_style
|
58
58
|
source_range = @code_action.dig(:data, :range)
|
59
59
|
return Error::EmptySelection if source_range[:start] == source_range[:end]
|
@@ -91,7 +91,7 @@ module RubyLsp
|
|
91
91
|
)
|
92
92
|
end
|
93
93
|
|
94
|
-
|
94
|
+
#: -> (Interface::CodeAction | Error)
|
95
95
|
def refactor_variable
|
96
96
|
source_range = @code_action.dig(:data, :range)
|
97
97
|
return Error::EmptySelection if source_range[:start] == source_range[:end]
|
@@ -189,7 +189,7 @@ module RubyLsp
|
|
189
189
|
)
|
190
190
|
end
|
191
191
|
|
192
|
-
|
192
|
+
#: -> (Interface::CodeAction | Error)
|
193
193
|
def refactor_method
|
194
194
|
source_range = @code_action.dig(:data, :range)
|
195
195
|
return Error::EmptySelection if source_range[:start] == source_range[:end]
|
@@ -261,7 +261,7 @@ module RubyLsp
|
|
261
261
|
)
|
262
262
|
end
|
263
263
|
|
264
|
-
|
264
|
+
#: (Hash[Symbol, untyped] range, String new_text) -> Interface::TextEdit
|
265
265
|
def create_text_edit(range, new_text)
|
266
266
|
Interface::TextEdit.new(
|
267
267
|
range: Interface::Range.new(
|
@@ -272,7 +272,7 @@ module RubyLsp
|
|
272
272
|
)
|
273
273
|
end
|
274
274
|
|
275
|
-
|
275
|
+
#: (Prism::BlockNode node, String? indentation) -> String
|
276
276
|
def recursively_switch_nested_block_styles(node, indentation)
|
277
277
|
parameters = node.parameters
|
278
278
|
body = node.body
|
@@ -301,7 +301,7 @@ module RubyLsp
|
|
301
301
|
source
|
302
302
|
end
|
303
303
|
|
304
|
-
|
304
|
+
#: (Prism::Node body, String? indentation) -> String
|
305
305
|
def switch_block_body(body, indentation)
|
306
306
|
# Check if there are any nested blocks inside of the current block
|
307
307
|
body_loc = body.location
|
@@ -330,7 +330,7 @@ module RubyLsp
|
|
330
330
|
indentation ? body_content.gsub(";", "\n") : "#{body_content.gsub("\n", ";")} "
|
331
331
|
end
|
332
332
|
|
333
|
-
|
333
|
+
#: -> (Interface::CodeAction | Error)
|
334
334
|
def create_attribute_accessor
|
335
335
|
source_range = @code_action.dig(:data, :range)
|
336
336
|
|
@@ -7,8 +7,6 @@ module RubyLsp
|
|
7
7
|
# request informs the editor of RuboCop quick fixes that can be applied. These are accessible by hovering over a
|
8
8
|
# specific diagnostic.
|
9
9
|
class CodeActions < Request
|
10
|
-
extend T::Sig
|
11
|
-
|
12
10
|
EXTRACT_TO_VARIABLE_TITLE = "Refactor: Extract Variable"
|
13
11
|
EXTRACT_TO_METHOD_TITLE = "Refactor: Extract Method"
|
14
12
|
TOGGLE_BLOCK_STYLE_TITLE = "Refactor: Toggle block style"
|
@@ -16,22 +14,17 @@ module RubyLsp
|
|
16
14
|
CREATE_ATTRIBUTE_WRITER = "Create Attribute Writer"
|
17
15
|
CREATE_ATTRIBUTE_ACCESSOR = "Create Attribute Accessor"
|
18
16
|
|
19
|
-
INSTANCE_VARIABLE_NODES =
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
],
|
28
|
-
T::Array[T.class_of(Prism::Node)],
|
29
|
-
)
|
17
|
+
INSTANCE_VARIABLE_NODES = [
|
18
|
+
Prism::InstanceVariableAndWriteNode,
|
19
|
+
Prism::InstanceVariableOperatorWriteNode,
|
20
|
+
Prism::InstanceVariableOrWriteNode,
|
21
|
+
Prism::InstanceVariableReadNode,
|
22
|
+
Prism::InstanceVariableTargetNode,
|
23
|
+
Prism::InstanceVariableWriteNode,
|
24
|
+
] #: Array[singleton(Prism::Node)]
|
30
25
|
|
31
26
|
class << self
|
32
|
-
|
33
|
-
|
34
|
-
sig { returns(Interface::CodeActionRegistrationOptions) }
|
27
|
+
#: -> Interface::CodeActionRegistrationOptions
|
35
28
|
def provider
|
36
29
|
Interface::CodeActionRegistrationOptions.new(
|
37
30
|
document_selector: nil,
|
@@ -40,22 +33,17 @@ module RubyLsp
|
|
40
33
|
end
|
41
34
|
end
|
42
35
|
|
43
|
-
|
44
|
-
params(
|
45
|
-
document: T.any(RubyDocument, ERBDocument),
|
46
|
-
range: T::Hash[Symbol, T.untyped],
|
47
|
-
context: T::Hash[Symbol, T.untyped],
|
48
|
-
).void
|
49
|
-
end
|
36
|
+
#: ((RubyDocument | ERBDocument) document, Hash[Symbol, untyped] range, Hash[Symbol, untyped] context) -> void
|
50
37
|
def initialize(document, range, context)
|
51
38
|
super()
|
52
39
|
@document = document
|
53
|
-
@uri =
|
40
|
+
@uri = document.uri #: URI::Generic
|
54
41
|
@range = range
|
55
42
|
@context = context
|
56
43
|
end
|
57
44
|
|
58
|
-
|
45
|
+
# @override
|
46
|
+
#: -> (Array[Interface::CodeAction] & Object)?
|
59
47
|
def perform
|
60
48
|
diagnostics = @context[:diagnostics]
|
61
49
|
|
@@ -88,7 +76,7 @@ module RubyLsp
|
|
88
76
|
|
89
77
|
private
|
90
78
|
|
91
|
-
|
79
|
+
#: -> Array[Interface::CodeAction]
|
92
80
|
def attribute_actions
|
93
81
|
return [] unless @document.is_a?(RubyDocument)
|
94
82
|
|
@@ -11,29 +11,17 @@ module RubyLsp
|
|
11
11
|
# [code lens](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeLens)
|
12
12
|
# request informs the editor of runnable commands such as testing and debugging.
|
13
13
|
class CodeLens < Request
|
14
|
-
extend T::Sig
|
15
|
-
|
16
14
|
class << self
|
17
|
-
|
18
|
-
|
19
|
-
sig { returns(Interface::CodeLensOptions) }
|
15
|
+
#: -> Interface::CodeLensOptions
|
20
16
|
def provider
|
21
17
|
Interface::CodeLensOptions.new(resolve_provider: false)
|
22
18
|
end
|
23
19
|
end
|
24
20
|
|
25
|
-
|
26
|
-
params(
|
27
|
-
global_state: GlobalState,
|
28
|
-
uri: URI::Generic,
|
29
|
-
dispatcher: Prism::Dispatcher,
|
30
|
-
).void
|
31
|
-
end
|
21
|
+
#: (GlobalState global_state, URI::Generic uri, Prism::Dispatcher dispatcher) -> void
|
32
22
|
def initialize(global_state, uri, dispatcher)
|
33
|
-
@response_builder =
|
34
|
-
ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens]
|
35
|
-
ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens],
|
36
|
-
)
|
23
|
+
@response_builder = ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens]
|
24
|
+
.new #: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens]
|
37
25
|
super()
|
38
26
|
Listeners::CodeLens.new(@response_builder, global_state, uri, dispatcher)
|
39
27
|
|
@@ -42,7 +30,8 @@ module RubyLsp
|
|
42
30
|
end
|
43
31
|
end
|
44
32
|
|
45
|
-
|
33
|
+
# @override
|
34
|
+
#: -> Array[Interface::CodeLens]
|
46
35
|
def perform
|
47
36
|
@response_builder.response
|
48
37
|
end
|