ruby-lsp 0.12.2 → 0.12.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/VERSION +1 -1
- data/exe/ruby-lsp-doctor +2 -2
- data/lib/ruby_indexer/lib/ruby_indexer/{visitor.rb → collector.rb} +108 -59
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +8 -3
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +9 -3
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +22 -4
- data/lib/ruby_indexer/ruby_indexer.rb +1 -1
- data/lib/ruby_indexer/test/index_test.rb +53 -0
- data/lib/ruby_indexer/test/method_test.rb +14 -0
- data/lib/ruby_lsp/document.rb +7 -9
- data/lib/ruby_lsp/executor.rb +29 -24
- data/lib/ruby_lsp/internal.rb +4 -0
- data/lib/ruby_lsp/requests/code_action_resolve.rb +8 -4
- data/lib/ruby_lsp/requests/completion.rb +49 -3
- data/lib/ruby_lsp/requests/definition.rb +52 -25
- data/lib/ruby_lsp/requests/document_highlight.rb +18 -8
- data/lib/ruby_lsp/requests/folding_ranges.rb +1 -1
- data/lib/ruby_lsp/requests/hover.rb +20 -0
- data/lib/ruby_lsp/requests/inlay_hints.rb +39 -1
- data/lib/ruby_lsp/requests/on_type_formatting.rb +16 -1
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +13 -5
- data/lib/ruby_lsp/requests/support/common.rb +22 -2
- data/lib/ruby_lsp/requests/support/dependency_detector.rb +0 -1
- data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -11
- data/lib/ruby_lsp/ruby_document.rb +14 -0
- data/lib/ruby_lsp/setup_bundler.rb +2 -0
- data/lib/ruby_lsp/store.rb +1 -3
- data/lib/ruby_lsp/utils.rb +9 -0
- metadata +8 -7
@@ -87,15 +87,19 @@ module RubyLsp
|
|
87
87
|
:start,
|
88
88
|
:line,
|
89
89
|
) && closest_node_loc.end_line - 1 >= source_range.dig(:end, :line)
|
90
|
-
|
91
|
-
target_line =
|
90
|
+
indentation_line_number = closest_node_loc.start_line - 1
|
91
|
+
target_line = indentation_line_number
|
92
92
|
else
|
93
93
|
target_line = closest_node_loc.end_line
|
94
|
-
|
94
|
+
indentation_line_number = closest_node_loc.end_line - 1
|
95
95
|
end
|
96
96
|
|
97
97
|
lines = @document.source.lines
|
98
|
-
|
98
|
+
|
99
|
+
indentation_line = lines[indentation_line_number]
|
100
|
+
return Error::InvalidTargetRange unless indentation_line
|
101
|
+
|
102
|
+
indentation = T.must(indentation_line[/\A */]).size
|
99
103
|
|
100
104
|
target_range = {
|
101
105
|
start: { line: target_line, character: indentation },
|
@@ -6,9 +6,14 @@ module RubyLsp
|
|
6
6
|
# 
|
7
7
|
#
|
8
8
|
# The [completion](https://microsoft.github.io/language-server-protocol/specification#textDocument_completion)
|
9
|
-
# suggests possible completions according to what the developer is typing.
|
10
|
-
#
|
11
|
-
#
|
9
|
+
# suggests possible completions according to what the developer is typing.
|
10
|
+
#
|
11
|
+
# Currently supported targets:
|
12
|
+
# - Classes
|
13
|
+
# - Modules
|
14
|
+
# - Constants
|
15
|
+
# - Require paths
|
16
|
+
# - Methods invoked on self only
|
12
17
|
#
|
13
18
|
# # Example
|
14
19
|
#
|
@@ -45,6 +50,7 @@ module RubyLsp
|
|
45
50
|
:on_string_node_enter,
|
46
51
|
:on_constant_path_node_enter,
|
47
52
|
:on_constant_read_node_enter,
|
53
|
+
:on_call_node_enter,
|
48
54
|
)
|
49
55
|
end
|
50
56
|
|
@@ -118,8 +124,48 @@ module RubyLsp
|
|
118
124
|
end
|
119
125
|
end
|
120
126
|
|
127
|
+
sig { params(node: Prism::CallNode).void }
|
128
|
+
def on_call_node_enter(node)
|
129
|
+
return if DependencyDetector.instance.typechecker
|
130
|
+
return unless self_receiver?(node)
|
131
|
+
|
132
|
+
name = node.message
|
133
|
+
return unless name
|
134
|
+
|
135
|
+
receiver_entries = @index[@nesting.join("::")]
|
136
|
+
return unless receiver_entries
|
137
|
+
|
138
|
+
receiver = T.must(receiver_entries.first)
|
139
|
+
|
140
|
+
candidates = T.cast(@index.prefix_search(name), T::Array[T::Array[RubyIndexer::Entry::Method]])
|
141
|
+
candidates.each do |entries|
|
142
|
+
entry = entries.find { |e| e.owner&.name == receiver.name }
|
143
|
+
next unless entry
|
144
|
+
|
145
|
+
@_response << build_method_completion(entry, node)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
121
149
|
private
|
122
150
|
|
151
|
+
sig { params(entry: RubyIndexer::Entry::Method, node: Prism::CallNode).returns(Interface::CompletionItem) }
|
152
|
+
def build_method_completion(entry, node)
|
153
|
+
name = entry.name
|
154
|
+
parameters = entry.parameters
|
155
|
+
new_text = parameters.empty? ? name : "#{name}(#{parameters.map(&:name).join(", ")})"
|
156
|
+
|
157
|
+
Interface::CompletionItem.new(
|
158
|
+
label: name,
|
159
|
+
filter_text: name,
|
160
|
+
text_edit: Interface::TextEdit.new(range: range_from_node(node), new_text: new_text),
|
161
|
+
kind: Constant::CompletionItemKind::METHOD,
|
162
|
+
label_details: Interface::CompletionItemLabelDetails.new(
|
163
|
+
description: entry.file_name,
|
164
|
+
),
|
165
|
+
documentation: markdown_from_index_entries(name, entry),
|
166
|
+
)
|
167
|
+
end
|
168
|
+
|
123
169
|
sig { params(label: String, node: Prism::StringNode).returns(Interface::CompletionItem) }
|
124
170
|
def build_completion(label, node)
|
125
171
|
Interface::CompletionItem.new(
|
@@ -9,7 +9,12 @@ module RubyLsp
|
|
9
9
|
# request](https://microsoft.github.io/language-server-protocol/specification#textDocument_definition) jumps to the
|
10
10
|
# definition of the symbol under the cursor.
|
11
11
|
#
|
12
|
-
# Currently
|
12
|
+
# Currently supported targets:
|
13
|
+
# - Classes
|
14
|
+
# - Modules
|
15
|
+
# - Constants
|
16
|
+
# - Require paths
|
17
|
+
# - Methods invoked on self only
|
13
18
|
#
|
14
19
|
# # Example
|
15
20
|
#
|
@@ -75,8 +80,52 @@ module RubyLsp
|
|
75
80
|
sig { params(node: Prism::CallNode).void }
|
76
81
|
def on_call_node_enter(node)
|
77
82
|
message = node.name
|
78
|
-
return unless message == :require || message == :require_relative
|
79
83
|
|
84
|
+
if message == :require || message == :require_relative
|
85
|
+
handle_require_definition(node)
|
86
|
+
else
|
87
|
+
handle_method_definition(node)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
sig { params(node: Prism::ConstantPathNode).void }
|
92
|
+
def on_constant_path_node_enter(node)
|
93
|
+
find_in_index(node.slice)
|
94
|
+
end
|
95
|
+
|
96
|
+
sig { params(node: Prism::ConstantReadNode).void }
|
97
|
+
def on_constant_read_node_enter(node)
|
98
|
+
find_in_index(node.slice)
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
sig { params(node: Prism::CallNode).void }
|
104
|
+
def handle_method_definition(node)
|
105
|
+
return unless self_receiver?(node)
|
106
|
+
|
107
|
+
message = node.message
|
108
|
+
return unless message
|
109
|
+
|
110
|
+
target_method = @index.resolve_method(message, @nesting.join("::"))
|
111
|
+
return unless target_method
|
112
|
+
|
113
|
+
location = target_method.location
|
114
|
+
file_path = target_method.file_path
|
115
|
+
return if defined_in_gem?(file_path)
|
116
|
+
|
117
|
+
@_response = Interface::Location.new(
|
118
|
+
uri: URI::Generic.from_path(path: file_path).to_s,
|
119
|
+
range: Interface::Range.new(
|
120
|
+
start: Interface::Position.new(line: location.start_line - 1, character: location.start_column),
|
121
|
+
end: Interface::Position.new(line: location.end_line - 1, character: location.end_column),
|
122
|
+
),
|
123
|
+
)
|
124
|
+
end
|
125
|
+
|
126
|
+
sig { params(node: Prism::CallNode).void }
|
127
|
+
def handle_require_definition(node)
|
128
|
+
message = node.name
|
80
129
|
arguments = node.arguments
|
81
130
|
return unless arguments
|
82
131
|
|
@@ -116,18 +165,6 @@ module RubyLsp
|
|
116
165
|
end
|
117
166
|
end
|
118
167
|
|
119
|
-
sig { params(node: Prism::ConstantPathNode).void }
|
120
|
-
def on_constant_path_node_enter(node)
|
121
|
-
find_in_index(node.slice)
|
122
|
-
end
|
123
|
-
|
124
|
-
sig { params(node: Prism::ConstantReadNode).void }
|
125
|
-
def on_constant_read_node_enter(node)
|
126
|
-
find_in_index(node.slice)
|
127
|
-
end
|
128
|
-
|
129
|
-
private
|
130
|
-
|
131
168
|
sig { params(value: String).void }
|
132
169
|
def find_in_index(value)
|
133
170
|
entries = @index.resolve(value, @nesting)
|
@@ -138,23 +175,13 @@ module RubyLsp
|
|
138
175
|
first_entry = T.must(entries.first)
|
139
176
|
return if first_entry.visibility == :private && first_entry.name != "#{@nesting.join("::")}::#{value}"
|
140
177
|
|
141
|
-
bundle_path = begin
|
142
|
-
Bundler.bundle_path.to_s
|
143
|
-
rescue Bundler::GemfileNotFound
|
144
|
-
nil
|
145
|
-
end
|
146
|
-
|
147
178
|
@_response = entries.filter_map do |entry|
|
148
179
|
location = entry.location
|
149
180
|
# If the project has Sorbet, then we only want to handle go to definition for constants defined in gems, as an
|
150
181
|
# additional behavior on top of jumping to RBIs. Sorbet can already handle go to definition for all constants
|
151
182
|
# in the project, even if the files are typed false
|
152
183
|
file_path = entry.file_path
|
153
|
-
if
|
154
|
-
!file_path.start_with?(RbConfig::CONFIG["rubylibdir"])
|
155
|
-
|
156
|
-
next
|
157
|
-
end
|
184
|
+
next if defined_in_gem?(file_path)
|
158
185
|
|
159
186
|
Interface::Location.new(
|
160
187
|
uri: URI::Generic.from_path(path: file_path).to_s,
|
@@ -97,7 +97,8 @@ module RubyLsp
|
|
97
97
|
Prism::LocalVariableWriteNode,
|
98
98
|
Prism::BlockParameterNode,
|
99
99
|
Prism::RequiredParameterNode,
|
100
|
-
Prism::
|
100
|
+
Prism::RequiredKeywordParameterNode,
|
101
|
+
Prism::OptionalKeywordParameterNode,
|
101
102
|
Prism::RestParameterNode,
|
102
103
|
Prism::OptionalParameterNode,
|
103
104
|
Prism::KeywordRestParameterNode,
|
@@ -137,8 +138,9 @@ module RubyLsp
|
|
137
138
|
Prism::ClassVariableReadNode, Prism::ClassVariableTargetNode, Prism::ClassVariableWriteNode,
|
138
139
|
Prism::LocalVariableAndWriteNode, Prism::LocalVariableOperatorWriteNode, Prism::LocalVariableOrWriteNode,
|
139
140
|
Prism::LocalVariableReadNode, Prism::LocalVariableTargetNode, Prism::LocalVariableWriteNode,
|
140
|
-
Prism::CallNode, Prism::BlockParameterNode, Prism::
|
141
|
-
Prism::
|
141
|
+
Prism::CallNode, Prism::BlockParameterNode, Prism::RequiredKeywordParameterNode,
|
142
|
+
Prism::RequiredKeywordParameterNode, Prism::KeywordRestParameterNode, Prism::OptionalParameterNode,
|
143
|
+
Prism::RequiredParameterNode, Prism::RestParameterNode
|
142
144
|
target
|
143
145
|
end
|
144
146
|
|
@@ -171,7 +173,8 @@ module RubyLsp
|
|
171
173
|
:on_constant_path_and_write_node_enter,
|
172
174
|
:on_constant_path_operator_write_node_enter,
|
173
175
|
:on_local_variable_write_node_enter,
|
174
|
-
:
|
176
|
+
:on_required_keyword_parameter_node_enter,
|
177
|
+
:on_optional_keyword_parameter_node_enter,
|
175
178
|
:on_rest_parameter_node_enter,
|
176
179
|
:on_optional_parameter_node_enter,
|
177
180
|
:on_keyword_rest_parameter_node_enter,
|
@@ -359,8 +362,15 @@ module RubyLsp
|
|
359
362
|
add_highlight(Constant::DocumentHighlightKind::WRITE, node.name_loc)
|
360
363
|
end
|
361
364
|
|
362
|
-
sig { params(node: Prism::
|
363
|
-
def
|
365
|
+
sig { params(node: Prism::RequiredKeywordParameterNode).void }
|
366
|
+
def on_required_keyword_parameter_node_enter(node)
|
367
|
+
return unless matches?(node, LOCAL_NODES)
|
368
|
+
|
369
|
+
add_highlight(Constant::DocumentHighlightKind::WRITE, node.name_loc)
|
370
|
+
end
|
371
|
+
|
372
|
+
sig { params(node: Prism::OptionalKeywordParameterNode).void }
|
373
|
+
def on_optional_keyword_parameter_node_enter(node)
|
364
374
|
return unless matches?(node, LOCAL_NODES)
|
365
375
|
|
366
376
|
add_highlight(Constant::DocumentHighlightKind::WRITE, node.name_loc)
|
@@ -551,8 +561,8 @@ module RubyLsp
|
|
551
561
|
Prism::ClassVariableTargetNode, Prism::ClassVariableWriteNode, Prism::LocalVariableAndWriteNode,
|
552
562
|
Prism::LocalVariableOperatorWriteNode, Prism::LocalVariableOrWriteNode, Prism::LocalVariableReadNode,
|
553
563
|
Prism::LocalVariableTargetNode, Prism::LocalVariableWriteNode, Prism::DefNode, Prism::BlockParameterNode,
|
554
|
-
Prism::
|
555
|
-
Prism::RequiredParameterNode, Prism::RestParameterNode
|
564
|
+
Prism::RequiredKeywordParameterNode, Prism::OptionalKeywordParameterNode, Prism::KeywordRestParameterNode,
|
565
|
+
Prism::OptionalParameterNode, Prism::RequiredParameterNode, Prism::RestParameterNode
|
556
566
|
|
557
567
|
node.name.to_s
|
558
568
|
when Prism::CallNode
|
@@ -94,7 +94,7 @@ module RubyLsp
|
|
94
94
|
opening_loc = node.opening_loc
|
95
95
|
closing_loc = node.closing_loc
|
96
96
|
|
97
|
-
add_lines_range(opening_loc.start_line, closing_loc.
|
97
|
+
add_lines_range(opening_loc.start_line, closing_loc.start_line - 1) if opening_loc && closing_loc
|
98
98
|
end
|
99
99
|
|
100
100
|
sig { params(node: Prism::ArrayNode).void }
|
@@ -51,6 +51,7 @@ module RubyLsp
|
|
51
51
|
:on_constant_read_node_enter,
|
52
52
|
:on_constant_write_node_enter,
|
53
53
|
:on_constant_path_node_enter,
|
54
|
+
:on_call_node_enter,
|
54
55
|
)
|
55
56
|
end
|
56
57
|
|
@@ -95,6 +96,25 @@ module RubyLsp
|
|
95
96
|
generate_hover(node.slice, node.location)
|
96
97
|
end
|
97
98
|
|
99
|
+
sig { params(node: Prism::CallNode).void }
|
100
|
+
def on_call_node_enter(node)
|
101
|
+
return if DependencyDetector.instance.typechecker
|
102
|
+
return unless self_receiver?(node)
|
103
|
+
|
104
|
+
message = node.message
|
105
|
+
return unless message
|
106
|
+
|
107
|
+
target_method = @index.resolve_method(message, @nesting.join("::"))
|
108
|
+
return unless target_method
|
109
|
+
|
110
|
+
location = target_method.location
|
111
|
+
|
112
|
+
@_response = Interface::Hover.new(
|
113
|
+
range: range_from_location(location),
|
114
|
+
contents: markdown_from_index_entries(message, target_method),
|
115
|
+
)
|
116
|
+
end
|
117
|
+
|
98
118
|
private
|
99
119
|
|
100
120
|
sig { params(name: String, location: Prism::Location).void }
|
@@ -18,6 +18,16 @@ module RubyLsp
|
|
18
18
|
# puts "handle some rescue"
|
19
19
|
# end
|
20
20
|
# ```
|
21
|
+
#
|
22
|
+
# # Example
|
23
|
+
#
|
24
|
+
# ```ruby
|
25
|
+
# var = "foo"
|
26
|
+
# {
|
27
|
+
# var: var, # Label "var" goes here in cases where the value is omitted
|
28
|
+
# a: "hello",
|
29
|
+
# }
|
30
|
+
# ```
|
21
31
|
class InlayHints < Listener
|
22
32
|
extend T::Sig
|
23
33
|
extend T::Generic
|
@@ -36,7 +46,7 @@ module RubyLsp
|
|
36
46
|
@_response = T.let([], ResponseType)
|
37
47
|
@range = range
|
38
48
|
|
39
|
-
dispatcher.register(self, :on_rescue_node_enter)
|
49
|
+
dispatcher.register(self, :on_rescue_node_enter, :on_implicit_node_enter)
|
40
50
|
end
|
41
51
|
|
42
52
|
sig { params(node: Prism::RescueNode).void }
|
@@ -53,6 +63,34 @@ module RubyLsp
|
|
53
63
|
tooltip: "StandardError is implied in a bare rescue",
|
54
64
|
)
|
55
65
|
end
|
66
|
+
|
67
|
+
sig { params(node: Prism::ImplicitNode).void }
|
68
|
+
def on_implicit_node_enter(node)
|
69
|
+
return unless visible?(node, @range)
|
70
|
+
|
71
|
+
node_value = node.value
|
72
|
+
loc = node.location
|
73
|
+
tooltip = ""
|
74
|
+
node_name = ""
|
75
|
+
case node_value
|
76
|
+
when Prism::CallNode
|
77
|
+
node_name = node_value.name
|
78
|
+
tooltip = "This is a method call. Method name: #{node_name}"
|
79
|
+
when Prism::ConstantReadNode
|
80
|
+
node_name = node_value.name
|
81
|
+
tooltip = "This is a constant: #{node_name}"
|
82
|
+
when Prism::LocalVariableReadNode
|
83
|
+
node_name = node_value.name
|
84
|
+
tooltip = "This is a local variable: #{node_name}"
|
85
|
+
end
|
86
|
+
|
87
|
+
@_response << Interface::InlayHint.new(
|
88
|
+
position: { line: loc.start_line - 1, character: loc.start_column + node_name.length + 1 },
|
89
|
+
label: node_name,
|
90
|
+
padding_left: true,
|
91
|
+
tooltip: tooltip,
|
92
|
+
)
|
93
|
+
end
|
56
94
|
end
|
57
95
|
end
|
58
96
|
end
|
@@ -51,7 +51,14 @@ module RubyLsp
|
|
51
51
|
if (comment_match = @previous_line.match(/^#(\s*)/))
|
52
52
|
handle_comment_line(T.must(comment_match[1]))
|
53
53
|
elsif @document.syntax_error?
|
54
|
-
|
54
|
+
match = /(?<=<<(-|~))(?<quote>['"`]?)(?<delimiter>\w+)\k<quote>/.match(@previous_line)
|
55
|
+
heredoc_delimiter = match && match.named_captures["delimiter"]
|
56
|
+
|
57
|
+
if heredoc_delimiter
|
58
|
+
handle_heredoc_end(heredoc_delimiter)
|
59
|
+
else
|
60
|
+
handle_statement_end
|
61
|
+
end
|
55
62
|
end
|
56
63
|
end
|
57
64
|
|
@@ -121,6 +128,14 @@ module RubyLsp
|
|
121
128
|
end
|
122
129
|
end
|
123
130
|
|
131
|
+
sig { params(delimiter: String).void }
|
132
|
+
def handle_heredoc_end(delimiter)
|
133
|
+
indents = " " * @indentation
|
134
|
+
add_edit_with_text("\n")
|
135
|
+
add_edit_with_text("#{indents}#{delimiter}")
|
136
|
+
move_cursor_to(@position[:line], @indentation + 2)
|
137
|
+
end
|
138
|
+
|
124
139
|
sig { params(spaces: String).void }
|
125
140
|
def handle_comment_line(spaces)
|
126
141
|
add_edit_with_text("##{spaces}")
|
@@ -135,7 +135,8 @@ module RubyLsp
|
|
135
135
|
:on_local_variable_write_node_enter,
|
136
136
|
:on_local_variable_read_node_enter,
|
137
137
|
:on_block_parameter_node_enter,
|
138
|
-
:
|
138
|
+
:on_required_keyword_parameter_node_enter,
|
139
|
+
:on_optional_keyword_parameter_node_enter,
|
139
140
|
:on_keyword_rest_parameter_node_enter,
|
140
141
|
:on_optional_parameter_node_enter,
|
141
142
|
:on_required_parameter_node_enter,
|
@@ -252,11 +253,18 @@ module RubyLsp
|
|
252
253
|
@current_scope << name.to_sym if name
|
253
254
|
end
|
254
255
|
|
255
|
-
sig { params(node: Prism::
|
256
|
-
def
|
257
|
-
|
258
|
-
|
256
|
+
sig { params(node: Prism::RequiredKeywordParameterNode).void }
|
257
|
+
def on_required_keyword_parameter_node_enter(node)
|
258
|
+
@current_scope << node.name
|
259
|
+
return unless visible?(node, @range)
|
260
|
+
|
261
|
+
location = node.name_loc
|
262
|
+
add_token(location.copy(length: location.length - 1), :parameter)
|
263
|
+
end
|
259
264
|
|
265
|
+
sig { params(node: Prism::OptionalKeywordParameterNode).void }
|
266
|
+
def on_optional_keyword_parameter_node_enter(node)
|
267
|
+
@current_scope << node.name
|
260
268
|
return unless visible?(node, @range)
|
261
269
|
|
262
270
|
location = node.name_loc
|
@@ -9,6 +9,9 @@ module RubyLsp
|
|
9
9
|
# https://github.com/Shopify/ruby-lsp-rails, or addons by created by developers outside of Shopify, so be
|
10
10
|
# cautious of changing anything.
|
11
11
|
extend T::Sig
|
12
|
+
extend T::Helpers
|
13
|
+
|
14
|
+
requires_ancestor { Kernel }
|
12
15
|
|
13
16
|
sig { params(node: Prism::Node).returns(Interface::Range) }
|
14
17
|
def range_from_node(node)
|
@@ -66,12 +69,29 @@ module RubyLsp
|
|
66
69
|
)
|
67
70
|
end
|
68
71
|
|
69
|
-
sig { params(
|
72
|
+
sig { params(file_path: String).returns(T.nilable(T::Boolean)) }
|
73
|
+
def defined_in_gem?(file_path)
|
74
|
+
DependencyDetector.instance.typechecker && BUNDLE_PATH && !file_path.start_with?(T.must(BUNDLE_PATH)) &&
|
75
|
+
!file_path.start_with?(RbConfig::CONFIG["rubylibdir"])
|
76
|
+
end
|
77
|
+
|
78
|
+
sig { params(node: Prism::CallNode).returns(T::Boolean) }
|
79
|
+
def self_receiver?(node)
|
80
|
+
receiver = node.receiver
|
81
|
+
receiver.nil? || receiver.is_a?(Prism::SelfNode)
|
82
|
+
end
|
83
|
+
|
84
|
+
sig do
|
85
|
+
params(
|
86
|
+
title: String,
|
87
|
+
entries: T.any(T::Array[RubyIndexer::Entry], RubyIndexer::Entry),
|
88
|
+
).returns(Interface::MarkupContent)
|
89
|
+
end
|
70
90
|
def markdown_from_index_entries(title, entries)
|
71
91
|
markdown_title = "```ruby\n#{title}\n```"
|
72
92
|
definitions = []
|
73
93
|
content = +""
|
74
|
-
entries.each do |entry|
|
94
|
+
Array(entries).each do |entry|
|
75
95
|
loc = entry.location
|
76
96
|
|
77
97
|
# We always handle locations as zero based. However, for file links in Markdown we need them to be one
|
@@ -66,7 +66,6 @@ module RubyLsp
|
|
66
66
|
|
67
67
|
sig { returns(T::Array[String]) }
|
68
68
|
def dependencies
|
69
|
-
# NOTE: If changing this behaviour, it's likely that the VS Code extension will also need changed.
|
70
69
|
@dependencies ||= T.let(
|
71
70
|
begin
|
72
71
|
Bundler.with_original_env { Bundler.default_gemfile }
|
@@ -20,6 +20,7 @@ module RubyLsp
|
|
20
20
|
#
|
21
21
|
class WorkspaceSymbol
|
22
22
|
extend T::Sig
|
23
|
+
include Support::Common
|
23
24
|
|
24
25
|
sig { params(query: T.nilable(String), index: RubyIndexer::Index).void }
|
25
26
|
def initialize(query, index)
|
@@ -29,21 +30,11 @@ module RubyLsp
|
|
29
30
|
|
30
31
|
sig { returns(T::Array[Interface::WorkspaceSymbol]) }
|
31
32
|
def run
|
32
|
-
bundle_path = begin
|
33
|
-
Bundler.bundle_path.to_s
|
34
|
-
rescue Bundler::GemfileNotFound
|
35
|
-
nil
|
36
|
-
end
|
37
|
-
|
38
33
|
@index.fuzzy_search(@query).filter_map do |entry|
|
39
34
|
# If the project is using Sorbet, we let Sorbet handle symbols defined inside the project itself and RBIs, but
|
40
35
|
# we still return entries defined in gems to allow developers to jump directly to the source
|
41
36
|
file_path = entry.file_path
|
42
|
-
if
|
43
|
-
!file_path.start_with?(RbConfig::CONFIG["rubylibdir"])
|
44
|
-
|
45
|
-
next
|
46
|
-
end
|
37
|
+
next if defined_in_gem?(file_path)
|
47
38
|
|
48
39
|
# We should never show private symbols when searching the entire workspace
|
49
40
|
next if entry.visibility == :private
|
@@ -82,6 +73,8 @@ module RubyLsp
|
|
82
73
|
Constant::SymbolKind::NAMESPACE
|
83
74
|
when RubyIndexer::Entry::Constant
|
84
75
|
Constant::SymbolKind::CONSTANT
|
76
|
+
when RubyIndexer::Entry::Method
|
77
|
+
entry.name == "initialize" ? Constant::SymbolKind::CONSTRUCTOR : Constant::SymbolKind::METHOD
|
85
78
|
end
|
86
79
|
end
|
87
80
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RubyLsp
|
5
|
+
class RubyDocument < Document
|
6
|
+
sig { override.returns(Prism::ParseResult) }
|
7
|
+
def parse
|
8
|
+
return @parse_result unless @needs_parsing
|
9
|
+
|
10
|
+
@needs_parsing = false
|
11
|
+
@parse_result = Prism.parse(@source)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -12,6 +12,8 @@ require "time"
|
|
12
12
|
# the Ruby LSP without including the gem in their application's Gemfile while at the same time giving us access to the
|
13
13
|
# exact locked versions of dependencies.
|
14
14
|
|
15
|
+
Bundler.ui.level = :silent
|
16
|
+
|
15
17
|
module RubyLsp
|
16
18
|
class SetupBundler
|
17
19
|
extend T::Sig
|
data/lib/ruby_lsp/store.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "ruby_lsp/document"
|
5
|
-
|
6
4
|
module RubyLsp
|
7
5
|
class Store
|
8
6
|
extend T::Sig
|
@@ -40,7 +38,7 @@ module RubyLsp
|
|
40
38
|
|
41
39
|
sig { params(uri: URI::Generic, source: String, version: Integer).void }
|
42
40
|
def set(uri:, source:, version:)
|
43
|
-
document =
|
41
|
+
document = RubyDocument.new(source: source, version: version, uri: uri, encoding: @encoding)
|
44
42
|
@state[uri.to_s] = document
|
45
43
|
end
|
46
44
|
|
data/lib/ruby_lsp/utils.rb
CHANGED
@@ -8,6 +8,15 @@ module RubyLsp
|
|
8
8
|
# This freeze is not redundant since the interpolated string is mutable
|
9
9
|
WORKSPACE_URI = T.let(URI::Generic.from_path(path: Dir.pwd), URI::Generic)
|
10
10
|
|
11
|
+
BUNDLE_PATH = T.let(
|
12
|
+
begin
|
13
|
+
Bundler.bundle_path.to_s
|
14
|
+
rescue Bundler::GemfileNotFound
|
15
|
+
nil
|
16
|
+
end,
|
17
|
+
T.nilable(String),
|
18
|
+
)
|
19
|
+
|
11
20
|
# A notification to be sent to the client
|
12
21
|
class Message
|
13
22
|
extend T::Sig
|
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.12.
|
4
|
+
version: 0.12.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: language_server-protocol
|
@@ -30,20 +30,20 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.17.1
|
34
34
|
- - "<"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: '0.
|
36
|
+
version: '0.18'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
41
|
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 0.
|
43
|
+
version: 0.17.1
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '0.
|
46
|
+
version: '0.18'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: sorbet-runtime
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,12 +78,12 @@ files:
|
|
78
78
|
- lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb
|
79
79
|
- lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb
|
80
80
|
- lib/ruby-lsp.rb
|
81
|
+
- lib/ruby_indexer/lib/ruby_indexer/collector.rb
|
81
82
|
- lib/ruby_indexer/lib/ruby_indexer/configuration.rb
|
82
83
|
- lib/ruby_indexer/lib/ruby_indexer/entry.rb
|
83
84
|
- lib/ruby_indexer/lib/ruby_indexer/index.rb
|
84
85
|
- lib/ruby_indexer/lib/ruby_indexer/indexable_path.rb
|
85
86
|
- lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb
|
86
|
-
- lib/ruby_indexer/lib/ruby_indexer/visitor.rb
|
87
87
|
- lib/ruby_indexer/ruby_indexer.rb
|
88
88
|
- lib/ruby_indexer/test/classes_and_modules_test.rb
|
89
89
|
- lib/ruby_indexer/test/configuration_test.rb
|
@@ -132,6 +132,7 @@ files:
|
|
132
132
|
- lib/ruby_lsp/requests/support/source_uri.rb
|
133
133
|
- lib/ruby_lsp/requests/support/syntax_tree_formatting_runner.rb
|
134
134
|
- lib/ruby_lsp/requests/workspace_symbol.rb
|
135
|
+
- lib/ruby_lsp/ruby_document.rb
|
135
136
|
- lib/ruby_lsp/server.rb
|
136
137
|
- lib/ruby_lsp/setup_bundler.rb
|
137
138
|
- lib/ruby_lsp/store.rb
|