Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 22 additions & 29 deletions lib/ruby_lsp/event_emitter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,60 +54,53 @@ def visit(node)
super
end

sig { override.params(node: SyntaxTree::ClassDeclaration).void }
def visit_class(node)
sig { override.params(node: YARP::ClassNode).void }
def visit_class_node(node)
@listeners[:on_class]&.each { |l| T.unsafe(l).on_class(node) }
super
@listeners[:after_class]&.each { |l| T.unsafe(l).after_class(node) }
end

sig { override.params(node: SyntaxTree::ModuleDeclaration).void }
def visit_module(node)
sig { override.params(node: YARP::ModuleNode).void }
def visit_module_node(node)
@listeners[:on_module]&.each { |l| T.unsafe(l).on_module(node) }
super
@listeners[:after_module]&.each { |l| T.unsafe(l).after_module(node) }
end

sig { override.params(node: SyntaxTree::Command).void }
def visit_command(node)
@listeners[:on_command]&.each { |l| T.unsafe(l).on_command(node) }
super
@listeners[:after_command]&.each { |l| T.unsafe(l).after_command(node) }
end

sig { override.params(node: SyntaxTree::CommandCall).void }
def visit_command_call(node)
@listeners[:on_command_call]&.each { |l| T.unsafe(l).on_command_call(node) }
sig { override.params(node: YARP::CallNode).void }
def visit_call_node(node)
@listeners[:on_call]&.each { |l| T.unsafe(l).on_call(node) }
super
@listeners[:after_call]&.each { |l| T.unsafe(l).after_call(node) }
end

sig { override.params(node: SyntaxTree::CallNode).void }
def visit_call(node)
@listeners[:on_call]&.each { |l| T.unsafe(l).on_call(node) }
sig { override.params(node: YARP::ConstantPathWriteNode).void }
def visit_constant_path_write_node(node)
@listeners[:on_constant_path_write_node]&.each { |l| T.unsafe(l).on_constant_path_write_node(node) }
super
@listeners[:after_call]&.each { |l| T.unsafe(l).after_call(node) }
end

sig { override.params(node: SyntaxTree::VCall).void }
def visit_vcall(node)
@listeners[:on_vcall]&.each { |l| T.unsafe(l).on_vcall(node) }
sig { override.params(node: YARP::ConstantWriteNode).void }
def visit_constant_write_node(node)
@listeners[:on_constant_write_node]&.each { |l| T.unsafe(l).on_constant_write_node(node) }
super
end

sig { override.params(node: SyntaxTree::ConstPathField).void }
def visit_const_path_field(node)
@listeners[:on_const_path_field]&.each { |l| T.unsafe(l).on_const_path_field(node) }
sig { override.params(node: YARP::InstanceVariableWriteNode).void }
def visit_instance_variable_write_node(node)
@listeners[:on_instance_variable_write]&.each { |l| T.unsafe(l).on_instance_variable_write(node) }
super
end

sig { override.params(node: SyntaxTree::TopConstField).void }
def visit_top_const_field(node)
@listeners[:on_top_const_field]&.each { |l| T.unsafe(l).on_top_const_field(node) }
sig { override.params(node: YARP::ClassVariableWriteNode).void }
def visit_class_variable_write_node(node)
@listeners[:on_class_variable_write]&.each { |l| T.unsafe(l).on_class_variable_write(node) }
super
end

sig { override.params(node: SyntaxTree::DefNode).void }
def visit_def(node)
sig { override.params(node: YARP::DefNode).void }
def visit_def_node(node)
@listeners[:on_def]&.each { |l| T.unsafe(l).on_def(node) }
super
@listeners[:after_def]&.each { |l| T.unsafe(l).after_def(node) }
Expand Down
2 changes: 1 addition & 1 deletion lib/ruby_lsp/executor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def run(request)
code_lens = Requests::CodeLens.new(uri, emitter, @message_queue, @test_library)

