Expose capture suffixes in queries

This commit is contained in:
Hendrik van Antwerpen 2021-11-23 19:22:24 +01:00
parent e81976d27a
commit ae7869d1a6
4 changed files with 92 additions and 10 deletions

View file

@ -665,6 +665,15 @@ extern "C" {
length: *mut u32,
) -> *const ::std::os::raw::c_char;
}
extern "C" {
#[doc = " Get the suffix of one of the query's captures, or one of the query's"]
#[doc = " string literals. Each capture and string is associated with a numeric"]
#[doc = " id based on the order that it appeared in the query's source."]
pub fn ts_query_capture_suffix_for_id(
arg1: *const TSQuery,
id: u32,
) -> ::std::os::raw::c_char;
}
extern "C" {
pub fn ts_query_string_value_for_id(
arg1: *const TSQuery,

View file

@ -98,12 +98,34 @@ pub struct TreeCursor<'a>(ffi::TSTreeCursor, PhantomData<&'a ()>);
pub struct Query {
ptr: NonNull<ffi::TSQuery>,
capture_names: Vec<String>,
capture_suffixes: Vec<QueryCaptureSuffix>,
text_predicates: Vec<Box<[TextPredicate]>>,
property_settings: Vec<Box<[QueryProperty]>>,
property_predicates: Vec<Box<[(QueryProperty, bool)]>>,
general_predicates: Vec<Box<[QueryPredicate]>>,
}
/// A suffix indicating the multiplicity of the capture value
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum QueryCaptureSuffix {
One,
OneOrMore,
ZeroOrMore,
ZeroOrOne,
}
impl From<u8> for QueryCaptureSuffix {
fn from(value: u8) -> QueryCaptureSuffix {
match value {
b'\0' => QueryCaptureSuffix::One,
b'+' => QueryCaptureSuffix::OneOrMore,
b'*' => QueryCaptureSuffix::ZeroOrMore,
b'?' => QueryCaptureSuffix::ZeroOrOne,
_ => panic!("Unrecognized suffix: {}", value as char),
}
}
}
/// A stateful object for executing a `Query` on a syntax `Tree`.
pub struct QueryCursor {
ptr: NonNull<ffi::TSQueryCursor>,
@ -1306,6 +1328,7 @@ impl Query {
let mut result = Query {
ptr: unsafe { NonNull::new_unchecked(ptr) },
capture_names: Vec::with_capacity(capture_count as usize),
capture_suffixes: Vec::with_capacity(capture_count as usize),
text_predicates: Vec::with_capacity(pattern_count),
property_predicates: Vec::with_capacity(pattern_count),
property_settings: Vec::with_capacity(pattern_count),
@ -1321,6 +1344,8 @@ impl Query {
let name = slice::from_raw_parts(name, length as usize);
let name = str::from_utf8_unchecked(name);
result.capture_names.push(name.to_string());
let suffix = ffi::ts_query_capture_suffix_for_id(ptr, i) as u8;
result.capture_suffixes.push(suffix.into());
}
}
@ -1524,6 +1549,11 @@ impl Query {
&self.capture_names
}
/// Get the suffixes of the captures used in the query.
pub fn capture_suffixes(&self) -> &[QueryCaptureSuffix] {
&self.capture_suffixes
}
/// Get the index for a given capture name.
pub fn capture_index_for_name(&self, name: &str) -> Option<u32> {
self.capture_names