class GraphQL::Language::Visitor
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::Language::Visitor.new(document) # Whenever you find a field, increment the field count: visitor[GraphQL::Language::Nodes::Field] << ->(node) { total_field_count += 1 } # When we finish, print the field count: visitor[GraphQL::Language::Nodes::Document].leave << ->(node) { p total_field_count } visitor.visit # => 6
Constants
- SKIP
If any hook returns this value, the {Visitor} stops visiting this node right away
Public Class Methods
new(document)
click to toggle source
# File lib/graphql/language/visitor.rb, line 20 def initialize(document) @document = document @visitors = {} end
Private Class Methods
apply_hooks(hooks, node, parent)
click to toggle source
If one of the visitors returns SKIP, stop visiting this node
# File lib/graphql/language/visitor.rb, line 63 def self.apply_hooks(hooks, node, parent) hooks.reduce(true) { |memo, proc| memo && (proc.call(node, parent) != SKIP) } end
Public Instance Methods
[](node_class)
click to toggle source
Get a {NodeVisitor} for `node_class` @param node_class [Class] The node class that you want to listen to @return [NodeVisitor]
@example Run a hook whenever you enter a new Field
visitor[GraphQL::Language::Nodes::Field] << ->(node, parent) { p "Here's a field" }
# File lib/graphql/language/visitor.rb, line 31 def [](node_class) @visitors[node_class] ||= NodeVisitor.new end
visit()
click to toggle source
Visit `document` and all children, applying hooks as you go @return [void]
# File lib/graphql/language/visitor.rb, line 37 def visit visit_node(@document, nil) end
Private Instance Methods
begin_visit(node, parent)
click to toggle source
# File lib/graphql/language/visitor.rb, line 51 def begin_visit(node, parent) node_visitor = self[node.class] self.class.apply_hooks(node_visitor.enter, node, parent) end
end_visit(node, parent)
click to toggle source
Should global `leave` visitors come first or last?
# File lib/graphql/language/visitor.rb, line 57 def end_visit(node, parent) node_visitor = self[node.class] self.class.apply_hooks(node_visitor.leave, node, parent) end
visit_node(node, parent)
click to toggle source
# File lib/graphql/language/visitor.rb, line 43 def visit_node(node, parent) begin_hooks_ok = begin_visit(node, parent) if begin_hooks_ok node.children.each { |child| visit_node(child, node) } end end_visit(node, parent) end