ruby-lsp 0.3.1 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9762389a7b7979afb57d6e6d2cf0d65b0b0a0b31f5a1fdd7045311c33a0c21d6
4
- data.tar.gz: 35cc2318946e650ee311129955d3674c7e693a87d25c5cc2f29c5a55e479d880
3
+ metadata.gz: 62174da68ba92c0af61878221168a02398c9b3df2867b63c063850b1787c7104
4
+ data.tar.gz: dc3d2e17e3fe2dcbb6578902eb3b672babc72d0f10511c021db767cfde709b0b
5
5
  SHA512:
6
- metadata.gz: 4735e18c297c992727d0a151ed7948cf6d4ea32b01fe411ed0774efdda7cdc0cf6533f5d71ad288aad9e6e717149932744376fdceda9fa4cd039b560934a9b47
7
- data.tar.gz: bd6e0c9a81a373c509f2f96b480543657a8d241a6e58ea25ec21c62ac60094f299af1c5f85d1555ad6ca1908c325e46569119271d4c6b7117f33f9919cf40bca
6
+ metadata.gz: c8295ce6739f9452dd20cab22ebb19fb099040f4782afa4dfd63b423b08ad73eedeb1fccc33113dcd7b27d38745e7112a6d272ea28652e00102a870c18c51b96
7
+ data.tar.gz: 1e1a2a681dcdf97bbb1f667211111b89ca274c1d89745bcd3cf8511fbc3d41416d0bb5a45f2fcaf85feb8b0469a5441b5500148136f849657d263531ffe5ff8a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.3.3
@@ -38,7 +38,7 @@ module RubyLsp
38
38
  type_parameters(:T)
39
39
  .params(
40
40
  request_name: Symbol,
41
- block: T.proc.params(document: Document).returns(T.type_parameter(:T))
41
+ block: T.proc.params(document: Document).returns(T.type_parameter(:T)),
42
42
  ).returns(T.type_parameter(:T))
43
43
  end
44
44
  def cache_fetch(request_name, &block)
@@ -26,7 +26,7 @@ module RubyLsp
26
26
  # for displaying window messages on errors
27
27
  sig do
28
28
  params(
29
- block: T.proc.bind(Handler).params(error: Exception, request: T::Hash[Symbol, T.untyped]).void
29
+ block: T.proc.bind(Handler).params(error: Exception, request: T::Hash[Symbol, T.untyped]).void,
30
30
  ).void
31
31
  end
32
32
  def on_error(&block)
@@ -85,7 +85,7 @@ module RubyLsp
85
85
  params(
86
86
  msg: String,
87
87
  parallel: T::Boolean,
88
- blk: T.proc.bind(Handler).params(request: T::Hash[Symbol, T.untyped]).returns(T.untyped)
88
+ blk: T.proc.bind(Handler).params(request: T::Hash[Symbol, T.untyped]).returns(T.untyped),
89
89
  ).returns(RequestHandler)
90
90
  end
91
91
  def on(msg, parallel: false, &blk)
@@ -103,7 +103,7 @@ module RubyLsp
103
103
  def clear_diagnostics(uri)
104
104
  @writer.write(
105
105
  method: "textDocument/publishDiagnostics",
106
- params: Interface::PublishDiagnosticsParams.new(uri: uri, diagnostics: [])
106
+ params: Interface::PublishDiagnosticsParams.new(uri: uri, diagnostics: []),
107
107
  )
108
108
  end
109
109
 
@@ -111,7 +111,7 @@ module RubyLsp
111
111
  def show_message(type, message)
112
112
  @writer.write(
113
113
  method: "window/showMessage",
114
- params: Interface::ShowMessageParams.new(type: type, message: message)
114
+ params: Interface::ShowMessageParams.new(type: type, message: message),
115
115
  )
116
116
  end
117
117
  end
@@ -7,8 +7,6 @@ module RubyLsp
7
7
  class Queue
8
8
  extend T::Sig
9
9
 
10
- class Cancelled < StandardError; end
11
-
12
10
  class Result < T::Struct
13
11
  const :response, T.untyped # rubocop:disable Sorbet/ForbidUntypedStructProps
14
12
  const :error, T.nilable(Exception)
@@ -30,7 +28,7 @@ module RubyLsp
30
28
  sig do
31
29
  params(
32
30
  writer: LanguageServer::Protocol::Transport::Stdio::Writer,
33
- handlers: T::Hash[String, Handler::RequestHandler]
31
+ handlers: T::Hash[String, Handler::RequestHandler],
34
32
  ).void
35
33
  end
36
34
  def initialize(writer, handlers)
@@ -40,8 +38,6 @@ module RubyLsp
40
38
  @job_queue = T.let(Thread::Queue.new, Thread::Queue)
41
39
  # The jobs hash is just a way of keeping a handle to jobs based on the request ID, so we can cancel them
42
40
  @jobs = T.let({}, T::Hash[T.any(String, Integer), Job])
43
- # The current job is a handle to cancel jobs that are currently being processed
44
- @current_job = T.let(nil, T.nilable(Job))
45
41
  @mutex = T.let(Mutex.new, Mutex)
46
42
  @worker = T.let(new_worker, Thread)
47
43
 
@@ -65,11 +61,6 @@ module RubyLsp
65
61
  @mutex.synchronize do
66
62
  # Cancel the job if it's still in the queue
67
63
  @jobs[id]&.cancel
68
-
69
- # Cancel the job if we're in the middle of processing it
70
- if @current_job&.request&.dig(:id) == id
71
- @worker.raise(Cancelled)
72
- end
73
64
  end
74
65
  end
75
66
 
@@ -92,8 +83,6 @@ module RubyLsp
92
83
 
93
84
  request_time = Benchmark.realtime do
94
85
  response = T.must(@handlers[request[:method]]).action.call(request)
95
- rescue Cancelled
96
- raise
97
86
  rescue StandardError, LoadError => e
