Class: RubyLsp::Requests::SemanticHighlighting
- Inherits:
-
BaseRequest
- Object
- SyntaxTree::Visitor
- BaseRequest
- RubyLsp::Requests::SemanticHighlighting
show all
- Extended by:
- T::Sig
- Includes:
- SyntaxTree::WithScope
- Defined in:
- lib/ruby_lsp/requests/semantic_highlighting.rb
Overview
Defined Under Namespace
Classes: SemanticToken
Constant Summary
collapse
- TOKEN_TYPES =
T.let(
{
namespace: 0,
type: 1,
class: 2,
enum: 3,
interface: 4,
struct: 5,
typeParameter: 6,
parameter: 7,
variable: 8,
property: 9,
enumMember: 10,
event: 11,
function: 12,
method: 13,
macro: 14,
keyword: 15,
modifier: 16,
comment: 17,
string: 18,
number: 19,
regexp: 20,
operator: 21,
decorator: 22,
}.freeze,
T::Hash[Symbol, Integer],
)
- TOKEN_MODIFIERS =
T.let(
{
declaration: 0,
definition: 1,
readonly: 2,
static: 3,
deprecated: 4,
abstract: 5,
async: 6,
modification: 7,
documentation: 8,
default_library: 9,
}.freeze,
T::Hash[Symbol, Integer],
)
- SPECIAL_RUBY_METHODS =
T.let(
[
Module.instance_methods(false),
Kernel.instance_methods(false),
Kernel.methods(false),
Bundler::Dsl.instance_methods(false),
Module.private_instance_methods(false),
].flatten.map(&:to_s),
T::Array[String],
)
Instance Method Summary
collapse
Methods inherited from BaseRequest
#visit_all
#create_code_lens, #full_constant_name, #range_from_syntax_tree_node, #visible?
Constructor Details
#initialize(document, range: nil, encoder: nil) ⇒ SemanticHighlighting
112
113
114
115
116
117
118
119
120
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 112
def initialize(document, range: nil, encoder: nil)
super(document)
@encoder = encoder
@tokens = T.let([], T::Array[SemanticToken])
@tree = T.let(T.must(document.tree), SyntaxTree::Node)
@range = range
@special_methods = T.let(nil, T.nilable(T::Array[String]))
end
|
Instance Method Details
#add_token(location, type, modifiers = []) ⇒ Object
355
356
357
358
359
360
361
362
363
364
365
366
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 355
def add_token(location, type, modifiers = [])
length = location.end_char - location.start_char
modifiers_indices = modifiers.filter_map { |modifier| TOKEN_MODIFIERS[modifier] }
@tokens.push(
SemanticToken.new(
location: location,
length: length,
type: T.must(TOKEN_TYPES[type]),
modifier: modifiers_indices,
),
)
end
|
#run ⇒ Object
130
131
132
133
134
135
136
137
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 130
def run
return @tokens unless @document.parsed?
visit(@tree)
return @tokens unless @encoder
@encoder.encode(@tokens)
end
|
#visit_binary(node) ⇒ Object
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 308
def visit_binary(node)
super
return unless node.operator == :=~
left = node.left
return unless left.is_a?(SyntaxTree::RegexpLiteral)
parts = left.parts
return unless parts.one?
content = parts.first
return unless content.is_a?(SyntaxTree::TStringContent)
Regexp.new(content.value, Regexp::FIXEDENCODING).names.each do |name|
local = current_scope.find_local(name)
next unless local
local.definitions.each { |definition| add_token(definition, :variable) }
end
end
|
#visit_block_var(node) ⇒ Object
274
275
276
277
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 274
def visit_block_var(node)
node.locals.each { |local| add_token(local.location, :variable) }
super
end
|
#visit_call(node) ⇒ Object
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 140
def visit_call(node)
return super unless visible?(node, @range)
visit(node.receiver)
message = node.message
if !message.is_a?(Symbol) && !special_method?(message.value)
type = Support::Sorbet.annotation?(node) ? :type : :method
add_token(message.location, type)
end
visit(node.arguments)
end
|
#visit_class(node) ⇒ Object
335
336
337
338
339
340
341
342
343
344
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 335
def visit_class(node)
return super unless visible?(node, @range)
add_token(node.constant.location, :class, [:declaration])
superclass = node.superclass
add_token(superclass.location, :class) if superclass
visit(node.bodystmt)
end
|
#visit_command(node) ⇒ Object
156
157
158
159
160
161
162
163
164
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 156
def visit_command(node)
return super unless visible?(node, @range)
unless special_method?(node.message.value)
add_token(node.message.location, :method)
end
visit(node.arguments)
visit(node.block)
end
|
#visit_command_call(node) ⇒ Object
167
168
169
170
171
172
173
174
175
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 167
def visit_command_call(node)
return super unless visible?(node, @range)
visit(node.receiver)
message = node.message
add_token(message.location, :method) unless message.is_a?(Symbol)
visit(node.arguments)
visit(node.block)
end
|
#visit_const(node) ⇒ Object
178
179
180
181
182
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 178
def visit_const(node)
return super unless visible?(node, @range)
add_token(node.location, :namespace)
end
|
#visit_def(node) ⇒ Object
185
186
187
188
189
190
191
192
193
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 185
def visit_def(node)
return super unless visible?(node, @range)
add_token(node.name.location, :method, [:declaration])
visit(node.params)
visit(node.bodystmt)
visit(node.target) if node.target
visit(node.operator) if node.operator
end
|
#visit_field(node) ⇒ Object
228
229
230
231
232
233
234
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 228
def visit_field(node)
return super unless visible?(node, @range)
add_token(node.name.location, :method)
super
end
|
#visit_kw(node) ⇒ Object
196
197
198
199
200
201
202
203
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 196
def visit_kw(node)
return super unless visible?(node, @range)
case node.value
when "self"
add_token(node.location, :variable, [:default_library])
end
end
|
#visit_lambda_var(node) ⇒ Object
281
282
283
284
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 281
def visit_lambda_var(node)
node.locals.each { |local| add_token(local.location, :variable) }
super
end
|
#visit_module(node) ⇒ Object
347
348
349
350
351
352
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 347
def visit_module(node)
return super unless visible?(node, @range)
add_token(node.constant.location, :class, [:declaration])
visit(node.bodystmt)
end
|
#visit_params(node) ⇒ Object
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 206
def visit_params(node)
return super unless visible?(node, @range)
node.keywords.each do |keyword, *|
location = keyword.location
add_token(location_without_colon(location), :parameter)
end
node.requireds.each do |required|
add_token(required.location, :parameter)
end
rest = node.keyword_rest
if rest && !rest.is_a?(SyntaxTree::ArgsForward) && !rest.is_a?(Symbol)
name = rest.name
add_token(name.location, :parameter) if name
end
super
end
|
#visit_var_field(node) ⇒ Object
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 237
def visit_var_field(node)
return super unless visible?(node, @range)
value = node.value
case value
when SyntaxTree::Ident
type = type_for_local(value)
add_token(value.location, type)
when Symbol
else
visit(value)
end
super
end
|
#visit_var_ref(node) ⇒ Object
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 256
def visit_var_ref(node)
return super unless visible?(node, @range)
value = node.value
case value
when SyntaxTree::Ident
type = type_for_local(value)
add_token(value.location, type)
when Symbol
else
visit(value)
end
end
|
#visit_vcall(node) ⇒ Object
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
|
# File 'lib/ruby_lsp/requests/semantic_highlighting.rb', line 287
def visit_vcall(node)
return super unless visible?(node, @range)
ident = node.value
value = ident.value
local = current_scope.find_local(value)
return if local.nil? && special_method?(value)
type = if local
:variable
elsif Support::Sorbet.annotation?(node)
:type
else
:method
end
add_token(node.value.location, type)
end
|