docs: def traverse(node, on_enter=None, on_leave=None):
      """ Traverses the specified Vim script AST node (depth first order).
      The on_enter/on_leave handler will be called with the specified node and
      the children. You can skip traversing child nodes by returning
      SKIP_CHILDREN.
      """
      node_type = NodeType(node['type'])
  
      if node_type not in ChildNodeAccessorMap:
          raise UnknownNodeTypeException(node_type)
  
      if on_enter:
          should_traverse_children = on_enter(node) is not SKIP_CHILDREN
      else:
          should_traverse_children = True
  
      if should_traverse_children:
          for property_accessor in ChildNodeAccessorMap[node_type]:
              accessor_func = property_accessor['accessor']
              prop_name = property_accessor['property_name']
  
              accessor_func(lambda child_node: traverse(child_node, on_enter, on_leave),
                            node[prop_name])
  
          for handler in _traverser_extensions:
              handler(node, on_enter=on_enter, on_leave=on_leave)
  
      if on_leave:
          on_leave(node)