98
87
  error = e
99
88
  end
@@ -105,29 +94,31 @@ module RubyLsp
105
94
  sig do
106
95
  params(
107
96
  result: Result,
108
- request: T::Hash[Symbol, T.untyped]
97
+ request: T::Hash[Symbol, T.untyped],
109
98
  ).void
110
99
  end
111
100
  def finalize_request(result, request)
112
- error = result.error
113
- if error
114
- T.must(@handlers[request[:method]]).error_handler&.call(error, request)
115
-
116
- @writer.write(
117
- id: request[:id],
118
- error: {
119
- code: LanguageServer::Protocol::Constant::ErrorCodes::INTERNAL_ERROR,
120
- message: result.error.inspect,
121
- data: request.to_json,
122
- },
123
- )
124
- elsif result.response != Handler::VOID
125
- @writer.write(id: request[:id], result: result.response)
126
- end
101
+ @mutex.synchronize do
102
+ error = result.error
103
+ if error
104
+ T.must(@handlers[request[:method]]).error_handler&.call(error, request)
105
+
106
+ @writer.write(
107
+ id: request[:id],
108
+ error: {
109
+ code: LanguageServer::Protocol::Constant::ErrorCodes::INTERNAL_ERROR,
110
+ message: error.inspect,
111
+ data: request.to_json,
112
+ },
113
+ )
114
+ elsif result.response != Handler::VOID
115
+ @writer.write(id: request[:id], result: result.response)
116
+ end
127
117
 
128
- request_time = result.request_time
129
- if request_time
130
- @writer.write(method: "telemetry/event", params: telemetry_params(request, request_time, result.error))
118
+ request_time = result.request_time
119
+ if request_time
120
+ @writer.write(method: "telemetry/event", params: telemetry_params(request, request_time, error))
121
+ end
131
122
  end
132
123
  end
133
124
 
@@ -139,28 +130,20 @@ module RubyLsp
139
130
  # Thread::Queue#pop is thread safe and will wait until an item is available
140
131
  loop do
141
132
  job = T.let(@job_queue.pop, T.nilable(Job))
142
- break if job.nil?
143
-
144
133
  # The only time when the job is nil is when the queue is closed and we can then terminate the thread
134
+ break if job.nil?
145
135
 
146
136
  request = job.request
147
- @mutex.synchronize do
148
- @jobs.delete(request[:id])
149
- @current_job = job
150
- end
137
+ @mutex.synchronize { @jobs.delete(request[:id]) }
151
138
 
152
- next if job.cancelled
153
-
154
- result = execute(request)
155
- rescue Cancelled
156
- # We need to return nil to the client even if the request was cancelled
157
- result = Queue::Result.new(response: nil, error: nil, request_time: nil)
158
- ensure
159
- @mutex.synchronize { @current_job = nil }
139
+ result = if job.cancelled
140
+ # We need to return nil to the client even if the request was cancelled
141
+ Queue::Result.new(response: nil, error: nil, request_time: nil)
142
+ else
143
+ execute(request)
144
+ end
160
145
 
161
- # If there's request, it means the worker was cancelled while waiting to pop from the queue or immediately
162
- # after
163
- finalize_request(result, request) unless result.nil? || request.nil?
146
+ finalize_request(result, request)
164
147
  end
165
148
  end
166
149
  end
@@ -169,7 +152,7 @@ module RubyLsp
169
152
  params(
170
153
  request: T::Hash[Symbol, T.untyped],
171
154
  request_time: Float,
172
- error: T.nilable(Exception)
155
+ error: T.nilable(Exception),
173
156
  ).returns(T::Hash[Symbol, T.any(String, Float)])
174
157
  end
175
158
  def telemetry_params(request, request_time, error)
@@ -184,6 +167,12 @@ module RubyLsp
184
167
  if error
185
168
  params[:errorClass] = error.class.name
186
169
  params[:errorMessage] = error.message
