Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b649e8a

Browse files
committedJan 11, 2025·
Implement the basic ast matchers for the function table
1 parent 6102c9f commit b649e8a

File tree

11 files changed

+276
-5
lines changed

11 files changed

+276
-5
lines changed
 

‎src/clang_ql/functions/ast/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ use gitql_core::signature::Signature;
88
use gitql_core::signature::StandardFunction;
99

1010
#[inline(always)]
11-
pub fn register_ast_functions(map: &mut HashMap<&'static str, StandardFunction>) {
11+
pub(crate) fn register_ast_functions(map: &mut HashMap<&'static str, StandardFunction>) {
1212
register_ast_function_functions(map);
1313
}
1414

1515
#[inline(always)]
16-
pub fn register_ast_signatures(map: &mut HashMap<&'static str, Signature>) {
16+
pub(crate) fn register_ast_signatures(map: &mut HashMap<&'static str, Signature>) {
1717
register_ast_function_signatures(map);
1818
}
+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
use std::collections::HashMap;
2+
3+
use gitql_ast::types::boolean::BoolType;
4+
use gitql_core::signature::Signature;
5+
use gitql_core::signature::StandardFunction;
6+
use gitql_core::values::base::Value;
7+
use gitql_core::values::boolean::BoolValue;
8+
9+
use crate::clang_ql::matchers::IsConstMethodMatcher;
10+
use crate::clang_ql::matchers::IsDeletedMethodMatcher;
11+
use crate::clang_ql::matchers::IsMethodMatcher;
12+
use crate::clang_ql::matchers::IsPureVirtualMatcher;
13+
use crate::clang_ql::matchers::IsStaticMethodMatcher;
14+
use crate::clang_ql::matchers::IsVirtualMatcher;
15+
use crate::clang_ql::types::FunctionMatcherType;
16+
use crate::clang_ql::types::FunctionType;
17+
use crate::clang_ql::values::FunctionMatcherValue;
18+
use crate::clang_ql::values::FunctionValue;
19+
20+
#[inline(always)]
21+
pub(crate) fn register_function_matchers_functions(
22+
map: &mut HashMap<&'static str, StandardFunction>,
23+
) {
24+
map.insert("m_function", match_function);
25+
26+
map.insert("m_virtual", match_virtual_function);
27+
map.insert("m_pure_virtual", match_pure_virtual_function);
28+
map.insert("m_static", match_static_function);
29+
map.insert("m_const", match_const_function);
30+
map.insert("m_deleted", match_deleted_function);
31+
map.insert("m_method", match_method_function);
32+
}
33+
34+
#[inline(always)]
35+
pub(crate) fn register_function_matchers_signatures(map: &mut HashMap<&'static str, Signature>) {
36+
map.insert(
37+
"m_function",
38+
Signature::with_return(Box::new(BoolType))
39+
.add_parameter(Box::new(FunctionType))
40+
.add_parameter(Box::new(FunctionMatcherType)),
41+
);
42+
43+
map.insert(
44+
"m_virtual",
45+
Signature::with_return(Box::new(FunctionMatcherType)),
46+
);
47+
48+
map.insert(
49+
"m_pure_virtual",
50+
Signature::with_return(Box::new(FunctionMatcherType)),
51+
);
52+
53+
map.insert(
54+
"m_const",
55+
Signature::with_return(Box::new(FunctionMatcherType)),
56+
);
57+
58+
map.insert(
59+
"m_deleted",
60+
Signature::with_return(Box::new(FunctionMatcherType)),
61+
);
62+
63+
map.insert(
64+
"m_method",
65+
Signature::with_return(Box::new(FunctionMatcherType)),
66+
);
67+
}
68+
69+
fn match_function(values: &[Box<dyn Value>]) -> Box<dyn Value> {
70+
let function_node = values[0].as_any().downcast_ref::<FunctionValue>().unwrap();
71+
let function_matcher = values[1]
72+
.as_any()
73+
.downcast_ref::<FunctionMatcherValue>()
74+
.unwrap();
75+
let is_matches = function_matcher.matcher.is_match(&function_node.node);
76+
Box::new(BoolValue::new(is_matches))
77+
}
78+
79+
fn match_virtual_function(_values: &[Box<dyn Value>]) -> Box<dyn Value> {
80+
let matcher = Box::new(IsVirtualMatcher);
81+
Box::new(FunctionMatcherValue::new(matcher))
82+
}
83+
84+
fn match_pure_virtual_function(_values: &[Box<dyn Value>]) -> Box<dyn Value> {
85+
let matcher = Box::new(IsPureVirtualMatcher);
86+
Box::new(FunctionMatcherValue::new(matcher))
87+
}
88+
89+
fn match_static_function(_values: &[Box<dyn Value>]) -> Box<dyn Value> {
90+
let matcher = Box::new(IsStaticMethodMatcher);
91+
Box::new(FunctionMatcherValue::new(matcher))
92+
}
93+
94+
fn match_const_function(_values: &[Box<dyn Value>]) -> Box<dyn Value> {
95+
let matcher = Box::new(IsConstMethodMatcher);
96+
Box::new(FunctionMatcherValue::new(matcher))
97+
}
98+
99+
fn match_deleted_function(_values: &[Box<dyn Value>]) -> Box<dyn Value> {
100+
let matcher = Box::new(IsDeletedMethodMatcher);
101+
Box::new(FunctionMatcherValue::new(matcher))
102+
}
103+
104+
fn match_method_function(_values: &[Box<dyn Value>]) -> Box<dyn Value> {
105+
let matcher = Box::new(IsMethodMatcher);
106+
Box::new(FunctionMatcherValue::new(matcher))
107+
}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use std::collections::HashMap;
2+
3+
use gitql_core::signature::Signature;
4+
use gitql_core::signature::StandardFunction;
5+
6+
mod function;
7+
8+
#[inline(always)]
9+
pub(crate) fn register_matchers_functions(map: &mut HashMap<&'static str, StandardFunction>) {
10+
function::register_function_matchers_functions(map);
11+
}
12+
13+
#[inline(always)]
14+
pub(crate) fn register_matchers_signatures(map: &mut HashMap<&'static str, Signature>) {
15+
function::register_function_matchers_signatures(map);
16+
}

‎src/clang_ql/functions/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ use gitql_std::standard::standard_function_signatures;
77
use gitql_std::standard::standard_functions;
88

99
mod ast;
10+
mod matchers;
1011

1112
#[inline(always)]
1213
pub fn clang_ql_functions() -> &'static HashMap<&'static str, StandardFunction> {
1314
static HASHMAP: OnceLock<HashMap<&'static str, StandardFunction>> = OnceLock::new();
1415
HASHMAP.get_or_init(|| {
1516
let mut map = standard_functions().to_owned();
1617
ast::register_ast_functions(&mut map);
18+
matchers::register_matchers_functions(&mut map);
1719
map
1820
})
1921
}
@@ -22,5 +24,6 @@ pub fn clang_ql_functions() -> &'static HashMap<&'static str, StandardFunction>
2224
pub fn clang_ql_functions_signatures() -> HashMap<&'static str, Signature> {
2325
let mut map = standard_function_signatures().to_owned();
2426
ast::register_ast_signatures(&mut map);
27+
matchers::register_matchers_signatures(&mut map);
2528
map
2629
}

‎src/clang_ql/matchers/function.rs

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use clang_sys::clang_CXXMethod_isConst;
2+
use clang_sys::clang_CXXMethod_isPureVirtual;
3+
use clang_sys::clang_CXXMethod_isStatic;
4+
use clang_sys::clang_CXXMethod_isVirtual;
5+
use clang_sys::clang_getCursorKind;
6+
use clang_sys::CXCursor_CXXMethod;
7+
8+
use crate::clang_ql::values::FunctionNode;
9+
10+
use super::FunctionMatcher;
11+
12+
#[derive(Clone)]
13+
pub struct IsVirtualMatcher;
14+
15+
impl FunctionMatcher for IsVirtualMatcher {
16+
fn is_match(&self, function: &FunctionNode) -> bool {
17+
unsafe { clang_CXXMethod_isVirtual(function.cursor) != 0 }
18+
}
19+
}
20+
21+
#[derive(Clone)]
22+
pub struct IsPureVirtualMatcher;
23+
24+
impl FunctionMatcher for IsPureVirtualMatcher {
25+
fn is_match(&self, function: &FunctionNode) -> bool {
26+
unsafe { clang_CXXMethod_isPureVirtual(function.cursor) != 0 }
27+
}
28+
}
29+
30+
#[derive(Clone)]
31+
pub struct IsStaticMethodMatcher;
32+
33+
impl FunctionMatcher for IsStaticMethodMatcher {
34+
fn is_match(&self, function: &FunctionNode) -> bool {
35+
unsafe { clang_CXXMethod_isStatic(function.cursor) != 0 }
36+
}
37+
}
38+
39+
#[derive(Clone)]
40+
pub struct IsConstMethodMatcher;
41+
42+
impl FunctionMatcher for IsConstMethodMatcher {
43+
fn is_match(&self, function: &FunctionNode) -> bool {
44+
unsafe { clang_CXXMethod_isConst(function.cursor) != 0 }
45+
}
46+
}
47+
48+
#[derive(Clone)]
49+
pub struct IsDeletedMethodMatcher;
50+
51+
impl FunctionMatcher for IsDeletedMethodMatcher {
52+
fn is_match(&self, function: &FunctionNode) -> bool {
53+
unsafe { clang_CXXMethod_isConst(function.cursor) != 0 }
54+
}
55+
}
56+
57+
#[derive(Clone)]
58+
pub struct IsMethodMatcher;
59+
60+
impl FunctionMatcher for IsMethodMatcher {
61+
fn is_match(&self, function: &FunctionNode) -> bool {
62+
unsafe {
63+
let cursor_kind = clang_getCursorKind(function.cursor);
64+
cursor_kind == CXCursor_CXXMethod
65+
}
66+
}
67+
}

‎src/clang_ql/matchers/mod.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,16 @@ use dyn_clone::DynClone;
22

33
use super::values::FunctionNode;
44

5+
mod function;
6+
pub use function::IsConstMethodMatcher;
7+
pub use function::IsDeletedMethodMatcher;
8+
pub use function::IsMethodMatcher;
9+
pub use function::IsPureVirtualMatcher;
10+
pub use function::IsStaticMethodMatcher;
11+
pub use function::IsVirtualMatcher;
12+
513
dyn_clone::clone_trait_object!(FunctionMatcher);
614

715
pub trait FunctionMatcher: DynClone {
8-
fn is_match(&self, function: FunctionNode) -> bool;
16+
fn is_match(&self, node: &FunctionNode) -> bool;
917
}

‎src/clang_ql/schema.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use gitql_std::aggregation::aggregation_functions;
1212
use gitql_std::window::window_function_signatures;
1313
use gitql_std::window::window_functions;
1414

15-
use super::functions::clang_ql_functions;
15+
use super::functions;
1616
use super::functions::clang_ql_functions_signatures;
1717
use super::types::FunctionType;
1818
use super::types::SourceLocType;
@@ -87,7 +87,7 @@ pub fn create_clang_ql_environment() -> Environment {
8787
};
8888

8989
let std_signatures = clang_ql_functions_signatures();
90-
let std_functions = clang_ql_functions();
90+
let std_functions = functions::clang_ql_functions();
9191

9292
let aggregation_signatures = aggregation_function_signatures();
9393
let aggregation_functions = aggregation_functions();

‎src/clang_ql/types/matcher.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use std::any::Any;
2+
3+
use gitql_ast::types::base::DataType;
4+
5+
#[derive(Clone)]
6+
pub struct FunctionMatcherType;
7+
8+
impl DataType for FunctionMatcherType {
9+
fn literal(&self) -> String {
10+
"FunctionMatcherType".to_string()
11+
}
12+
13+
#[allow(clippy::borrowed_box)]
14+
fn equals(&self, other: &Box<dyn DataType>) -> bool {
15+
let self_type: Box<dyn DataType> = Box::new(FunctionMatcherType);
16+
other.is_any()
17+
|| other.is_variant_contains(&self_type)
18+
|| other
19+
.as_any()
20+
.downcast_ref::<FunctionMatcherType>()
21+
.is_some()
22+
}
23+
24+
fn as_any(&self) -> &dyn Any {
25+
self
26+
}
27+
}

‎src/clang_ql/types/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ pub use source_location::SourceLocType;
33

44
mod function;
55
pub use function::FunctionType;
6+
7+
mod matcher;
8+
pub use matcher::FunctionMatcherType;

‎src/clang_ql/values/matcher.rs

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use gitql_core::values::base::Value;
2+
3+
use crate::clang_ql::matchers::FunctionMatcher;
4+
use crate::clang_ql::types::FunctionMatcherType;
5+
6+
#[derive(Clone)]
7+
pub struct FunctionMatcherValue {
8+
pub matcher: Box<dyn FunctionMatcher>,
9+
}
10+
11+
impl FunctionMatcherValue {
12+
pub fn new(matcher: Box<dyn FunctionMatcher>) -> Self {
13+
FunctionMatcherValue { matcher }
14+
}
15+
}
16+
17+
impl Value for FunctionMatcherValue {
18+
fn literal(&self) -> String {
19+
"FunctionMatcherValue".to_string()
20+
}
21+
22+
fn equals(&self, _other: &Box<dyn Value>) -> bool {
23+
false
24+
}
25+
26+
fn compare(&self, _other: &Box<dyn Value>) -> Option<std::cmp::Ordering> {
27+
None
28+
}
29+
30+
fn data_type(&self) -> Box<dyn gitql_ast::types::base::DataType> {
31+
Box::new(FunctionMatcherType)
32+
}
33+
34+
fn as_any(&self) -> &dyn std::any::Any {
35+
self
36+
}
37+
}

‎src/clang_ql/values/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ pub use source_location::SourceLocValue;
55
mod function;
66
pub use function::FunctionNode;
77
pub use function::FunctionValue;
8+
9+
mod matcher;
10+
pub use matcher::FunctionMatcherValue;

0 commit comments

Comments
 (0)
Please sign in to comment.