Class: SyntaxTree::Parser::PinVisitor

Inherits:
Visitor show all
Defined in:
lib/syntax_tree/parser.rb

Overview

Ugh… I really do not like this class. Basically, ripper doesn’t provide enough information about where pins are located in the tree. It only gives events for ^ ops and var_ref nodes. You have to piece it together yourself.

Note that there are edge cases here that we straight up do not address, because I honestly think it’s going to be faster to write a new parser than to address them. For example, this will not work properly:

foo in ^((bar = 0; bar; baz))

If someone actually does something like that, we’ll have to find another way to make this work.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from BasicVisitor

valid_visit_methods, #visit_all, #visit_child_nodes, visit_method, visit_methods

Constructor Details

#initialize(pins) ⇒ PinVisitor

Returns a new instance of PinVisitor.



659
660
661
662
# File 'lib/syntax_tree/parser.rb', line 659

def initialize(pins)
  @pins = pins
  @stack = []
end

Instance Attribute Details

#pinsObject (readonly)

Returns the value of attribute pins.



657
658
659
# File 'lib/syntax_tree/parser.rb', line 657

def pins
  @pins
end

#stackObject (readonly)

Returns the value of attribute stack.



657
658
659
# File 'lib/syntax_tree/parser.rb', line 657

def stack
  @stack
end

Class Method Details

.visit(node, tokens) ⇒ Object



677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
# File 'lib/syntax_tree/parser.rb', line 677

def self.visit(node, tokens)
  start_char = node.start_char
  allocated = []

  tokens.reverse_each do |token|
    char = token.location.start_char
    break if char <= start_char

    if token.is_a?(Op) && token.value == "^"
      allocated.unshift(tokens.delete(token))
    end
  end

  new(allocated).visit(node) if allocated.any?
end

Instance Method Details

#visit(node) ⇒ Object



664
665
666
667
668
669
# File 'lib/syntax_tree/parser.rb', line 664

def visit(node)
  return if pins.empty?
  stack << node
  super
  stack.pop
end