Class: TreeSitter::QueryMatch

Inherits:
Object
  • Object
show all
Defined in:
lib/tree_sitter/query_match.rb

Overview

A match for a Query.

Instance Method Summary collapse

Instance Method Details

#nodes_for_capture_index(index) ⇒ TreeSitter::Node

All nodes at a given capture index.

Parameters:

  • index (Integer)

Returns:



13
# File 'lib/tree_sitter/query_match.rb', line 13

def nodes_for_capture_index(index) = captures.filter_map { |capture| capture.node if capture.index == index }

#satisfies_text_predicate?(query, src) ⇒ Boolean

Whether the TreeSitter::QueryMatch satisfies the text predicates in the query.

This is a translation from the [rust bindings](github.com/tree-sitter/tree-sitter/blob/e553578696fe86071846ed612ee476d0167369c1/lib/binding_rust/lib.rs#L2502). Because it’s a direct translation, it’s way too long and we need to shut up rubocop. TODO: refactor + simplify when satable.

Returns:

  • (Boolean)


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/tree_sitter/query_match.rb', line 20

def satisfies_text_predicate?(query, src) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
  return true if query.text_predicates[pattern_index].nil?

  query # rubocop:disable Metrics/BlockLength
    .text_predicates[pattern_index]
    .all? do |predicate|
      case predicate.type
      in TextPredicateCapture::EQ_CAPTURE
        fst_nodes = nodes_for_capture_index(predicate.fst)
        snd_nodes = nodes_for_capture_index(predicate.snd)
        res = nil
        consumed = 0
        fst_nodes.zip(snd_nodes).each do |node1, node2|
          text1 = node_text(node1, src)
          text2 = node_text(node2, src)
          if (text1 == text2) != predicate.positive? && predicate.match_all?
            res = false
            break
          end
          if (text1 == text2) == predicate.positive? && !predicate.match_all?
            res = true
            break
          end
          consumed += 1
        end
        (res.nil? && consumed == fst_nodes.length && consumed == snd_nodes.length) \
          || res

      in TextPredicateCapture::EQ_STRING
        nodes = nodes_for_capture_index(predicate.fst)
        res = true
        nodes.each do |node|
          text = node_text(node, src)
          if (predicate.snd == text) != predicate.positive? && predicate.match_all?
            res = false
            break
          end
          if (predicate.snd == text) == predicate.positive? && !predicate.match_all?
            res = true
            break
          end
        end
        res

      in TextPredicateCapture::MATCH_STRING
        nodes = nodes_for_capture_index(predicate.fst)
        res = true
        nodes.each do |node|
          text = node_text(node, src)
          if predicate.snd.match?(text) != predicate.positive? && predicate.match_all?
            res = false
            break
          end
          if predicate.snd.match?(text) == predicate.positive? && !predicate.match_all?
            res = true
            break
          end
        end
        res

      in TextPredicateCapture::ANY_STRING
        nodes = nodes_for_capture_index(predicate.fst)
        res = true
        nodes.each do |node|
          text = node_text(node, src)
          if predicate.snd.any? { |v| v == text } != predicate.positive?
            res = false
            break
          end
        end
        res

      end
    end
end