Skip to content

Commit 18c1b33

Browse files
committed
Implement Binary combine matchers
1 parent 62c6cc0 commit 18c1b33

File tree

4 files changed

+112
-1
lines changed

4 files changed

+112
-1
lines changed

src/clang_ql/matchers/combine.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,56 @@ impl<T: Clone> Matcher<T> for CombineMatcher<T> {
7272
}
7373
}
7474

75+
#[derive(PartialEq, Clone)]
76+
enum CombineBinaryMatcherKind {
77+
And,
78+
Or,
79+
Xor,
80+
}
81+
82+
#[derive(Clone)]
83+
pub struct CombineBinaryMatcher<T> {
84+
lhs: Box<dyn Matcher<T>>,
85+
rhs: Box<dyn Matcher<T>>,
86+
kind: CombineBinaryMatcherKind,
87+
}
88+
89+
impl<T: Clone> CombineBinaryMatcher<T> {
90+
pub fn and(lhs: Box<dyn Matcher<T>>, rhs: Box<dyn Matcher<T>>) -> Self {
91+
CombineBinaryMatcher {
92+
lhs,
93+
rhs,
94+
kind: CombineBinaryMatcherKind::And,
95+
}
96+
}
97+
98+
pub fn or(lhs: Box<dyn Matcher<T>>, rhs: Box<dyn Matcher<T>>) -> Self {
99+
CombineBinaryMatcher {
100+
lhs,
101+
rhs,
102+
kind: CombineBinaryMatcherKind::Or,
103+
}
104+
}
105+
106+
pub fn xor(lhs: Box<dyn Matcher<T>>, rhs: Box<dyn Matcher<T>>) -> Self {
107+
CombineBinaryMatcher {
108+
lhs,
109+
rhs,
110+
kind: CombineBinaryMatcherKind::Xor,
111+
}
112+
}
113+
}
114+
115+
impl<T: Clone> Matcher<T> for CombineBinaryMatcher<T> {
116+
fn is_match(&self, node: &T) -> bool {
117+
match &self.kind {
118+
CombineBinaryMatcherKind::And => self.lhs.is_match(node) && self.rhs.is_match(node),
119+
CombineBinaryMatcherKind::Or => self.lhs.is_match(node) || self.rhs.is_match(node),
120+
CombineBinaryMatcherKind::Xor => self.lhs.is_match(node) ^ self.rhs.is_match(node),
121+
}
122+
}
123+
}
124+
75125
#[derive(Clone)]
76126
enum CombineUnaryMatcherKind {
77127
Not,

src/clang_ql/matchers/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub use function::IsStaticMethodMatcher;
1616
pub use function::IsVirtualMatcher;
1717

1818
mod combine;
19+
pub use combine::CombineBinaryMatcher;
1920
pub use combine::CombineMatcher;
2021
pub use combine::UnaryCombineMatcher;
2122

src/clang_ql/types/matcher.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,30 @@ impl DataType for FunctionMatcherType {
2525
self
2626
}
2727

28+
fn can_perform_logical_and_op_with(&self) -> Vec<Box<dyn DataType>> {
29+
vec![Box::new(FunctionMatcherType)]
30+
}
31+
32+
fn logical_and_op_result_type(&self, _other: &Box<dyn DataType>) -> Box<dyn DataType> {
33+
Box::new(FunctionMatcherType)
34+
}
35+
36+
fn can_perform_logical_or_op_with(&self) -> Vec<Box<dyn DataType>> {
37+
vec![Box::new(FunctionMatcherType)]
38+
}
39+
40+
fn logical_or_op_result_type(&self, _other: &Box<dyn DataType>) -> Box<dyn DataType> {
41+
Box::new(FunctionMatcherType)
42+
}
43+
44+
fn can_perform_logical_xor_op_with(&self) -> Vec<Box<dyn DataType>> {
45+
vec![Box::new(FunctionMatcherType)]
46+
}
47+
48+
fn logical_xor_op_result_type(&self, _other: &Box<dyn DataType>) -> Box<dyn DataType> {
49+
Box::new(FunctionMatcherType)
50+
}
51+
2852
fn can_perform_bang_op(&self) -> bool {
2953
true
3054
}

src/clang_ql/values/matcher.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use gitql_core::values::base::Value;
22

3-
use crate::clang_ql::matchers::{Matcher, UnaryCombineMatcher};
3+
use crate::clang_ql::matchers::{CombineBinaryMatcher, Matcher, UnaryCombineMatcher};
44
use crate::clang_ql::types::FunctionMatcherType;
55

66
use super::FunctionNode;
@@ -37,6 +37,42 @@ impl Value for FunctionMatcherValue {
3737
self
3838
}
3939

40+
fn logical_and_op(&self, other: &Box<dyn Value>) -> Result<Box<dyn Value>, String> {
41+
let lhs = self.matcher.clone();
42+
let rhs = other
43+
.as_any()
44+
.downcast_ref::<FunctionMatcherValue>()
45+
.unwrap()
46+
.matcher
47+
.clone();
48+
let combine_matcher = Box::new(CombineBinaryMatcher::and(lhs, rhs));
49+
Ok(Box::new(FunctionMatcherValue::new(combine_matcher)))
50+
}
51+
52+
fn logical_or_op(&self, other: &Box<dyn Value>) -> Result<Box<dyn Value>, String> {
53+
let lhs = self.matcher.clone();
54+
let rhs = other
55+
.as_any()
56+
.downcast_ref::<FunctionMatcherValue>()
57+
.unwrap()
58+
.matcher
59+
.clone();
60+
let combine_matcher = Box::new(CombineBinaryMatcher::or(lhs, rhs));
61+
Ok(Box::new(FunctionMatcherValue::new(combine_matcher)))
62+
}
63+
64+
fn logical_xor_op(&self, other: &Box<dyn Value>) -> Result<Box<dyn Value>, String> {
65+
let lhs = self.matcher.clone();
66+
let rhs = other
67+
.as_any()
68+
.downcast_ref::<FunctionMatcherValue>()
69+
.unwrap()
70+
.matcher
71+
.clone();
72+
let combine_matcher = Box::new(CombineBinaryMatcher::xor(lhs, rhs));
73+
Ok(Box::new(FunctionMatcherValue::new(combine_matcher)))
74+
}
75+
4076
fn bang_op(&self) -> Result<Box<dyn Value>, String> {
4177
let combine_matcher = Box::new(UnaryCombineMatcher::not(self.matcher.clone()));
4278
Ok(Box::new(FunctionMatcherValue::new(combine_matcher)))

0 commit comments

Comments
 (0)