ruby-lsp 0.10.1 → 0.11.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/README.md +4 -4
- data/VERSION +1 -1
- data/exe/ruby-lsp-check +1 -1
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +40 -5
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +141 -5
- data/lib/ruby_indexer/lib/ruby_indexer/visitor.rb +66 -18
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +23 -0
- data/lib/ruby_indexer/test/configuration_test.rb +2 -0
- data/lib/ruby_indexer/test/constant_test.rb +202 -0
- data/lib/ruby_indexer/test/index_test.rb +20 -0
- data/lib/ruby_lsp/{extension.rb → addon.rb} +27 -25
- data/lib/ruby_lsp/check_docs.rb +7 -8
- data/lib/ruby_lsp/document.rb +35 -38
- data/lib/ruby_lsp/event_emitter.rb +239 -77
- data/lib/ruby_lsp/executor.rb +45 -55
- data/lib/ruby_lsp/internal.rb +2 -3
- data/lib/ruby_lsp/listener.rb +8 -7
- data/lib/ruby_lsp/parameter_scope.rb +33 -0
- data/lib/ruby_lsp/requests/base_request.rb +3 -3
- data/lib/ruby_lsp/requests/code_action_resolve.rb +14 -14
- data/lib/ruby_lsp/requests/code_lens.rb +39 -63
- data/lib/ruby_lsp/requests/completion.rb +54 -32
- data/lib/ruby_lsp/requests/definition.rb +30 -27
- data/lib/ruby_lsp/requests/diagnostics.rb +26 -3
- data/lib/ruby_lsp/requests/document_highlight.rb +18 -19
- data/lib/ruby_lsp/requests/document_link.rb +50 -9
- data/lib/ruby_lsp/requests/document_symbol.rb +82 -75
- data/lib/ruby_lsp/requests/folding_ranges.rb +199 -222
- data/lib/ruby_lsp/requests/formatting.rb +5 -6
- data/lib/ruby_lsp/requests/hover.rb +33 -22
- data/lib/ruby_lsp/requests/inlay_hints.rb +2 -3
- data/lib/ruby_lsp/requests/selection_ranges.rb +65 -40
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +187 -145
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +3 -4
- data/lib/ruby_lsp/requests/support/annotation.rb +18 -17
- data/lib/ruby_lsp/requests/support/common.rb +17 -26
- data/lib/ruby_lsp/requests/support/dependency_detector.rb +67 -42
- data/lib/ruby_lsp/requests/support/highlight_target.rb +64 -45
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +9 -4
- data/lib/ruby_lsp/requests/support/selection_range.rb +5 -4
- data/lib/ruby_lsp/requests/support/sorbet.rb +2 -57
- data/lib/ruby_lsp/requests/support/syntax_tree_formatting_runner.rb +7 -1
- data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -1
- data/lib/ruby_lsp/server.rb +6 -44
- data/lib/ruby_lsp/utils.rb +2 -12
- metadata +11 -30
@@ -28,10 +28,10 @@ module RubyLsp
|
|
28
28
|
@uri = T.let(document.uri, URI::Generic)
|
29
29
|
end
|
30
30
|
|
31
|
-
sig { override.returns(T.nilable(T.all(T::Array[
|
31
|
+
sig { override.returns(T.nilable(T.all(T::Array[Interface::Diagnostic], Object))) }
|
32
32
|
def run
|
33
33
|
# Running RuboCop is slow, so to avoid excessive runs we only do so if the file is syntactically valid
|
34
|
-
return if @document.syntax_error?
|
34
|
+
return syntax_error_diagnostics if @document.syntax_error?
|
35
35
|
|
36
36
|
return unless defined?(Support::RuboCopDiagnosticsRunner)
|
37
37
|
|
@@ -39,7 +39,30 @@ module RubyLsp
|
|
39
39
|
path = @uri.to_standardized_path
|
40
40
|
return unless path.nil? || path.start_with?(T.must(WORKSPACE_URI.to_standardized_path))
|
41
41
|
|
42
|
-
Support::RuboCopDiagnosticsRunner.instance.run(@uri, @document)
|
42
|
+
Support::RuboCopDiagnosticsRunner.instance.run(@uri, @document).map!(&:to_lsp_diagnostic)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
sig { returns(T.nilable(T::Array[Interface::Diagnostic])) }
|
48
|
+
def syntax_error_diagnostics
|
49
|
+
@document.parse_result.errors.map do |error|
|
50
|
+
Interface::Diagnostic.new(
|
51
|
+
range: Interface::Range.new(
|
52
|
+
start: Interface::Position.new(
|
53
|
+
line: error.location.start_line - 1,
|
54
|
+
character: error.location.start_column,
|
55
|
+
),
|
56
|
+
end: Interface::Position.new(
|
57
|
+
line: error.location.end_line - 1,
|
58
|
+
character: error.location.end_column,
|
59
|
+
),
|
60
|
+
),
|
61
|
+
message: error.message,
|
62
|
+
severity: Constant::DiagnosticSeverity::ERROR,
|
63
|
+
source: "YARP",
|
64
|
+
)
|
65
|
+
end
|
43
66
|
end
|
44
67
|
end
|
45
68
|
end
|
@@ -32,8 +32,8 @@ module RubyLsp
|
|
32
32
|
|
33
33
|
sig do
|
34
34
|
params(
|
35
|
-
target: T.nilable(
|
36
|
-
parent: T.nilable(
|
35
|
+
target: T.nilable(YARP::Node),
|
36
|
+
parent: T.nilable(YARP::Node),
|
37
37
|
emitter: EventEmitter,
|
38
38
|
message_queue: Thread::Queue,
|
39
39
|
).void
|
@@ -47,11 +47,21 @@ module RubyLsp
|
|
47
47
|
|
48
48
|
highlight_target =
|
49
49
|
case target
|
50
|
-
when
|
50
|
+
when YARP::GlobalVariableReadNode, YARP::GlobalVariableAndWriteNode, YARP::GlobalVariableOperatorWriteNode,
|
51
|
+
YARP::GlobalVariableOrWriteNode, YARP::GlobalVariableTargetNode, YARP::GlobalVariableWriteNode,
|
52
|
+
YARP::InstanceVariableAndWriteNode, YARP::InstanceVariableOperatorWriteNode,
|
53
|
+
YARP::InstanceVariableOrWriteNode, YARP::InstanceVariableReadNode, YARP::InstanceVariableTargetNode,
|
54
|
+
YARP::InstanceVariableWriteNode, YARP::ConstantAndWriteNode, YARP::ConstantOperatorWriteNode,
|
55
|
+
YARP::ConstantOrWriteNode, YARP::ConstantPathAndWriteNode, YARP::ConstantPathNode,
|
56
|
+
YARP::ConstantPathOperatorWriteNode, YARP::ConstantPathOrWriteNode, YARP::ConstantPathTargetNode,
|
57
|
+
YARP::ConstantPathWriteNode, YARP::ConstantReadNode, YARP::ConstantTargetNode, YARP::ConstantWriteNode,
|
58
|
+
YARP::ClassVariableAndWriteNode, YARP::ClassVariableOperatorWriteNode, YARP::ClassVariableOrWriteNode,
|
59
|
+
YARP::ClassVariableReadNode, YARP::ClassVariableTargetNode, YARP::ClassVariableWriteNode,
|
60
|
+
YARP::LocalVariableAndWriteNode, YARP::LocalVariableOperatorWriteNode, YARP::LocalVariableOrWriteNode,
|
61
|
+
YARP::LocalVariableReadNode, YARP::LocalVariableTargetNode, YARP::LocalVariableWriteNode, YARP::CallNode,
|
62
|
+
YARP::BlockParameterNode, YARP::KeywordParameterNode, YARP::KeywordRestParameterNode,
|
63
|
+
YARP::OptionalParameterNode, YARP::RequiredParameterNode, YARP::RestParameterNode
|
51
64
|
Support::HighlightTarget.new(target)
|
52
|
-
when SyntaxTree::Ident
|
53
|
-
relevant_node = parent.is_a?(SyntaxTree::Params) ? target : parent
|
54
|
-
Support::HighlightTarget.new(relevant_node)
|
55
65
|
end
|
56
66
|
|
57
67
|
@target = T.let(highlight_target, T.nilable(Support::HighlightTarget))
|
@@ -59,7 +69,7 @@ module RubyLsp
|
|
59
69
|
emitter.register(self, :on_node) if @target
|
60
70
|
end
|
61
71
|
|
62
|
-
sig { params(node: T.nilable(
|
72
|
+
sig { params(node: T.nilable(YARP::Node)).void }
|
63
73
|
def on_node(node)
|
64
74
|
return if node.nil?
|
65
75
|
|
@@ -69,20 +79,9 @@ module RubyLsp
|
|
69
79
|
|
70
80
|
private
|
71
81
|
|
72
|
-
DIRECT_HIGHLIGHTS = T.let(
|
73
|
-
[
|
74
|
-
SyntaxTree::GVar,
|
75
|
-
SyntaxTree::IVar,
|
76
|
-
SyntaxTree::Const,
|
77
|
-
SyntaxTree::CVar,
|
78
|
-
SyntaxTree::VarField,
|
79
|
-
],
|
80
|
-
T::Array[T.class_of(SyntaxTree::Node)],
|
81
|
-
)
|
82
|
-
|
83
82
|
sig { params(match: Support::HighlightTarget::HighlightMatch).void }
|
84
83
|
def add_highlight(match)
|
85
|
-
range =
|
84
|
+
range = range_from_location(match.location)
|
86
85
|
@_response << Interface::DocumentHighlight.new(range: range, kind: match.type)
|
87
86
|
end
|
88
87
|
end
|
@@ -75,8 +75,15 @@ module RubyLsp
|
|
75
75
|
sig { override.returns(ResponseType) }
|
76
76
|
attr_reader :_response
|
77
77
|
|
78
|
-
sig
|
79
|
-
|
78
|
+
sig do
|
79
|
+
params(
|
80
|
+
uri: URI::Generic,
|
81
|
+
comments: T::Array[YARP::Comment],
|
82
|
+
emitter: EventEmitter,
|
83
|
+
message_queue: Thread::Queue,
|
84
|
+
).void
|
85
|
+
end
|
86
|
+
def initialize(uri, comments, emitter, message_queue)
|
80
87
|
super(emitter, message_queue)
|
81
88
|
|
82
89
|
# Match the version based on the version in the RBI file name. Notice that the `@` symbol is sanitized to `%40`
|
@@ -85,13 +92,49 @@ module RubyLsp
|
|
85
92
|
version_match = path ? /(?<=%40)[\d.]+(?=\.rbi$)/.match(path) : nil
|
86
93
|
@gem_version = T.let(version_match && version_match[0], T.nilable(String))
|
87
94
|
@_response = T.let([], T::Array[Interface::DocumentLink])
|
95
|
+
@lines_to_comments = T.let(
|
96
|
+
comments.to_h do |comment|
|
97
|
+
[comment.location.end_line, comment]
|
98
|
+
end,
|
99
|
+
T::Hash[Integer, YARP::Comment],
|
100
|
+
)
|
88
101
|
|
89
|
-
emitter.register(self, :
|
102
|
+
emitter.register(self, :on_def, :on_class, :on_module, :on_constant_write, :on_constant_path_write)
|
90
103
|
end
|
91
104
|
|
92
|
-
sig { params(node:
|
93
|
-
def
|
94
|
-
|
105
|
+
sig { params(node: YARP::DefNode).void }
|
106
|
+
def on_def(node)
|
107
|
+
extract_document_link(node)
|
108
|
+
end
|
109
|
+
|
110
|
+
sig { params(node: YARP::ClassNode).void }
|
111
|
+
def on_class(node)
|
112
|
+
extract_document_link(node)
|
113
|
+
end
|
114
|
+
|
115
|
+
sig { params(node: YARP::ModuleNode).void }
|
116
|
+
def on_module(node)
|
117
|
+
extract_document_link(node)
|
118
|
+
end
|
119
|
+
|
120
|
+
sig { params(node: YARP::ConstantWriteNode).void }
|
121
|
+
def on_constant_write(node)
|
122
|
+
extract_document_link(node)
|
123
|
+
end
|
124
|
+
|
125
|
+
sig { params(node: YARP::ConstantPathWriteNode).void }
|
126
|
+
def on_constant_path_write(node)
|
127
|
+
extract_document_link(node)
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
sig { params(node: YARP::Node).void }
|
133
|
+
def extract_document_link(node)
|
134
|
+
comment = @lines_to_comments[node.location.start_line - 1]
|
135
|
+
return unless comment
|
136
|
+
|
137
|
+
match = comment.location.slice.match(%r{source://.*#\d+$})
|
95
138
|
return unless match
|
96
139
|
|
97
140
|
uri = T.cast(URI(T.must(match[0])), URI::Source)
|
@@ -102,14 +145,12 @@ module RubyLsp
|
|
102
145
|
return if file_path.nil?
|
103
146
|
|
104
147
|
@_response << Interface::DocumentLink.new(
|
105
|
-
range:
|
148
|
+
range: range_from_location(comment.location),
|
106
149
|
target: "file://#{file_path}##{uri.line_number}",
|
107
150
|
tooltip: "Jump to #{file_path}##{uri.line_number}",
|
108
151
|
)
|
109
152
|
end
|
110
153
|
|
111
|
-
private
|
112
|
-
|
113
154
|
# Try to figure out the gem version for a source:// link. The order of precedence is:
|
114
155
|
# 1. The version in the URI
|
115
156
|
# 2. The version in the RBI file name
|
@@ -64,20 +64,21 @@ module RubyLsp
|
|
64
64
|
self,
|
65
65
|
:on_class,
|
66
66
|
:after_class,
|
67
|
-
:
|
68
|
-
:
|
67
|
+
:on_call,
|
68
|
+
:on_constant_path_write,
|
69
|
+
:on_constant_write,
|
69
70
|
:on_def,
|
70
71
|
:after_def,
|
71
72
|
:on_module,
|
72
73
|
:after_module,
|
73
|
-
:
|
74
|
-
:
|
74
|
+
:on_instance_variable_write,
|
75
|
+
:on_class_variable_write,
|
75
76
|
)
|
76
77
|
end
|
77
78
|
|
78
|
-
sig { override.params(
|
79
|
-
def initialize_external_listener(
|
80
|
-
|
79
|
+
sig { override.params(addon: Addon).returns(T.nilable(Listener[ResponseType])) }
|
80
|
+
def initialize_external_listener(addon)
|
81
|
+
addon.create_document_symbol_listener(@emitter, @message_queue)
|
81
82
|
end
|
82
83
|
|
83
84
|
# Merges responses from other listeners
|
@@ -87,116 +88,122 @@ module RubyLsp
|
|
87
88
|
self
|
88
89
|
end
|
89
90
|
|
90
|
-
sig { params(node:
|
91
|
+
sig { params(node: YARP::ClassNode).void }
|
91
92
|
def on_class(node)
|
92
93
|
@stack << create_document_symbol(
|
93
|
-
name:
|
94
|
+
name: node.constant_path.location.slice,
|
94
95
|
kind: Constant::SymbolKind::CLASS,
|
95
|
-
|
96
|
-
|
96
|
+
range_location: node.location,
|
97
|
+
selection_range_location: node.constant_path.location,
|
97
98
|
)
|
98
99
|
end
|
99
100
|
|
100
|
-
sig { params(node:
|
101
|
+
sig { params(node: YARP::ClassNode).void }
|
101
102
|
def after_class(node)
|
102
103
|
@stack.pop
|
103
104
|
end
|
104
105
|
|
105
|
-
sig { params(node:
|
106
|
-
def
|
107
|
-
return unless ATTR_ACCESSORS.include?(node.
|
106
|
+
sig { params(node: YARP::CallNode).void }
|
107
|
+
def on_call(node)
|
108
|
+
return unless ATTR_ACCESSORS.include?(node.name) && node.receiver.nil?
|
108
109
|
|
109
|
-
node.arguments
|
110
|
-
|
110
|
+
arguments = node.arguments
|
111
|
+
return unless arguments
|
112
|
+
|
113
|
+
arguments.arguments.each do |argument|
|
114
|
+
next unless argument.is_a?(YARP::SymbolNode)
|
115
|
+
|
116
|
+
name = argument.value
|
117
|
+
next unless name
|
111
118
|
|
112
119
|
create_document_symbol(
|
113
|
-
name:
|
120
|
+
name: name,
|
114
121
|
kind: Constant::SymbolKind::FIELD,
|
115
|
-
|
116
|
-
|
122
|
+
range_location: argument.location,
|
123
|
+
selection_range_location: T.must(argument.value_loc),
|
117
124
|
)
|
118
125
|
end
|
119
126
|
end
|
120
127
|
|
121
|
-
sig { params(node:
|
122
|
-
def
|
128
|
+
sig { params(node: YARP::ConstantPathWriteNode).void }
|
129
|
+
def on_constant_path_write(node)
|
130
|
+
create_document_symbol(
|
131
|
+
name: node.target.location.slice,
|
132
|
+
kind: Constant::SymbolKind::CONSTANT,
|
133
|
+
range_location: node.location,
|
134
|
+
selection_range_location: node.target.location,
|
135
|
+
)
|
136
|
+
end
|
137
|
+
|
138
|
+
sig { params(node: YARP::ConstantWriteNode).void }
|
139
|
+
def on_constant_write(node)
|
123
140
|
create_document_symbol(
|
124
|
-
name: node.
|
141
|
+
name: node.name.to_s,
|
125
142
|
kind: Constant::SymbolKind::CONSTANT,
|
126
|
-
|
127
|
-
|
143
|
+
range_location: node.location,
|
144
|
+
selection_range_location: node.name_loc,
|
145
|
+
)
|
146
|
+
end
|
147
|
+
|
148
|
+
sig { params(node: YARP::DefNode).void }
|
149
|
+
def after_def(node)
|
150
|
+
@stack.pop
|
151
|
+
end
|
152
|
+
|
153
|
+
sig { params(node: YARP::ModuleNode).void }
|
154
|
+
def on_module(node)
|
155
|
+
@stack << create_document_symbol(
|
156
|
+
name: node.constant_path.location.slice,
|
157
|
+
kind: Constant::SymbolKind::MODULE,
|
158
|
+
range_location: node.location,
|
159
|
+
selection_range_location: node.constant_path.location,
|
128
160
|
)
|
129
161
|
end
|
130
162
|
|
131
|
-
sig { params(node:
|
163
|
+
sig { params(node: YARP::DefNode).void }
|
132
164
|
def on_def(node)
|
133
|
-
|
165
|
+
receiver = node.receiver
|
134
166
|
|
135
|
-
if
|
136
|
-
name = "self.#{node.name
|
167
|
+
if receiver.is_a?(YARP::SelfNode)
|
168
|
+
name = "self.#{node.name}"
|
137
169
|
kind = Constant::SymbolKind::METHOD
|
138
170
|
else
|
139
|
-
name = node.name.
|
171
|
+
name = node.name.to_s
|
140
172
|
kind = name == "initialize" ? Constant::SymbolKind::CONSTRUCTOR : Constant::SymbolKind::METHOD
|
141
173
|
end
|
142
174
|
|
143
175
|
symbol = create_document_symbol(
|
144
176
|
name: name,
|
145
177
|
kind: kind,
|
146
|
-
|
147
|
-
|
178
|
+
range_location: node.location,
|
179
|
+
selection_range_location: node.name_loc,
|
148
180
|
)
|
149
181
|
|
150
182
|
@stack << symbol
|
151
183
|
end
|
152
184
|
|
153
|
-
sig { params(node:
|
154
|
-
def after_def(node)
|
155
|
-
@stack.pop
|
156
|
-
end
|
157
|
-
|
158
|
-
sig { params(node: SyntaxTree::ModuleDeclaration).void }
|
159
|
-
def on_module(node)
|
160
|
-
@stack << create_document_symbol(
|
161
|
-
name: full_constant_name(node.constant),
|
162
|
-
kind: Constant::SymbolKind::MODULE,
|
163
|
-
range_node: node,
|
164
|
-
selection_range_node: node.constant,
|
165
|
-
)
|
166
|
-
end
|
167
|
-
|
168
|
-
sig { params(node: SyntaxTree::ModuleDeclaration).void }
|
185
|
+
sig { params(node: YARP::ModuleNode).void }
|
169
186
|
def after_module(node)
|
170
187
|
@stack.pop
|
171
188
|
end
|
172
189
|
|
173
|
-
sig { params(node:
|
174
|
-
def
|
190
|
+
sig { params(node: YARP::InstanceVariableWriteNode).void }
|
191
|
+
def on_instance_variable_write(node)
|
175
192
|
create_document_symbol(
|
176
|
-
name: node.
|
177
|
-
kind: Constant::SymbolKind::
|
178
|
-
|
179
|
-
|
193
|
+
name: node.name.to_s,
|
194
|
+
kind: Constant::SymbolKind::VARIABLE,
|
195
|
+
range_location: node.name_loc,
|
196
|
+
selection_range_location: node.name_loc,
|
180
197
|
)
|
181
198
|
end
|
182
199
|
|
183
|
-
sig { params(node:
|
184
|
-
def
|
185
|
-
value = node.value
|
186
|
-
kind = case value
|
187
|
-
when SyntaxTree::Const
|
188
|
-
Constant::SymbolKind::CONSTANT
|
189
|
-
when SyntaxTree::CVar, SyntaxTree::IVar
|
190
|
-
Constant::SymbolKind::VARIABLE
|
191
|
-
else
|
192
|
-
return
|
193
|
-
end
|
194
|
-
|
200
|
+
sig { params(node: YARP::ClassVariableWriteNode).void }
|
201
|
+
def on_class_variable_write(node)
|
195
202
|
create_document_symbol(
|
196
|
-
name:
|
197
|
-
kind:
|
198
|
-
|
199
|
-
|
203
|
+
name: node.name.to_s,
|
204
|
+
kind: Constant::SymbolKind::VARIABLE,
|
205
|
+
range_location: node.name_loc,
|
206
|
+
selection_range_location: node.name_loc,
|
200
207
|
)
|
201
208
|
end
|
202
209
|
|
@@ -206,16 +213,16 @@ module RubyLsp
|
|
206
213
|
params(
|
207
214
|
name: String,
|
208
215
|
kind: Integer,
|
209
|
-
|
210
|
-
|
216
|
+
range_location: YARP::Location,
|
217
|
+
selection_range_location: YARP::Location,
|
211
218
|
).returns(Interface::DocumentSymbol)
|
212
219
|
end
|
213
|
-
def create_document_symbol(name:, kind:,
|
220
|
+
def create_document_symbol(name:, kind:, range_location:, selection_range_location:)
|
214
221
|
symbol = Interface::DocumentSymbol.new(
|
215
222
|
name: name,
|
216
223
|
kind: kind,
|
217
|
-
range:
|
218
|
-
selection_range:
|
224
|
+
range: range_from_location(range_location),
|
225
|
+
selection_range: range_from_location(selection_range_location),
|
219
226
|
children: [],
|
220
227
|
)
|
221
228
|
|