ruby-lsp 0.3.0 → 0.3.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/CHANGELOG.md +13 -0
- data/VERSION +1 -1
- data/lib/ruby_lsp/handler.rb +2 -2
- data/lib/ruby_lsp/queue.rb +22 -16
- data/lib/ruby_lsp/requests/formatting.rb +2 -0
- data/lib/ruby_lsp/requests/on_type_formatting.rb +16 -2
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +17 -0
- data/lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb +9 -34
- data/lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb +9 -23
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +69 -0
- data/lib/ruby_lsp/server.rb +15 -17
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9762389a7b7979afb57d6e6d2cf0d65b0b0a0b31f5a1fdd7045311c33a0c21d6
|
4
|
+
data.tar.gz: 35cc2318946e650ee311129955d3674c7e693a87d25c5cc2f29c5a55e479d880
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4735e18c297c992727d0a151ed7948cf6d4ea32b01fe411ed0774efdda7cdc0cf6533f5d71ad288aad9e6e717149932744376fdceda9fa4cd039b560934a9b47
|
7
|
+
data.tar.gz: bd6e0c9a81a373c509f2f96b480543657a8d241a6e58ea25ec21c62ac60094f299af1c5f85d1555ad6ca1908c325e46569119271d4c6b7117f33f9919cf40bca
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,19 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
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
|
+
|
9
22
|
## [0.3.0]
|
10
23
|
- Add on type formatting completions (https://github.com/Shopify/ruby-lsp/pull/253)
|
11
24
|
- Upgrade syntax_tree requirement to >= 3.4 (https://github.com/Shopify/ruby-lsp/pull/254)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
data/lib/ruby_lsp/handler.rb
CHANGED
@@ -20,13 +20,13 @@ module RubyLsp
|
|
20
20
|
const :action, T.proc.params(request: T::Hash[Symbol, T.untyped]).returns(T.untyped)
|
21
21
|
const :parallel, T::Boolean
|
22
22
|
prop :error_handler,
|
23
|
-
T.nilable(T.proc.params(error:
|
23
|
+
T.nilable(T.proc.params(error: Exception, request: T::Hash[Symbol, T.untyped]).void)
|
24
24
|
|
25
25
|
# A proc that runs in case a request has errored. Receives the error and the original request as arguments. Useful
|
26
26
|
# for displaying window messages on errors
|
27
27
|
sig do
|
28
28
|
params(
|
29
|
-
block: T.proc.bind(Handler).params(error:
|
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)
|
data/lib/ruby_lsp/queue.rb
CHANGED
@@ -7,11 +7,11 @@ module RubyLsp
|
|
7
7
|
class Queue
|
8
8
|
extend T::Sig
|
9
9
|
|
10
|
-
class Cancelled <
|
10
|
+
class Cancelled < StandardError; end
|
11
11
|
|
12
12
|
class Result < T::Struct
|
13
13
|
const :response, T.untyped # rubocop:disable Sorbet/ForbidUntypedStructProps
|
14
|
-
const :error, T.nilable(
|
14
|
+
const :error, T.nilable(Exception)
|
15
15
|
const :request_time, T.nilable(Float)
|
16
16
|
end
|
17
17
|
|
@@ -88,11 +88,13 @@ module RubyLsp
|
|
88
88
|
sig { params(request: T::Hash[Symbol, T.untyped]).returns(Queue::Result) }
|
89
89
|
def execute(request)
|
90
90
|
response = T.let(nil, T.untyped)
|
91
|
-
error = T.let(nil, T.nilable(
|
91
|
+
error = T.let(nil, T.nilable(Exception))
|
92
92
|
|
93
93
|
request_time = Benchmark.realtime do
|
94
94
|
response = T.must(@handlers[request[:method]]).action.call(request)
|
95
|
-
rescue
|
95
|
+
rescue Cancelled
|
96
|
+
raise
|
97
|
+
rescue StandardError, LoadError => e
|
96
98
|
error = e
|
97
99
|
end
|
98
100
|
|
@@ -135,7 +137,10 @@ module RubyLsp
|
|
135
137
|
def new_worker
|
136
138
|
Thread.new do
|
137
139
|
# Thread::Queue#pop is thread safe and will wait until an item is available
|
138
|
-
|
140
|
+
loop do
|
141
|
+
job = T.let(@job_queue.pop, T.nilable(Job))
|
142
|
+
break if job.nil?
|
143
|
+
|
139
144
|
# The only time when the job is nil is when the queue is closed and we can then terminate the thread
|
140
145
|
|
141
146
|
request = job.request
|
@@ -144,17 +149,18 @@ module RubyLsp
|
|
144
149
|
@current_job = job
|
145
150
|
end
|
146
151
|
|
147
|
-
|
148
|
-
next if job.cancelled
|
152
|
+
next if job.cancelled
|
149
153
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
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 }
|
160
|
+
|
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?
|
158
164
|
end
|
159
165
|
end
|
160
166
|
end
|
@@ -163,7 +169,7 @@ module RubyLsp
|
|
163
169
|
params(
|
164
170
|
request: T::Hash[Symbol, T.untyped],
|
165
171
|
request_time: Float,
|
166
|
-
error: T.nilable(
|
172
|
+
error: T.nilable(Exception)
|
167
173
|
).returns(T::Hash[Symbol, T.any(String, Float)])
|
168
174
|
end
|
169
175
|
def telemetry_params(request, request_time, error)
|
@@ -41,7 +41,9 @@ module RubyLsp
|
|
41
41
|
|
42
42
|
sig { override.returns(T.nilable(T.all(T::Array[Interface::TextEdit], Object))) }
|
43
43
|
def run
|
44
|
-
|
44
|
+
handle_comment_line
|
45
|
+
|
46
|
+
return @edits unless @document.syntax_errors?
|
45
47
|
|
46
48
|
case @trigger_character
|
47
49
|
when "{"
|
@@ -59,7 +61,7 @@ module RubyLsp
|
|
59
61
|
|
60
62
|
sig { void }
|
61
63
|
def handle_pipe
|
62
|
-
return unless /
|
64
|
+
return unless /((?<=do)|(?<={))\s+\|/.match?(@previous_line)
|
63
65
|
|
64
66
|
add_edit_with_text("|")
|
65
67
|
move_cursor_to(@position[:line], @position[:character])
|
@@ -83,6 +85,18 @@ module RubyLsp
|
|
83
85
|
move_cursor_to(@position[:line], @indentation + 2)
|
84
86
|
end
|
85
87
|
|
88
|
+
sig { void }
|
89
|
+
def handle_comment_line
|
90
|
+
return unless @trigger_character == "\n"
|
91
|
+
|
92
|
+
is_comment_match = @previous_line.match(/^#(\s*)/)
|
93
|
+
return unless is_comment_match
|
94
|
+
|
95
|
+
spaces = T.must(is_comment_match[1])
|
96
|
+
add_edit_with_text("##{spaces}")
|
97
|
+
move_cursor_to(@position[:line], @indentation + spaces.size + 1)
|
98
|
+
end
|
99
|
+
|
86
100
|
sig { params(text: String).void }
|
87
101
|
def add_edit_with_text(text)
|
88
102
|
position = Interface::Position.new(
|
@@ -185,6 +185,10 @@ module RubyLsp
|
|
185
185
|
add_token(location_without_colon(location), :variable)
|
186
186
|
end
|
187
187
|
|
188
|
+
node.requireds.each do |required|
|
189
|
+
add_token(required.location, :variable)
|
190
|
+
end
|
191
|
+
|
188
192
|
rest = node.keyword_rest
|
189
193
|
return if rest.nil? || rest.is_a?(SyntaxTree::ArgsForward)
|
190
194
|
|
@@ -217,6 +221,19 @@ module RubyLsp
|
|
217
221
|
add_token(node.value.location, :method) unless special_method?(node.value.value)
|
218
222
|
end
|
219
223
|
|
224
|
+
sig { params(node: SyntaxTree::ClassDeclaration).void }
|
225
|
+
def visit_class(node)
|
226
|
+
add_token(node.constant.location, :class, [:declaration])
|
227
|
+
add_token(node.superclass.location, :class) if node.superclass
|
228
|
+
visit(node.bodystmt)
|
229
|
+
end
|
230
|
+
|
231
|
+
sig { params(node: SyntaxTree::ModuleDeclaration).void }
|
232
|
+
def visit_module(node)
|
233
|
+
add_token(node.constant.location, :class, [:declaration])
|
234
|
+
visit(node.bodystmt)
|
235
|
+
end
|
236
|
+
|
220
237
|
sig { params(location: SyntaxTree::Location, type: Symbol, modifiers: T::Array[Symbol]).void }
|
221
238
|
def add_token(location, type, modifiers = [])
|
222
239
|
length = location.end_char - location.start_char
|
@@ -1,11 +1,8 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
rescue LoadError
|
7
|
-
return
|
8
|
-
end
|
4
|
+
require "ruby_lsp/requests/support/rubocop_runner"
|
5
|
+
return unless defined?(::RubyLsp::Requests::Support::RuboCopRunner)
|
9
6
|
|
10
7
|
require "cgi"
|
11
8
|
require "singleton"
|
@@ -14,46 +11,24 @@ module RubyLsp
|
|
14
11
|
module Requests
|
15
12
|
module Support
|
16
13
|
# :nodoc:
|
17
|
-
class RuboCopDiagnosticsRunner
|
14
|
+
class RuboCopDiagnosticsRunner
|
18
15
|
extend T::Sig
|
19
16
|
include Singleton
|
20
17
|
|
21
18
|
sig { void }
|
22
19
|
def initialize
|
23
|
-
@
|
24
|
-
@uri = T.let(nil, T.nilable(String))
|
25
|
-
@diagnostics = T.let([], T::Array[Support::RuboCopDiagnostic])
|
26
|
-
|
27
|
-
super(
|
28
|
-
::RuboCop::Options.new.parse([
|
29
|
-
"--stderr", # Print any output to stderr so that our stdout does not get polluted
|
30
|
-
"--force-exclusion",
|
31
|
-
"--format",
|
32
|
-
"RuboCop::Formatter::BaseFormatter", # Suppress any output by using the base formatter
|
33
|
-
]).first,
|
34
|
-
::RuboCop::ConfigStore.new
|
35
|
-
)
|
20
|
+
@runner = T.let(RuboCopRunner.new, RuboCopRunner)
|
36
21
|
end
|
37
22
|
|
38
23
|
sig { params(uri: String, document: Document).returns(T::Array[Support::RuboCopDiagnostic]) }
|
39
24
|
def run(uri, document)
|
40
|
-
|
41
|
-
@uri = uri
|
42
|
-
|
43
|
-
file = CGI.unescape(URI.parse(uri).path)
|
44
|
-
# We communicate with Rubocop via stdin
|
45
|
-
@options[:stdin] = document.source
|
46
|
-
|
25
|
+
filename = CGI.unescape(URI.parse(uri).path)
|
47
26
|
# Invoke RuboCop with just this file in `paths`
|
48
|
-
|
49
|
-
@diagnostics
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
27
|
+
@runner.run(filename, document.source)
|
53
28
|
|
54
|
-
|
55
|
-
|
56
|
-
|
29
|
+
@runner.offenses.map do |offense|
|
30
|
+
Support::RuboCopDiagnostic.new(offense, uri)
|
31
|
+
end
|
57
32
|
end
|
58
33
|
end
|
59
34
|
end
|
@@ -1,11 +1,8 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
rescue LoadError
|
7
|
-
return
|
8
|
-
end
|
4
|
+
require "ruby_lsp/requests/support/rubocop_runner"
|
5
|
+
return unless defined?(::RubyLsp::Requests::Support::RuboCopRunner)
|
9
6
|
|
10
7
|
require "cgi"
|
11
8
|
require "singleton"
|
@@ -14,35 +11,24 @@ module RubyLsp
|
|
14
11
|
module Requests
|
15
12
|
module Support
|
16
13
|
# :nodoc:
|
17
|
-
class RuboCopFormattingRunner
|
14
|
+
class RuboCopFormattingRunner
|
18
15
|
extend T::Sig
|
19
16
|
include Singleton
|
20
17
|
|
21
18
|
sig { void }
|
22
19
|
def initialize
|
23
|
-
|
24
|
-
|
25
|
-
super(
|
26
|
-
::RuboCop::Options.new.parse([
|
27
|
-
"--stderr", # Print any output to stderr so that our stdout does not get polluted
|
28
|
-
"--force-exclusion",
|
29
|
-
"--format",
|
30
|
-
"RuboCop::Formatter::BaseFormatter", # Suppress any output by using the base formatter
|
31
|
-
"-a", # --auto-correct
|
32
|
-
]).first,
|
33
|
-
::RuboCop::ConfigStore.new
|
34
|
-
)
|
20
|
+
# -a is for "--auto-correct" (or "--autocorrect" on newer versions of RuboCop)
|
21
|
+
@runner = T.let(RuboCopRunner.new("-a"), RuboCopRunner)
|
35
22
|
end
|
36
23
|
|
37
24
|
sig { params(uri: String, document: Document).returns(T.nilable(String)) }
|
38
25
|
def run(uri, document)
|
39
|
-
|
40
|
-
# We communicate with Rubocop via stdin
|
41
|
-
@options[:stdin] = document.source
|
26
|
+
filename = CGI.unescape(URI.parse(uri).path)
|
42
27
|
|
43
28
|
# Invoke RuboCop with just this file in `paths`
|
44
|
-
|
45
|
-
|
29
|
+
@runner.run(filename, document.source)
|
30
|
+
|
31
|
+
@runner.formatted_source
|
46
32
|
end
|
47
33
|
end
|
48
34
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "rubocop"
|
6
|
+
rescue LoadError
|
7
|
+
return
|
8
|
+
end
|
9
|
+
|
10
|
+
module RubyLsp
|
11
|
+
module Requests
|
12
|
+
module Support
|
13
|
+
# :nodoc:
|
14
|
+
class RuboCopRunner < RuboCop::Runner
|
15
|
+
extend T::Sig
|
16
|
+
|
17
|
+
sig { returns(T::Array[RuboCop::Cop::Offense]) }
|
18
|
+
attr_reader :offenses
|
19
|
+
|
20
|
+
DEFAULT_ARGS = T.let([
|
21
|
+
"--stderr", # Print any output to stderr so that our stdout does not get polluted
|
22
|
+
"--force-exclusion",
|
23
|
+
"--format",
|
24
|
+
"RuboCop::Formatter::BaseFormatter", # Suppress any output by using the base formatter
|
25
|
+
].freeze, T::Array[String])
|
26
|
+
|
27
|
+
sig { params(args: String).void }
|
28
|
+
def initialize(*args)
|
29
|
+
@options = T.let({}, T::Hash[Symbol, T.untyped])
|
30
|
+
@offenses = T.let([], T::Array[RuboCop::Cop::Offense])
|
31
|
+
@errors = T.let([], T::Array[String])
|
32
|
+
@warnings = T.let([], T::Array[String])
|
33
|
+
|
34
|
+
args += DEFAULT_ARGS
|
35
|
+
rubocop_options = ::RuboCop::Options.new.parse(args).first
|
36
|
+
config_store = ::RuboCop::ConfigStore.new
|
37
|
+
|
38
|
+
super(rubocop_options, config_store)
|
39
|
+
end
|
40
|
+
|
41
|
+
sig { params(path: String, contents: String).void }
|
42
|
+
def run(path, contents)
|
43
|
+
# Clear Runner state between runs since we get a single instance of this class
|
44
|
+
# on every use site.
|
45
|
+
@errors = []
|
46
|
+
@warnings = []
|
47
|
+
@offenses = []
|
48
|
+
@options[:stdin] = contents
|
49
|
+
|
50
|
+
super([path])
|
51
|
+
rescue RuboCop::Runner::InfiniteCorrectionLoop => error
|
52
|
+
raise Formatting::Error, error.message
|
53
|
+
end
|
54
|
+
|
55
|
+
sig { returns(String) }
|
56
|
+
def formatted_source
|
57
|
+
@options[:stdin]
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
sig { params(_file: String, offenses: T::Array[RuboCop::Cop::Offense]).void }
|
63
|
+
def file_finished(_file, offenses)
|
64
|
+
@offenses = offenses
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/ruby_lsp/server.rb
CHANGED
@@ -55,24 +55,23 @@ module RubyLsp
|
|
55
55
|
)
|
56
56
|
end
|
57
57
|
|
58
|
-
# TODO: switch back to using Interface::ServerCapabilities once the gem is updated for spec 3.17
|
59
58
|
Interface::InitializeResult.new(
|
60
|
-
capabilities:
|
61
|
-
|
59
|
+
capabilities: Interface::ServerCapabilities.new(
|
60
|
+
text_document_sync: Interface::TextDocumentSyncOptions.new(
|
62
61
|
change: Constant::TextDocumentSyncKind::INCREMENTAL,
|
63
62
|
open_close: true,
|
64
63
|
),
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
64
|
+
selection_range_provider: enabled_features.include?("selectionRanges"),
|
65
|
+
document_symbol_provider: document_symbol_provider,
|
66
|
+
document_link_provider: document_link_provider,
|
67
|
+
folding_range_provider: folding_ranges_provider,
|
68
|
+
semantic_tokens_provider: semantic_tokens_provider,
|
69
|
+
document_formatting_provider: enabled_features.include?("formatting"),
|
70
|
+
document_highlight_provider: enabled_features.include?("documentHighlights"),
|
71
|
+
code_action_provider: enabled_features.include?("codeActions"),
|
72
|
+
document_on_type_formatting_provider: on_type_formatting_provider,
|
73
|
+
diagnostic_provider: diagnostics_provider,
|
74
|
+
)
|
76
75
|
)
|
77
76
|
end
|
78
77
|
|
@@ -156,9 +155,8 @@ module RubyLsp
|
|
156
155
|
uri = request.dig(:params, :textDocument, :uri)
|
157
156
|
|
158
157
|
Requests::Formatting.new(uri, store.get(uri)).run
|
159
|
-
|
160
|
-
show_message(Constant::MessageType::ERROR, "
|
161
|
-
nil
|
158
|
+
end.on_error do |error|
|
159
|
+
show_message(Constant::MessageType::ERROR, "Formatting error: #{error.message}")
|
162
160
|
end
|
163
161
|
|
164
162
|
on("textDocument/onTypeFormatting", parallel: true) do |request|
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lsp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: language_server-protocol
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 3.17.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 3.17.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: sorbet-runtime
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- lib/ruby_lsp/requests/support/rubocop_diagnostic.rb
|
87
87
|
- lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb
|
88
88
|
- lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb
|
89
|
+
- lib/ruby_lsp/requests/support/rubocop_runner.rb
|
89
90
|
- lib/ruby_lsp/requests/support/selection_range.rb
|
90
91
|
- lib/ruby_lsp/requests/support/semantic_token_encoder.rb
|
91
92
|
- lib/ruby_lsp/requests/support/source_uri.rb
|