170
+
171
+ log_params = request[:params]&.reject { |k, _| k == :textDocument }
172
+ params[:params] = log_params.to_json if log_params&.any?
173
+
174
+ backtrace = error.backtrace
175
+ params[:backtrace] = backtrace.map { |bt| bt.sub(/^#{Dir.home}/, "~") }.join("\n") if backtrace
187
176
  end
188
177
 
189
178
  params[:uri] = uri.sub(%r{.*://#{Dir.home}}, "~") if uri
@@ -23,7 +23,7 @@ module RubyLsp
23
23
  params(
24
24
  uri: String,
25
25
  document: Document,
26
- range: T::Range[Integer]
26
+ range: T::Range[Integer],
27
27
  ).void
28
28
  end
29
29
  def initialize(uri, document, range)
@@ -33,7 +33,7 @@ module RubyLsp
33
33
  T.any(
34
34
  T.all(T::Array[Support::RuboCopDiagnostic], Object),
35
35
  T.all(T::Array[Support::SyntaxErrorDiagnostic], Object),
36
- )
36
+ ),
37
37
  )
38
38
  end
39
39
  def run
@@ -43,7 +43,7 @@ module RubyLsp
43
43
  @highlights
44
44
  end
45
45
 
46
- sig { params(node: T.nilable(SyntaxTree::Node)).void }
46
+ sig { override.params(node: T.nilable(SyntaxTree::Node)).void }
47
47
  def visit(node)
48
48
  return if node.nil?
49
49
 
@@ -25,7 +25,7 @@ module RubyLsp
25
25
  [*::Gem::Specification.default_stubs, *::Gem::Specification.stubs].map! do |s|
26
26
  [s.name, s.version.to_s]
27
27
  end.to_h.freeze,
28
- T::Hash[String, String]
28
+ T::Hash[String, String],
29
29
  )
30
30
 
31
31
  class << self
@@ -82,7 +82,7 @@ module RubyLsp
82
82
  @links
83
83
  end
84
84
 
85
- sig { params(node: SyntaxTree::Comment).void }
85
+ sig { override.params(node: SyntaxTree::Comment).void }
86
86
  def visit_comment(node)
87
87
  match = node.value.match(%r{source://.*#\d+$})
88
88
  return unless match
@@ -95,7 +95,7 @@ module RubyLsp
95
95
  @links << LanguageServer::Protocol::Interface::DocumentLink.new(
96
96
  range: range_from_syntax_tree_node(node),
97
97
  target: "file://#{file_path}##{uri.line_number}",
98
- tooltip: "Jump to #{file_path}##{uri.line_number}"
98
+ tooltip: "Jump to #{file_path}##{uri.line_number}",
99
99
  )
100
100
  end
101
101
 
@@ -79,7 +79,7 @@ module RubyLsp
79
79
  @root = T.let(SymbolHierarchyRoot.new, SymbolHierarchyRoot)
80
80
  @stack = T.let(
81
81
  [@root],
82
- T::Array[T.any(SymbolHierarchyRoot, LanguageServer::Protocol::Interface::DocumentSymbol)]
82
+ T::Array[T.any(SymbolHierarchyRoot, LanguageServer::Protocol::Interface::DocumentSymbol)],
83
83
  )
84
84
  end
85
85
 
@@ -89,13 +89,13 @@ module RubyLsp
89
89
  @root.children
90
90
  end
91
91
 
92
- sig { params(node: SyntaxTree::ClassDeclaration).void }
92
+ sig { override.params(node: SyntaxTree::ClassDeclaration).void }
93
93
  def visit_class(node)
94
94
  symbol = create_document_symbol(
95
95
  name: fully_qualified_name(node),
96
96
  kind: :class,
97
97
  range_node: node,
98
- selection_range_node: node.constant
98
+ selection_range_node: node.constant,
99
99
  )
100
100
 
101
101
  @stack << symbol
@@ -103,7 +103,7 @@ module RubyLsp
103
103
  @stack.pop
104
104
  end
105
105
 
106
- sig { params(node: SyntaxTree::Command).void }
106
+ sig { override.params(node: SyntaxTree::Command).void }
107
107
  def visit_command(node)
108
108
  return unless ATTR_ACCESSORS.include?(node.message.value)
109
109
 
@@ -114,22 +114,22 @@ module RubyLsp
114
114
  name: argument.value.value,
115
115
  kind: :field,
116
116
  range_node: argument,
117
- selection_range_node: argument.value
117
+ selection_range_node: argument.value,
118
118
  )
119
119
  end
120
120
  end
121
121
 
122
- sig { params(node: SyntaxTree::ConstPathField).void }
122
+ sig { override.params(node: SyntaxTree::ConstPathField).void }
123
123
  def visit_const_path_field(node)
124
124
  create_document_symbol(
125
125
  name: node.constant.value,
126
126
  kind: :constant,
127
127
  range_node: node,
128
- selection_range_node: node.constant
128
+ selection_range_node: node.constant,
129
129
  )
130
130
  end
131
131
 
132
- sig { params(node: SyntaxTree::Def).void }
132
+ sig { override.params(node: SyntaxTree::Def).void }
133
133
  def visit_def(node)
134
134
  name = node.name.value
135
135
 
@@ -137,7 +137,7 @@ module RubyLsp
137
137
  name: name,
138
138
  kind: name == "initialize" ? :constructor : :method,
139
139
  range_node: node,
140
- selection_range_node: node.name
140
+ selection_range_node: node.name,
141
141
  )
142
142
 
143
143
  @stack << symbol
@@ -145,7 +145,7 @@ module RubyLsp
145
145
  @stack.pop
146
146
  end
147
147
 
148
- sig { params(node: SyntaxTree::DefEndless).void }
148
+ sig { override.params(node: SyntaxTree::DefEndless).void }
149
149
  def visit_def_endless(node)
150
150
  name = node.name.value
151
151
 
@@ -153,7 +153,7 @@ module RubyLsp
153
153
  name: name,
154
154
  kind: name == "initialize" ? :constructor : :method,
155
155
  range_node: node,
156
- selection_range_node: node.name
156
+ selection_range_node: node.name,
157
157
  )
158
158
 
159
159
  @stack << symbol
@@ -161,13 +161,13 @@ module RubyLsp
161
161
  @stack.pop
162
162
  end
163
163
 
164
- sig { params(node: SyntaxTree::Defs).void }
164
+ sig { override.params(node: SyntaxTree::Defs).void }
165
165
  def visit_defs(node)
166
166
  symbol = create_document_symbol(
167
167
  name: "self.#{node.name.value}",
168
168
  kind: :method,
169
169
  range_node: node,
170
- selection_range_node: node.name
170
+ selection_range_node: node.name,
171
171
  )
172
172
 
173
173
  @stack << symbol
@@ -175,13 +175,13 @@ module RubyLsp
175
175
  @stack.pop
176
176
  end
177
177
 
178
- sig { params(node: SyntaxTree::ModuleDeclaration).void }
178
+ sig { override.params(node: SyntaxTree::ModuleDeclaration).void }
179
179
  def visit_module(node)
180
180
  symbol = create_document_symbol(
181
181
  name: fully_qualified_name(node),
182
182
  kind: :module,
183
183
  range_node: node,
184
- selection_range_node: node.constant
184
+ selection_range_node: node.constant,
185
185
  )
186
186
 
187
187
  @stack << symbol
@@ -189,17 +189,17 @@ module RubyLsp
189
189
  @stack.pop
190
190
  end
191
191
 
192
- sig { params(node: SyntaxTree::TopConstField).void }
192
+ sig { override.params(node: SyntaxTree::TopConstField).void }
193
193
  def visit_top_const_field(node)
194
194
  create_document_symbol(
195
195
  name: node.constant.value,
196
196
  kind: :constant,
197
197
  range_node: node,
198
- selection_range_node: node.constant
198
+ selection_range_node: node.constant,
199
199
  )