semantic_highlighting = Requests::SemanticHighlighting.new(emitter, @message_queue)
emitter.visit(document.tree) if document.parsed?
emitter.visit(document.tree)

code_lens.merge_external_listeners_responses!

Expand Down
116 changes: 63 additions & 53 deletions lib/ruby_lsp/requests/document_symbol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,127 +96,131 @@ def initialize(emitter, message_queue)
self,
:on_class,
:after_class,
:on_command,
:on_const_path_field,
:on_call,
:on_constant_path_write_node,
:on_constant_write_node,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vinistock this wasn't in your original commit but I found I had to add it, maybe due to a YARP change.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andyw8 shouldn't we also remove the node suffix here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, fixed in 768b8c6 on the yarp branch.

:on_def,
:after_def,
:on_module,
:after_module,
:on_top_const_field,
:on_var_field,
:on_instance_variable_write,
:on_class_variable_write,
)
end

sig { params(node: SyntaxTree::ClassDeclaration).void }
sig { params(node: YARP::ClassNode).void }
def on_class(node)
@stack << create_document_symbol(
name: full_constant_name(node.constant),
name: node.constant_path.location.slice,
kind: :class,
range_node: node,
selection_range_node: node.constant,
selection_range_node: node.constant_path,
)
end

sig { params(node: SyntaxTree::ClassDeclaration).void }
sig { params(node: YARP::ClassNode).void }
def after_class(node)
@stack.pop
end

sig { params(node: SyntaxTree::Command).void }
def on_command(node)
return unless ATTR_ACCESSORS.include?(node.message.value)
sig { params(node: YARP::CallNode).void }
def on_call(node)
return unless ATTR_ACCESSORS.include?(node.name) && node.receiver.nil?

node.arguments.parts.each do |argument|
next unless argument.is_a?(SyntaxTree::SymbolLiteral)
arguments = node.arguments
return unless arguments

arguments.arguments.each do |argument|
next unless argument.is_a?(YARP::SymbolNode)

create_document_symbol(
name: argument.value.value,
name: argument.value,
kind: :field,
range_node: argument,
selection_range_node: argument.value,
selection_range_node: argument,
)
end
end

sig { params(node: SyntaxTree::ConstPathField).void }
def on_const_path_field(node)
sig { params(node: YARP::ConstantPathWriteNode).void }
def on_constant_path_write_node(node)
create_document_symbol(
name: node.target.location.slice,
kind: :constant,
range_node: node,
selection_range_node: node.target,
)
end

sig { params(node: YARP::ConstantWriteNode).void }
def on_constant_write_node(node)
create_document_symbol(
name: node.constant.value,
name: node.name,
kind: :constant,
range_node: node,
selection_range_node: node.constant,
selection_range_node: node.name_loc,
)
end

sig { params(node: SyntaxTree::DefNode).void }
sig { params(node: YARP::DefNode).void }
def on_def(node)
target = node.target
receiver = node.receiver

if target.is_a?(SyntaxTree::VarRef) && target.value.is_a?(SyntaxTree::Kw) && target.value.value == "self"
name = "self.#{node.name.value}"
if receiver.is_a?(YARP::SelfNode)
name = "self.#{node.name}"
kind = :method
else
name = node.name.value
name = node.name
kind = name == "initialize" ? :constructor : :method
end

symbol = create_document_symbol(
name: name,
kind: kind,
range_node: node,
selection_range_node: node.name,
selection_range_node: node.name_loc,
)

@stack << symbol
end

sig { params(node: SyntaxTree::DefNode).void }
sig { params(node: YARP::DefNode).void }
def after_def(node)
@stack.pop
end

sig { params(node: SyntaxTree::ModuleDeclaration).void }
sig { params(node: YARP::ModuleNode).void }
def on_module(node)
@stack << create_document_symbol(
name: full_constant_name(node.constant),
name: node.constant_path.location.slice,
kind: :module,
range_node: node,
selection_range_node: node.constant,
selection_range_node: node.constant_path,
)
end

sig { params(node: SyntaxTree::ModuleDeclaration).void }
sig { params(node: YARP::ModuleNode).void }
def after_module(node)
@stack.pop
end

sig { params(node: SyntaxTree::TopConstField).void }
def on_top_const_field(node)
sig { params(node: YARP::InstanceVariableWriteNode).void }
def on_instance_variable_write(node)
create_document_symbol(
name: node.constant.value,
kind: :constant,
name: node.name,
kind: :variable,
range_node: node,
selection_range_node: node.constant,
selection_range_node: node.name_loc,
)
end

sig { params(node: SyntaxTree::VarField).void }
def on_var_field(node)
value = node.value
kind = case value
when SyntaxTree::Const
:constant
when SyntaxTree::CVar, SyntaxTree::IVar
:variable
else
return
end

sig { params(node: YARP::ClassVariableWriteNode).void }
def on_class_variable_write(node)
create_document_symbol(
name: value.value,
kind: kind,
name: node.name,
kind: :variable,
range_node: node,
selection_range_node: value,
selection_range_node: node.name_loc,
)
end

Expand All @@ -226,16 +230,22 @@ def on_var_field(node)
params(
name: String,
kind: Symbol,
range_node: SyntaxTree::Node,
selection_range_node: SyntaxTree::Node,
range_node: YARP::Node,
selection_range_node: T.any(YARP::Node, YARP::Location),
).returns(Interface::DocumentSymbol)
end
def create_document_symbol(name:, kind:, range_node:, selection_range_node:)
selection_range = if selection_range_node.is_a?(YARP::Node)
range_from_syntax_tree_node(selection_range_node)
else
range_from_location(selection_range_node)
end

symbol = Interface::DocumentSymbol.new(
name: name,
kind: SYMBOL_KIND[kind],
range: range_from_syntax_tree_node(range_node),
selection_range: range_from_syntax_tree_node(selection_range_node),
selection_range: selection_range,
children: [],
)

Expand Down
32 changes: 11 additions & 21 deletions lib/ruby_lsp/requests/support/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module Common
# or extensions by created by developers outside of Shopify, so be cautious of changing anything.
extend T::Sig

sig { params(node: SyntaxTree::Node).returns(Interface::Range) }
sig { params(node: YARP::Node).returns(Interface::Range) }
def range_from_syntax_tree_node(node)
loc = node.location

Expand All @@ -22,25 +22,15 @@ def range_from_syntax_tree_node(node)
)
end

sig do
params(node: T.any(SyntaxTree::ConstPathRef, SyntaxTree::ConstRef, SyntaxTree::TopConstRef)).returns(String)
end
def full_constant_name(node)
name = node.constant.value.dup
constant = T.let(node, SyntaxTree::Node)

while constant.is_a?(SyntaxTree::ConstPathRef)
constant = constant.parent

case constant
when SyntaxTree::ConstPathRef
name.prepend("#{constant.constant.value}::")
when SyntaxTree::VarRef
name.prepend("#{constant.value.value}::")
end
end

name
sig { params(location: YARP::Location).returns(Interface::Range) }
def range_from_location(location)
Interface::Range.new(
start: Interface::Position.new(
line: location.start_line - 1,
character: location.start_column,
),
end: Interface::Position.new(line: location.end_line - 1, character: location.end_column),
)
end

sig { params(node: T.nilable(YARP::Node), range: T.nilable(T::Range[Integer])).returns(T::Boolean) }
Expand All @@ -54,7 +44,7 @@ def visible?(node, range)

sig do
params(
node: SyntaxTree::Node,
node: YARP::Node,
title: String,
command_name: String,
arguments: T.nilable(T::Array[T.untyped]),
Expand Down
Loading