ruby_tree_sitter 1.2.0-x86_64-linux → 1.3.0-x86_64-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/ext/tree_sitter/query.c +7 -0
 - data/ext/tree_sitter/query_cursor.c +18 -2
 - data/lib/tree_sitter/helpers.rb +23 -0
 - data/lib/tree_sitter/query.rb +191 -0
 - data/lib/tree_sitter/query_captures.rb +28 -0
 - data/lib/tree_sitter/query_cursor.rb +27 -0
 - data/lib/tree_sitter/query_match.rb +100 -0
 - data/lib/tree_sitter/query_matches.rb +25 -0
 - data/lib/tree_sitter/query_predicate.rb +14 -0
 - data/lib/tree_sitter/text_predicate_capture.rb +37 -0
 - data/lib/tree_sitter/tree_sitter.so +0 -0
 - data/lib/tree_sitter/version.rb +1 -1
 - data/lib/tree_sitter.rb +8 -1
 - data/lib/tree_stand/parser.rb +2 -2
 - metadata +10 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: a0f7c51b289e769ad5701be586b28d61f41f0979ee6fd3c08f87481ae307f146
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 988052e5b5b5c41e9a9d974398c6c6cae401f2068a2ad4013d80198f3437c029
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 9ef62c5ea3bd4451b03b43e6efc2c3501191ffcd9ea96dfe12d2e66b249d1f16f58e82d6127d833a6c8105e3f910dda2ba898a138d5e6d2756615bf69fcb2e05
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 5bd46cc66e845c9091005a5eadeccb3db2984e0bbc5bf6d12e9fc4e3fd126f9ab6f1d37970fbe6760eee096ec2c011d4d328d5610a9e873ed313df3842caceb3
         
     | 
    
        data/ext/tree_sitter/query.c
    CHANGED
    
    | 
         @@ -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  
     | 
| 
      
 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",  
     | 
| 
      
 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
         
     | 
| 
         Binary file 
     | 
    
        data/lib/tree_sitter/version.rb
    CHANGED
    
    
    
        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 })
         
     | 
    
        data/lib/tree_stand/parser.rb
    CHANGED
    
    | 
         @@ -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  
     | 
| 
      
 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. 
     | 
| 
      
 183 
     | 
    
         
            +
                  TreeSitter::Language.load(name.tr('-', '_'), T.unsafe(lib))
         
     | 
| 
       184 
184 
     | 
    
         
             
                end
         
     | 
| 
       185 
185 
     | 
    
         | 
| 
       186 
186 
     | 
    
         
             
                # @param language [String]
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: ruby_tree_sitter
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.3.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: x86_64-linux
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Firas al-Khalil
         
     | 
| 
         @@ -9,7 +9,7 @@ authors: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       10 
10 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       11 
11 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       12 
     | 
    
         
            -
            date: 2024- 
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2024-06-26 00:00:00.000000000 Z
         
     | 
| 
       13 
13 
     | 
    
         
             
            dependencies:
         
     | 
| 
       14 
14 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       15 
15 
     | 
    
         
             
              name: sorbet-runtime
         
     | 
| 
         @@ -74,7 +74,15 @@ files: 
     | 
|
| 
       74 
74 
     | 
    
         
             
            - ext/tree_sitter/tree_sitter.c
         
     | 
| 
       75 
75 
     | 
    
         
             
            - ext/tree_sitter/tree_sitter.h
         
     | 
| 
       76 
76 
     | 
    
         
             
            - lib/tree_sitter.rb
         
     | 
| 
      
 77 
     | 
    
         
            +
            - lib/tree_sitter/helpers.rb
         
     | 
| 
       77 
78 
     | 
    
         
             
            - lib/tree_sitter/node.rb
         
     | 
| 
      
 79 
     | 
    
         
            +
            - lib/tree_sitter/query.rb
         
     | 
| 
      
 80 
     | 
    
         
            +
            - lib/tree_sitter/query_captures.rb
         
     | 
| 
      
 81 
     | 
    
         
            +
            - lib/tree_sitter/query_cursor.rb
         
     | 
| 
      
 82 
     | 
    
         
            +
            - lib/tree_sitter/query_match.rb
         
     | 
| 
      
 83 
     | 
    
         
            +
            - lib/tree_sitter/query_matches.rb
         
     | 
| 
      
 84 
     | 
    
         
            +
            - lib/tree_sitter/query_predicate.rb
         
     | 
| 
      
 85 
     | 
    
         
            +
            - lib/tree_sitter/text_predicate_capture.rb
         
     | 
| 
       78 
86 
     | 
    
         
             
            - lib/tree_sitter/tree_sitter.so
         
     | 
| 
       79 
87 
     | 
    
         
             
            - lib/tree_sitter/version.rb
         
     | 
| 
       80 
88 
     | 
    
         
             
            - lib/tree_stand.rb
         
     |