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

#visit_all, #visit_child_nodes, visit_method, visit_methods

Constructor Details

#initialize(pins) ⇒ PinVisitor

Returns a new instance of PinVisitor.



631
632
633
634
# File 'lib/syntax_tree/parser.rb', line 631

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

Instance Attribute Details

#pinsObject (readonly)

Returns the value of attribute pins.



629
630
631
# File 'lib/syntax_tree/parser.rb', line 629

def pins
  @pins
end

#stackObject (readonly)

Returns the value of attribute stack.



629
630
631
# File 'lib/syntax_tree/parser.rb', line 629

def stack
  @stack
end

Class Method Details

.visit(node, tokens) ⇒ Object



648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
# File 'lib/syntax_tree/parser.rb', line 648

def self.visit(node, tokens)
  start_char = node.location.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



636
637
638
639
640
641
# File 'lib/syntax_tree/parser.rb', line 636

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

#visit_var_ref(node) ⇒ Object



643
644
645
646
# File 'lib/syntax_tree/parser.rb', line 643

def visit_var_ref(node)
  pins.shift
  node.pin(stack[-2])
end