query: Add not-eq? predicate in rust & wasm binding

This commit is contained in:
Max Brunsfeld 2020-02-19 21:33:58 -08:00
parent f67c0526fd
commit 33492ca9df
2 changed files with 21 additions and 10 deletions

View file

@ -158,8 +158,8 @@ pub enum QueryError {
#[derive(Debug)]
enum TextPredicate {
CaptureEqString(u32, String),
CaptureEqCapture(u32, u32),
CaptureEqString(u32, String, bool),
CaptureEqCapture(u32, u32, bool),
CaptureMatchString(u32, regex::bytes::Regex),
}
@ -1251,7 +1251,7 @@ impl Query {
// Build a predicate for each of the known predicate function names.
let operator_name = &string_values[p[0].value_id as usize];
match operator_name.as_str() {
"eq?" => {
"eq?" | "not-eq?" => {
if p.len() != 3 {
return Err(QueryError::Predicate(format!(
"Wrong number of arguments to eq? predicate. Expected 2, got {}.",
@ -1265,12 +1265,18 @@ impl Query {
)));
}
let is_positive = operator_name == "eq?";
text_predicates.push(if p[2].type_ == type_capture {
TextPredicate::CaptureEqCapture(p[1].value_id, p[2].value_id)
TextPredicate::CaptureEqCapture(
p[1].value_id,
p[2].value_id,
is_positive,
)
} else {
TextPredicate::CaptureEqString(
p[1].value_id,
string_values[p[2].value_id as usize].clone(),
is_positive,
)
});
}
@ -1555,14 +1561,14 @@ impl<'a> QueryMatch<'a> {
query.text_predicates[self.pattern_index]
.iter()
.all(|predicate| match predicate {
TextPredicate::CaptureEqCapture(i, j) => {
TextPredicate::CaptureEqCapture(i, j, is_positive) => {
let node1 = self.capture_for_index(*i).unwrap();
let node2 = self.capture_for_index(*j).unwrap();
text_callback(node1).as_ref() == text_callback(node2).as_ref()
(text_callback(node1).as_ref() == text_callback(node2).as_ref()) == *is_positive
}
TextPredicate::CaptureEqString(i, s) => {
TextPredicate::CaptureEqString(i, s, is_positive) => {
let node = self.capture_for_index(*i).unwrap();
text_callback(node).as_ref() == s.as_bytes()
(text_callback(node).as_ref() == s.as_bytes()) == *is_positive
}
TextPredicate::CaptureMatchString(i, r) => {
let node = self.capture_for_index(*i).unwrap();

View file

@ -742,7 +742,10 @@ class Language {
throw new Error('Predicates must begin with a literal value');
}
const operator = steps[0].value;
let isPositive = true;
switch (operator) {
case 'not-eq?':
isPositive = false;
case 'eq?':
if (steps.length !== 3) throw new Error(
`Wrong number of arguments to \`eq?\` predicate. Expected 2, got ${steps.length - 1}`
@ -759,14 +762,16 @@ class Language {
if (c.name === captureName1) node1 = c.node;
if (c.name === captureName2) node2 = c.node;
}
return node1.text === node2.text
return (node1.text === node2.text) === isPositive;
});
} else {
const captureName = steps[1].name;
const stringValue = steps[2].value;
predicates[i].push(function(captures) {
for (const c of captures) {
if (c.name === captureName) return c.node.text === stringValue;
if (c.name === captureName) {
return (c.node.text === stringValue) === isPositive;
};
}
return false;
});