class SyntaxTree::MatchVisitor
would match correctly against the AST.
This visitor transforms the AST into a Ruby pattern matching expression that
def comments(node)
def comments(node) return if node.comments.empty? q.nest(0) do q.text("comments: [") q.indent do q.breakable("") q.seplist(node.comments) { |comment| visit(comment) } end q.breakable("") q.text("]") end end
def field(name, value)
def field(name, value) q.nest(0) do q.text(name) q.text(": ") visit(value) end end
def initialize(q)
def initialize(q) @q = q end
def list(name, values)
def list(name, values) q.group do q.text(name) q.text(": [") q.indent do q.breakable("") q.seplist(values) { |value| visit(value) } end q.breakable("") q.text("]") end end
def node(node, _type)
def node(node, _type) items = [] q.with_target(items) { yield } if items.empty? q.text(node.class.name) return end q.group do q.text(node.class.name) q.text("[") q.indent do q.breakable("") q.seplist(items) { |item| q.target << item } end q.breakable("") q.text("]") end end
def pairs(name, values)
def pairs(name, values) q.group do q.text(name) q.text(": [") q.indent do q.breakable("") q.seplist(values) do |(key, value)| q.group do q.text("[") q.indent do q.breakable("") visit(key) q.text(",") q.breakable visit(value || nil) end q.breakable("") q.text("]") end end end q.breakable("") q.text("]") end end
def text(name, value)
def text(name, value) q.nest(0) do q.text(name) q.text(": ") value.pretty_print(q) end end
def visit(node)
def visit(node) case node when Node super when String # pp will split up a string on newlines and concat them together using a # "+" operator. This breaks the pattern matching expression. So instead # we're going to check here for strings and manually put the entire # value into the output buffer. q.text(node.inspect) else node.pretty_print(q) end end