File: treewalker.rb

package info (click to toggle)
ruby-gitlab-pg-query 2.0.4-3
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 15,584 kB
  • sloc: ansic: 143,939; ruby: 2,096; makefile: 4
file content (37 lines) | stat: -rw-r--r-- 1,145 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
module PgQuery
  class ParserResult
    private

    def treewalker!(tree) # rubocop:disable Metrics/CyclomaticComplexity
      nodes = [[tree.dup, []]]

      loop do
        parent_node, parent_location = nodes.shift

        case parent_node
        when Google::Protobuf::MessageExts
          parent_node.to_h.keys.each do |parent_field|
            node = parent_node[parent_field.to_s]
            next if node.nil?
            location = parent_location + [parent_field]

            yield(parent_node, parent_field, node, location) if node.is_a?(Google::Protobuf::MessageExts) || node.is_a?(Google::Protobuf::RepeatedField)

            nodes << [node, location] unless node.nil?
          end
        when Google::Protobuf::RepeatedField
          nodes += parent_node.map.with_index { |e, idx| [e, parent_location + [idx]] }
        end

        break if nodes.empty?
      end
    end

    def find_tree_location(tree, searched_location)
      treewalker! tree do |parent_node, parent_field, node, location|
        next unless location == searched_location
        yield(parent_node, parent_field, node)
      end
    end
  end
end