200
200
  end
201
201
 
202
- sig { params(node: SyntaxTree::VarField).void }
202
+ sig { override.params(node: SyntaxTree::VarField).void }
203
203
  def visit_var_field(node)
204
204
  kind = case node.value
205
205
  when SyntaxTree::Const
@@ -214,7 +214,7 @@ module RubyLsp
214
214
  name: node.value.value,
215
215
  kind: kind,
216
216
  range_node: node,
217
- selection_range_node: node.value
217
+ selection_range_node: node.value,
218
218
  )
219
219
  end
220
220
 
@@ -225,7 +225,7 @@ module RubyLsp
225
225
  name: String,
226
226
  kind: Symbol,
227
227
  range_node: SyntaxTree::Node,
228
- selection_range_node: SyntaxTree::Node
228
+ selection_range_node: SyntaxTree::Node,
229
229
  ).returns(LanguageServer::Protocol::Interface::DocumentSymbol)
230
230
  end
231
231
  def create_document_symbol(name:, kind:, range_node:, selection_range_node:)
@@ -73,7 +73,7 @@ module RubyLsp
73
73
 
74
74
  private
75
75
 
76
- sig { params(node: T.nilable(SyntaxTree::Node)).void }
76
+ sig { override.params(node: T.nilable(SyntaxTree::Node)).void }
77
77
  def visit(node)
78
78
  return unless handle_partial_range(node)
79
79
 
@@ -137,7 +137,7 @@ module RubyLsp
137
137
  LanguageServer::Protocol::Interface::FoldingRange.new(
138
138
  start_line: @start_line,
139
139
  end_line: @end_line,
140
- kind: @kind
140
+ kind: @kind,
141
141
  )
142
142
  end
143
143
 
@@ -248,7 +248,7 @@ module RubyLsp
248
248
  @ranges << LanguageServer::Protocol::Interface::FoldingRange.new(
249
249
  start_line: start_line - 1,
250
250
  end_line: end_line - 1,
251
- kind: "region"
251
+ kind: "region",
252
252
  )
253
253
  end
254
254
  end
@@ -42,9 +42,9 @@ module RubyLsp
42
42
  LanguageServer::Protocol::Interface::TextEdit.new(
43
43
  range: LanguageServer::Protocol::Interface::Range.new(
44
44
  start: LanguageServer::Protocol::Interface::Position.new(line: 0, character: 0),
45
- end: LanguageServer::Protocol::Interface::Position.new(line: size, character: size)
45
+ end: LanguageServer::Protocol::Interface::Position.new(line: size, character: size),
46
46
  ),
47
- new_text: formatted_text
47
+ new_text: formatted_text,
48
48
  ),
49
49
  ]
50
50
  end
@@ -0,0 +1,56 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RubyLsp
5
+ module Requests
6
+ # ![Inlay hint demo](../../misc/inlay_hint.gif)
7
+ #
8
+ # [Inlay hints](https://microsoft.github.io/language-server-protocol/specification#textDocument_inlayHint)
9
+ # are labels added directly in the code that explicitly show the user something that might
10
+ # otherwise just be implied.
11
+ #
12
+ # # Example
13
+ #
14
+ # ```ruby
15
+ # begin
16
+ # puts "do something that might raise"
17
+ # rescue # Label "StandardError" goes here as a bare rescue implies rescuing StandardError
18
+ # puts "handle some rescue"
19
+ # end
20
+ # ```
21
+ class InlayHints < BaseRequest
22
+ RESCUE_STRING_LENGTH = T.let("rescue".length, Integer)
23
+
24
+ sig { params(document: Document, range: T::Range[Integer]).void }
25
+ def initialize(document, range)
26
+ super(document)
27
+
28
+ @hints = T.let([], T::Array[LanguageServer::Protocol::Interface::InlayHint])
29
+ @range = range
30
+ end
31
+
32
+ sig { override.returns(T.all(T::Array[LanguageServer::Protocol::Interface::InlayHint], Object)) }
33
+ def run
34
+ visit(@document.tree)
35
+ @hints
36
+ end
37
+
38
+ sig { override.params(node: SyntaxTree::Rescue).void }
39
+ def visit_rescue(node)
40
+ return unless node.exception.nil?
41
+
42
+ loc = node.location
43
+ return unless @range.cover?(loc.start_line - 1) && @range.cover?(loc.end_line - 1)
44
+
45
+ @hints << LanguageServer::Protocol::Interface::InlayHint.new(
46
+ position: { line: loc.start_line - 1, character: loc.start_column + RESCUE_STRING_LENGTH },
47
+ label: "StandardError",
48
+ padding_left: true,
49
+ tooltip: "StandardError is implied in a bare rescue",
50
+ )
51
+
52
+ super
53
+ end
54
+ end
55
+ end
56
+ end
@@ -101,15 +101,15 @@ module RubyLsp
101
101
  def add_edit_with_text(text)
102
102
  position = Interface::Position.new(
103
103
  line: @position[:line],
104
- character: @position[:character]
104
+ character: @position[:character],
105
105
  )
106
106
 
107
107
  @edits << Interface::TextEdit.new(
108
108
  range: Interface::Range.new(
109
109
  start: position,
110
- end: position
110
+ end: position,
111
111
  ),
112
- new_text: text
112
+ new_text: text,
113
113
  )
114
114
  end
115
115
 
@@ -117,7 +117,7 @@ module RubyLsp
117
117
  def move_cursor_to(line, character)
118
118
  position = Interface::Position.new(
119
119
  line: line,
120
- character: character
120
+ character: character,
121
121
  )
122
122
 
123
123
  # The $0 is a special snippet anchor that moves the cursor to that given position. See the snippets
