Class: TreeSitter::Query

Inherits:
Object
  • Object
show all
Defined in:
lib/tree_sitter/query.rb,
ext/tree_sitter/query.c

Overview

Query is a wrapper around a tree-sitter query.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(language, source) ⇒ Query

Create a new query from a string containing one or more S-expression patterns. The query is associated with a particular language, and can only be run on syntax nodes parsed with that language.

If all of the given patterns are valid, this returns a TreeSitter::Query.

Parameters:

Raises:

  • (RuntimeError)


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'ext/tree_sitter/query.c', line 126

static VALUE query_initialize(VALUE self, VALUE language, VALUE source) {
  // FIXME: should we raise an exception here?
  TSLanguage *lang = value_to_language(language);
  const char *src = StringValuePtr(source);
  uint32_t len = (uint32_t)RSTRING_LEN(source);
  uint32_t error_offset = 0;
  TSQueryError error_type;

  TSQuery *res = ts_query_new(lang, src, len, &error_offset, &error_type);

  if (res == NULL || error_offset > 0) {
    VALUE query_creation_error = rb_const_get(mTreeSitter, rb_intern("QueryCreationError"));
    rb_raise(query_creation_error, "Could not create query: TSQueryError%s",
             query_error_str(error_type));
  } else {
    SELF = res;
  }

  rb_iv_set(self, "@text_predicates", rb_ary_new());
  rb_iv_set(self, "@property_predicates", rb_ary_new());
  rb_iv_set(self, "@property_settings", rb_ary_new());
  rb_iv_set(self, "@general_predicates", rb_ary_new());

  rb_funcall(self, rb_intern("process"), 1, source);

  return self;
}

Instance Attribute Details

#capture_namesObject (readonly)

Returns the value of attribute capture_names.



8
9
10
# File 'lib/tree_sitter/query.rb', line 8

def capture_names
  @capture_names
end

#capture_quantifiersObject (readonly)

Returns the value of attribute capture_quantifiers.



9
10
11
# File 'lib/tree_sitter/query.rb', line 9

def capture_quantifiers
  @capture_quantifiers
end

#general_predicatesObject (readonly)

Returns the value of attribute general_predicates.



13
14
15
# File 'lib/tree_sitter/query.rb', line 13

def general_predicates
  @general_predicates
end

#property_predicatesObject (readonly)

Returns the value of attribute property_predicates.



11
12
13
# File 'lib/tree_sitter/query.rb', line 11

def property_predicates
  @property_predicates
end

#property_settingsObject (readonly)

Returns the value of attribute property_settings.



12
13
14
# File 'lib/tree_sitter/query.rb', line 12

def property_settings
  @property_settings
end

#text_predicatesObject (readonly)

Returns the value of attribute text_predicates.



10
11
12
# File 'lib/tree_sitter/query.rb', line 10

def text_predicates
  @text_predicates
end

Instance Method Details

#capture_countInteger

Get the number of captures literals in the query.

Returns:

  • (Integer)


14
15
16
# File 'ext/tree_sitter/query.c', line 14

static VALUE query_capture_count(VALUE self) {
  return UINT2NUM(ts_query_capture_count(SELF));
}

#capture_name_for_id(index) ⇒ String

Get the name and length of one of the query’s captures, or one of the query’s string literals. Each capture and string is associated with a numeric id based on the order that it appeared in the query’s source.

Parameters:

  • index (Integer)

Returns:

  • (String)

Raises:

  • (IndexError)

    if out of range.



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'ext/tree_sitter/query.c', line 29

static VALUE query_capture_name_for_id(VALUE self, VALUE index) {
  const TSQuery *query = SELF;
  uint32_t idx = NUM2UINT(index);
  uint32_t range = ts_query_capture_count(query);

  if (idx >= range) {
    rb_raise(rb_eIndexError, "Index %d out of range (len = %d)", idx, range);
  } else {
    uint32_t length;
    const char *name = ts_query_capture_name_for_id(query, idx, &length);
    return safe_str2(name, length);
  }
}

#capture_quantifier_for_id(query_idx, capture_idx) ⇒ Integer

Get the quantifier of the query’s captures. Each capture is associated with a numeric id based on the order that it appeared in the query’s source.

Parameters:

  • query_idx (Integer)
  • capture_idx (Integer)

Returns:

  • (Integer)

Raises:

  • (IndexError)

    if out of range.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'ext/tree_sitter/query.c', line 54

static VALUE query_capture_quantifier_for_id(VALUE self, VALUE query_idx,
                                             VALUE capture_idx) {
  const TSQuery *query = SELF;
  uint32_t pattern = NUM2UINT(query_idx);
  uint32_t index = NUM2UINT(capture_idx);
  uint32_t range = ts_query_capture_count(query);

  if (index >= range) {
    rb_raise(rb_eIndexError, "Capture ID %d out of range (len = %d)", index,
             range);
  } else {
    return UINT2NUM(ts_query_capture_quantifier_for_id(query, pattern, index));
  }
}

#disable_capture(capture) ⇒ nil

