Class: Spoom::Deadcode::Remover::NodeFinder
- Defined in:
- lib/spoom/deadcode/remover.rb
Instance Attribute Summary collapse
-
#node ⇒ Object
readonly
: Prism::Node?.
-
#nodes_nesting ⇒ Object
readonly
: Array.
Class Method Summary collapse
-
.find(source, location, kind) ⇒ Object
: (String source, Location location, Definition::Kind? kind) -> NodeContext.
-
.node_match_kind?(node, kind) ⇒ Boolean
: (Prism::Node node, Definition::Kind kind) -> bool.
Instance Method Summary collapse
-
#initialize(location, kind) ⇒ NodeFinder
constructor
: (Location location, Definition::Kind? kind) -> void.
-
#visit(node) ⇒ Object
: (Prism::Node? node) -> void.
Methods inherited from Visitor
#visit_alias_global_variable_node, #visit_alias_method_node, #visit_alternation_pattern_node, #visit_and_node, #visit_arguments_node, #visit_array_node, #visit_array_pattern_node, #visit_assoc_node, #visit_assoc_splat_node, #visit_back_reference_read_node, #visit_begin_node, #visit_block_argument_node, #visit_block_local_variable_node, #visit_block_node, #visit_block_parameter_node, #visit_block_parameters_node, #visit_break_node, #visit_call_and_write_node, #visit_call_node, #visit_call_operator_write_node, #visit_call_or_write_node, #visit_call_target_node, #visit_capture_pattern_node, #visit_case_match_node, #visit_case_node, #visit_child_nodes, #visit_class_node, #visit_class_variable_and_write_node, #visit_class_variable_operator_write_node, #visit_class_variable_or_write_node, #visit_class_variable_read_node, #visit_class_variable_target_node, #visit_class_variable_write_node, #visit_constant_and_write_node, #visit_constant_operator_write_node, #visit_constant_or_write_node, #visit_constant_path_and_write_node, #visit_constant_path_node, #visit_constant_path_operator_write_node, #visit_constant_path_or_write_node, #visit_constant_path_target_node, #visit_constant_path_write_node, #visit_constant_read_node, #visit_constant_target_node, #visit_constant_write_node, #visit_def_node, #visit_defined_node, #visit_else_node, #visit_embedded_statements_node, #visit_embedded_variable_node, #visit_ensure_node, #visit_false_node, #visit_find_pattern_node, #visit_flip_flop_node, #visit_float_node, #visit_for_node, #visit_forwarding_arguments_node, #visit_forwarding_parameter_node, #visit_forwarding_super_node, #visit_global_variable_and_write_node, #visit_global_variable_operator_write_node, #visit_global_variable_or_write_node, #visit_global_variable_read_node, #visit_global_variable_target_node, #visit_global_variable_write_node, #visit_hash_node, #visit_hash_pattern_node, #visit_if_node, #visit_imaginary_node, #visit_implicit_node, #visit_implicit_rest_node, #visit_in_node, #visit_index_and_write_node, #visit_index_operator_write_node, #visit_index_or_write_node, #visit_index_target_node, #visit_instance_variable_and_write_node, #visit_instance_variable_operator_write_node, #visit_instance_variable_or_write_node, #visit_instance_variable_read_node, #visit_instance_variable_target_node, #visit_instance_variable_write_node, #visit_integer_node, #visit_interpolated_match_last_line_node, #visit_interpolated_regular_expression_node, #visit_interpolated_string_node, #visit_interpolated_symbol_node, #visit_interpolated_x_string_node, #visit_keyword_hash_node, #visit_keyword_rest_parameter_node, #visit_lambda_node, #visit_local_variable_and_write_node, #visit_local_variable_operator_write_node, #visit_local_variable_or_write_node, #visit_local_variable_read_node, #visit_local_variable_target_node, #visit_local_variable_write_node, #visit_match_last_line_node, #visit_match_predicate_node, #visit_match_required_node, #visit_match_write_node, #visit_missing_node, #visit_module_node, #visit_multi_target_node, #visit_multi_write_node, #visit_next_node, #visit_nil_node, #visit_no_keywords_parameter_node, #visit_numbered_parameters_node, #visit_numbered_reference_read_node, #visit_optional_keyword_parameter_node, #visit_optional_parameter_node, #visit_or_node, #visit_parameters_node, #visit_parentheses_node, #visit_pinned_expression_node, #visit_pinned_variable_node, #visit_post_execution_node, #visit_pre_execution_node, #visit_program_node, #visit_range_node, #visit_rational_node, #visit_redo_node, #visit_regular_expression_node, #visit_required_keyword_parameter_node, #visit_required_parameter_node, #visit_rescue_modifier_node, #visit_rescue_node, #visit_rest_parameter_node, #visit_retry_node, #visit_return_node, #visit_self_node, #visit_singleton_class_node, #visit_source_encoding_node, #visit_source_file_node, #visit_source_line_node, #visit_splat_node, #visit_statements_node, #visit_string_node, #visit_super_node, #visit_symbol_node, #visit_true_node, #visit_undef_node, #visit_unless_node, #visit_until_node, #visit_when_node, #visit_while_node, #visit_x_string_node, #visit_yield_node
Constructor Details
#initialize(location, kind) ⇒ NodeFinder
: (Location location, Definition::Kind? kind) -> void
598 599 600 601 602 603 604 |
# File 'lib/spoom/deadcode/remover.rb', line 598 def initialize(location, kind) super() @location = location @kind = kind @node = T.let(nil, T.nilable(Prism::Node)) @nodes_nesting = T.let([], T::Array[Prism::Node]) end |
Instance Attribute Details
#node ⇒ Object (readonly)
: Prism::Node?
592 593 594 |
# File 'lib/spoom/deadcode/remover.rb', line 592 def node @node end |
#nodes_nesting ⇒ Object (readonly)
: Array
595 596 597 |
# File 'lib/spoom/deadcode/remover.rb', line 595 def nodes_nesting @nodes_nesting end |
Class Method Details
.find(source, location, kind) ⇒ Object
: (String source, Location location, Definition::Kind? kind) -> NodeContext
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 |
# File 'lib/spoom/deadcode/remover.rb', line 533 def find(source, location, kind) result = Prism.parse(source) unless result.success? = result.errors.map do |e| "#{e.} (at #{e.location.start_line}:#{e.location.start_column})." end.join(" ") raise ParseError, "Error while parsing #{location.file}: #{}" end visitor = new(location, kind) visitor.visit(result.value) node = visitor.node unless node raise Error, "Can't find node at #{location}" end if kind && !node_match_kind?(node, kind) raise Error, "Can't find node at #{location}, expected #{kind} but got #{node.class}" end comments_by_line = T.let( result.comments.to_h do |comment| [comment.location.start_line, comment] end, T::Hash[Integer, Prism::Comment], ) NodeContext.new(source, comments_by_line, node, visitor.nodes_nesting) end |
.node_match_kind?(node, kind) ⇒ Boolean
: (Prism::Node node, Definition::Kind kind) -> bool
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 |
# File 'lib/spoom/deadcode/remover.rb', line 567 def node_match_kind?(node, kind) case kind when Definition::Kind::AttrReader, Definition::Kind::AttrWriter node.is_a?(Prism::SymbolNode) when Definition::Kind::Class node.is_a?(Prism::ClassNode) when Definition::Kind::Constant node.is_a?(Prism::ConstantWriteNode) || node.is_a?(Prism::ConstantAndWriteNode) || node.is_a?(Prism::ConstantOrWriteNode) || node.is_a?(Prism::ConstantOperatorWriteNode) || node.is_a?(Prism::ConstantPathWriteNode) || node.is_a?(Prism::ConstantPathAndWriteNode) || node.is_a?(Prism::ConstantPathOrWriteNode) || node.is_a?(Prism::ConstantPathOperatorWriteNode) || node.is_a?(Prism::ConstantTargetNode) when Definition::Kind::Method node.is_a?(Prism::DefNode) when Definition::Kind::Module node.is_a?(Prism::ModuleNode) end end |
Instance Method Details
#visit(node) ⇒ Object
: (Prism::Node? node) -> void
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 |
# File 'lib/spoom/deadcode/remover.rb', line 608 def visit(node) return unless node location = Location.from_prism(@location.file, node.location) if location == @location # We found the node we're looking for at `@location` @node = node # The node we found matches the kind we're looking for, we can stop here return if @kind && self.class.node_match_kind?(node, @kind) # There may be a more precise child inside the node that also matches `@location`, let's visit them @nodes_nesting << node super(node) @nodes_nesting.pop if @nodes_nesting.last == @node elsif location.include?(@location) # The node we're looking for is inside `node`, let's visit it @nodes_nesting << node super(node) end end |