Add ts_query_disable_pattern API

This commit is contained in:
Max Brunsfeld 2020-01-15 17:08:55 -08:00
parent 58617cfa0c
commit f3747863df
5 changed files with 84 additions and 4 deletions

View file

@ -1238,6 +1238,45 @@ fn test_query_comments() {
});
}
#[test]
fn test_query_disable_pattern() {
allocations::record(|| {
let language = get_language("javascript");
let mut query = Query::new(
language,
"
(function_declaration
name: (identifier) @name)
(function_declaration
body: (statement_block) @body)
(class_declaration
name: (identifier) @name)
(class_declaration
body: (class_body) @body)
",
)
.unwrap();
// disable the patterns that match names
query.disable_pattern(0);
query.disable_pattern(2);
let source = "class A { constructor() {} } function b() { return 1; }";
let mut parser = Parser::new();
parser.set_language(language).unwrap();
let tree = parser.parse(source, None).unwrap();
let mut cursor = QueryCursor::new();
let matches = cursor.matches(&query, tree.root_node(), to_callback(source));
assert_eq!(
collect_matches(matches, &query, source),
&[
(3, vec![("body", "{ constructor() {} }")]),
(1, vec![("body", "{ return 1; }")]),
],
);
});
}
fn collect_matches<'a>(
matches: impl Iterator<Item = QueryMatch<'a>>,
query: &'a Query,

View file

@ -668,6 +668,12 @@ extern "C" {
arg3: u32,
);
}
extern "C" {
#[doc = " Disable a certain pattern within a query. This prevents the pattern"]
#[doc = " from matching and removes most of the overhead associated with the"]
#[doc = " pattern."]
pub fn ts_query_disable_pattern(arg1: *mut TSQuery, arg2: u32);
}
extern "C" {
#[doc = " Create a new cursor for executing a given query."]
#[doc = ""]

View file

@ -1322,6 +1322,14 @@ impl Query {
}
}
/// Disable a certain pattern within a query.
///
/// This prevents the pattern from matching, and also avoids any resource usage
/// associated with the pattern.
pub fn disable_pattern(&mut self, index: usize) {
unsafe { ffi::ts_query_disable_pattern(self.ptr.as_ptr(), index as u32) }
}
fn parse_property(
function_name: &str,
capture_names: &[String],

View file

@ -732,12 +732,22 @@ const char *ts_query_string_value_for_id(
);
/**
* 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.
* 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.
*/
void ts_query_disable_capture(TSQuery *, const char *, uint32_t);
/**
* 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.
*/
void ts_query_disable_pattern(TSQuery *, uint32_t);
/**
* Create a new cursor for executing a given query.
*

View file

@ -893,6 +893,8 @@ void ts_query_disable_capture(
const char *name,
uint32_t length
) {
// Remove capture information for any pattern step that previously
// captured with the given name.
int id = symbol_table_id_for_name(&self->captures, name, length);
if (id != -1) {
for (unsigned i = 0; i < self->steps.size; i++) {
@ -901,8 +903,23 @@ void ts_query_disable_capture(
step->capture_id = NONE;
}
}
ts_query__finalize_steps(self);
}
}
void ts_query_disable_pattern(
TSQuery *self,
uint32_t pattern_index
) {
// Remove the given pattern from the pattern map. Its steps will still
// be in the `steps` array, but they will never be read.
for (unsigned i = 0; i < self->pattern_map.size; i++) {
PatternEntry *pattern = &self->pattern_map.contents[i];
if (pattern->pattern_index == pattern_index) {
array_erase(&self->pattern_map, i);
i--;
}
}
ts_query__finalize_steps(self);
}
/***************