Class: RubyLsp::Listeners::SemanticHighlighting
- Inherits:
-
Object
- Object
- RubyLsp::Listeners::SemanticHighlighting
- Extended by:
- T::Sig
- Includes:
- Requests::Support::Common
- Defined in:
- lib/ruby_lsp/listeners/semantic_highlighting.rb
Constant Summary collapse
- 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
-
#initialize(dispatcher, response_builder, range: nil) ⇒ SemanticHighlighting
constructor
A new instance of SemanticHighlighting.
- #on_block_local_variable_node_enter(node) ⇒ Object
- #on_block_node_enter(node) ⇒ Object
- #on_block_node_leave(node) ⇒ Object
- #on_block_parameter_node_enter(node) ⇒ Object
- #on_call_node_enter(node) ⇒ Object
- #on_class_node_enter(node) ⇒ Object
- #on_constant_and_write_node_enter(node) ⇒ Object
- #on_constant_operator_write_node_enter(node) ⇒ Object
- #on_constant_or_write_node_enter(node) ⇒ Object
- #on_constant_path_node_enter(node) ⇒ Object
- #on_constant_read_node_enter(node) ⇒ Object
- #on_constant_target_node_enter(node) ⇒ Object
- #on_constant_write_node_enter(node) ⇒ Object
- #on_def_node_enter(node) ⇒ Object
- #on_def_node_leave(node) ⇒ Object
- #on_implicit_node_enter(node) ⇒ Object
- #on_implicit_node_leave(node) ⇒ Object
- #on_keyword_rest_parameter_node_enter(node) ⇒ Object
- #on_local_variable_and_write_node_enter(node) ⇒ Object
- #on_local_variable_operator_write_node_enter(node) ⇒ Object
- #on_local_variable_or_write_node_enter(node) ⇒ Object
- #on_local_variable_read_node_enter(node) ⇒ Object
- #on_local_variable_target_node_enter(node) ⇒ Object
- #on_local_variable_write_node_enter(node) ⇒ Object
- #on_match_write_node_enter(node) ⇒ Object
- #on_match_write_node_leave(node) ⇒ Object
- #on_module_node_enter(node) ⇒ Object
- #on_optional_keyword_parameter_node_enter(node) ⇒ Object
- #on_optional_parameter_node_enter(node) ⇒ Object
- #on_required_keyword_parameter_node_enter(node) ⇒ Object
- #on_required_parameter_node_enter(node) ⇒ Object
- #on_rest_parameter_node_enter(node) ⇒ Object
- #on_self_node_enter(node) ⇒ Object
Methods included from Requests::Support::Common
#categorized_markdown_from_index_entries, #constant_name, #create_code_lens, #each_constant_path_part, #kind_for_entry, #markdown_from_index_entries, #namespace_constant_name, #not_in_dependencies?, #range_from_location, #range_from_node, #self_receiver?, #sorbet_level_true_or_higher?, #visible?
Constructor Details
#initialize(dispatcher, response_builder, range: nil) ⇒ SemanticHighlighting
Returns a new instance of SemanticHighlighting.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 28 def initialize(dispatcher, response_builder, range: nil) @response_builder = response_builder @range = range @special_methods = T.let(nil, T.nilable(T::Array[String])) @current_scope = T.let(ParameterScope.new, ParameterScope) @inside_regex_capture = T.let(false, T::Boolean) @inside_implicit_node = T.let(false, T::Boolean) dispatcher.register( self, :on_call_node_enter, :on_class_node_enter, :on_def_node_enter, :on_def_node_leave, :on_block_node_enter, :on_block_node_leave, :on_self_node_enter, :on_module_node_enter, :on_local_variable_write_node_enter, :on_local_variable_read_node_enter, :on_block_parameter_node_enter, :on_required_keyword_parameter_node_enter, :on_optional_keyword_parameter_node_enter, :on_keyword_rest_parameter_node_enter, :on_optional_parameter_node_enter, :on_required_parameter_node_enter, :on_rest_parameter_node_enter, :on_constant_read_node_enter, :on_constant_write_node_enter, :on_constant_and_write_node_enter, :on_constant_operator_write_node_enter, :on_constant_or_write_node_enter, :on_constant_target_node_enter, :on_constant_path_node_enter, :on_local_variable_and_write_node_enter, :on_local_variable_operator_write_node_enter, :on_local_variable_or_write_node_enter, :on_local_variable_target_node_enter, :on_block_local_variable_node_enter, :on_match_write_node_enter, :on_match_write_node_leave, :on_implicit_node_enter, :on_implicit_node_leave, ) end |
Instance Method Details
#on_block_local_variable_node_enter(node) ⇒ Object
174 175 176 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 174 def on_block_local_variable_node_enter(node) @response_builder.add_token(node.location, :variable) end |
#on_block_node_enter(node) ⇒ Object
164 165 166 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 164 def on_block_node_enter(node) @current_scope = ParameterScope.new(@current_scope) end |
#on_block_node_leave(node) ⇒ Object
169 170 171 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 169 def on_block_node_leave(node) @current_scope = T.must(@current_scope.parent) end |
#on_block_parameter_node_enter(node) ⇒ Object
179 180 181 182 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 179 def on_block_parameter_node_enter(node) name = node.name @current_scope << name.to_sym if name end |
#on_call_node_enter(node) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 75 def on_call_node_enter(node) return if @inside_implicit_node return unless visible?(node, @range) = node. return unless # We can't push a semantic token for [] and []= because the argument inside the brackets is a part of # the message_loc return if .start_with?("[") && (.end_with?("]") || .end_with?("]=")) return if == "=~" return if special_method?() type = Requests::Support::Sorbet.annotation?(node) ? :type : :method @response_builder.add_token(T.must(node.), type) end |
#on_class_node_enter(node) ⇒ Object
303 304 305 306 307 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 333 334 335 336 337 338 339 340 341 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 303 def on_class_node_enter(node) return unless visible?(node, @range) constant_path = node.constant_path if constant_path.is_a?(Prism::ConstantReadNode) @response_builder.add_token(constant_path.location, :class, [:declaration]) else each_constant_path_part(constant_path) do |part| loc = case part when Prism::ConstantPathNode part.name_loc when Prism::ConstantReadNode part.location end next unless loc @response_builder.add_token(loc, :class, [:declaration]) end end superclass = node.superclass if superclass.is_a?(Prism::ConstantReadNode) @response_builder.add_token(superclass.location, :class) elsif superclass each_constant_path_part(superclass) do |part| loc = case part when Prism::ConstantPathNode part.name_loc when Prism::ConstantReadNode part.location end next unless loc @response_builder.add_token(loc, :class) end end end |
#on_constant_and_write_node_enter(node) ⇒ Object
123 124 125 126 127 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 123 def on_constant_and_write_node_enter(node) return unless visible?(node, @range) @response_builder.add_token(node.name_loc, :namespace) end |
#on_constant_operator_write_node_enter(node) ⇒ Object
130 131 132 133 134 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 130 def on_constant_operator_write_node_enter(node) return unless visible?(node, @range) @response_builder.add_token(node.name_loc, :namespace) end |
#on_constant_or_write_node_enter(node) ⇒ Object
137 138 139 140 141 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 137 def on_constant_or_write_node_enter(node) return unless visible?(node, @range) @response_builder.add_token(node.name_loc, :namespace) end |
#on_constant_path_node_enter(node) ⇒ Object
379 380 381 382 383 384 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 379 def on_constant_path_node_enter(node) return if @inside_implicit_node return unless visible?(node, @range) @response_builder.add_token(node.name_loc, :namespace) end |
#on_constant_read_node_enter(node) ⇒ Object
108 109 110 111 112 113 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 108 def on_constant_read_node_enter(node) return if @inside_implicit_node return unless visible?(node, @range) @response_builder.add_token(node.location, :namespace) end |
#on_constant_target_node_enter(node) ⇒ Object
144 145 146 147 148 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 144 def on_constant_target_node_enter(node) return unless visible?(node, @range) @response_builder.add_token(node.location, :namespace) end |
#on_constant_write_node_enter(node) ⇒ Object
116 117 118 119 120 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 116 def on_constant_write_node_enter(node) return unless visible?(node, @range) @response_builder.add_token(node.name_loc, :namespace) end |
#on_def_node_enter(node) ⇒ Object
151 152 153 154 155 156 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 151 def on_def_node_enter(node) @current_scope = ParameterScope.new(@current_scope) return unless visible?(node, @range) @response_builder.add_token(node.name_loc, :method, [:declaration]) end |
#on_def_node_leave(node) ⇒ Object
159 160 161 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 159 def on_def_node_leave(node) @current_scope = T.must(@current_scope.parent) end |
#on_implicit_node_enter(node) ⇒ Object
367 368 369 370 371 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 367 def on_implicit_node_enter(node) return unless visible?(node, @range) @inside_implicit_node = true end |
#on_implicit_node_leave(node) ⇒ Object
374 375 376 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 374 def on_implicit_node_leave(node) @inside_implicit_node = false end |
#on_keyword_rest_parameter_node_enter(node) ⇒ Object
203 204 205 206 207 208 209 210 211 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 203 def on_keyword_rest_parameter_node_enter(node) name = node.name if name @current_scope << name.to_sym @response_builder.add_token(T.must(node.name_loc), :parameter) if visible?(node, @range) end end |
#on_local_variable_and_write_node_enter(node) ⇒ Object
269 270 271 272 273 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 269 def on_local_variable_and_write_node_enter(node) return unless visible?(node, @range) @response_builder.add_token(node.name_loc, @current_scope.type_for(node.name)) end |
#on_local_variable_operator_write_node_enter(node) ⇒ Object
276 277 278 279 280 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 276 def on_local_variable_operator_write_node_enter(node) return unless visible?(node, @range) @response_builder.add_token(node.name_loc, @current_scope.type_for(node.name)) end |
#on_local_variable_or_write_node_enter(node) ⇒ Object
283 284 285 286 287 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 283 def on_local_variable_or_write_node_enter(node) return unless visible?(node, @range) @response_builder.add_token(node.name_loc, @current_scope.type_for(node.name)) end |
#on_local_variable_read_node_enter(node) ⇒ Object
255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 255 def on_local_variable_read_node_enter(node) return if @inside_implicit_node return unless visible?(node, @range) # Numbered parameters if /_\d+/.match?(node.name) @response_builder.add_token(node.location, :parameter) return end @response_builder.add_token(node.location, @current_scope.type_for(node.name)) end |
#on_local_variable_target_node_enter(node) ⇒ Object
290 291 292 293 294 295 296 297 298 299 300 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 290 def on_local_variable_target_node_enter(node) # If we're inside a regex capture, Prism will add LocalVariableTarget nodes for each captured variable. # Unfortunately, if the regex contains a backslash, the location will be incorrect and we'll end up highlighting # the entire regex as a local variable. We process these captures in process_regexp_locals instead and then # prevent pushing local variable target tokens. See https://github.com/ruby/prism/issues/1912 return if @inside_regex_capture return unless visible?(node, @range) @response_builder.add_token(node.location, @current_scope.type_for(node.name)) end |
#on_local_variable_write_node_enter(node) ⇒ Object
248 249 250 251 252 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 248 def on_local_variable_write_node_enter(node) return unless visible?(node, @range) @response_builder.add_token(node.name_loc, @current_scope.type_for(node.name)) end |
#on_match_write_node_enter(node) ⇒ Object
93 94 95 96 97 98 99 100 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 93 def on_match_write_node_enter(node) call = node.call if call. == "=~" @inside_regex_capture = true process_regexp_locals(call) end end |
#on_match_write_node_leave(node) ⇒ Object
103 104 105 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 103 def on_match_write_node_leave(node) @inside_regex_capture = true if node.call. == "=~" end |
#on_module_node_enter(node) ⇒ Object
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 344 def on_module_node_enter(node) return unless visible?(node, @range) constant_path = node.constant_path if constant_path.is_a?(Prism::ConstantReadNode) @response_builder.add_token(constant_path.location, :namespace, [:declaration]) else each_constant_path_part(constant_path) do |part| loc = case part when Prism::ConstantPathNode part.name_loc when Prism::ConstantReadNode part.location end next unless loc @response_builder.add_token(loc, :namespace, [:declaration]) end end end |
#on_optional_keyword_parameter_node_enter(node) ⇒ Object
194 195 196 197 198 199 200 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 194 def on_optional_keyword_parameter_node_enter(node) @current_scope << node.name return unless visible?(node, @range) location = node.name_loc @response_builder.add_token(location.copy(length: location.length - 1), :parameter) end |
#on_optional_parameter_node_enter(node) ⇒ Object
214 215 216 217 218 219 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 214 def on_optional_parameter_node_enter(node) @current_scope << node.name return unless visible?(node, @range) @response_builder.add_token(node.name_loc, :parameter) end |
#on_required_keyword_parameter_node_enter(node) ⇒ Object
185 186 187 188 189 190 191 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 185 def on_required_keyword_parameter_node_enter(node) @current_scope << node.name return unless visible?(node, @range) location = node.name_loc @response_builder.add_token(location.copy(length: location.length - 1), :parameter) end |
#on_required_parameter_node_enter(node) ⇒ Object
222 223 224 225 226 227 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 222 def on_required_parameter_node_enter(node) @current_scope << node.name return unless visible?(node, @range) @response_builder.add_token(node.location, :parameter) end |
#on_rest_parameter_node_enter(node) ⇒ Object
230 231 232 233 234 235 236 237 238 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 230 def on_rest_parameter_node_enter(node) name = node.name if name @current_scope << name.to_sym @response_builder.add_token(T.must(node.name_loc), :parameter) if visible?(node, @range) end end |
#on_self_node_enter(node) ⇒ Object
241 242 243 244 245 |
# File 'lib/ruby_lsp/listeners/semantic_highlighting.rb', line 241 def on_self_node_enter(node) return unless visible?(node, @range) @response_builder.add_token(node.location, :variable, [:default_library]) end |