class Liquid::ParseTreeVisitor

def self.for(node, callbacks = Hash.new(proc {}))

def self.for(node, callbacks = Hash.new(proc {}))
  if defined?(node.class::ParseTreeVisitor)
    node.class::ParseTreeVisitor
  else
    self
  end.new(node, callbacks)
end

def add_callback_for(*classes, &block)

def add_callback_for(*classes, &block)
  callback = block
  callback = ->(node, _) { yield node } if block.arity.abs == 1
  callback = ->(_, _) { yield } if block.arity.zero?
  classes.each { |klass| @callbacks[klass] = callback }
  self
end

def children

def children
  @node.respond_to?(:nodelist) ? Array(@node.nodelist) : []
end

def initialize(node, callbacks)

def initialize(node, callbacks)
  @node      = node
  @callbacks = callbacks
end

def visit(context = nil)

def visit(context = nil)
  children.map do |node|
    item, new_context = @callbacks[node.class].call(node, context)
    [
      item,
      ParseTreeVisitor.for(node, @callbacks).visit(new_context || context),
    ]
  end
end