ruby-lsp 0.23.14 → 0.23.16
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-launcher +9 -1
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +2 -2
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +6 -3
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +4 -2
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +60 -30
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +5 -4
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +5 -1
- data/lib/ruby_indexer/test/class_variables_test.rb +14 -14
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +65 -40
- data/lib/ruby_indexer/test/configuration_test.rb +6 -4
- data/lib/ruby_indexer/test/constant_test.rb +34 -34
- data/lib/ruby_indexer/test/enhancements_test.rb +1 -1
- data/lib/ruby_indexer/test/index_test.rb +139 -135
- data/lib/ruby_indexer/test/instance_variables_test.rb +37 -37
- data/lib/ruby_indexer/test/method_test.rb +118 -118
- data/lib/ruby_indexer/test/prefix_tree_test.rb +13 -13
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +64 -70
- data/lib/ruby_indexer/test/test_case.rb +2 -2
- data/lib/ruby_lsp/document.rb +6 -1
- data/lib/ruby_lsp/erb_document.rb +12 -4
- data/lib/ruby_lsp/global_state.rb +1 -1
- data/lib/ruby_lsp/listeners/code_lens.rb +3 -3
- data/lib/ruby_lsp/listeners/completion.rb +24 -11
- data/lib/ruby_lsp/listeners/definition.rb +1 -1
- data/lib/ruby_lsp/listeners/document_link.rb +3 -1
- data/lib/ruby_lsp/listeners/document_symbol.rb +3 -3
- data/lib/ruby_lsp/listeners/folding_ranges.rb +8 -4
- data/lib/ruby_lsp/listeners/hover.rb +2 -2
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +12 -5
- data/lib/ruby_lsp/listeners/signature_help.rb +5 -1
- data/lib/ruby_lsp/listeners/spec_style.rb +1 -1
- data/lib/ruby_lsp/listeners/test_style.rb +8 -8
- data/lib/ruby_lsp/requests/code_action_resolve.rb +14 -15
- data/lib/ruby_lsp/requests/completion_resolve.rb +1 -1
- data/lib/ruby_lsp/requests/hover.rb +2 -2
- data/lib/ruby_lsp/requests/on_type_formatting.rb +4 -2
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +1 -2
- data/lib/ruby_lsp/requests/references.rb +2 -1
- data/lib/ruby_lsp/requests/rename.rb +8 -5
- data/lib/ruby_lsp/requests/selection_ranges.rb +1 -1
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +4 -4
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +2 -2
- data/lib/ruby_lsp/requests/support/common.rb +3 -1
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +2 -2
- data/lib/ruby_lsp/requests/support/source_uri.rb +5 -3
- data/lib/ruby_lsp/response_builders/document_symbol.rb +3 -2
- data/lib/ruby_lsp/response_builders/hover.rb +1 -1
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +1 -1
- data/lib/ruby_lsp/ruby_document.rb +2 -2
- data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
- data/lib/ruby_lsp/server.rb +14 -5
- data/lib/ruby_lsp/setup_bundler.rb +7 -3
- data/lib/ruby_lsp/static_docs.rb +8 -1
- data/lib/ruby_lsp/store.rb +3 -2
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +164 -0
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +105 -0
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +94 -0
- data/lib/ruby_lsp/type_inferrer.rb +4 -1
- data/lib/ruby_lsp/utils.rb +12 -2
- metadata +6 -6
- data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +0 -109
- data/lib/ruby_lsp/test_reporter.rb +0 -207
- data/lib/ruby_lsp/test_unit_test_runner.rb +0 -98
@@ -299,7 +299,7 @@ module RubyLsp
|
|
299
299
|
methods = @index.resolve_method(message, type.name, inherited_only: inherited_only)
|
300
300
|
return unless methods
|
301
301
|
|
302
|
-
first_method =
|
302
|
+
first_method = methods.first #: as !nil
|
303
303
|
|
304
304
|
title = "#{message}#{first_method.decorated_parameters}"
|
305
305
|
title << first_method.formatted_signatures
|
@@ -365,7 +365,7 @@ module RubyLsp
|
|
365
365
|
|
366
366
|
# We should only show hover for private constants if the constant is defined in the same namespace as the
|
367
367
|
# reference
|
368
|
-
first_entry =
|
368
|
+
first_entry = entries.first #: as !nil
|
369
369
|
return if first_entry.private? && first_entry.name != "#{@node_context.fully_qualified_name}::#{name}"
|
370
370
|
|
371
371
|
categorized_markdown_from_index_entries(name, entries).each do |category, content|
|
@@ -67,12 +67,18 @@ module RubyLsp
|
|
67
67
|
return if special_method?(message)
|
68
68
|
|
69
69
|
if Requests::Support::Sorbet.annotation?(node)
|
70
|
-
@response_builder.add_token(
|
70
|
+
@response_builder.add_token(
|
71
|
+
node.message_loc, #: as !nil
|
72
|
+
:type,
|
73
|
+
)
|
71
74
|
elsif !node.receiver && !node.opening_loc
|
72
75
|
# If the node has a receiver, then the syntax is not ambiguous and semantic highlighting is not necessary to
|
73
76
|
# determine that the token is a method call. The only ambiguous case is method calls with implicit self
|
74
77
|
# receiver and no parenthesis, which may be confused with local variables
|
75
|
-
@response_builder.add_token(
|
78
|
+
@response_builder.add_token(
|
79
|
+
node.message_loc, #: as !nil
|
80
|
+
:method,
|
81
|
+
)
|
76
82
|
end
|
77
83
|
end
|
78
84
|
|
@@ -98,7 +104,7 @@ module RubyLsp
|
|
98
104
|
|
99
105
|
#: (Prism::DefNode node) -> void
|
100
106
|
def on_def_node_leave(node)
|
101
|
-
@current_scope =
|
107
|
+
@current_scope = @current_scope.parent #: as !nil
|
102
108
|
end
|
103
109
|
|
104
110
|
#: (Prism::BlockNode node) -> void
|
@@ -108,7 +114,7 @@ module RubyLsp
|
|
108
114
|
|
109
115
|
#: (Prism::BlockNode node) -> void
|
110
116
|
def on_block_node_leave(node)
|
111
|
-
@current_scope =
|
117
|
+
@current_scope = @current_scope.parent #: as !nil
|
112
118
|
end
|
113
119
|
|
114
120
|
#: (Prism::BlockLocalVariableNode node) -> void
|
@@ -301,7 +307,8 @@ module RubyLsp
|
|
301
307
|
# For each capture name we find in the regexp, look for a local in the current_scope
|
302
308
|
Regexp.new(content, Regexp::FIXEDENCODING).names.each do |name|
|
303
309
|
# The +3 is to compensate for the "(?<" part of the capture name
|
304
|
-
|
310
|
+
capture_name_index = content.index("(?<#{name}>") #: as !nil
|
311
|
+
capture_name_offset = capture_name_index + 3
|
305
312
|
local_var_loc = loc.copy(start_offset: loc.start_offset + capture_name_offset, length: name.length)
|
306
313
|
|
307
314
|
local = @current_scope.lookup(name)
|
@@ -69,7 +69,11 @@ module RubyLsp
|
|
69
69
|
signature.matches?(arguments)
|
70
70
|
end || 0
|
71
71
|
|
72
|
-
parameter_length = [
|
72
|
+
parameter_length = [
|
73
|
+
signatures[active_sig_index] #: as !nil
|
74
|
+
.parameters.length - 1,
|
75
|
+
0,
|
76
|
+
].max
|
73
77
|
active_parameter = (arguments.length - 1).clamp(0, parameter_length)
|
74
78
|
|
75
79
|
# If there are arguments, then we need to check if there's a trailing comma after the end of the last argument
|
@@ -22,7 +22,7 @@ module RubyLsp
|
|
22
22
|
queue = items.dup
|
23
23
|
|
24
24
|
until queue.empty?
|
25
|
-
item =
|
25
|
+
item = queue.shift #: as !nil
|
26
26
|
tags = Set.new(item[:tags])
|
27
27
|
next unless tags.include?("framework:minitest") || tags.include?("framework:test_unit")
|
28
28
|
|
@@ -93,9 +93,9 @@ module RubyLsp
|
|
93
93
|
if examples.empty?
|
94
94
|
"^#{group_regex}(#|::)"
|
95
95
|
elsif examples.length == 1
|
96
|
-
"^#{group_regex}##{examples[0]}
|
96
|
+
"^#{group_regex}##{examples[0]}\\$"
|
97
97
|
else
|
98
|
-
"^#{group_regex}#(#{examples.join("|")})
|
98
|
+
"^#{group_regex}#(#{examples.join("|")})\\$"
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
@@ -116,13 +116,13 @@ module RubyLsp
|
|
116
116
|
Shellwords.escape(TestDiscovery::DYNAMIC_REFERENCE_MARKER),
|
117
117
|
".*",
|
118
118
|
)
|
119
|
-
command = +"#{BASE_COMMAND} -Itest #{file_path} --testcase \"/^#{group_regex}
|
119
|
+
command = +"#{BASE_COMMAND} -Itest #{file_path} --testcase \"/^#{group_regex}\\$/\""
|
120
120
|
|
121
121
|
unless examples.empty?
|
122
122
|
command << if examples.length == 1
|
123
|
-
" --name \"/#{examples[0]}
|
123
|
+
" --name \"/#{examples[0]}\\$/\""
|
124
124
|
else
|
125
|
-
" --name \"/(#{examples.join("|")})
|
125
|
+
" --name \"/(#{examples.join("|")})\\$/\""
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
@@ -133,8 +133,8 @@ module RubyLsp
|
|
133
133
|
|
134
134
|
include Requests::Support::Common
|
135
135
|
|
136
|
-
MINITEST_REPORTER_PATH = File.expand_path("../
|
137
|
-
TEST_UNIT_REPORTER_PATH = File.expand_path("../
|
136
|
+
MINITEST_REPORTER_PATH = File.expand_path("../test_reporters/minitest_reporter.rb", __dir__) #: String
|
137
|
+
TEST_UNIT_REPORTER_PATH = File.expand_path("../test_reporters/test_unit_reporter.rb", __dir__) #: String
|
138
138
|
ACCESS_MODIFIERS = [:public, :private, :protected].freeze
|
139
139
|
BASE_COMMAND = begin
|
140
140
|
Bundler.with_original_env { Bundler.default_lockfile }
|
@@ -97,7 +97,7 @@ module RubyLsp
|
|
97
97
|
return Error::EmptySelection if source_range[:start] == source_range[:end]
|
98
98
|
|
99
99
|
start_index, end_index = @document.find_index_by_position(source_range[:start], source_range[:end])
|
100
|
-
extracted_source =
|
100
|
+
extracted_source = @document.source[start_index...end_index] #: as !nil
|
101
101
|
|
102
102
|
# Find the closest statements node, so that we place the refactor in a valid position
|
103
103
|
node_context = RubyDocument
|
@@ -115,10 +115,10 @@ module RubyLsp
|
|
115
115
|
|
116
116
|
# Find the node with the end line closest to the requested position, so that we can place the refactor
|
117
117
|
# immediately after that closest node
|
118
|
-
closest_node =
|
118
|
+
closest_node = closest_statements.child_nodes.compact.min_by do |node|
|
119
119
|
distance = source_range.dig(:start, :line) - (node.location.end_line - 1)
|
120
120
|
distance <= 0 ? Float::INFINITY : distance
|
121
|
-
end
|
121
|
+
end #: as !nil
|
122
122
|
|
123
123
|
return Error::InvalidTargetRange if closest_node.is_a?(Prism::MissingNode)
|
124
124
|
|
@@ -153,7 +153,8 @@ module RubyLsp
|
|
153
153
|
indentation_line = lines[indentation_line_number]
|
154
154
|
return Error::InvalidTargetRange unless indentation_line
|
155
155
|
|
156
|
-
indentation =
|
156
|
+
indentation = indentation_line[/\A */] #: as !nil
|
157
|
+
.size
|
157
158
|
|
158
159
|
target_range = {
|
159
160
|
start: { line: target_line, character: indentation },
|
@@ -195,7 +196,7 @@ module RubyLsp
|
|
195
196
|
return Error::EmptySelection if source_range[:start] == source_range[:end]
|
196
197
|
|
197
198
|
start_index, end_index = @document.find_index_by_position(source_range[:start], source_range[:end])
|
198
|
-
extracted_source =
|
199
|
+
extracted_source = @document.source[start_index...end_index] #: as !nil
|
199
200
|
|
200
201
|
# Find the closest method declaration node, so that we place the refactor in a valid position
|
201
202
|
node_context = RubyDocument.locate(
|
@@ -379,16 +380,14 @@ module RubyLsp
|
|
379
380
|
|
380
381
|
attribute_name = node.name[1..]
|
381
382
|
indentation = " " * (closest_node.location.start_column + 2)
|
382
|
-
attribute_accessor_source =
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
end,
|
391
|
-
)
|
383
|
+
attribute_accessor_source = case @code_action[:title]
|
384
|
+
when CodeActions::CREATE_ATTRIBUTE_READER
|
385
|
+
"#{indentation}attr_reader :#{attribute_name}\n\n"
|
386
|
+
when CodeActions::CREATE_ATTRIBUTE_WRITER
|
387
|
+
"#{indentation}attr_writer :#{attribute_name}\n\n"
|
388
|
+
when CodeActions::CREATE_ATTRIBUTE_ACCESSOR
|
389
|
+
"#{indentation}attr_accessor :#{attribute_name}\n\n"
|
390
|
+
end #: as !nil
|
392
391
|
|
393
392
|
target_start_line = closest_node.location.start_line
|
394
393
|
target_range = {
|
@@ -51,7 +51,9 @@ module RubyLsp
|
|
51
51
|
# But if it's a RBS signature starting with `#:`, we'll ignore it
|
52
52
|
# so users can immediately continue typing the method definition
|
53
53
|
if (comment_match = @previous_line.match(/^#(?!:)(\s*)/))
|
54
|
-
handle_comment_line(
|
54
|
+
handle_comment_line(
|
55
|
+
comment_match[1], #: as !nil
|
56
|
+
)
|
55
57
|
elsif @document.syntax_error?
|
56
58
|
match = /(<<((-|~)?))(?<quote>['"`]?)(?<delimiter>\w+)\k<quote>/.match(@previous_line)
|
57
59
|
heredoc_delimiter = match && match.named_captures["delimiter"]
|
@@ -76,7 +78,7 @@ module RubyLsp
|
|
76
78
|
current_line = @lines[@position[:line]]
|
77
79
|
return unless /((?<=do)|(?<={))\s+\|/.match?(current_line)
|
78
80
|
|
79
|
-
line =
|
81
|
+
line = current_line #: as !nil
|
80
82
|
|
81
83
|
# If the user inserts the closing pipe manually to the end of the block argument, we need to avoid adding
|
82
84
|
# an additional one and remove the previous one. This also helps to remove the user who accidentally
|
@@ -49,8 +49,7 @@ module RubyLsp
|
|
49
49
|
|
50
50
|
# While the spec allows for multiple entries, VSCode seems to only support one
|
51
51
|
# We'll just return the first one for now
|
52
|
-
first_entry =
|
53
|
-
|
52
|
+
first_entry = entries.first #: as !nil
|
54
53
|
range = range_from_location(first_entry.location)
|
55
54
|
|
56
55
|
[
|
@@ -106,7 +106,8 @@ module RubyLsp
|
|
106
106
|
entries = @global_state.index.resolve(name, node_context.nesting)
|
107
107
|
return unless entries
|
108
108
|
|
109
|
-
fully_qualified_name =
|
109
|
+
fully_qualified_name = entries.first #: as !nil
|
110
|
+
.name
|
110
111
|
RubyIndexer::ReferenceFinder::ConstTarget.new(fully_qualified_name)
|
111
112
|
when
|
112
113
|
Prism::InstanceVariableAndWriteNode,
|
@@ -63,10 +63,11 @@ module RubyLsp
|
|
63
63
|
return unless entries
|
64
64
|
|
65
65
|
if (conflict_entries = @global_state.index.resolve(@new_name, node_context.nesting))
|
66
|
-
raise InvalidNameError, "The new name is already in use by #{
|
66
|
+
raise InvalidNameError, "The new name is already in use by #{conflict_entries.first&.name}"
|
67
67
|
end
|
68
68
|
|
69
|
-
fully_qualified_name =
|
69
|
+
fully_qualified_name = entries.first #: as !nil
|
70
|
+
.name
|
70
71
|
reference_target = RubyIndexer::ReferenceFinder::ConstTarget.new(fully_qualified_name)
|
71
72
|
changes = collect_text_edits(reference_target, name)
|
72
73
|
|
@@ -97,9 +98,9 @@ module RubyLsp
|
|
97
98
|
# rename the files for the user.
|
98
99
|
#
|
99
100
|
# We also look for an associated test file and rename it too
|
100
|
-
short_name =
|
101
|
+
short_name = fully_qualified_name.split("::").last #: as !nil
|
101
102
|
|
102
|
-
|
103
|
+
@global_state.index[fully_qualified_name]&.each do |entry|
|
103
104
|
# Do not rename files that are not part of the workspace
|
104
105
|
uri = entry.uri
|
105
106
|
file_path = uri.full_path
|
@@ -112,7 +113,9 @@ module RubyLsp
|
|
112
113
|
file_name = file_from_constant_name(short_name)
|
113
114
|
|
114
115
|
if "#{file_name}.rb" == entry.file_name
|
115
|
-
new_file_name = file_from_constant_name(
|
116
|
+
new_file_name = file_from_constant_name(
|
117
|
+
@new_name.split("::").last, #: as !nil
|
118
|
+
)
|
116
119
|
|
117
120
|
new_uri = URI::Generic.from_path(path: File.join(
|
118
121
|
File.dirname(file_path),
|
@@ -32,7 +32,7 @@ module RubyLsp
|
|
32
32
|
next unless node
|
33
33
|
|
34
34
|
range = Support::SelectionRange.new(range: range_from_location(node.location), parent: parent)
|
35
|
-
|
35
|
+
queue.unshift(*node.child_nodes.map { |child| [child, range] })
|
36
36
|
@ranges.unshift(range)
|
37
37
|
end
|
38
38
|
|
@@ -43,8 +43,8 @@ module RubyLsp
|
|
43
43
|
# Filter the tokens based on the first different position. This must happen at this stage, before we try to
|
44
44
|
# find the next position from the end or else we risk confusing sets of token that may have different lengths,
|
45
45
|
# but end with the exact same token
|
46
|
-
old_tokens =
|
47
|
-
new_tokens =
|
46
|
+
old_tokens = previous_tokens[first_different_position...] #: as !nil
|
47
|
+
new_tokens = current_tokens[first_different_position...] #: as !nil
|
48
48
|
|
49
49
|
# Then search from the end to find the first token that doesn't match. Since the user is normally editing the
|
50
50
|
# middle of the file, this will minimize the number of edits since the end of the token array has not changed
|
@@ -53,8 +53,8 @@ module RubyLsp
|
|
53
53
|
end || 0
|
54
54
|
|
55
55
|
# Filter the old and new tokens to only the section that will be replaced/inserted/deleted
|
56
|
-
old_tokens =
|
57
|
-
new_tokens =
|
56
|
+
old_tokens = old_tokens[...old_tokens.length - first_different_token_from_end] #: as !nil
|
57
|
+
new_tokens = new_tokens[...new_tokens.length - first_different_token_from_end] #: as !nil
|
58
58
|
|
59
59
|
# And we send back a single edit, replacing an entire section for the new tokens
|
60
60
|
Interface::SemanticTokensDelta.new(
|
@@ -29,7 +29,7 @@ module RubyLsp
|
|
29
29
|
|
30
30
|
#: -> String
|
31
31
|
def ast_for_range
|
32
|
-
range =
|
32
|
+
range = @range #: as !nil
|
33
33
|
start_char, end_char = @document.find_index_by_position(range[:start], range[:end])
|
34
34
|
|
35
35
|
queue = @tree.statements.body.dup
|
@@ -46,7 +46,7 @@ module RubyLsp
|
|
46
46
|
if (start_char..end_char).cover?(loc.start_offset..loc.end_offset)
|
47
47
|
found_nodes << node
|
48
48
|
else
|
49
|
-
|
49
|
+
queue.unshift(*node.child_nodes)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -54,7 +54,9 @@ module RubyLsp
|
|
54
54
|
#: (String file_path) -> bool?
|
55
55
|
def not_in_dependencies?(file_path)
|
56
56
|
BUNDLE_PATH &&
|
57
|
-
!file_path.start_with?(
|
57
|
+
!file_path.start_with?(
|
58
|
+
BUNDLE_PATH, #: as !nil
|
59
|
+
) &&
|
58
60
|
!file_path.start_with?(RbConfig::CONFIG["rubylibdir"])
|
59
61
|
end
|
60
62
|
|
@@ -21,7 +21,7 @@ module RubyLsp
|
|
21
21
|
# @override
|
22
22
|
#: (URI::Generic uri, RubyDocument document) -> String?
|
23
23
|
def run_formatting(uri, document)
|
24
|
-
filename =
|
24
|
+
filename = uri.to_standardized_path || uri.opaque #: as !nil
|
25
25
|
|
26
26
|
# Invoke RuboCop with just this file in `paths`
|
27
27
|
@format_runner.run(filename, document.source)
|
@@ -38,7 +38,7 @@ module RubyLsp
|
|
38
38
|
# @override
|
39
39
|
#: (URI::Generic uri, RubyDocument document) -> Array[Interface::Diagnostic]?
|
40
40
|
def run_diagnostic(uri, document)
|
41
|
-
filename =
|
41
|
+
filename = uri.to_standardized_path || uri.opaque #: as !nil
|
42
42
|
# Invoke RuboCop with just this file in `paths`
|
43
43
|
@diagnostic_runner.run(filename, document.source)
|
44
44
|
|
@@ -21,8 +21,10 @@ module URI
|
|
21
21
|
# have the uri gem in their own bundle and thus not use a compatible version.
|
22
22
|
PARSER = const_defined?(:RFC2396_PARSER) ? RFC2396_PARSER : DEFAULT_PARSER #: RFC2396_Parser
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
self #: as untyped # rubocop:disable Style/RedundantSelf
|
25
|
+
.alias_method(:gem_name, :host)
|
26
|
+
self #: as untyped # rubocop:disable Style/RedundantSelf
|
27
|
+
.alias_method(:line_number, :fragment)
|
26
28
|
|
27
29
|
#: String?
|
28
30
|
attr_reader :gem_version
|
@@ -71,7 +73,7 @@ module URI
|
|
71
73
|
if URI.respond_to?(:register_scheme)
|
72
74
|
URI.register_scheme("SOURCE", self)
|
73
75
|
else
|
74
|
-
@@schemes = @@schemes # rubocop:disable Style/ClassVars
|
76
|
+
@@schemes = @@schemes #: Hash[String, untyped] # rubocop:disable Style/ClassVars
|
75
77
|
@@schemes["SOURCE"] = self
|
76
78
|
end
|
77
79
|
end
|
@@ -38,13 +38,14 @@ module RubyLsp
|
|
38
38
|
|
39
39
|
#: -> (SymbolHierarchyRoot | Interface::DocumentSymbol)
|
40
40
|
def last
|
41
|
-
|
41
|
+
@stack.last #: as !nil
|
42
42
|
end
|
43
43
|
|
44
44
|
# @override
|
45
45
|
#: -> Array[Interface::DocumentSymbol]
|
46
46
|
def response
|
47
|
-
|
47
|
+
@stack.first #: as !nil
|
48
|
+
.children
|
48
49
|
end
|
49
50
|
end
|
50
51
|
end
|
@@ -35,7 +35,7 @@ module RubyLsp
|
|
35
35
|
# @override
|
36
36
|
#: -> ResponseType
|
37
37
|
def response
|
38
|
-
result =
|
38
|
+
result = @response[:title] #: as !nil
|
39
39
|
result << "\n" << @response[:links] if @response[:links]
|
40
40
|
result << "\n" << @response[:documentation] if @response[:documentation]
|
41
41
|
|
@@ -64,7 +64,7 @@ module RubyLsp
|
|
64
64
|
start_line: location.start_line,
|
65
65
|
start_code_unit_column: location.cached_start_code_units_column(@code_units_cache),
|
66
66
|
length: length,
|
67
|
-
type:
|
67
|
+
type: TOKEN_TYPES[type], #: as !nil
|
68
68
|
modifier: modifiers_indices,
|
69
69
|
),
|
70
70
|
)
|
@@ -53,7 +53,7 @@ module RubyLsp
|
|
53
53
|
# Add the next child_nodes to the queue to be processed. The order here is important! We want to move in the
|
54
54
|
# same order as the visiting mechanism, which means searching the child nodes before moving on to the next
|
55
55
|
# sibling
|
56
|
-
|
56
|
+
queue.unshift(*candidate.child_nodes)
|
57
57
|
|
58
58
|
# Skip if the current node doesn't cover the desired position
|
59
59
|
loc = candidate.location
|
@@ -195,7 +195,7 @@ module RubyLsp
|
|
195
195
|
# Add the next child_nodes to the queue to be processed. The order here is important! We want to move in the
|
196
196
|
# same order as the visiting mechanism, which means searching the child nodes before moving on to the next
|
197
197
|
# sibling
|
198
|
-
|
198
|
+
queue.unshift(*candidate.child_nodes)
|
199
199
|
|
200
200
|
# Skip if the current node doesn't cover the desired position
|
201
201
|
loc = candidate.location
|
@@ -13,8 +13,10 @@ def compose(raw_initialize)
|
|
13
13
|
workspace_path ||= Dir.pwd
|
14
14
|
|
15
15
|
env = RubyLsp::SetupBundler.new(workspace_path, launcher: true).setup!
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
|
17
|
+
File.open(File.join(".ruby-lsp", "bundle_env"), "w") do |f|
|
18
|
+
f.flock(File::LOCK_EX)
|
19
|
+
f.write(env.map { |k, v| "#{k}=#{v}" }.join("\n"))
|
20
|
+
f.flush
|
21
|
+
end
|
20
22
|
end
|
data/lib/ruby_lsp/server.rb
CHANGED
@@ -223,7 +223,8 @@ module RubyLsp
|
|
223
223
|
configured_features = options.dig(:initializationOptions, :enabledFeatures)
|
224
224
|
|
225
225
|
configured_hints = options.dig(:initializationOptions, :featuresConfiguration, :inlayHint)
|
226
|
-
|
226
|
+
@store.features_configuration.dig(:inlayHint) #: as !nil
|
227
|
+
.configuration.merge!(configured_hints) if configured_hints
|
227
228
|
|
228
229
|
enabled_features = case configured_features
|
229
230
|
when Array
|
@@ -294,6 +295,7 @@ module RubyLsp
|
|
294
295
|
addon_detection: true,
|
295
296
|
compose_bundle: true,
|
296
297
|
go_to_relevant_file: true,
|
298
|
+
full_test_discovery: true,
|
297
299
|
},
|
298
300
|
),
|
299
301
|
serverInfo: {
|
@@ -488,7 +490,11 @@ module RubyLsp
|
|
488
490
|
document_symbol = Requests::DocumentSymbol.new(uri, dispatcher)
|
489
491
|
document_link = Requests::DocumentLink.new(uri, parse_result.comments, dispatcher)
|
490
492
|
code_lens = Requests::CodeLens.new(@global_state, uri, dispatcher)
|
491
|
-
inlay_hint = Requests::InlayHints.new(
|
493
|
+
inlay_hint = Requests::InlayHints.new(
|
494
|
+
document,
|
495
|
+
@store.features_configuration.dig(:inlayHint), #: as !nil
|
496
|
+
dispatcher,
|
497
|
+
)
|
492
498
|
|
493
499
|
if document.is_a?(RubyDocument) && document.should_index?
|
494
500
|
# Re-index the file as it is modified. This mode of indexing updates entries only. Require path trees are only
|
@@ -815,7 +821,7 @@ module RubyLsp
|
|
815
821
|
return
|
816
822
|
end
|
817
823
|
|
818
|
-
hints_configurations =
|
824
|
+
hints_configurations = @store.features_configuration.dig(:inlayHint) #: as !nil
|
819
825
|
dispatcher = Prism::Dispatcher.new
|
820
826
|
|
821
827
|
unless document.is_a?(RubyDocument) || document.is_a?(ERBDocument)
|
@@ -1056,7 +1062,8 @@ module RubyLsp
|
|
1056
1062
|
end
|
1057
1063
|
|
1058
1064
|
Addon.file_watcher_addons.each do |addon|
|
1059
|
-
|
1065
|
+
addon #: as untyped
|
1066
|
+
.workspace_did_change_watched_files(changes)
|
1060
1067
|
rescue => e
|
1061
1068
|
send_log_message(
|
1062
1069
|
"Error in #{addon.name} add-on while processing watched file notifications: #{e.full_message}",
|
@@ -1393,7 +1400,9 @@ module RubyLsp
|
|
1393
1400
|
Open3.capture3(
|
1394
1401
|
Gem.ruby,
|
1395
1402
|
"-I",
|
1396
|
-
File.dirname(
|
1403
|
+
File.dirname(
|
1404
|
+
__dir__, #: as !nil
|
1405
|
+
),
|
1397
1406
|
File.expand_path("../../exe/ruby-lsp-launcher", __dir__),
|
1398
1407
|
@global_state.workspace_uri.to_s,
|
1399
1408
|
chdir: @global_state.workspace_path,
|
@@ -260,7 +260,8 @@ module RubyLsp
|
|
260
260
|
# The ENV can only be merged after checking if an update is required because we depend on the original value of
|
261
261
|
# ENV["BUNDLE_GEMFILE"], which gets overridden after the merge
|
262
262
|
should_update = should_bundle_update?
|
263
|
-
|
263
|
+
ENV #: as untyped
|
264
|
+
.merge!(env)
|
264
265
|
|
265
266
|
unless should_update && !force_install
|
266
267
|
Bundler::CLI::Install.new({ "no-cache" => true }).run
|
@@ -405,12 +406,15 @@ module RubyLsp
|
|
405
406
|
def correct_relative_remote_paths
|
406
407
|
content = @custom_lockfile.read
|
407
408
|
content.gsub!(/remote: (.*)/) do |match|
|
408
|
-
|
409
|
+
last_match = Regexp.last_match #: as !nil
|
410
|
+
path = last_match[1]
|
409
411
|
|
410
412
|
# We should only apply the correction if the remote is a relative path. It might also be a URI, like
|
411
413
|
# `https://rubygems.org` or an absolute path, in which case we shouldn't do anything
|
412
414
|
if path && !URI(path).scheme
|
413
|
-
|
415
|
+
bundle_dir = @gemfile #: as !nil
|
416
|
+
.dirname
|
417
|
+
"remote: #{File.expand_path(path, bundle_dir)}"
|
414
418
|
else
|
415
419
|
match
|
416
420
|
end
|
data/lib/ruby_lsp/static_docs.rb
CHANGED
@@ -3,7 +3,14 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
# The path to the `static_docs` directory, where we keep long-form static documentation
|
6
|
-
STATIC_DOCS_PATH = File.join(
|
6
|
+
STATIC_DOCS_PATH = File.join(
|
7
|
+
File.dirname(
|
8
|
+
File.dirname(
|
9
|
+
__dir__, #: as !nil
|
10
|
+
),
|
11
|
+
),
|
12
|
+
"static_docs",
|
13
|
+
) #: String
|
7
14
|
|
8
15
|
# A map of keyword => short documentation to be displayed on hover or completion
|
9
16
|
KEYWORD_DOCS = {
|
data/lib/ruby_lsp/store.rb
CHANGED
@@ -46,7 +46,7 @@ module RubyLsp
|
|
46
46
|
end
|
47
47
|
|
48
48
|
set(uri: uri, source: File.binread(path), version: 0, language_id: language_id)
|
49
|
-
|
49
|
+
@state[uri.to_s] #: as !nil
|
50
50
|
rescue Errno::ENOENT
|
51
51
|
raise NonExistingDocumentError, uri.to_s
|
52
52
|
end
|
@@ -65,7 +65,8 @@ module RubyLsp
|
|
65
65
|
|
66
66
|
#: (uri: URI::Generic, edits: Array[Hash[Symbol, untyped]], version: Integer) -> void
|
67
67
|
def push_edits(uri:, edits:, version:)
|
68
|
-
|
68
|
+
@state[uri.to_s] #: as !nil
|
69
|
+
.push_edits(edits, version: version)
|
69
70
|
end
|
70
71
|
|
71
72
|
#: -> void
|