ruby-lsp 0.23.20 → 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/VERSION +1 -1
- data/exe/ruby-lsp +10 -4
- data/exe/ruby-lsp-check +0 -4
- data/exe/ruby-lsp-launcher +25 -11
- data/exe/ruby-lsp-test-exec +6 -0
- data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +0 -1
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +0 -1
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +7 -1
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +1 -4
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +10 -19
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +29 -7
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +2 -2
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +12 -8
- data/lib/ruby_indexer/test/configuration_test.rb +1 -2
- data/lib/ruby_indexer/test/index_test.rb +39 -0
- data/lib/ruby_indexer/test/instance_variables_test.rb +24 -0
- data/lib/ruby_indexer/test/method_test.rb +17 -0
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +2 -2
- data/lib/ruby_indexer/test/reference_finder_test.rb +79 -14
- data/lib/ruby_lsp/addon.rb +44 -15
- data/lib/ruby_lsp/base_server.rb +34 -26
- data/lib/ruby_lsp/document.rb +162 -52
- data/lib/ruby_lsp/erb_document.rb +8 -3
- data/lib/ruby_lsp/global_state.rb +21 -0
- data/lib/ruby_lsp/internal.rb +0 -2
- data/lib/ruby_lsp/listeners/completion.rb +14 -3
- data/lib/ruby_lsp/listeners/hover.rb +7 -0
- data/lib/ruby_lsp/listeners/inlay_hints.rb +5 -3
- data/lib/ruby_lsp/listeners/spec_style.rb +126 -67
- data/lib/ruby_lsp/listeners/test_discovery.rb +18 -15
- data/lib/ruby_lsp/listeners/test_style.rb +56 -23
- data/lib/ruby_lsp/requests/code_action_resolve.rb +3 -3
- data/lib/ruby_lsp/requests/code_lens.rb +14 -5
- data/lib/ruby_lsp/requests/completion.rb +1 -1
- data/lib/ruby_lsp/requests/definition.rb +1 -1
- data/lib/ruby_lsp/requests/discover_tests.rb +2 -2
- data/lib/ruby_lsp/requests/document_highlight.rb +1 -1
- data/lib/ruby_lsp/requests/hover.rb +1 -1
- data/lib/ruby_lsp/requests/inlay_hints.rb +3 -3
- data/lib/ruby_lsp/requests/on_type_formatting.rb +1 -1
- data/lib/ruby_lsp/requests/prepare_rename.rb +1 -1
- data/lib/ruby_lsp/requests/references.rb +10 -6
- data/lib/ruby_lsp/requests/rename.rb +8 -6
- data/lib/ruby_lsp/requests/request.rb +6 -7
- data/lib/ruby_lsp/requests/selection_ranges.rb +1 -1
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +1 -1
- data/lib/ruby_lsp/requests/signature_help.rb +1 -1
- data/lib/ruby_lsp/requests/support/common.rb +1 -3
- data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +2 -2
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +13 -3
- data/lib/ruby_lsp/response_builders/response_builder.rb +6 -8
- data/lib/ruby_lsp/ruby_document.rb +10 -5
- data/lib/ruby_lsp/server.rb +95 -110
- data/lib/ruby_lsp/setup_bundler.rb +59 -25
- data/lib/ruby_lsp/static_docs.rb +1 -0
- data/lib/ruby_lsp/store.rb +0 -10
- data/lib/ruby_lsp/test_helper.rb +1 -4
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +18 -7
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +54 -7
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +0 -1
- data/lib/ruby_lsp/utils.rb +47 -11
- data/static_docs/break.md +103 -0
- metadata +7 -19
- data/lib/ruby_lsp/load_sorbet.rb +0 -62
@@ -100,7 +100,7 @@ module RubyLsp
|
|
100
100
|
|
101
101
|
# Find the closest statements node, so that we place the refactor in a valid position
|
102
102
|
node_context = RubyDocument
|
103
|
-
.locate(@document.
|
103
|
+
.locate(@document.ast,
|
104
104
|
start_index,
|
105
105
|
node_types: [
|
106
106
|
Prism::StatementsNode,
|
@@ -207,7 +207,7 @@ module RubyLsp
|
|
207
207
|
|
208
208
|
# Find the closest method declaration node, so that we place the refactor in a valid position
|
209
209
|
node_context = RubyDocument.locate(
|
210
|
-
@document.
|
210
|
+
@document.ast,
|
211
211
|
start_index,
|
212
212
|
node_types: [Prism::DefNode],
|
213
213
|
code_units_cache: @document.code_units_cache,
|
@@ -365,7 +365,7 @@ module RubyLsp
|
|
365
365
|
end
|
366
366
|
end
|
367
367
|
|
368
|
-
node = node #: as Prism::InstanceVariableAndWriteNode | Prism::InstanceVariableOperatorWriteNode | Prism::InstanceVariableOrWriteNode | Prism::InstanceVariableReadNode | Prism::InstanceVariableTargetNode | Prism::InstanceVariableWriteNode
|
368
|
+
node = node #: as Prism::InstanceVariableAndWriteNode | Prism::InstanceVariableOperatorWriteNode | Prism::InstanceVariableOrWriteNode | Prism::InstanceVariableReadNode | Prism::InstanceVariableTargetNode | Prism::InstanceVariableWriteNode
|
369
369
|
|
370
370
|
node_context = @document.locate_node(
|
371
371
|
{
|
@@ -18,17 +18,25 @@ module RubyLsp
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
#: (GlobalState
|
22
|
-
def initialize(global_state,
|
21
|
+
#: (GlobalState, RubyDocument | ERBDocument, Prism::Dispatcher) -> void
|
22
|
+
def initialize(global_state, document, dispatcher)
|
23
23
|
@response_builder = ResponseBuilders::CollectionResponseBuilder
|
24
24
|
.new #: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens]
|
25
25
|
super()
|
26
26
|
|
27
|
+
@document = document
|
27
28
|
@test_builder = ResponseBuilders::TestCollection.new #: ResponseBuilders::TestCollection
|
29
|
+
uri = document.uri
|
30
|
+
file_path = uri.full_path
|
31
|
+
code_lens_config = global_state.feature_configuration(:codeLens)
|
32
|
+
test_lenses_enabled = (!code_lens_config || code_lens_config.enabled?(:enableTestCodeLens)) &&
|
33
|
+
file_path && File.fnmatch?(TEST_PATH_PATTERN, file_path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
|
28
34
|
|
29
35
|
if global_state.enabled_feature?(:fullTestDiscovery)
|
30
|
-
|
31
|
-
|
36
|
+
if test_lenses_enabled
|
37
|
+
Listeners::TestStyle.new(@test_builder, global_state, dispatcher, uri)
|
38
|
+
Listeners::SpecStyle.new(@test_builder, global_state, dispatcher, uri)
|
39
|
+
end
|
32
40
|
else
|
33
41
|
Listeners::CodeLens.new(@response_builder, global_state, uri, dispatcher)
|
34
42
|
end
|
@@ -36,7 +44,7 @@ module RubyLsp
|
|
36
44
|
Addon.addons.each do |addon|
|
37
45
|
addon.create_code_lens_listener(@response_builder, uri, dispatcher)
|
38
46
|
|
39
|
-
if global_state.enabled_feature?(:fullTestDiscovery)
|
47
|
+
if global_state.enabled_feature?(:fullTestDiscovery) && test_lenses_enabled
|
40
48
|
addon.create_discover_tests_listener(@test_builder, dispatcher, uri)
|
41
49
|
end
|
42
50
|
end
|
@@ -45,6 +53,7 @@ module RubyLsp
|
|
45
53
|
# @override
|
46
54
|
#: -> Array[Interface::CodeLens]
|
47
55
|
def perform
|
56
|
+
@document.cache_set("rubyLsp/discoverTests", @test_builder.response)
|
48
57
|
@response_builder.response + @test_builder.code_lens
|
49
58
|
end
|
50
59
|
end
|
@@ -43,7 +43,7 @@ module RubyLsp
|
|
43
43
|
addon.create_discover_tests_listener(@response_builder, @dispatcher, @document.uri)
|
44
44
|
end
|
45
45
|
|
46
|
-
@dispatcher.visit(@document.
|
46
|
+
@dispatcher.visit(@document.ast)
|
47
47
|
else
|
48
48
|
@global_state.synchronize do
|
49
49
|
RubyIndexer::DeclarationListener.new(
|
@@ -64,7 +64,7 @@ module RubyLsp
|
|
64
64
|
# Dispatch the events both for indexing the test file and discovering the tests. The order here is
|
65
65
|
# important because we need the index to be aware of the existing classes/modules/methods before the test
|
66
66
|
# listeners can do their work
|
67
|
-
@dispatcher.visit(@document.
|
67
|
+
@dispatcher.visit(@document.ast)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -24,7 +24,7 @@ module RubyLsp
|
|
24
24
|
delegate_request_if_needed!(global_state, document, char_position)
|
25
25
|
|
26
26
|
node_context = RubyDocument.locate(
|
27
|
-
document.
|
27
|
+
document.ast,
|
28
28
|
char_position,
|
29
29
|
node_types: Listeners::Hover::ALLOWED_TARGETS,
|
30
30
|
code_units_cache: document.code_units_cache,
|
@@ -16,13 +16,13 @@ module RubyLsp
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
#: ((RubyDocument | ERBDocument)
|
20
|
-
def initialize(
|
19
|
+
#: (GlobalState, (RubyDocument | ERBDocument), Prism::Dispatcher) -> void
|
20
|
+
def initialize(global_state, document, dispatcher)
|
21
21
|
super()
|
22
22
|
|
23
23
|
@response_builder = ResponseBuilders::CollectionResponseBuilder
|
24
24
|
.new #: ResponseBuilders::CollectionResponseBuilder[Interface::InlayHint]
|
25
|
-
Listeners::InlayHints.new(@response_builder,
|
25
|
+
Listeners::InlayHints.new(global_state, @response_builder, dispatcher)
|
26
26
|
end
|
27
27
|
|
28
28
|
# @override
|
@@ -162,7 +162,7 @@ module RubyLsp
|
|
162
162
|
|
163
163
|
#: (Integer line, Integer character) -> void
|
164
164
|
def move_cursor_to(line, character)
|
165
|
-
return unless /Visual Studio Code|Cursor|VSCodium/.match?(@client_name)
|
165
|
+
return unless /Visual Studio Code|Cursor|VSCodium|Windsurf/.match?(@client_name)
|
166
166
|
|
167
167
|
position = Interface::Position.new(
|
168
168
|
line: line,
|
@@ -22,7 +22,7 @@ module RubyLsp
|
|
22
22
|
char_position, _ = @document.find_index_by_position(@position)
|
23
23
|
|
24
24
|
node_context = RubyDocument.locate(
|
25
|
-
@document.
|
25
|
+
@document.ast,
|
26
26
|
char_position,
|
27
27
|
node_types: [Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::ConstantPathTargetNode],
|
28
28
|
code_units_cache: @document.code_units_cache,
|
@@ -26,7 +26,7 @@ module RubyLsp
|
|
26
26
|
char_position, _ = @document.find_index_by_position(position)
|
27
27
|
|
28
28
|
node_context = RubyDocument.locate(
|
29
|
-
@document.
|
29
|
+
@document.ast,
|
30
30
|
char_position,
|
31
31
|
node_types: [
|
32
32
|
Prism::ConstantReadNode,
|
@@ -55,7 +55,7 @@ module RubyLsp
|
|
55
55
|
)
|
56
56
|
end
|
57
57
|
|
58
|
-
target = target #: as Prism::ConstantReadNode | Prism::ConstantPathNode | Prism::ConstantPathTargetNode | Prism::InstanceVariableAndWriteNode | Prism::InstanceVariableOperatorWriteNode | Prism::InstanceVariableOrWriteNode | Prism::InstanceVariableReadNode | Prism::InstanceVariableTargetNode | Prism::InstanceVariableWriteNode | Prism::CallNode | Prism::DefNode,
|
58
|
+
target = target #: as Prism::ConstantReadNode | Prism::ConstantPathNode | Prism::ConstantPathTargetNode | Prism::InstanceVariableAndWriteNode | Prism::InstanceVariableOperatorWriteNode | Prism::InstanceVariableOrWriteNode | Prism::InstanceVariableReadNode | Prism::InstanceVariableTargetNode | Prism::InstanceVariableWriteNode | Prism::CallNode | Prism::DefNode,
|
59
59
|
|
60
60
|
reference_target = create_reference_target(target, node_context)
|
61
61
|
return @locations unless reference_target
|
@@ -66,7 +66,7 @@ module RubyLsp
|
|
66
66
|
# of reading from disk
|
67
67
|
next if @store.key?(uri)
|
68
68
|
|
69
|
-
parse_result = Prism.
|
69
|
+
parse_result = Prism.parse_lex_file(path)
|
70
70
|
collect_references(reference_target, parse_result, uri)
|
71
71
|
rescue Errno::EISDIR, Errno::ENOENT
|
72
72
|
# If `path` is a directory, just ignore it and continue. If the file doesn't exist, then we also ignore it.
|
@@ -101,13 +101,17 @@ module RubyLsp
|
|
101
101
|
Prism::InstanceVariableReadNode,
|
102
102
|
Prism::InstanceVariableTargetNode,
|
103
103
|
Prism::InstanceVariableWriteNode
|
104
|
-
|
104
|
+
receiver_type = @global_state.type_inferrer.infer_receiver_type(node_context)
|
105
|
+
return unless receiver_type
|
106
|
+
|
107
|
+
ancestors = @global_state.index.linearized_ancestors_of(receiver_type.name)
|
108
|
+
RubyIndexer::ReferenceFinder::InstanceVariableTarget.new(target_node.name.to_s, ancestors)
|
105
109
|
when Prism::CallNode, Prism::DefNode
|
106
110
|
RubyIndexer::ReferenceFinder::MethodTarget.new(target_node.name.to_s)
|
107
111
|
end
|
108
112
|
end
|
109
113
|
|
110
|
-
#: (RubyIndexer::ReferenceFinder::Target target, Prism::
|
114
|
+
#: (RubyIndexer::ReferenceFinder::Target target, Prism::LexResult parse_result, URI::Generic uri) -> void
|
111
115
|
def collect_references(target, parse_result, uri)
|
112
116
|
dispatcher = Prism::Dispatcher.new
|
113
117
|
finder = RubyIndexer::ReferenceFinder.new(
|
@@ -117,7 +121,7 @@ module RubyLsp
|
|
117
121
|
uri,
|
118
122
|
include_declarations: @params.dig(:context, :includeDeclaration) || true,
|
119
123
|
)
|
120
|
-
dispatcher.visit(parse_result.value)
|
124
|
+
dispatcher.visit(parse_result.value.first)
|
121
125
|
|
122
126
|
finder.references.each do |reference|
|
123
127
|
@locations << Interface::Location.new(
|
@@ -34,7 +34,7 @@ module RubyLsp
|
|
34
34
|
char_position, _ = @document.find_index_by_position(@position)
|
35
35
|
|
36
36
|
node_context = RubyDocument.locate(
|
37
|
-
@document.
|
37
|
+
@document.ast,
|
38
38
|
char_position,
|
39
39
|
node_types: [Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::ConstantPathTargetNode],
|
40
40
|
code_units_cache: @document.code_units_cache,
|
@@ -136,25 +136,27 @@ module RubyLsp
|
|
136
136
|
next if @store.key?(uri)
|
137
137
|
|
138
138
|
parse_result = Prism.parse_file(path)
|
139
|
-
edits = collect_changes(target, parse_result, name, uri)
|
139
|
+
edits = collect_changes(target, parse_result.value, name, uri)
|
140
140
|
changes[uri.to_s] = edits unless edits.empty?
|
141
141
|
rescue Errno::EISDIR, Errno::ENOENT
|
142
142
|
# If `path` is a directory, just ignore it and continue. If the file doesn't exist, then we also ignore it.
|
143
143
|
end
|
144
144
|
|
145
145
|
@store.each do |uri, document|
|
146
|
-
|
146
|
+
next unless document.is_a?(RubyDocument) || document.is_a?(ERBDocument)
|
147
|
+
|
148
|
+
edits = collect_changes(target, document.ast, name, document.uri)
|
147
149
|
changes[uri] = edits unless edits.empty?
|
148
150
|
end
|
149
151
|
|
150
152
|
changes
|
151
153
|
end
|
152
154
|
|
153
|
-
#: (RubyIndexer::ReferenceFinder::Target target, Prism::
|
154
|
-
def collect_changes(target,
|
155
|
+
#: (RubyIndexer::ReferenceFinder::Target target, Prism::Node ast, String name, URI::Generic uri) -> Array[Interface::TextEdit]
|
156
|
+
def collect_changes(target, ast, name, uri)
|
155
157
|
dispatcher = Prism::Dispatcher.new
|
156
158
|
finder = RubyIndexer::ReferenceFinder.new(target, @global_state.index, dispatcher, uri)
|
157
|
-
dispatcher.visit(
|
159
|
+
dispatcher.visit(ast)
|
158
160
|
|
159
161
|
finder.references.map do |reference|
|
160
162
|
adjust_reference_for_edit(name, reference)
|
@@ -3,16 +3,15 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
+
# @abstract
|
6
7
|
class Request
|
7
|
-
extend T::Helpers
|
8
|
-
extend T::Sig
|
9
|
-
|
10
8
|
class InvalidFormatter < StandardError; end
|
11
9
|
|
12
|
-
abstract
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
# @abstract
|
11
|
+
#: -> untyped
|
12
|
+
def perform
|
13
|
+
raise AbstractMethodInvokedError
|
14
|
+
end
|
16
15
|
|
17
16
|
private
|
18
17
|
|
@@ -27,7 +27,7 @@ module RubyLsp
|
|
27
27
|
delegate_request_if_needed!(global_state, document, char_position)
|
28
28
|
|
29
29
|
node_context = RubyDocument.locate(
|
30
|
-
document.
|
30
|
+
document.ast,
|
31
31
|
char_position,
|
32
32
|
node_types: [Prism::CallNode],
|
33
33
|
code_units_cache: document.code_units_cache,
|
@@ -4,13 +4,11 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
6
|
module Support
|
7
|
+
# @requires_ancestor: Kernel
|
7
8
|
module Common
|
8
9
|
# WARNING: Methods in this class may be used by Ruby LSP add-ons such as
|
9
10
|
# https://github.com/Shopify/ruby-lsp-rails, or add-ons by created by developers outside of Shopify, so be
|
10
11
|
# cautious of changing anything.
|
11
|
-
extend T::Helpers
|
12
|
-
|
13
|
-
requires_ancestor { Kernel }
|
14
12
|
|
15
13
|
#: (Prism::Node node) -> Interface::Range
|
16
14
|
def range_from_node(node)
|
@@ -4,25 +4,26 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
6
|
module Support
|
7
|
+
# Empty module to avoid the runtime component. This is an interface defined in sorbet/rbi/shims/ruby_lsp.rbi
|
8
|
+
# @interface
|
7
9
|
module Formatter
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
sig { abstract.params(uri: URI::Generic, document: RubyDocument).returns(T.nilable(String)) }
|
14
|
-
def run_formatting(uri, document); end
|
10
|
+
# @abstract
|
11
|
+
#: (URI::Generic, RubyLsp::RubyDocument) -> String?
|
12
|
+
def run_formatting(uri, document)
|
13
|
+
raise AbstractMethodInvokedError
|
14
|
+
end
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
# @abstract
|
17
|
+
#: (URI::Generic, String, Integer) -> String?
|
18
|
+
def run_range_formatting(uri, source, base_indentation)
|
19
|
+
raise AbstractMethodInvokedError
|
20
|
+
end
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
).returns(T.nilable(T::Array[Interface::Diagnostic]))
|
22
|
+
# @abstract
|
23
|
+
#: (URI::Generic, RubyLsp::RubyDocument) -> Array[Interface::Diagnostic]?
|
24
|
+
def run_diagnostic(uri, document)
|
25
|
+
raise AbstractMethodInvokedError
|
24
26
|
end
|
25
|
-
def run_diagnostic(uri, document); end
|
26
27
|
end
|
27
28
|
end
|
28
29
|
end
|
@@ -24,7 +24,7 @@ module RubyLsp
|
|
24
24
|
filename = uri.to_standardized_path || uri.opaque #: as !nil
|
25
25
|
|
26
26
|
# Invoke RuboCop with just this file in `paths`
|
27
|
-
@format_runner.run(filename, document.source)
|
27
|
+
@format_runner.run(filename, document.source, document.parse_result)
|
28
28
|
@format_runner.formatted_source
|
29
29
|
end
|
30
30
|
|
@@ -40,7 +40,7 @@ module RubyLsp
|
|
40
40
|
def run_diagnostic(uri, document)
|
41
41
|
filename = uri.to_standardized_path || uri.opaque #: as !nil
|
42
42
|
# Invoke RuboCop with just this file in `paths`
|
43
|
-
@diagnostic_runner.run(filename, document.source)
|
43
|
+
@diagnostic_runner.run(filename, document.source, document.parse_result)
|
44
44
|
|
45
45
|
@diagnostic_runner.offenses.map do |offense|
|
46
46
|
Support::RuboCopDiagnostic.new(
|
@@ -81,6 +81,7 @@ module RubyLsp
|
|
81
81
|
@offenses = [] #: Array[::RuboCop::Cop::Offense]
|
82
82
|
@errors = [] #: Array[String]
|
83
83
|
@warnings = [] #: Array[String]
|
84
|
+
# @prism_result = nil #: Prism::ParseLexResult?
|
84
85
|
|
85
86
|
args += DEFAULT_ARGS
|
86
87
|
rubocop_options = ::RuboCop::Options.new.parse(args).first
|
@@ -92,8 +93,8 @@ module RubyLsp
|
|
92
93
|
super(rubocop_options, config_store)
|
93
94
|
end
|
94
95
|
|
95
|
-
#: (String
|
96
|
-
def run(path, contents)
|
96
|
+
#: (String, String, Prism::ParseLexResult) -> void
|
97
|
+
def run(path, contents, prism_result)
|
97
98
|
# Clear Runner state between runs since we get a single instance of this class
|
98
99
|
# on every use site.
|
99
100
|
@errors = []
|
@@ -101,6 +102,11 @@ module RubyLsp
|
|
101
102
|
@offenses = []
|
102
103
|
@options[:stdin] = contents
|
103
104
|
|
105
|
+
# Setting the Prism result before running the RuboCop runner makes it reuse the existing AST and avoids
|
106
|
+
# double-parsing. Unfortunately, this leads to a bunch of cops failing to execute properly under LSP mode.
|
107
|
+
# Uncomment this once reusing the Prism result is more stable
|
108
|
+
# @prism_result = prism_result
|
109
|
+
|
104
110
|
super([path])
|
105
111
|
|
106
112
|
# RuboCop rescues interrupts and then sets the `@aborting` variable to true. We don't want them to be rescued,
|
@@ -111,7 +117,11 @@ module RubyLsp
|
|
111
117
|
rescue ::RuboCop::ValidationError => error
|
112
118
|
raise ConfigurationError, error.message
|
113
119
|
rescue StandardError => error
|
114
|
-
|
120
|
+
# Maintain the original backtrace so that debugging cops that are breaking is easier, but re-raise as a
|
121
|
+
# different error class
|
122
|
+
internal_error = InternalRuboCopError.new(error)
|
123
|
+
internal_error.set_backtrace(error.backtrace)
|
124
|
+
raise internal_error
|
115
125
|
end
|
116
126
|
|
117
127
|
#: -> String
|
@@ -3,15 +3,13 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
|
+
# @abstract
|
6
7
|
class ResponseBuilder
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
sig { abstract.returns(T.anything) }
|
14
|
-
def response; end
|
8
|
+
# @abstract
|
9
|
+
#: -> top
|
10
|
+
def response
|
11
|
+
raise AbstractMethodInvokedError
|
12
|
+
end
|
15
13
|
end
|
16
14
|
end
|
17
15
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
5
|
-
#: [ParseResultType = Prism::
|
5
|
+
#: [ParseResultType = Prism::ParseLexResult]
|
6
6
|
class RubyDocument < Document
|
7
7
|
METHODS_THAT_CHANGE_DECLARATIONS = [
|
8
8
|
:private_constant,
|
@@ -26,7 +26,7 @@ module RubyLsp
|
|
26
26
|
queue = node.child_nodes.compact #: Array[Prism::Node?]
|
27
27
|
closest = node
|
28
28
|
parent = nil #: Prism::Node?
|
29
|
-
nesting_nodes = [] #: Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)]
|
29
|
+
nesting_nodes = [] #: Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)]
|
30
30
|
|
31
31
|
nesting_nodes << node if node.is_a?(Prism::ProgramNode)
|
32
32
|
call_node = nil #: Prism::CallNode?
|
@@ -129,11 +129,16 @@ module RubyLsp
|
|
129
129
|
return false unless @needs_parsing
|
130
130
|
|
131
131
|
@needs_parsing = false
|
132
|
-
@parse_result = Prism.
|
132
|
+
@parse_result = Prism.parse_lex(@source)
|
133
133
|
@code_units_cache = @parse_result.code_units_cache(@encoding)
|
134
134
|
true
|
135
135
|
end
|
136
136
|
|
137
|
+
#: -> Prism::ProgramNode
|
138
|
+
def ast
|
139
|
+
@parse_result.value.first
|
140
|
+
end
|
141
|
+
|
137
142
|
# @override
|
138
143
|
#: -> bool
|
139
144
|
def syntax_error?
|
@@ -151,7 +156,7 @@ module RubyLsp
|
|
151
156
|
start_position, end_position = find_index_by_position(range[:start], range[:end])
|
152
157
|
|
153
158
|
desired_range = (start_position...end_position)
|
154
|
-
queue =
|
159
|
+
queue = ast.child_nodes.compact #: Array[Prism::Node?]
|
155
160
|
|
156
161
|
until queue.empty?
|
157
162
|
candidate = queue.shift
|
@@ -179,7 +184,7 @@ module RubyLsp
|
|
179
184
|
char_position, _ = find_index_by_position(position)
|
180
185
|
|
181
186
|
RubyDocument.locate(
|
182
|
-
|
187
|
+
ast,
|
183
188
|
char_position,
|
184
189
|
code_units_cache: @code_units_cache,
|
185
190
|
node_types: node_types,
|