Disable a certain capture within a query.

This prevents the capture from being returned in matches, and also avoids any resource usage associated with recording the capture. Currently, there is no way to undo this.

Parameters:

  • capture (String)

Returns:

  • (nil)


80
81
82
83
84
85
# File 'ext/tree_sitter/query.c', line 80

static VALUE query_disable_capture(VALUE self, VALUE capture) {
  const char *cap = StringValuePtr(capture);
  uint32_t length = (uint32_t)RSTRING_LEN(capture);
  ts_query_disable_capture(SELF, cap, length);
  return Qnil;
}

#disable_pattern(pattern) ⇒ nil

Disable a certain pattern within a query.

This prevents the pattern from matching and removes most of the overhead associated with the pattern. Currently, there is no way to undo this.

Parameters:

  • pattern (Integer)

Returns:

  • (nil)

Raises:

  • (IndexError)

    if out of range.



99
100
101
102
103
104
105
106
107
108
109
110
# File 'ext/tree_sitter/query.c', line 99

static VALUE query_disable_pattern(VALUE self, VALUE pattern) {
  TSQuery *query = SELF;
  uint32_t index = NUM2UINT(pattern);
  uint32_t range = ts_query_pattern_count(query);

  if (index >= range) {
    rb_raise(rb_eIndexError, "Index %d out of range (len = %d)", index, range);
  } else {
    ts_query_disable_pattern(query, index);
    return Qnil;
  }
}

#pattern_countInteger

Get the number of patterns in the query.

Returns:

  • (Integer)


159
160
161
# File 'ext/tree_sitter/query.c', line 159

static VALUE query_pattern_count(VALUE self) {
  return UINT2NUM(ts_query_pattern_count(SELF));
}

#pattern_guaranteed_at_step?(byte_offset) ⇒ Integer

Check if a given pattern is guaranteed to match once a given step is reached. The step is specified by its byte offset in the query’s source code.

Parameters:

  • byte_offset (Integer)

Returns:

  • (Integer)


171
172
173
174
# File 'ext/tree_sitter/query.c', line 171

static VALUE query_pattern_guaranteed_at_step(VALUE self, VALUE byte_offset) {
  return UINT2NUM(
      ts_query_is_pattern_guaranteed_at_step(SELF, NUM2UINT(byte_offset)));
}

#predicates_for_pattern(pattern_index) ⇒ Array<QueryPredicateStep>

Get all of the predicates for the given pattern in the query.

The predicates are represented as a single array of steps. There are three types of steps in this array, which correspond to the three legal values for the type field:

Parameters:

  • pattern_index (Integer)

Returns:



196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'ext/tree_sitter/query.c', line 196

static VALUE query_predicates_for_pattern(VALUE self, VALUE pattern_index) {
  const TSQuery *query = SELF;
  uint32_t index = NUM2UINT(pattern_index);
  uint32_t length;
  const TSQueryPredicateStep *steps =
      ts_query_predicates_for_pattern(query, index, &length);
  VALUE res = rb_ary_new_capa(length);

  for (uint32_t i = 0; i < length; i++) {
    rb_ary_push(res, new_query_predicate_step(&steps[i]));
  }

  return res;
}

#start_byte_for_pattern(pattern_index) ⇒ Integer

Get the byte offset where the given pattern starts in the query’s source.

This can be useful when combining queries by concatenating their source code strings.

Parameters:

  • pattern_index (Integer)

Returns:

  • (Integer)

Raises:

  • (IndexError)

    if out of range.



223
224
225
226
227
228
229
230
231
232
233
# File 'ext/tree_sitter/query.c', line 223

static VALUE query_start_byte_for_pattern(VALUE self, VALUE pattern_index) {
  const TSQuery *query = SELF;
  uint32_t index = NUM2UINT(pattern_index);
  uint32_t range = ts_query_pattern_count(query);

  if (index >= range) {
    rb_raise(rb_eIndexError, "Index %d out of range (len = %d)", index, range);
  } else {
    return UINT2NUM(ts_query_start_byte_for_pattern(SELF, index));
  }
}

#string_countInteger

Get the number of string literals in the query.

Returns:

  • (Integer)


240
241
242
# File 'ext/tree_sitter/query.c', line 240

static VALUE query_string_count(VALUE self) {
  return UINT2NUM(ts_query_string_count(SELF));
}

#string_value_for_id(id) ⇒ String

Parameters:

  • id (Integer)

Returns:

  • (String)

Raises:

  • (IndexError)

    if out of range.



251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'ext/tree_sitter/query.c', line 251

static VALUE query_string_value_for_id(VALUE self, VALUE id) {
  const TSQuery *query = SELF;
  uint32_t index = NUM2UINT(id);
  uint32_t range = ts_query_string_count(query);

  if (index >= range) {
    rb_raise(rb_eIndexError, "Index %d out of range (len = %d)", index, range);
  } else {
    uint32_t length;
    const char *string = ts_query_string_value_for_id(query, index, &length);
    return safe_str2(string, length);
  }
}