ruby_tree_sitter 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76f6accef62b96e6e67a815317815eee260d79c439e2efad49d2f235329d4b8e
4
- data.tar.gz: 4affeaa090844fd467042247444f6cfdf5f98e63bc79e11cd8ff6b23ffac0795
3
+ metadata.gz: '08eb24a38613d42859f2f16fd021da1ff1f4d65cfe377ef00044c0d94f34f706'
4
+ data.tar.gz: 64a1df4c4310fa4f93dd664b6a19f91f8fc10cfc0bd49895d75773bae451dbc5
5
5
  SHA512:
6
- metadata.gz: f0e629b66d07a20f5a4d9b274f7a16ec1ca3b748d66548878b58e153129b158844674eb7d8d512781ba7ab2a56cf9b97213587aadf6e66e00a55e595eb263390
7
- data.tar.gz: b648d4546b019f336b7e84a945d6741bfb6ae320525abf9300d288f8e6b84059f5f2b4ecfa199502e5eae638f41b816ccaeb50693e509ae9cbb81d4f04f7c0e5
6
+ metadata.gz: 6b592c3285d0d6ba7e93fac74ad446af847f5e35e6493210ac1a538e57ed4793396e3c287626d94d39580ea9b3b3b8f15a77d3d66fdea751b44204d74ce01cd2
7
+ data.tar.gz: e3e253584245fdc79a4c05f38a9525c7647a650faf9cc8d273f5ee5df24db8bcd5cd399cabe712f1840df029ddc2868d43b1b25fe6c966d2f63d583e0f666eb4
@@ -140,6 +140,13 @@ static VALUE query_initialize(VALUE self, VALUE language, VALUE source) {
140
140
  SELF = res;
141
141
  }
142
142
 
143
+ rb_iv_set(self, "@text_predicates", rb_ary_new());
144
+ rb_iv_set(self, "@property_predicates", rb_ary_new());
145
+ rb_iv_set(self, "@property_settings", rb_ary_new());
146
+ rb_iv_set(self, "@general_predicates", rb_ary_new());
147
+
148
+ rb_funcall(self, rb_intern("process"), 1, source);
149
+
143
150
  return self;
144
151
  }
145
152
 
@@ -49,7 +49,7 @@ DATA_FROM_VALUE(TSQueryCursor *, query_cursor)
49
49
  *
50
50
  * @return [QueryCursor]
51
51
  */
