query: Add not-eq? predicate in rust & wasm binding
This commit is contained in:
parent
f67c0526fd
commit
33492ca9df
2 changed files with 21 additions and 10 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue