lib/ruby_indexer/lib/ruby_indexer/visitor.rb in ruby-lsp-0.11.2 vs lib/ruby_indexer/lib/ruby_indexer/visitor.rb in ruby-lsp-0.12.0
- old
+ new
@@ -1,120 +1,152 @@
# typed: strict
# frozen_string_literal: true
module RubyIndexer
- class IndexVisitor < YARP::Visitor
+ class IndexVisitor < Prism::Visitor
extend T::Sig
- sig { params(index: Index, parse_result: YARP::ParseResult, file_path: String).void }
+ sig { params(index: Index, parse_result: Prism::ParseResult, file_path: String).void }
def initialize(index, parse_result, file_path)
@index = index
@file_path = file_path
@stack = T.let([], T::Array[String])
@comments_by_line = T.let(
parse_result.comments.to_h do |c|
[c.location.start_line, c]
end,
- T::Hash[Integer, YARP::Comment],
+ T::Hash[Integer, Prism::Comment],
)
super()
end
- sig { override.params(node: YARP::ClassNode).void }
+ sig { override.params(node: Prism::ClassNode).void }
def visit_class_node(node)
- add_index_entry(node, Index::Entry::Class)
+ add_class_entry(node)
end
- sig { override.params(node: YARP::ModuleNode).void }
+ sig { override.params(node: Prism::ModuleNode).void }
def visit_module_node(node)
- add_index_entry(node, Index::Entry::Module)
+ add_module_entry(node)
end
- sig { override.params(node: YARP::ConstantPathWriteNode).void }
+ sig { override.params(node: Prism::MultiWriteNode).void }
+ def visit_multi_write_node(node)
+ value = node.value
+ values = value.is_a?(Prism::ArrayNode) && value.opening_loc ? value.elements : []
+
+ node.targets.each_with_index do |target, i|
+ current_value = values[i]
+ # The moment we find a splat on the right hand side of the assignment, we can no longer figure out which value
+ # gets assigned to what
+ values.clear if current_value.is_a?(Prism::SplatNode)
+
+ case target
+ when Prism::ConstantTargetNode
+ add_constant(target, fully_qualify_name(target.name.to_s), current_value)
+ when Prism::ConstantPathTargetNode
+ add_constant(target, fully_qualify_name(target.slice), current_value)
+ end
+ end
+ end
+
+ sig { override.params(node: Prism::ConstantPathWriteNode).void }
def visit_constant_path_write_node(node)
# ignore variable constants like `var::FOO` or `self.class::FOO`
target = node.target
- return unless target.parent.nil? || target.parent.is_a?(YARP::ConstantReadNode)
+ return unless target.parent.nil? || target.parent.is_a?(Prism::ConstantReadNode)
name = fully_qualify_name(target.location.slice)
add_constant(node, name)
end
- sig { override.params(node: YARP::ConstantPathOrWriteNode).void }
+ sig { override.params(node: Prism::ConstantPathOrWriteNode).void }
def visit_constant_path_or_write_node(node)
# ignore variable constants like `var::FOO` or `self.class::FOO`
target = node.target
- return unless target.parent.nil? || target.parent.is_a?(YARP::ConstantReadNode)
+ return unless target.parent.nil? || target.parent.is_a?(Prism::ConstantReadNode)
name = fully_qualify_name(target.location.slice)
add_constant(node, name)
end
- sig { override.params(node: YARP::ConstantPathOperatorWriteNode).void }
+ sig { override.params(node: Prism::ConstantPathOperatorWriteNode).void }
def visit_constant_path_operator_write_node(node)
# ignore variable constants like `var::FOO` or `self.class::FOO`
target = node.target
- return unless target.parent.nil? || target.parent.is_a?(YARP::ConstantReadNode)
+ return unless target.parent.nil? || target.parent.is_a?(Prism::ConstantReadNode)
name = fully_qualify_name(target.location.slice)
add_constant(node, name)
end
- sig { override.params(node: YARP::ConstantPathAndWriteNode).void }
+ sig { override.params(node: Prism::ConstantPathAndWriteNode).void }
def visit_constant_path_and_write_node(node)
# ignore variable constants like `var::FOO` or `self.class::FOO`
target = node.target
- return unless target.parent.nil? || target.parent.is_a?(YARP::ConstantReadNode)
+ return unless target.parent.nil? || target.parent.is_a?(Prism::ConstantReadNode)
name = fully_qualify_name(target.location.slice)
add_constant(node, name)
end
- sig { override.params(node: YARP::ConstantWriteNode).void }
+ sig { override.params(node: Prism::ConstantWriteNode).void }
def visit_constant_write_node(node)
name = fully_qualify_name(node.name.to_s)
add_constant(node, name)
end
- sig { override.params(node: YARP::ConstantOrWriteNode).void }
+ sig { override.params(node: Prism::ConstantOrWriteNode).void }
def visit_constant_or_write_node(node)
name = fully_qualify_name(node.name.to_s)
add_constant(node, name)
end
- sig { override.params(node: YARP::ConstantAndWriteNode).void }
+ sig { override.params(node: Prism::ConstantAndWriteNode).void }
def visit_constant_and_write_node(node)
name = fully_qualify_name(node.name.to_s)
add_constant(node, name)
end
- sig { override.params(node: YARP::ConstantOperatorWriteNode).void }
+ sig { override.params(node: Prism::ConstantOperatorWriteNode).void }
def visit_constant_operator_write_node(node)
name = fully_qualify_name(node.name.to_s)
add_constant(node, name)
end
- sig { override.params(node: YARP::CallNode).void }
+ sig { override.params(node: Prism::CallNode).void }
def visit_call_node(node)
message = node.message
handle_private_constant(node) if message == "private_constant"
end
+ sig { override.params(node: Prism::DefNode).void }
+ def visit_def_node(node)
+ method_name = node.name.to_s
+ comments = collect_comments(node)
+ case node.receiver
+ when nil
+ @index << Entry::InstanceMethod.new(method_name, @file_path, node.location, comments, node.parameters)
+ when Prism::SelfNode
+ @index << Entry::SingletonMethod.new(method_name, @file_path, node.location, comments, node.parameters)
+ end
+ end
+
private
- sig { params(node: YARP::CallNode).void }
+ sig { params(node: Prism::CallNode).void }
def handle_private_constant(node)
arguments = node.arguments&.arguments
return unless arguments
first_argument = arguments.first
name = case first_argument
- when YARP::StringNode
+ when Prism::StringNode
first_argument.content
- when YARP::SymbolNode
+ when Prism::SymbolNode
first_argument.value
end
return unless name
@@ -128,61 +160,81 @@
end
sig do
params(
node: T.any(
- YARP::ConstantWriteNode,
- YARP::ConstantOrWriteNode,
- YARP::ConstantAndWriteNode,
- YARP::ConstantOperatorWriteNode,
- YARP::ConstantPathWriteNode,
- YARP::ConstantPathOrWriteNode,
- YARP::ConstantPathOperatorWriteNode,
- YARP::ConstantPathAndWriteNode,
+ Prism::ConstantWriteNode,
+ Prism::ConstantOrWriteNode,
+ Prism::ConstantAndWriteNode,
+ Prism::ConstantOperatorWriteNode,
+ Prism::ConstantPathWriteNode,
+ Prism::ConstantPathOrWriteNode,
+ Prism::ConstantPathOperatorWriteNode,
+ Prism::ConstantPathAndWriteNode,
+ Prism::ConstantTargetNode,
+ Prism::ConstantPathTargetNode,
),
name: String,
+ value: T.nilable(Prism::Node),
).void
end
- def add_constant(node, name)
- value = node.value
+ def add_constant(node, name, value = nil)
+ value = node.value unless node.is_a?(Prism::ConstantTargetNode) || node.is_a?(Prism::ConstantPathTargetNode)
comments = collect_comments(node)
@index << case value
- when YARP::ConstantReadNode, YARP::ConstantPathNode
- Index::Entry::UnresolvedAlias.new(value.slice, @stack.dup, name, @file_path, node.location, comments)
- when YARP::ConstantWriteNode, YARP::ConstantAndWriteNode, YARP::ConstantOrWriteNode,
- YARP::ConstantOperatorWriteNode
+ when Prism::ConstantReadNode, Prism::ConstantPathNode
+ Entry::UnresolvedAlias.new(value.slice, @stack.dup, name, @file_path, node.location, comments)
+ when Prism::ConstantWriteNode, Prism::ConstantAndWriteNode, Prism::ConstantOrWriteNode,
+ Prism::ConstantOperatorWriteNode
# If the right hand side is another constant assignment, we need to visit it because that constant has to be
# indexed too
visit(value)
- Index::Entry::UnresolvedAlias.new(value.name.to_s, @stack.dup, name, @file_path, node.location, comments)
- when YARP::ConstantPathWriteNode, YARP::ConstantPathOrWriteNode, YARP::ConstantPathOperatorWriteNode,
- YARP::ConstantPathAndWriteNode
+ Entry::UnresolvedAlias.new(value.name.to_s, @stack.dup, name, @file_path, node.location, comments)
+ when Prism::ConstantPathWriteNode, Prism::ConstantPathOrWriteNode, Prism::ConstantPathOperatorWriteNode,
+ Prism::ConstantPathAndWriteNode
visit(value)
- Index::Entry::UnresolvedAlias.new(value.target.slice, @stack.dup, name, @file_path, node.location, comments)
+ Entry::UnresolvedAlias.new(value.target.slice, @stack.dup, name, @file_path, node.location, comments)
else
- Index::Entry::Constant.new(name, @file_path, node.location, comments)
+ Entry::Constant.new(name, @file_path, node.location, comments)
end
end
- sig { params(node: T.any(YARP::ClassNode, YARP::ModuleNode), klass: T.class_of(Index::Entry)).void }
- def add_index_entry(node, klass)
+ sig { params(node: Prism::ModuleNode).void }
+ def add_module_entry(node)
name = node.constant_path.location.slice
+ return visit_child_nodes(node) unless /^[A-Z:]/.match?(name)
- unless /^[A-Z:]/.match?(name)
- return visit_child_nodes(node)
- end
+ comments = collect_comments(node)
+ @index << Entry::Module.new(fully_qualify_name(name), @file_path, node.location, comments)
+ @stack << name
+ visit_child_nodes(node)
+ @stack.pop
+ end
+
+ sig { params(node: Prism::ClassNode).void }
+ def add_class_entry(node)
+ name = node.constant_path.location.slice
+ return visit_child_nodes(node) unless /^[A-Z:]/.match?(name)
+
comments = collect_comments(node)
- @index << klass.new(fully_qualify_name(name), @file_path, node.location, comments)
+
+ superclass = node.superclass
+ parent_class = case superclass
+ when Prism::ConstantReadNode, Prism::ConstantPathNode
+ superclass.slice
+ end
+
+ @index << Entry::Class.new(fully_qualify_name(name), @file_path, node.location, comments, parent_class)
@stack << name
visit(node.body)
@stack.pop
end
- sig { params(node: YARP::Node).returns(T::Array[String]) }
+ sig { params(node: Prism::Node).returns(T::Array[String]) }
def collect_comments(node)
comments = []
start_line = node.location.start_line - 1
start_line -= 1 unless @comments_by_line.key?(start_line)