52
- static VALUE query_cursor_exec(VALUE self, VALUE query, VALUE node) {
52
+ static VALUE query_cursor_exec_static(VALUE self, VALUE query, VALUE node) {
53
53
  VALUE res = query_cursor_allocate(cQueryCursor);
54
54
  query_cursor_t *query_cursor = unwrap(res);
55
55
  ts_query_cursor_exec(query_cursor->data, value_to_query(query),
@@ -57,6 +57,21 @@ static VALUE query_cursor_exec(VALUE self, VALUE query, VALUE node) {
57
57
  return res;
58
58
  }
59
59
 
60
+ /**
61
+ * Start running a given query on a given node.
62
+ *
63
+ * @param query [Query]
64
+ * @param node [Node]
65
+ *
66
+ * @return [QueryCursor]
67
+ */
68
+ static VALUE query_cursor_exec(VALUE self, VALUE query, VALUE node) {
69
+ query_cursor_t *query_cursor = unwrap(self);
70
+ ts_query_cursor_exec(query_cursor->data, value_to_query(query),
71
+ value_to_node(node));
72
+ return self;
73
+ }
74
+
60
75
  /**
61
76
  * Manage the maximum number of in-progress matches allowed by this query
62
77
  * cursor.
@@ -190,13 +205,14 @@ void init_query_cursor(void) {
190
205
  rb_define_alloc_func(cQueryCursor, query_cursor_allocate);
191
206
 
192
207
  /* Module methods */
193
- rb_define_module_function(cQueryCursor, "exec", query_cursor_exec, 2);
208
+ rb_define_module_function(cQueryCursor, "exec", query_cursor_exec_static, 2);
194
209
 
195
210
  /* Class methods */
196
211
  // Accessors
197
212
  DECLARE_ACCESSOR(cQueryCursor, query_cursor, match_limit)
198
213
 
199
214
  // Other
215
+ rb_define_method(cQueryCursor, "exec", query_cursor_exec, 2);
200
216
  rb_define_method(cQueryCursor, "exceed_match_limit?",
201
217
  query_cursor_did_exceed_match_limit, 0);
202
218
  rb_define_method(cQueryCursor, "match_limit", query_cursor_get_match_limit,
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # splits an array like [rust](https://doc.rust-lang.org/std/primitive.slice.html#method.split)
4
+ def array_split_like_rust(array, &block)
5
+ return enum_for(__method__, array) if !block_given?
6
+
7
+ return [] if array.empty?
8
+
9
+ result = []
10
+ current_slice = []
11
+
12
+ array.each do |element|
13
+ if yield(element)
14
+ result << current_slice
15
+ current_slice = []
16
+ else
17
+ current_slice << element
18
+ end
19
+ end
20
+
21
+ result << current_slice
22
+ result
23
+ end
@@ -0,0 +1,191 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helpers'
4
+
5
+ module TreeSitter
6
+ # Query is a wrapper around a tree-sitter query.
7
+ class Query
8
+ attr_reader :capture_names
9
+ attr_reader :capture_quantifiers
10
+ attr_reader :text_predicates
11
+ attr_reader :property_predicates
12
+ attr_reader :property_settings
13
+ attr_reader :general_predicates
14
+
15
+ private
16
+
17
+ # Called from query.c on initialize.
18
+ #
19
+ # Prepares all the predicates so we could process them in places like
20
+ # {QueryMatch#satisfies_text_predicate?}.
21
+ #
22
+ # This is translation from the [rust bindings](https://github.com/tree-sitter/tree-sitter/blob/e553578696fe86071846ed612ee476d0167369c1/lib/binding_rust/lib.rs#L1860)
23
+ # Because it's a direct translation, it's way too long and we need to shut up rubocop.
24
+ # TODO: refactor + simplify when stable.
25
+ def process(source) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
26
+ string_count = self.string_count
27
+ capture_count = self.capture_count
28
+ pattern_count = self.pattern_count
29
+
30
+ # Build a vector of strings to store the capture names.
31
+ capture_names = capture_count.times.map { |i| capture_name_for_id(i) }
32
+
33
+ # Build a vector to store capture qunatifiers.
34
+ capture_quantifiers =
35
+ pattern_count.times.map do |i|
36
+ capture_count.times.map do |j|
37
+ capture_quantifier_for_id(i, j)
38
+ end
39
+ end
40
+
41
+ # Build a vector of strings to represent literal values used in predicates.
42
+ string_values = string_count.times.map { |i| string_value_for_id(i) }
43
+
44
+ # Build a vector of predicates for each pattern.
45
+ pattern_count.times do |i| # rubocop:disable Metrics/BlockLength
46
+ predicate_steps = predicates_for_pattern(i)
47
+ byte_offset = start_byte_for_pattern(i)
48
+ row =
49
+ source.chars.map.with_index
50
+ .take_while { |_, i| i < byte_offset } # rubocop:disable Lint/ShadowingOuterLocalVariable
51
+ .filter { |c, _| c == "\n" }
52
+ .size
53
+ text_predicates = []
54
+ property_predicates = []
55
+ property_settings = []
56
+ general_predicates = []
57
+
58
+ array_split_like_rust(predicate_steps) { |s| s.type == QueryPredicateStep::DONE } # rubocop:disable Metrics/BlockLength
59
+ .each do |p|
60
+ next if p.empty?
61
+
62
+ if p[0] == QueryPredicateStep::STRING
63
+ cap = capture_names[p[0].value_id]
64
+ raise ArgumentError, <<~MSG.chomp
65
+ L#{row}: Expected predicate to start with a function name. Got @#{cap}.
66
+ MSG
67
+ end
68
+
69
+ # Build a predicate for each of the known predicate function names.
70
+ operator_name = string_values[p[0].value_id]
71
+
72
+ case operator_name
73
+ in 'any-eq?' | 'any-not-eq?' | 'eq?' | 'not-eq?'
74
+ if p.size != 3
75
+ raise ArgumentError, <<~MSG.chomp
76
+ L#{row}: Wrong number of arguments to ##{operator_name} predicate. Expected 2, got #{p.size - 1}.
77
+ MSG
78
+ end
79
+
80
+ if p[1].type != QueryPredicateStep::CAPTURE
81
+ lit = string_values[p[1].value_id]
82
+ raise ArgumentError, <<~MSG.chomp
83
+ L#{row}: First argument to ##{operator_name} predicate must be a capture name. Got literal "#{lit}".
84
+ MSG
85
+ end
86
+
87
+ is_positive = %w[eq? any-eq?].include?(operator_name)
88
+ match_all = %w[eq? not-eq?].include?(operator_name)
89
+ # NOTE: in the rust impl, match_all can hit an unreachable! but I am simplifying
90
+ # for readability. Same applies for the other `in` branches.
91
+ text_predicates <<
92
+ if p[2].type == QueryPredicateStep::CAPTURE
93
+ TextPredicateCapture.eq_capture(p[1].value_id, p[2].value_id, is_positive, match_all)
94
+ else
95
+ TextPredicateCapture.eq_string(p[1].value_id, string_values[p[2].value_id], is_positive, match_all)
96
+ end
97
+
98
+ in 'match?' | 'not-match?' | 'any-match?' | 'any-not-match?'
99
+ if p.size != 3
100
+ raise ArgumentError, <<~MSG.chomp
101
+ L#{row}: Wrong number of arguments to ##{operator_name} predicate. Expected 2, got #{p.size - 1}.
102
+ MSG
103
+ end
104
+
105
+ if p[1].type != QueryPredicateStep::CAPTURE
106
+ lit = string_values[p[1].value_id]
107
+ raise ArgumentError, <<~MSG.chomp
108
+ L#{row}: First argument to ##{operator_name} predicate must be a capture name. Got literal "#{lit}".
109
+ MSG
110
+ end
111
+
112
+ if p[2].type == QueryPredicateStep::CAPTURE
113
+ cap = capture_names[p[2].value_id]
114
+ raise ArgumentError, <<~MSG.chomp
115
+ L#{row}: First argument to ##{operator_name} predicate must be a literal. Got capture @#{cap}".
116
+ MSG
117
+ end
118
+
119
+ is_positive = %w[match? any-match?].include?(operator_name)
120
+ match_all = %w[match? not-match?].include?(operator_name)
121
+ regex = /#{string_values[p[2].value_id]}/
122
+
123
+ text_predicates << TextPredicateCapture.match_string(p[1].value_id, regex, is_positive, match_all)
124
+
125
+ in 'set!'
126
+ property_settings << 'todo!'
127
+
128
+ in 'is?' | 'is-not?'
129
+ property_predicates << 'todo!'
130
+
131
+ in 'any-of?' | 'not-any-of?'
132
+ if p.size < 2
133
+ raise ArgumentError, <<~MSG.chomp
134
+ L#{row}: Wrong number of arguments to ##{operator_name} predicate. Expected at least 1, got #{p.size - 1}.
135
+ MSG
136
+ end
137
+
138
+ if p[1].type != QueryPredicateStep::CAPTURE
139
+ lit = string_values[p[1].value_id]
140
+ raise ArgumentError, <<~MSG.chomp
141
+ L#{row}: First argument to ##{operator_name} predicate must be a capture name. Got literal "#{lit}".
142
+ MSG
143
+ end
144
+
145
+ is_positive = operator_name == 'any_of'
146
+ values = []
147
+
148
+ p[2..].each do |arg|
149
+ if arg.type == QueryPredicateStep::CAPTURE
150
+ lit = string_values[arg.value_id]
151
+ raise ArgumentError, <<~MSG.chomp
152
+ L#{row}: First argument to ##{operator_name} predicate must be a capture name. Got literal "#{lit}".
153
+ MSG
154
+ end
155
+ values << string_values[arg.value_id]
156
+ end
157
+
158
+ # TODO: is the map to to_s necessary in ruby?
159
+ text_predicates <<
160
+ TextPredicateCapture.any_string(p[1].value_id, values.map(&:to_s), is_positive, match_all)
161
+ else
162
+ general_predicates <<
163
+ QueryPredicate.new(
164
+ operator_name,
165
+ p[1..].map do |a|
166
+ if a.type == QueryPredicateStep::CAPTURE
167
+ { capture: a.value_id }
168
+ else
169
+ { string: string_values[a.value_id] }
170
+ end
171
+ end,
172
+ )
173
+ end
174
+
175
+ @text_predicates << text_predicates
176
+ @property_predicates << property_predicates
177
+ @property_settings << property_settings
178
+ @general_predicates << general_predicates
179
+ end
180
+
181
+ @capture_names = capture_names
182
+ @capture_quantifiers = capture_quantifiers
183
+ end
184
+ end
185
+
186
+ # TODO
187
+ def parse_property
188
+ # todo
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TreeSitter
4
+ # A sequence of {TreeSitter::QueryCapture} associated with a given {TreeSitter::QueryCursor}.
5
+ class QueryCaptures
6
+ def initialize(cursor, query, src)
7
+ @cursor = cursor
8
+ @query = query
9
+ @src = src
10
+ end
11
+
12
+ # Iterator over captures.
13
+ #
14
+ # @yieldparam match [TreeSitter::QueryMatch]
15
+ # @yieldparam capture_index [Integer]
16
+ def each
17
+ return enum_for __method__ if !block_given?
18
+
19
+ while (capture_index, match = @cursor.next_capture)
20
+ next if !match.is_a?(TreeSitter::QueryMatch)
21
+
22
+ if match.satisfies_text_predicate?(@query, @src)
23
+ yield [match, capture_index]
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TreeSitter
4
+ # A Cursor for {Query}.
5
+ class QueryCursor
6
+ # Iterate over all of the matches in the order that they were found.
7
+ #
8
+ # Each match contains the index of the pattern that matched, and a list of
9
+ # captures. Because multiple patterns can match the same set of nodes,
10
+ # one match may contain captures that appear *before* some of the
11
+ # captures from a previous match.
12
+ def matches(query, node, src)
13
+ self.exec(query, node)
14
+ QueryMatches.new(self, query, src)
15
+ end
16
+
17
+ # Iterate over all of the individual captures in the order that they
18
+ # appear.
19
+ #
20
+ # This is useful if you don't care about which pattern matched, and just
21
+ # want a single, ordered sequence of captures.
22
+ def captures(query, node, src)
23
+ self.exec(query, node)
24
+ QueryCaptures.new(self, query, src)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'query_captures'
4
+
5
+ module TreeSitter
6
+ # A match for a {Query}.
7
+ class QueryMatch
8
+ # All nodes at a given capture index.
9
+ #
10
+ # @param index [Integer]
11
+ #
12
+ # @return [TreeSitter::Node]
13
+ def nodes_for_capture_index(index) = captures.filter_map { |capture| capture.node if capture.index == index }
14
+
15
+ # Whether the {QueryMatch} satisfies the text predicates in the query.
16
+ #
17
+ # This is a translation from the [rust bindings](https://github.com/tree-sitter/tree-sitter/blob/e553578696fe86071846ed612ee476d0167369c1/lib/binding_rust/lib.rs#L2502).
18
+ # Because it's a direct translation, it's way too long and we need to shut up rubocop.
19
+ # TODO: refactor + simplify when satable.
20
+ def satisfies_text_predicate?(query, src) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
21
+ return true if query.text_predicates[pattern_index].nil?
22
+
23
+ query # rubocop:disable Metrics/BlockLength
24
+ .text_predicates[pattern_index]
25
+ .all? do |predicate|
26
+ case predicate.type
27
+ in TextPredicateCapture::EQ_CAPTURE
28
+ fst_nodes = nodes_for_capture_index(predicate.fst)
29
+ snd_nodes = nodes_for_capture_index(predicate.snd)
30
+ res = nil
31
+ consumed = 0
32
+ fst_nodes.zip(snd_nodes).each do |node1, node2|
33
+ text1 = node_text(node1, src)
34
+ text2 = node_text(node2, src)
35
+ if (text1 == text2) != predicate.positive? && predicate.match_all?
36
+ res = false
37
+ break
38
+ end
39
+ if (text1 == text2) == predicate.positive? && !predicate.match_all?
40
+ res = true
41
+ break
42
+ end
43
+ consumed += 1
44
+ end
45
+ (res.nil? && consumed == fst_nodes.length && consumed == snd_nodes.length) \
46
+ || res
47
+
48
+ in TextPredicateCapture::EQ_STRING
49
+ nodes = nodes_for_capture_index(predicate.fst)
50
+ res = true
51
+ nodes.each do |node|
52
+ text = node_text(node, src)
53
+ if (predicate.snd == text) != predicate.positive? && predicate.match_all?
54
+ res = false
55
+ break
56
+ end
57
+ if (predicate.snd == text) == predicate.positive? && !predicate.match_all?
58
+ res = true
59
+ break
60
+ end
61
+ end
62
+ res
63
+
64
+ in TextPredicateCapture::MATCH_STRING
65
+ nodes = nodes_for_capture_index(predicate.fst)
66
+ res = true
67
+ nodes.each do |node|
68
+ text = node_text(node, src)
69
+ if predicate.snd.match?(text) != predicate.positive? && predicate.match_all?
70
+ res = false
71
+ break
72
+ end
73
+ if predicate.snd.match?(text) == predicate.positive? && !predicate.match_all?
74
+ res = true
75
+ break
76
+ end
77
+ end
78
+ res
79
+
80
+ in TextPredicateCapture::ANY_STRING
81
+ nodes = nodes_for_capture_index(predicate.fst)
82
+ res = true
83
+ nodes.each do |node|
84
+ text = node_text(node, src)
85
+ if predicate.snd.any? { |v| v == text } != predicate.positive?
86
+ res = false
87
+ break
88
+ end
89
+ end
90
+ res
91
+
92
+ end
93
+ end
94
+ end
95
+
96
+ private
97
+
98
+ def node_text(node, text) = text.byteslice(node.start_byte...node.end_byte)
99
+ end
100
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TreeSitter
4
+ # A sequence of {QueryMatch} associated with a given {QueryCursor}.
5
+ class QueryMatches
6
+ def initialize(cursor, query, src)
7
+ @cursor = cursor
8
+ @query = query
9
+ @src = src
10
+ end
11
+
12
+ # Iterator over matches.
13
+ #
14
+ # @yieldparam match [TreeSitter::QueryMatch]
15
+ def each
16
+ return enum_for __method__ if !block_given?
17
+
18
+ while match = @cursor.next_match
19
+ if match.satisfies_text_predicate?(@query, @src)
20
+ yield match
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TreeSitter
4
+ # A {Query} predicate generic representation.
5
+ class QueryPredicate
6
+ attr_accessor :operator
7
+ attr_accessor :args
8
+
9
+ def initialize(operator, args)
10
+ @operator = operator
11
+ @args = args
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TreeSitter
4
+ # A representation for text predicates.
5
+ class TextPredicateCapture
6
+ EQ_CAPTURE = 0 # Equality Capture
7
+ EQ_STRING = 1 # Equality String
8
+ MATCH_STRING = 2 # Match String
9
+ ANY_STRING = 3 # Any String
10
+
11
+ attr_reader :fst
12
+ attr_reader :snd
13
+ attr_reader :type
14
+
15
+ # Create a TextPredicateCapture for {EQ_CAPTURE}.
16
+ def self.eq_capture(...) = new(EQ_CAPTURE, ...)
17
+ # Create a TextPredicateCapture for {EQ_STRING}.
18
+ def self.eq_string(...) = new(EQ_STRING, ...)
19
+ # Create a TextPredicateCapture for {MATCH_STRING}.
20
+ def self.match_string(...) = new(MATCH_STRING, ...)
21
+ # Create a TextPredicateCapture for {ANY_STRING}.
22
+ def self.any_string(...) = new(ANY_STRING, ...)
23
+
24
+ def initialize(type, fst, snd, positive, match_all)
25
+ @type = type
26
+ @fst = fst
27
+ @snd = snd
28
+ @positive = positive
29
+ @match_all = match_all
30
+ end
31
+
32
+ # `#eq` is positive, `#not-eq` is not.
33
+ def positive? = @positive
34
+ # `#any-` means don't match all.
35
+ def match_all? = @match_all
36
+ end
37
+ end
@@ -4,5 +4,5 @@ module TreeSitter
4
4
  # The version of the tree-sitter library.
5
5
  TREESITTER_VERSION = '0.22.6'
6
6
  # The current version of the gem.
7
- VERSION = '1.2.0'
7
+ VERSION = '1.3.0'
8
8
  end
data/lib/tree_sitter.rb CHANGED
@@ -6,9 +6,16 @@ end
6
6
 
7
7
  require 'set'
8
8
 
9
+ require 'tree_sitter/tree_sitter'
9
10
  require 'tree_sitter/version'
10
11
 
11
- require 'tree_sitter/tree_sitter'
12
12
  require 'tree_sitter/node'
13
+ require 'tree_sitter/query'
14
+ require 'tree_sitter/query_captures'
15
+ require 'tree_sitter/query_cursor'
16
+ require 'tree_sitter/query_match'
17
+ require 'tree_sitter/query_matches'
18
+ require 'tree_sitter/query_predicate'
19
+ require 'tree_sitter/text_predicate_capture'
13
20
 
14
21
  ObjectSpace.define_finalizer(TreeSitter::Tree.class, proc { TreeSitter::Tree.finalizer })
@@ -43,7 +43,7 @@ module TreeStand
43
43
  .freeze
44
44
 
45
45
  # The default paths we use to lookup parsers when no specific
46
- # {TreeStand::Config#parser_path} is {nil}.
46
+ # {TreeStand::Config#parser_path} is `nil`.
47
47
  # Order matters.
48
48
  LIBDIRS = [
49
49
  'tree-sitter-parsers',
@@ -180,7 +180,7 @@ module TreeStand
180
180
 
181
181
  # We know that the bindings will accept `lib`, but I don't know how to tell sorbet
182
182
  # the types in ext/tree_sitter where `load` is defined.
183
- TreeSitter::Language.load(name.gsub(/-/, '_'), T.unsafe(lib))
183
+ TreeSitter::Language.load(name.tr('-', '_'), T.unsafe(lib))
184
184
  end
185
185
 
186
186
  # @param language [String]
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_tree_sitter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Firas al-Khalil
8
8
  - Derek Stride
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-05-27 00:00:00.000000000 Z
12
+ date: 2024-06-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sorbet-runtime
@@ -39,7 +39,7 @@ dependencies:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
- description:
42
+ description:
43
43
  email:
44
44
  - firasalkhalil@gmail.com
45
45
  - derek@stride.host
@@ -75,7 +75,15 @@ files:
75
75
  - ext/tree_sitter/tree_sitter.c
76
76
  - ext/tree_sitter/tree_sitter.h
77
77
  - lib/tree_sitter.rb
78
+ - lib/tree_sitter/helpers.rb
78
79
  - lib/tree_sitter/node.rb
80
+ - lib/tree_sitter/query.rb
81
+ - lib/tree_sitter/query_captures.rb
82
+ - lib/tree_sitter/query_cursor.rb
83
+ - lib/tree_sitter/query_match.rb
84
+ - lib/tree_sitter/query_matches.rb
85
+ - lib/tree_sitter/query_predicate.rb
86
+ - lib/tree_sitter/text_predicate_capture.rb
79
87
  - lib/tree_sitter/version.rb
80
88
  - lib/tree_stand.rb
81
89
  - lib/tree_stand/ast_modifier.rb
@@ -99,7 +107,7 @@ metadata:
99
107
  source_code_uri: https://www.github.com/Faveod/ruby-tree-sitter
100
108
  changelog_uri: https://www.github.com/Faveod/ruby-tree-sitter
101
109
  documentation_uri: https://faveod.github.io/ruby-tree-sitter/
102
- post_install_message:
110
+ post_install_message:
103
111
  rdoc_options: []
104
112
  require_paths:
105
113
  - lib
@@ -115,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
123
  version: '0'
116
124
  requirements: []
117
125
  rubygems_version: 3.4.19
118
- signing_key:
126
+ signing_key:
119
127
  specification_version: 4
120
128
  summary: Ruby bindings for Tree-Sitter
121
129
  test_files: []