ruby-lsp 0.13.3 → 0.14.0
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 +3 -2
- data/VERSION +1 -1
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +4 -8
- data/lib/ruby_indexer/lib/ruby_indexer/collector.rb +5 -1
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +4 -2
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +8 -3
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +9 -0
- data/lib/ruby_indexer/test/index_test.rb +27 -0
- data/lib/ruby_lsp/addon.rb +21 -10
- data/lib/ruby_lsp/check_docs.rb +8 -8
- data/lib/ruby_lsp/executor.rb +28 -10
- data/lib/ruby_lsp/internal.rb +1 -1
- data/lib/ruby_lsp/listeners/code_lens.rb +54 -55
- data/lib/ruby_lsp/listeners/completion.rb +17 -16
- data/lib/ruby_lsp/listeners/definition.rb +10 -16
- data/lib/ruby_lsp/listeners/document_highlight.rb +6 -11
- data/lib/ruby_lsp/listeners/document_link.rb +6 -12
- data/lib/ruby_lsp/listeners/document_symbol.rb +95 -55
- data/lib/ruby_lsp/listeners/folding_ranges.rb +19 -23
- data/lib/ruby_lsp/listeners/hover.rb +26 -30
- data/lib/ruby_lsp/listeners/inlay_hints.rb +7 -13
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -124
- data/lib/ruby_lsp/listeners/signature_help.rb +11 -13
- data/lib/ruby_lsp/requests/code_lens.rb +9 -17
- data/lib/ruby_lsp/requests/completion.rb +7 -9
- data/lib/ruby_lsp/requests/definition.rb +10 -22
- data/lib/ruby_lsp/requests/document_highlight.rb +7 -5
- data/lib/ruby_lsp/requests/document_link.rb +7 -6
- data/lib/ruby_lsp/requests/document_symbol.rb +5 -11
- data/lib/ruby_lsp/requests/folding_ranges.rb +11 -6
- data/lib/ruby_lsp/requests/hover.rb +18 -24
- data/lib/ruby_lsp/requests/inlay_hints.rb +7 -8
- data/lib/ruby_lsp/requests/on_type_formatting.rb +12 -2
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +10 -8
- data/lib/ruby_lsp/requests/signature_help.rb +53 -18
- data/lib/ruby_lsp/requests/support/common.rb +23 -10
- data/lib/ruby_lsp/requests/support/dependency_detector.rb +5 -1
- data/lib/ruby_lsp/requests.rb +0 -1
- data/lib/ruby_lsp/response_builders/collection_response_builder.rb +29 -0
- data/lib/ruby_lsp/response_builders/document_symbol.rb +57 -0
- data/lib/ruby_lsp/response_builders/hover.rb +49 -0
- data/lib/ruby_lsp/response_builders/response_builder.rb +16 -0
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +199 -0
- data/lib/ruby_lsp/response_builders/signature_help.rb +28 -0
- data/lib/ruby_lsp/response_builders.rb +13 -0
- data/lib/ruby_lsp/server.rb +3 -3
- data/lib/ruby_lsp/setup_bundler.rb +30 -5
- data/lib/ruby_lsp/store.rb +4 -4
- metadata +14 -9
- data/lib/ruby_lsp/listener.rb +0 -33
- data/lib/ruby_lsp/requests/support/semantic_token_encoder.rb +0 -73
@@ -0,0 +1,199 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RubyLsp
|
5
|
+
module ResponseBuilders
|
6
|
+
class SemanticHighlighting < ResponseBuilder
|
7
|
+
class UndefinedTokenType < StandardError; end
|
8
|
+
|
9
|
+
TOKEN_TYPES = T.let(
|
10
|
+
{
|
11
|
+
namespace: 0,
|
12
|
+
type: 1,
|
13
|
+
class: 2,
|
14
|
+
enum: 3,
|
15
|
+
interface: 4,
|
16
|
+
struct: 5,
|
17
|
+
typeParameter: 6,
|
18
|
+
parameter: 7,
|
19
|
+
variable: 8,
|
20
|
+
property: 9,
|
21
|
+
enumMember: 10,
|
22
|
+
event: 11,
|
23
|
+
function: 12,
|
24
|
+
method: 13,
|
25
|
+
macro: 14,
|
26
|
+
keyword: 15,
|
27
|
+
modifier: 16,
|
28
|
+
comment: 17,
|
29
|
+
string: 18,
|
30
|
+
number: 19,
|
31
|
+
regexp: 20,
|
32
|
+
operator: 21,
|
33
|
+
decorator: 22,
|
34
|
+
}.freeze,
|
35
|
+
T::Hash[Symbol, Integer],
|
36
|
+
)
|
37
|
+
|
38
|
+
TOKEN_MODIFIERS = T.let(
|
39
|
+
{
|
40
|
+
declaration: 0,
|
41
|
+
definition: 1,
|
42
|
+
readonly: 2,
|
43
|
+
static: 3,
|
44
|
+
deprecated: 4,
|
45
|
+
abstract: 5,
|
46
|
+
async: 6,
|
47
|
+
modification: 7,
|
48
|
+
documentation: 8,
|
49
|
+
default_library: 9,
|
50
|
+
}.freeze,
|
51
|
+
T::Hash[Symbol, Integer],
|
52
|
+
)
|
53
|
+
|
54
|
+
extend T::Sig
|
55
|
+
|
56
|
+
ResponseType = type_member { { fixed: Interface::SemanticTokens } }
|
57
|
+
|
58
|
+
sig { void }
|
59
|
+
def initialize
|
60
|
+
super
|
61
|
+
@stack = T.let([], T::Array[SemanticToken])
|
62
|
+
end
|
63
|
+
|
64
|
+
sig { params(location: Prism::Location, type: Symbol, modifiers: T::Array[Symbol]).void }
|
65
|
+
def add_token(location, type, modifiers = [])
|
66
|
+
length = location.end_offset - location.start_offset
|
67
|
+
modifiers_indices = modifiers.filter_map { |modifier| TOKEN_MODIFIERS[modifier] }
|
68
|
+
@stack.push(
|
69
|
+
SemanticToken.new(
|
70
|
+
location: location,
|
71
|
+
length: length,
|
72
|
+
type: T.must(TOKEN_TYPES[type]),
|
73
|
+
modifier: modifiers_indices,
|
74
|
+
),
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
sig { returns(T.nilable(SemanticToken)) }
|
79
|
+
def last
|
80
|
+
@stack.last
|
81
|
+
end
|
82
|
+
|
83
|
+
sig { override.returns(Interface::SemanticTokens) }
|
84
|
+
def response
|
85
|
+
SemanticTokenEncoder.new.encode(@stack)
|
86
|
+
end
|
87
|
+
|
88
|
+
class SemanticToken
|
89
|
+
extend T::Sig
|
90
|
+
|
91
|
+
sig { returns(Prism::Location) }
|
92
|
+
attr_reader :location
|
93
|
+
|
94
|
+
sig { returns(Integer) }
|
95
|
+
attr_reader :length
|
96
|
+
|
97
|
+
sig { returns(Integer) }
|
98
|
+
attr_reader :type
|
99
|
+
|
100
|
+
sig { returns(T::Array[Integer]) }
|
101
|
+
attr_reader :modifier
|
102
|
+
|
103
|
+
sig { params(location: Prism::Location, length: Integer, type: Integer, modifier: T::Array[Integer]).void }
|
104
|
+
def initialize(location:, length:, type:, modifier:)
|
105
|
+
@location = location
|
106
|
+
@length = length
|
107
|
+
@type = type
|
108
|
+
@modifier = modifier
|
109
|
+
end
|
110
|
+
|
111
|
+
sig { params(type_symbol: Symbol).void }
|
112
|
+
def replace_type(type_symbol)
|
113
|
+
type_int = TOKEN_TYPES[type_symbol]
|
114
|
+
raise UndefinedTokenType, "Undefined token type: #{type_symbol}" unless type_int
|
115
|
+
|
116
|
+
@type = type_int
|
117
|
+
end
|
118
|
+
|
119
|
+
sig { params(modifier_symbols: T::Array[Symbol]).void }
|
120
|
+
def replace_modifier(modifier_symbols)
|
121
|
+
@modifier = modifier_symbols.filter_map do |modifier_symbol|
|
122
|
+
modifier_index = TOKEN_MODIFIERS[modifier_symbol]
|
123
|
+
raise UndefinedTokenType, "Undefined token modifier: #{modifier_symbol}" unless modifier_index
|
124
|
+
|
125
|
+
modifier_index
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class SemanticTokenEncoder
|
131
|
+
extend T::Sig
|
132
|
+
|
133
|
+
sig { void }
|
134
|
+
def initialize
|
135
|
+
@current_row = T.let(0, Integer)
|
136
|
+
@current_column = T.let(0, Integer)
|
137
|
+
end
|
138
|
+
|
139
|
+
sig do
|
140
|
+
params(
|
141
|
+
tokens: T::Array[SemanticToken],
|
142
|
+
).returns(Interface::SemanticTokens)
|
143
|
+
end
|
144
|
+
def encode(tokens)
|
145
|
+
sorted_tokens = tokens.sort_by.with_index do |token, index|
|
146
|
+
# Enumerable#sort_by is not deterministic when the compared values are equal.
|
147
|
+
# When that happens, we need to use the index as a tie breaker to ensure
|
148
|
+
# that the order of the tokens is always the same.
|
149
|
+
[token.location.start_line, token.location.start_column, index]
|
150
|
+
end
|
151
|
+
|
152
|
+
delta = sorted_tokens.flat_map do |token|
|
153
|
+
compute_delta(token)
|
154
|
+
end
|
155
|
+
|
156
|
+
Interface::SemanticTokens.new(data: delta)
|
157
|
+
end
|
158
|
+
|
159
|
+
# The delta array is computed according to the LSP specification:
|
160
|
+
# > The protocol for the token format relative uses relative
|
161
|
+
# > positions, because most tokens remain stable relative to
|
162
|
+
# > each other when edits are made in a file. This simplifies
|
163
|
+
# > the computation of a delta if a server supports it. So each
|
164
|
+
# > token is represented using 5 integers.
|
165
|
+
|
166
|
+
# For more information on how each number is calculated, read:
|
167
|
+
# https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens
|
168
|
+
sig { params(token: SemanticToken).returns(T::Array[Integer]) }
|
169
|
+
def compute_delta(token)
|
170
|
+
row = token.location.start_line - 1
|
171
|
+
column = token.location.start_column
|
172
|
+
|
173
|
+
begin
|
174
|
+
delta_line = row - @current_row
|
175
|
+
|
176
|
+
delta_column = column
|
177
|
+
delta_column -= @current_column if delta_line == 0
|
178
|
+
|
179
|
+
[delta_line, delta_column, token.length, token.type, encode_modifiers(token.modifier)]
|
180
|
+
ensure
|
181
|
+
@current_row = row
|
182
|
+
@current_column = column
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# Encode an array of modifiers to positions onto a bit flag
|
187
|
+
# For example, [:default_library] will be encoded as
|
188
|
+
# 0b1000000000, as :default_library is the 10th bit according
|
189
|
+
# to the token modifiers index map.
|
190
|
+
sig { params(modifiers: T::Array[Integer]).returns(Integer) }
|
191
|
+
def encode_modifiers(modifiers)
|
192
|
+
modifiers.inject(0) do |encoded_modifiers, modifier|
|
193
|
+
encoded_modifiers | (1 << modifier)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RubyLsp
|
5
|
+
module ResponseBuilders
|
6
|
+
class SignatureHelp < ResponseBuilder
|
7
|
+
ResponseType = type_member { { fixed: T.nilable(Interface::SignatureHelp) } }
|
8
|
+
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig { void }
|
12
|
+
def initialize
|
13
|
+
super
|
14
|
+
@signature_help = T.let(nil, ResponseType)
|
15
|
+
end
|
16
|
+
|
17
|
+
sig { params(signature_help: ResponseType).void }
|
18
|
+
def replace(signature_help)
|
19
|
+
@signature_help = signature_help
|
20
|
+
end
|
21
|
+
|
22
|
+
sig { override.returns(ResponseType) }
|
23
|
+
def response
|
24
|
+
@signature_help
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RubyLsp
|
5
|
+
module ResponseBuilders
|
6
|
+
autoload :CollectionResponseBuilder, "ruby_lsp/response_builders/collection_response_builder"
|
7
|
+
autoload :DocumentSymbol, "ruby_lsp/response_builders/document_symbol"
|
8
|
+
autoload :Hover, "ruby_lsp/response_builders/hover"
|
9
|
+
autoload :ResponseBuilder, "ruby_lsp/response_builders/response_builder"
|
10
|
+
autoload :SemanticHighlighting, "ruby_lsp/response_builders/semantic_highlighting"
|
11
|
+
autoload :SignatureHelp, "ruby_lsp/response_builders/signature_help"
|
12
|
+
end
|
13
|
+
end
|
data/lib/ruby_lsp/server.rb
CHANGED
@@ -58,7 +58,7 @@ module RubyLsp
|
|
58
58
|
|
59
59
|
sig { void }
|
60
60
|
def start
|
61
|
-
|
61
|
+
$stderr.puts("Starting Ruby LSP v#{VERSION}...")
|
62
62
|
|
63
63
|
# Requests that have to be executed sequentially or in the main process are implemented here. All other requests
|
64
64
|
# fall under the else branch which just pushes requests to the queue
|
@@ -73,7 +73,7 @@ module RubyLsp
|
|
73
73
|
when "$/setTrace"
|
74
74
|
VOID
|
75
75
|
when "shutdown"
|
76
|
-
|
76
|
+
$stderr.puts("Shutting down Ruby LSP...")
|
77
77
|
|
78
78
|
@message_queue.close
|
79
79
|
# Close the queue so that we can no longer receive items
|
@@ -92,7 +92,7 @@ module RubyLsp
|
|
92
92
|
# We return zero if shutdown has already been received or one otherwise as per the recommendation in the spec
|
93
93
|
# https://microsoft.github.io/language-server-protocol/specification/#exit
|
94
94
|
status = @store.empty? ? 0 : 1
|
95
|
-
|
95
|
+
$stderr.puts("Shutdown complete with status #{status}")
|
96
96
|
exit(status)
|
97
97
|
else
|
98
98
|
# Default case: push the request to the queue to be executed by the worker
|
@@ -59,7 +59,9 @@ module RubyLsp
|
|
59
59
|
|
60
60
|
# Do not setup a custom bundle if both `ruby-lsp` and `debug` are already in the Gemfile
|
61
61
|
if @dependencies["ruby-lsp"] && @dependencies["debug"]
|
62
|
-
|
62
|
+
$stderr.puts(
|
63
|
+
"Ruby LSP> Skipping custom bundle setup since both `ruby-lsp` and `debug` are already in #{@gemfile}",
|
64
|
+
)
|
63
65
|
|
64
66
|
# If the user decided to add the `ruby-lsp` and `debug` to their Gemfile after having already run the Ruby LSP,
|
65
67
|
# then we need to remove the `.ruby-lsp` folder, otherwise we will run `bundle install` for the top level and
|
@@ -76,7 +78,7 @@ module RubyLsp
|
|
76
78
|
write_custom_gemfile
|
77
79
|
|
78
80
|
unless @gemfile&.exist? && @lockfile&.exist?
|
79
|
-
|
81
|
+
$stderr.puts("Ruby LSP> Skipping lockfile copies because there's no top level bundle")
|
80
82
|
return run_bundle_install(@custom_gemfile)
|
81
83
|
end
|
82
84
|
|
@@ -84,11 +86,14 @@ module RubyLsp
|
|
84
86
|
current_lockfile_hash = Digest::SHA256.hexdigest(lockfile_contents)
|
85
87
|
|
86
88
|
if @custom_lockfile.exist? && @lockfile_hash_path.exist? && @lockfile_hash_path.read == current_lockfile_hash
|
87
|
-
|
89
|
+
$stderr.puts(
|
90
|
+
"Ruby LSP> Skipping custom bundle setup since #{@custom_lockfile} already exists and is up to date",
|
91
|
+
)
|
88
92
|
return run_bundle_install(@custom_gemfile)
|
89
93
|
end
|
90
94
|
|
91
95
|
FileUtils.cp(@lockfile.to_s, @custom_lockfile.to_s)
|
96
|
+
correct_relative_remote_paths
|
92
97
|
@lockfile_hash_path.write(current_lockfile_hash)
|
93
98
|
run_bundle_install(@custom_gemfile)
|
94
99
|
end
|
@@ -208,8 +213,8 @@ module RubyLsp
|
|
208
213
|
command << "1>&2"
|
209
214
|
|
210
215
|
# Add bundle update
|
211
|
-
|
212
|
-
|
216
|
+
$stderr.puts("Ruby LSP> Running bundle install for the custom bundle. This may take a while...")
|
217
|
+
$stderr.puts("Ruby LSP> Command: #{command}")
|
213
218
|
system(env, command)
|
214
219
|
[bundle_gemfile.to_s, expanded_path, env["BUNDLE_APP_CONFIG"]]
|
215
220
|
end
|
@@ -227,5 +232,25 @@ module RubyLsp
|
|
227
232
|
# If the last updated file doesn't exist or was updated more than 4 hours ago, we should update
|
228
233
|
!@last_updated_path.exist? || Time.parse(@last_updated_path.read) < (Time.now - FOUR_HOURS)
|
229
234
|
end
|
235
|
+
|
236
|
+
# When a lockfile has remote references based on relative file paths, we need to ensure that they are pointing to
|
237
|
+
# the correct place since after copying the relative path is no longer valid
|
238
|
+
sig { void }
|
239
|
+
def correct_relative_remote_paths
|
240
|
+
content = @custom_lockfile.read
|
241
|
+
content.gsub!(/remote: (.*)/) do |match|
|
242
|
+
path = T.must(Regexp.last_match)[1]
|
243
|
+
|
244
|
+
# We should only apply the correction if the remote is a relative path. It might also be a URI, like
|
245
|
+
# `https://rubygems.org` or an absolute path, in which case we shouldn't do anything
|
246
|
+
if path&.start_with?(".")
|
247
|
+
"remote: #{File.expand_path(path, T.must(@gemfile).dirname)}"
|
248
|
+
else
|
249
|
+
match
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
@custom_lockfile.write(content)
|
254
|
+
end
|
230
255
|
end
|
231
256
|
end
|
data/lib/ruby_lsp/store.rb
CHANGED
@@ -23,6 +23,9 @@ module RubyLsp
|
|
23
23
|
sig { returns(T::Hash[Symbol, RequestConfig]) }
|
24
24
|
attr_accessor :features_configuration
|
25
25
|
|
26
|
+
sig { returns(String) }
|
27
|
+
attr_accessor :client_name
|
28
|
+
|
26
29
|
sig { void }
|
27
30
|
def initialize
|
28
31
|
@state = T.let({}, T::Hash[String, Document])
|
@@ -33,10 +36,6 @@ module RubyLsp
|
|
33
36
|
@workspace_uri = T.let(URI::Generic.from_path(path: Dir.pwd), URI::Generic)
|
34
37
|
@features_configuration = T.let(
|
35
38
|
{
|
36
|
-
codeLens: RequestConfig.new({
|
37
|
-
enableAll: false,
|
38
|
-
gemfileLinks: true,
|
39
|
-
}),
|
40
39
|
inlayHint: RequestConfig.new({
|
41
40
|
enableAll: false,
|
42
41
|
implicitRescue: false,
|
@@ -45,6 +44,7 @@ module RubyLsp
|
|
45
44
|
},
|
46
45
|
T::Hash[Symbol, RequestConfig],
|
47
46
|
)
|
47
|
+
@client_name = T.let("Unknown", String)
|
48
48
|
end
|
49
49
|
|
50
50
|
sig { params(uri: URI::Generic).returns(Document) }
|
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.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: language_server-protocol
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
version: 0.19.0
|
34
34
|
- - "<"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: '0.
|
36
|
+
version: '0.22'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -43,21 +43,21 @@ dependencies:
|
|
43
43
|
version: 0.19.0
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '0.
|
46
|
+
version: '0.22'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: sorbet-runtime
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 0.5.
|
53
|
+
version: 0.5.10782
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 0.5.
|
60
|
+
version: 0.5.10782
|
61
61
|
description: An opinionated language server for Ruby
|
62
62
|
email:
|
63
63
|
- ruby@shopify.com
|
@@ -97,7 +97,6 @@ files:
|
|
97
97
|
- lib/ruby_lsp/document.rb
|
98
98
|
- lib/ruby_lsp/executor.rb
|
99
99
|
- lib/ruby_lsp/internal.rb
|
100
|
-
- lib/ruby_lsp/listener.rb
|
101
100
|
- lib/ruby_lsp/listeners/code_lens.rb
|
102
101
|
- lib/ruby_lsp/listeners/completion.rb
|
103
102
|
- lib/ruby_lsp/listeners/definition.rb
|
@@ -139,11 +138,17 @@ files:
|
|
139
138
|
- lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb
|
140
139
|
- lib/ruby_lsp/requests/support/rubocop_runner.rb
|
141
140
|
- lib/ruby_lsp/requests/support/selection_range.rb
|
142
|
-
- lib/ruby_lsp/requests/support/semantic_token_encoder.rb
|
143
141
|
- lib/ruby_lsp/requests/support/sorbet.rb
|
144
142
|
- lib/ruby_lsp/requests/support/source_uri.rb
|
145
143
|
- lib/ruby_lsp/requests/support/syntax_tree_formatting_runner.rb
|
146
144
|
- lib/ruby_lsp/requests/workspace_symbol.rb
|
145
|
+
- lib/ruby_lsp/response_builders.rb
|
146
|
+
- lib/ruby_lsp/response_builders/collection_response_builder.rb
|
147
|
+
- lib/ruby_lsp/response_builders/document_symbol.rb
|
148
|
+
- lib/ruby_lsp/response_builders/hover.rb
|
149
|
+
- lib/ruby_lsp/response_builders/response_builder.rb
|
150
|
+
- lib/ruby_lsp/response_builders/semantic_highlighting.rb
|
151
|
+
- lib/ruby_lsp/response_builders/signature_help.rb
|
147
152
|
- lib/ruby_lsp/ruby_document.rb
|
148
153
|
- lib/ruby_lsp/server.rb
|
149
154
|
- lib/ruby_lsp/setup_bundler.rb
|
@@ -169,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
169
174
|
- !ruby/object:Gem::Version
|
170
175
|
version: '0'
|
171
176
|
requirements: []
|
172
|
-
rubygems_version: 3.5.
|
177
|
+
rubygems_version: 3.5.6
|
173
178
|
signing_key:
|
174
179
|
specification_version: 4
|
175
180
|
summary: An opinionated language server for Ruby
|
data/lib/ruby_lsp/listener.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
module RubyLsp
|
5
|
-
# Listener is an abstract class to be used by requests for listening to events emitted when visiting an AST using the
|
6
|
-
# Prism::Dispatcher.
|
7
|
-
class Listener
|
8
|
-
extend T::Sig
|
9
|
-
extend T::Helpers
|
10
|
-
extend T::Generic
|
11
|
-
include Requests::Support::Common
|
12
|
-
|
13
|
-
ResponseType = type_member
|
14
|
-
|
15
|
-
abstract!
|
16
|
-
|
17
|
-
sig { params(dispatcher: Prism::Dispatcher).void }
|
18
|
-
def initialize(dispatcher)
|
19
|
-
super()
|
20
|
-
@dispatcher = dispatcher
|
21
|
-
end
|
22
|
-
|
23
|
-
sig { returns(ResponseType) }
|
24
|
-
def response
|
25
|
-
_response
|
26
|
-
end
|
27
|
-
|
28
|
-
# Override this method with an attr_reader that returns the response of your listener. The listener should
|
29
|
-
# accumulate results in a @response variable and then provide the reader so that it is accessible
|
30
|
-
sig { abstract.returns(ResponseType) }
|
31
|
-
def _response; end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
module RubyLsp
|
5
|
-
module Requests
|
6
|
-
module Support
|
7
|
-
class SemanticTokenEncoder
|
8
|
-
extend T::Sig
|
9
|
-
|
10
|
-
sig { void }
|
11
|
-
def initialize
|
12
|
-
@current_row = T.let(0, Integer)
|
13
|
-
@current_column = T.let(0, Integer)
|
14
|
-
end
|
15
|
-
|
16
|
-
sig do
|
17
|
-
params(
|
18
|
-
tokens: T::Array[Listeners::SemanticHighlighting::SemanticToken],
|
19
|
-
).returns(Interface::SemanticTokens)
|
20
|
-
end
|
21
|
-
def encode(tokens)
|
22
|
-
delta = tokens
|
23
|
-
.sort_by do |token|
|
24
|
-
[token.location.start_line, token.location.start_column]
|
25
|
-
end
|
26
|
-
.flat_map do |token|
|
27
|
-
compute_delta(token)
|
28
|
-
end
|
29
|
-
|
30
|
-
Interface::SemanticTokens.new(data: delta)
|
31
|
-
end
|
32
|
-
|
33
|
-
# The delta array is computed according to the LSP specification:
|
34
|
-
# > The protocol for the token format relative uses relative
|
35
|
-
# > positions, because most tokens remain stable relative to
|
36
|
-
# > each other when edits are made in a file. This simplifies
|
37
|
-
# > the computation of a delta if a server supports it. So each
|
38
|
-
# > token is represented using 5 integers.
|
39
|
-
|
40
|
-
# For more information on how each number is calculated, read:
|
41
|
-
# https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens
|
42
|
-
sig { params(token: Listeners::SemanticHighlighting::SemanticToken).returns(T::Array[Integer]) }
|
43
|
-
def compute_delta(token)
|
44
|
-
row = token.location.start_line - 1
|
45
|
-
column = token.location.start_column
|
46
|
-
|
47
|
-
begin
|
48
|
-
delta_line = row - @current_row
|
49
|
-
|
50
|
-
delta_column = column
|
51
|
-
delta_column -= @current_column if delta_line == 0
|
52
|
-
|
53
|
-
[delta_line, delta_column, token.length, token.type, encode_modifiers(token.modifier)]
|
54
|
-
ensure
|
55
|
-
@current_row = row
|
56
|
-
@current_column = column
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# Encode an array of modifiers to positions onto a bit flag
|
61
|
-
# For example, [:default_library] will be encoded as
|
62
|
-
# 0b1000000000, as :default_library is the 10th bit according
|
63
|
-
# to the token modifiers index map.
|
64
|
-
sig { params(modifiers: T::Array[Integer]).returns(Integer) }
|
65
|
-
def encode_modifiers(modifiers)
|
66
|
-
modifiers.inject(0) do |encoded_modifiers, modifier|
|
67
|
-
encoded_modifiers | (1 << modifier)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|