@@ -126,9 +126,9 @@ module RubyLsp
126
126
  @edits << Interface::TextEdit.new(
127
127
  range: Interface::Range.new(
128
128
  start: position,
129
- end: position
129
+ end: position,
130
130
  ),
131
- new_text: "$0"
131
+ new_text: "$0",
132
132
  )
133
133
  end
134
134
 
@@ -76,7 +76,7 @@ module RubyLsp
76
76
 
77
77
  private
78
78
 
79
- sig { params(node: T.nilable(SyntaxTree::Node)).void }
79
+ sig { override.params(node: T.nilable(SyntaxTree::Node)).void }
80
80
  def visit(node)
81
81
  return if node.nil?
82
82
 
@@ -93,7 +93,7 @@ module RubyLsp
93
93
  sig do
94
94
  params(
95
95
  location: SyntaxTree::Location,
96
- parent: T.nilable(Support::SelectionRange)
96
+ parent: T.nilable(Support::SelectionRange),
97
97
  ).returns(Support::SelectionRange)
98
98
  end
99
99
  def create_selection_range(location, parent = nil)
@@ -108,7 +108,7 @@ module RubyLsp
108
108
  character: location.end_column,
109
109
  ),
110
110
  ),
111
- parent: parent
111
+ parent: parent,
112
112
  )
113
113
  end
114
114
  end
@@ -90,7 +90,7 @@ module RubyLsp
90
90
  T.any(
91
91
  LanguageServer::Protocol::Interface::SemanticTokens,
92
92
  T.all(T::Array[SemanticToken], Object),
93
- )
93
+ ),
94
94
  )
95
95
  end
96
96
  def run
@@ -100,12 +100,7 @@ module RubyLsp
100
100
  @encoder.encode(@tokens)
101
101
  end
102
102
 
103
- sig { params(node: SyntaxTree::ARefField).void }
104
- def visit_a_ref_field(node)
105
- add_token(node.collection.value.location, :variable)
106
- end
107
-
108
- sig { params(node: SyntaxTree::Call).void }
103
+ sig { override.params(node: SyntaxTree::Call).void }
109
104
  def visit_call(node)
110
105
  visit(node.receiver)
111
106
 
@@ -115,32 +110,32 @@ module RubyLsp
115
110
  visit(node.arguments)
116
111
  end
117
112
 
118
- sig { params(node: SyntaxTree::Command).void }
113
+ sig { override.params(node: SyntaxTree::Command).void }
119
114
  def visit_command(node)
120
115
  add_token(node.message.location, :method) unless special_method?(node.message.value)
121
116
  visit(node.arguments)
122
117
  end
123
118
 
124
- sig { params(node: SyntaxTree::CommandCall).void }
119
+ sig { override.params(node: SyntaxTree::CommandCall).void }
125
120
  def visit_command_call(node)
126
121
  visit(node.receiver)
127
122
  add_token(node.message.location, :method)
128
123
  visit(node.arguments)
129
124
  end
130
125
 
131
- sig { params(node: SyntaxTree::Const).void }
126
+ sig { override.params(node: SyntaxTree::Const).void }
132
127
  def visit_const(node)
133
128
  add_token(node.location, :namespace)
134
129
  end
135
130
 
136
- sig { params(node: SyntaxTree::Def).void }
131
+ sig { override.params(node: SyntaxTree::Def).void }
137
132
  def visit_def(node)
138
133
  add_token(node.name.location, :method, [:declaration])
139
134
  visit(node.params)
140
135
  visit(node.bodystmt)
141
136
  end
142
137
 
143
- sig { params(node: SyntaxTree::DefEndless).void }
138
+ sig { override.params(node: SyntaxTree::DefEndless).void }
144
139
  def visit_def_endless(node)
145
140
  add_token(node.name.location, :method, [:declaration])
146
141
  visit(node.paren)
@@ -148,7 +143,7 @@ module RubyLsp
148
143
  visit(node.statement)
149
144
  end
150
145
 
151
- sig { params(node: SyntaxTree::Defs).void }
146
+ sig { override.params(node: SyntaxTree::Defs).void }
152
147
  def visit_defs(node)
153
148
  visit(node.target)
154
149
  visit(node.operator)
@@ -157,13 +152,13 @@ module RubyLsp
157
152
  visit(node.bodystmt)
158
153
  end
159
154
 
160
- sig { params(node: SyntaxTree::FCall).void }
155
+ sig { override.params(node: SyntaxTree::FCall).void }
161
156
  def visit_fcall(node)
162
157
  add_token(node.value.location, :method) unless special_method?(node.value.value)
163
158
  visit(node.arguments)
164
159
  end
165
160
 
166
- sig { params(node: SyntaxTree::Kw).void }
161
+ sig { override.params(node: SyntaxTree::Kw).void }
167
162
  def visit_kw(node)
168
163
  case node.value
169
164
  when "self"
@@ -171,14 +166,7 @@ module RubyLsp
171
166
  end
172
167
  end
173
168
 
174
- sig { params(node: SyntaxTree::MAssign).void }
175
- def visit_m_assign(node)
176
- node.target.parts.each do |var_ref|
177
- add_token(var_ref.value.location, :variable)
178
- end
179
- end
180
-
181
- sig { params(node: SyntaxTree::Params).void }
169
+ sig { override.params(node: SyntaxTree::Params).void }
182
170
  def visit_params(node)
183
171
  node.keywords.each do |keyword,|
184
172
  location = keyword.location
@@ -196,7 +184,7 @@ module RubyLsp
196
184
  add_token(name.location, :variable) if name
197
185
  end
198
186
 
199
- sig { params(node: SyntaxTree::VarField).void }
187
+ sig { override.params(node: SyntaxTree::VarField).void }
200
188
  def visit_var_field(node)
201
189
  case node.value
202
190
  when SyntaxTree::Ident
@@ -206,7 +194,7 @@ module RubyLsp
206
194
  end
207
195
  end
208
196
 
