Sha256: b6ecb64f9612274623793a6c3377e58c35bf786afec606a7dc9cf4cf712508f8
Contents?: true
Size: 1.59 KB
Versions: 2
Compression:
Stored size: 1.59 KB
Contents
# Depth-first traversal through the tree, calling hooks at each stop. # # @example: Create a visitor, add hooks, then search a document # total_field_count = 0 # visitor = GraphQL::Visitor.new # visitor[GraphQL::Nodes::Field] << -> (node) { total_field_count += 1 } # visitor[GraphQL::Nodes::Document].leave << -> (node) { p total_field_count } # visitor.visit(document) # # => 6 # class GraphQL::Visitor SKIP = :_skip attr_reader :enter, :leave def initialize @visitors = {} @enter = [] @leave = [] end def [](node_class) @visitors[node_class] ||= NodeVisitor.new end # Apply built-up vistors to `document` def visit(root, parent=nil) begin_visit(root, parent) && root.children.reduce(true) { |memo, child| memo && visit(child, root) } end_visit(root, parent) end private def begin_visit(node, parent) self.class.apply_hooks(enter, node, parent) node_visitor = self[node.class] self.class.apply_hooks(node_visitor.enter, node, parent) end # Should global `leave` visitors come first or last? def end_visit(node, parent) self.class.apply_hooks(leave, node, parent) node_visitor = self[node.class] self.class.apply_hooks(node_visitor.leave, node, parent) end # If one of the visitors returns SKIP, stop visiting this node def self.apply_hooks(hooks, node, parent) hooks.reduce(true) { |memo, proc| memo && (proc.call(node, parent) != SKIP) } end class NodeVisitor attr_reader :enter, :leave def initialize @enter = [] @leave = [] end def <<(hook) enter << hook end end end
Version data entries
2 entries across 2 versions & 1 rubygems
Version | Path |
---|---|
graphql-0.3.0 | lib/graph_ql/parser/visitor.rb |
graphql-0.2.0 | lib/graph_ql/parser/visitor.rb |