209
- sig { params(node: SyntaxTree::VarRef).void }
197
+ sig { override.params(node: SyntaxTree::VarRef).void }
210
198
  def visit_var_ref(node)
211
199
  case node.value
212
200
  when SyntaxTree::Ident
@@ -216,19 +204,19 @@ module RubyLsp
216
204
  end
217
205
  end
218
206
 
219
- sig { params(node: SyntaxTree::VCall).void }
207
+ sig { override.params(node: SyntaxTree::VCall).void }
220
208
  def visit_vcall(node)
221
209
  add_token(node.value.location, :method) unless special_method?(node.value.value)
222
210
  end
223
211
 
224
- sig { params(node: SyntaxTree::ClassDeclaration).void }
212
+ sig { override.params(node: SyntaxTree::ClassDeclaration).void }
225
213
  def visit_class(node)
226
214
  add_token(node.constant.location, :class, [:declaration])
227
215
  add_token(node.superclass.location, :class) if node.superclass
228
216
  visit(node.bodystmt)
229
217
  end
230
218
 
231
- sig { params(node: SyntaxTree::ModuleDeclaration).void }
219
+ sig { override.params(node: SyntaxTree::ModuleDeclaration).void }
232
220
  def visit_module(node)
233
221
  add_token(node.constant.location, :class, [:declaration])
234
222
  visit(node.bodystmt)
@@ -243,8 +231,8 @@ module RubyLsp
243
231
  location: location,
244
232
  length: length,
245
233
  type: T.must(TOKEN_TYPES[type]),
246
- modifier: modifiers_indices
247
- )
234
+ modifier: modifiers_indices,
235
+ ),
248
236
  )
249
237
  end
250
238
 
@@ -25,7 +25,7 @@ module RubyLsp
25
25
  @uri = uri
26
26
  @replacements = T.let(
27
27
  offense.correctable? ? offense_replacements : [],
28
- T::Array[LanguageServer::Protocol::Interface::TextEdit]
28
+ T::Array[LanguageServer::Protocol::Interface::TextEdit],
29
29
  )
30
30
  end
31
31
 
@@ -49,11 +49,11 @@ module RubyLsp
49
49
  LanguageServer::Protocol::Interface::TextDocumentEdit.new(
50
50
  text_document: LanguageServer::Protocol::Interface::OptionalVersionedTextDocumentIdentifier.new(
51
51
  uri: @uri,
52
- version: nil
52
+ version: nil,
53
53
  ),
54
- edits: @replacements
54
+ edits: @replacements,
55
55
  ),
56
- ]
56
+ ],
57
57
  ),
58
58
  is_preferred: true,
59
59
  )
@@ -76,13 +76,13 @@ module RubyLsp
76
76
  range: LanguageServer::Protocol::Interface::Range.new(
77
77
  start: LanguageServer::Protocol::Interface::Position.new(
78
78
  line: @offense.line - 1,
79
- character: @offense.column
79
+ character: @offense.column,
80
80
  ),
81
81
  end: LanguageServer::Protocol::Interface::Position.new(
82
82
  line: @offense.last_line - 1,
83
- character: @offense.last_column
84
- )
85
- )
83
+ character: @offense.last_column,
84
+ ),
85
+ ),
86
86
  )
87
87
  end
88
88
 
@@ -95,9 +95,9 @@ module RubyLsp
95
95
  range: LanguageServer::Protocol::Interface::Range.new(
96
96
  start: LanguageServer::Protocol::Interface::Position.new(line: range.line - 1, character: range.column),
97
97
  end: LanguageServer::Protocol::Interface::Position.new(line: range.last_line - 1,
98
- character: range.last_column)
98
+ character: range.last_column),
99
99
  ),
100
- new_text: replacement
100
+ new_text: replacement,
101
101
  )
102
102
  end
103
103
  end
@@ -7,6 +7,12 @@ rescue LoadError
7
7
  return
8
8
  end
9
9
 
10
+ begin
11
+ gem("rubocop", ">= 1.4.0")
12
+ rescue LoadError
13
+ raise StandardError, "Incompatible RuboCop version. Ruby LSP requires >= 1.4.0"
14
+ end
15
+
10
16
  module RubyLsp
11
17
  module Requests
12
18
  module Support
@@ -14,6 +20,8 @@ module RubyLsp
14
20
  class RuboCopRunner < RuboCop::Runner
15
21
  extend T::Sig
16
22
 
23
+ class ConfigurationError < StandardError; end
24
+
17
25
  sig { returns(T::Array[RuboCop::Cop::Offense]) }
18
26
  attr_reader :offenses
19
27
 
@@ -50,6 +58,8 @@ module RubyLsp
50
58
  super([path])
51
59
  rescue RuboCop::Runner::InfiniteCorrectionLoop => error
52
60
  raise Formatting::Error, error.message
61
+ rescue RuboCop::ValidationError => error
62
+ raise ConfigurationError, error.message
53
63
  end
54
64
 
55
65
  sig { returns(String) }
@@ -15,7 +15,7 @@ module RubyLsp
15
15
 
16
16
  sig do
17
17
  params(
18
- tokens: T::Array[SemanticHighlighting::SemanticToken]
18
+ tokens: T::Array[SemanticHighlighting::SemanticToken],
19
19
  ).returns(LanguageServer::Protocol::Interface::SemanticTokens)
20
20
  end
21
21
  def encode(tokens)
@@ -30,7 +30,7 @@ module URI
30
30
  gem_name: String,
31
31
  gem_version: T.nilable(String),
32
32
  path: String,
33
- line_number: T.nilable(String)
33
+ line_number: T.nilable(String),
34
34
  ).returns(URI::Source)
35
35
  end
36
36
  def build(gem_name:, gem_version:, path:, line_number:)
@@ -23,7 +23,7 @@ module RubyLsp
23
23
  message: "Syntax error",
24
24
  source: "SyntaxTree",
25
25
  severity: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
26
- range: @edit[:range]
26
+ range: @edit[:range],
27
27
  )
28
28
  end
29
29
  end
@@ -14,6 +14,8 @@ module RubyLsp
14
14
  # - {RubyLsp::Requests::Diagnostics}
15
15
  # - {RubyLsp::Requests::CodeActions}
16
16
  # - {RubyLsp::Requests::DocumentHighlight}
17
+ # - {RubyLsp::Requests::InlayHints}
18
+
17
19
  module Requests
18
20
  autoload :BaseRequest, "ruby_lsp/requests/base_request"
19
21
  autoload :DocumentSymbol, "ruby_lsp/requests/document_symbol"
@@ -26,6 +28,7 @@ module RubyLsp
26
28
  autoload :Diagnostics, "ruby_lsp/requests/diagnostics"
27
29
  autoload :CodeActions, "ruby_lsp/requests/code_actions"
28
30
  autoload :DocumentHighlight, "ruby_lsp/requests/document_highlight"
31
+ autoload :InlayHints, "ruby_lsp/requests/inlay_hints"
29
32
 
30
33
  # :nodoc:
31
34
  module Support
@@ -15,7 +15,7 @@ module RubyLsp
15
15
  hierarchical_document_symbol_support: true,
16
16
  symbol_kind: {
17
17
  value_set: Requests::DocumentSymbol::SYMBOL_KIND.values,
18
- }
18
+ },
19
19
  )
20
20
  end
21
21
 
@@ -32,12 +32,12 @@ module RubyLsp
32
32
  document_selector: { scheme: "file", language: "ruby" },
33
33
  legend: Interface::SemanticTokensLegend.new(
34
34
  token_types: Requests::SemanticHighlighting::TOKEN_TYPES.keys,
35
- token_modifiers: Requests::SemanticHighlighting::TOKEN_MODIFIERS.keys
35
+ token_modifiers: Requests::SemanticHighlighting::TOKEN_MODIFIERS.keys,
36
36
  ),
37
37
  range: false,
38
38
  full: {
39
39
  delta: true,
40
- }
40
+ },
41
41
  )
42
42
  end
43
43
 
@@ -51,10 +51,14 @@ module RubyLsp
51
51
  on_type_formatting_provider = if enabled_features.include?("onTypeFormatting")
52
52
  Interface::DocumentOnTypeFormattingOptions.new(
53
53
  first_trigger_character: "{",
54
- more_trigger_character: ["\n", "|"]
54
+ more_trigger_character: ["\n", "|"],
55
55
  )
56
56
  end
57
57
 
58
+ inlay_hint_provider = if enabled_features.include?("inlayHint")
59
+ Interface::InlayHintOptions.new(resolve_provider: false)
60
+ end
61
+
58
62
  Interface::InitializeResult.new(
59
63
  capabilities: Interface::ServerCapabilities.new(
60
64
  text_document_sync: Interface::TextDocumentSyncOptions.new(
@@ -71,7 +75,8 @@ module RubyLsp
71
75
  code_action_provider: enabled_features.include?("codeActions"),
72
76
  document_on_type_formatting_provider: on_type_formatting_provider,
73
77
  diagnostic_provider: diagnostics_provider,
74
- )
78
+ inlay_hint_provider: inlay_hint_provider,
79
+ ),
75
80
  )
76
81
  end
77
82
 
@@ -144,9 +149,9 @@ module RubyLsp
144
149
  T.cast(
145
150
  Requests::SemanticHighlighting.new(
146
151
  document,
147
- encoder: Requests::Support::SemanticTokenEncoder.new
152
+ encoder: Requests::Support::SemanticTokenEncoder.new,
148
153
  ).run,
149
- LanguageServer::Protocol::Interface::SemanticTokens
154
+ LanguageServer::Protocol::Interface::SemanticTokens,
150
155
  )
151
156
  end
152
157
  end
@@ -186,12 +191,23 @@ module RubyLsp
186
191
  end
187
192
  end
188
193
 
194
+ on("textDocument/inlayHint", parallel: true) do |request|
195
+ document = store.get(request.dig(:params, :textDocument, :uri))
196
+ range = request.dig(:params, :range)
197
+ start_line = range.dig(:start, :line)
198
+ end_line = range.dig(:end, :line)
199
+
200
+ if document.parsed?
201
+ Requests::InlayHints.new(document, start_line..end_line).run
202
+ end
203
+ end
204
+
189
205
  on("$/cancelRequest") do |request|
190
206
  cancel_request(request[:params][:id])
191
207
  Handler::VOID
192
208
  end
193
209
 
194
- on("textDocument/diagnostic") do |request|
210
+ on("textDocument/diagnostic", parallel: true) do |request|
195
211
  uri = request.dig(:params, :textDocument, :uri)
196
212
  response = store.cache_fetch(uri, :diagnostics) do |document|
197
213
  Requests::Diagnostics.new(uri, document).run
@@ -199,9 +215,7 @@ module RubyLsp
199
215
 
200
216
  { kind: "full", items: response.map(&:to_lsp_diagnostic) } if response
201
217
  end.on_error do |error|
202
- if error.is_a?(RuboCop::ValidationError)
203
- show_message(Constant::MessageType::ERROR, "Error in RuboCop configuration file: #{error.message}")
204
- end
218
+ show_message(Constant::MessageType::ERROR, "Error running diagnostics: #{error.message}")
205
219
  end
206
220
 
207
221
  on("shutdown") { shutdown }
@@ -54,7 +54,7 @@ module RubyLsp
54
54
  .params(
55
55
  uri: String,
56
56
  request_name: Symbol,
57
- block: T.proc.params(document: Document).returns(T.type_parameter(:T))
57
+ block: T.proc.params(document: Document).returns(T.type_parameter(:T)),
58
58
  ).returns(T.nilable(T.type_parameter(:T)))
59
59
  end
60
60
  def cache_fetch(uri, request_name, &block)
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.3.1
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-06 00:00:00.000000000 Z
11
+ date: 2022-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: language_server-protocol
@@ -60,7 +60,6 @@ executables:
60
60
  extensions: []
61
61
  extra_rdoc_files: []
62
62
  files:
63
- - CHANGELOG.md
64
63
  - LICENSE.txt
65
64
  - README.md
66
65
  - VERSION
@@ -79,6 +78,7 @@ files:
79
78
  - lib/ruby_lsp/requests/document_symbol.rb
80
79
  - lib/ruby_lsp/requests/folding_ranges.rb
81
80
  - lib/ruby_lsp/requests/formatting.rb
81
+ - lib/ruby_lsp/requests/inlay_hints.rb
82
82
  - lib/ruby_lsp/requests/on_type_formatting.rb
83
83
  - lib/ruby_lsp/requests/selection_ranges.rb
84
84
  - lib/ruby_lsp/requests/semantic_highlighting.rb
data/CHANGELOG.md DELETED
@@ -1,70 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to the "ruby-lsp" extension will be documented in this file.
4
-
5
- Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
6
-
7
- ## [Unreleased]
8
-
9
- ## [0.3.1]
10
-
11
- - Resolve TODO for LSP v3.17 (https://github.com/Shopify/ruby-lsp/pull/268)
12
- - Add dependency constraint for LSP v3.17 (https://github.com/Shopify/ruby-lsp/pull/269)
13
- - Handle class/module declarations as a class token with declaration modifier (https://github.com/Shopify/ruby-lsp/pull/260)
14
- - Handle required parameters in semantic highlighting (https://github.com/Shopify/ruby-lsp/pull/271)
15
- - Add comment continuation via on type on_type_formatting (https://github.com/Shopify/ruby-lsp/pull/274)
16
- - Make RuboCop runner use composition instead of inheritance (https://github.com/Shopify/ruby-lsp/pull/278)
17
- - Protect worker against cancellation during popping (https://github.com/Shopify/ruby-lsp/pull/280)
18
- - Handle formatting errors in on_error block (https://github.com/Shopify/ruby-lsp/pull/279)
19
- - Fix on type formatting pipe completion for regular or expressions (https://github.com/Shopify/ruby-lsp/pull/282)
20
- - Do not fail on LoadError (https://github.com/Shopify/ruby-lsp/pull/292)
21
-
22
- ## [0.3.0]
23
- - Add on type formatting completions (https://github.com/Shopify/ruby-lsp/pull/253)
24
- - Upgrade syntax_tree requirement to >= 3.4 (https://github.com/Shopify/ruby-lsp/pull/254)
25
- - Show error message when there's a InfiniteCorrectionLoop exception (https://github.com/Shopify/ruby-lsp/pull/252)
26
- - Add request cancellation (https://github.com/Shopify/ruby-lsp/pull/243)
27
-
28
- ## [0.2.0]
29
-
30
- - Add semantic token for keyword and keyword rest params (https://github.com/Shopify/ruby-lsp/pull/142)
31
- - Return error responses on exceptions (https://github.com/Shopify/ruby-lsp/pull/160)
32
- - Sanitize home directory for telemetry (https://github.com/Shopify/ruby-lsp/pull/171)
33
- - Avoid adding semantic tokens for special methods (https://github.com/Shopify/ruby-lsp/pull/162)
34
- - Properly respect excluded files in RuboCop requests (https://github.com/Shopify/ruby-lsp/pull/173)
35
- - Clear diagnostics when closing files (https://github.com/Shopify/ruby-lsp/pull/174)
36
- - Avoid pushing ranges for single line partial ranges (https://github.com/Shopify/ruby-lsp/pull/185)
37
- - Change folding ranges to include closing tokens (https://github.com/Shopify/ruby-lsp/pull/181)
38
- - Remove RuboCop dependency and fallback to SyntaxTree formatting (https://github.com/Shopify/ruby-lsp/pull/184)
39
-
40
- ## [0.1.0]
41
-
42
- - Implement token modifiers in SemanticTokenEncoder ([#112](https://github.com/Shopify/ruby-lsp/pull/112))
43
- - Add semantic token for name in a method definition ([#133](https://github.com/Shopify/ruby-lsp/pull/133))
44
- - Add semantic highighting for def endless and singleton method names ([#134](https://github.com/Shopify/ruby-lsp/pull/134))
45
- - Add semantic token for keyword self ([#137](https://github.com/Shopify/ruby-lsp/pull/137))
46
- - Add semantic token for constants ([#138](https://github.com/Shopify/ruby-lsp/pull/138))
47
- - Improve error handling + fix formatting hanging issue ([#149](https://github.com/Shopify/ruby-lsp/pull/149))
48
- - Set the minimum syntax_tree version to 2.4 ([#151](https://github.com/Shopify/ruby-lsp/pull/151))
49
-
50
- ## [0.0.4]
51
-
52
- - Add basic document highlight (https://github.com/Shopify/ruby-lsp/pull/91)
53
- - Add error telemetry (https://github.com/Shopify/ruby-lsp/pull/100)
54
- - Always push telemetry events from the server (https://github.com/Shopify/ruby-lsp/pull/109)
55
- - Fix multibyte character handling (https://github.com/Shopify/ruby-lsp/pull/122)
56
- - Add Sorbet to the Ruby LSP (https://github.com/Shopify/ruby-lsp/pull/119, https://github.com/Shopify/ruby-lsp/pull/123)
57
-
58
- ## [0.0.3]
59
-
60
- - Fixed code actions return hanging
61
- - Moved to incremental text synchronization
62
- - Added syntax error resiliency
63
-
64
- ## [0.0.2]
65
-
66
- - Alpha release including
67
- - RuboCop formatting, diagnostics and quick fixes
68
- - Folding ranges
69
- - Initial semantic highlighting
70
- - Document symbols