Skip to content

Commit

Permalink
Restructure the tables to allow more customizations
Browse files Browse the repository at this point in the history
  • Loading branch information
AmrDeveloper committed Jan 11, 2025
1 parent 9400824 commit 85cb18b
Show file tree
Hide file tree
Showing 15 changed files with 205 additions and 127 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ gitql-ast = "0.31.0"
gitql-parser = "0.34.0"
gitql-engine = "0.35.0"
clang-sys = "1.8.1"
dyn-clone = "1.0.17"
6 changes: 6 additions & 0 deletions docs/ASTFunctions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
### AST function node functions

| Function | Parameters | Return | Description |
| :-------------: | :----------------: | :----: | :----------------------------------: |
| is_virtual | (n : FunctionType) | Bool | True if the function is virtual |
| is_pure_virtual | (n : FunctionType) | Bool | True if the function is pure virtual |
50 changes: 3 additions & 47 deletions src/clang_ql/data_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::clang_ql::visitors::function;
use crate::clang_ql::visitors::global;
use crate::clang_ql::visitors::unions;

use super::values::FunctionValue;
use super::values::SourceLocValue;

pub struct ClangDataProvider {
Expand Down Expand Up @@ -238,58 +239,13 @@ fn select_functions(
continue;
}

if column_name == "args_count" {
values.push(Box::new(IntValue::new(function.arguments_count as i64)));
continue;
}

if column_name == "class_name" {
values.push(Box::new(TextValue::new(function.class_name.to_owned())));
continue;
}

if column_name == "return_type" {
values.push(Box::new(TextValue::new(function.return_type.to_owned())));
continue;
}

if column_name == "is_method" {
values.push(Box::new(BoolValue::new(function.is_method)));
continue;
}

if column_name == "is_virtual" {
values.push(Box::new(BoolValue::new(function.is_virtual)));
continue;
}

if column_name == "is_pure_virtual" {
values.push(Box::new(BoolValue::new(function.is_pure_virtual)));
continue;
}

if column_name == "is_static" {
values.push(Box::new(BoolValue::new(function.is_static)));
continue;
}

if column_name == "is_const" {
values.push(Box::new(BoolValue::new(function.is_const)));
continue;
}

if column_name == "has_template" {
values.push(Box::new(BoolValue::new(function.has_template)));
continue;
}

if column_name == "access_modifier" {
values.push(Box::new(IntValue::new(function.access_modifier as i64)));
continue;
}

if column_name == "is_variadic" {
values.push(Box::new(BoolValue::new(function.is_variadic)));
if column_name == "ast_function" {
values.push(Box::new(FunctionValue::new(function.clone())));
continue;
}

Expand Down
43 changes: 43 additions & 0 deletions src/clang_ql/functions/ast/functions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use std::collections::HashMap;

use clang_sys::clang_CXXMethod_isPureVirtual;
use clang_sys::clang_CXXMethod_isVirtual;
use gitql_ast::types::boolean::BoolType;
use gitql_core::signature::Signature;
use gitql_core::signature::StandardFunction;
use gitql_core::values::base::Value;
use gitql_core::values::boolean::BoolValue;

use crate::clang_ql::types::FunctionType;
use crate::clang_ql::values::FunctionValue;

#[inline(always)]
pub fn register_ast_function_functions(map: &mut HashMap<&'static str, StandardFunction>) {
map.insert("is_virtual", function_is_virtual);
map.insert("is_pure_virtual", is_pure_virtual);
}

#[inline(always)]
pub fn register_ast_function_signatures(map: &mut HashMap<&'static str, Signature>) {
map.insert(
"is_virtual",
Signature::with_return(Box::new(BoolType)).add_parameter(Box::new(FunctionType)),
);

map.insert(
"is_pure_virtual",
Signature::with_return(Box::new(BoolType)).add_parameter(Box::new(FunctionType)),
);
}

fn function_is_virtual(values: &[Box<dyn Value>]) -> Box<dyn Value> {
let ast_node = values[0].as_any().downcast_ref::<FunctionValue>().unwrap();
let is_virtual = unsafe { clang_CXXMethod_isVirtual(ast_node.node.cursor) != 0 };
Box::new(BoolValue::new(is_virtual))
}

fn is_pure_virtual(values: &[Box<dyn Value>]) -> Box<dyn Value> {
let ast_node = values[0].as_any().downcast_ref::<FunctionValue>().unwrap();
let is_virtual = unsafe { clang_CXXMethod_isPureVirtual(ast_node.node.cursor) != 0 };
Box::new(BoolValue::new(is_virtual))
}
18 changes: 18 additions & 0 deletions src/clang_ql/functions/ast/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
mod functions;
use functions::register_ast_function_functions;
use functions::register_ast_function_signatures;

use std::collections::HashMap;

use gitql_core::signature::Signature;
use gitql_core::signature::StandardFunction;

#[inline(always)]
pub fn register_ast_functions(map: &mut HashMap<&'static str, StandardFunction>) {
register_ast_function_functions(map);
}

#[inline(always)]
pub fn register_ast_signatures(map: &mut HashMap<&'static str, Signature>) {
register_ast_function_signatures(map);
}
26 changes: 26 additions & 0 deletions src/clang_ql/functions/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use std::collections::HashMap;
use std::sync::OnceLock;

use gitql_core::signature::Signature;
use gitql_core::signature::StandardFunction;
use gitql_std::standard::standard_function_signatures;
use gitql_std::standard::standard_functions;

mod ast;

#[inline(always)]
pub fn clang_ql_functions() -> &'static HashMap<&'static str, StandardFunction> {
static HASHMAP: OnceLock<HashMap<&'static str, StandardFunction>> = OnceLock::new();
HASHMAP.get_or_init(|| {
let mut map = standard_functions().to_owned();
ast::register_ast_functions(&mut map);
map
})
}

#[inline(always)]
pub fn clang_ql_functions_signatures() -> HashMap<&'static str, Signature> {
let mut map = standard_function_signatures().to_owned();
ast::register_ast_signatures(&mut map);
map
}
9 changes: 9 additions & 0 deletions src/clang_ql/matchers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use dyn_clone::DynClone;

use super::values::FunctionNode;

dyn_clone::clone_trait_object!(FunctionMatcher);

pub trait FunctionMatcher: DynClone {
fn is_match(&self, function: FunctionNode) -> bool;
}
2 changes: 2 additions & 0 deletions src/clang_ql/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pub mod clang_parser;
pub mod data_provider;
pub mod functions;
pub mod matchers;
pub mod schema;
pub mod types;
pub mod values;
Expand Down
32 changes: 7 additions & 25 deletions src/clang_ql/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,23 @@ use gitql_core::environment::Environment;
use gitql_core::schema::Schema;
use gitql_std::aggregation::aggregation_function_signatures;
use gitql_std::aggregation::aggregation_functions;
use gitql_std::standard::standard_function_signatures;
use gitql_std::standard::standard_functions;
use gitql_std::window::window_function_signatures;
use gitql_std::window::window_functions;

use super::functions::clang_ql_functions;
use super::functions::clang_ql_functions_signatures;
use super::types::FunctionType;
use super::types::SourceLocType;

fn tables_fields_types() -> HashMap<&'static str, Box<dyn DataType>> {
let mut map: HashMap<&'static str, Box<dyn DataType>> = HashMap::new();
map.insert("name", Box::new(TextType));
map.insert("type", Box::new(TextType));
map.insert("signature", Box::new(TextType));
map.insert("class_name", Box::new(TextType));
map.insert("ast_function", Box::new(FunctionType));

map.insert("access_modifier", Box::new(IntType));

map.insert("is_method", Box::new(BoolType));
map.insert("is_virtual", Box::new(BoolType));
map.insert("is_pure_virtual", Box::new(BoolType));
map.insert("is_static", Box::new(BoolType));
map.insert("is_const", Box::new(BoolType));
map.insert("is_variadic", Box::new(BoolType));
map.insert("is_volatile", Box::new(BoolType));
map.insert("is_struct", Box::new(BoolType));
map.insert("has_template", Box::new(BoolType));

map.insert("return_type", Box::new(TextType));
map.insert("type_literal", Box::new(TextType));
Expand All @@ -47,7 +39,6 @@ fn tables_fields_types() -> HashMap<&'static str, Box<dyn DataType>> {
map.insert("size", Box::new(IntType));
map.insert("align", Box::new(IntType));

// Source code location columns
map.insert("source_loc", Box::new(SourceLocType));
map
}
Expand Down Expand Up @@ -79,17 +70,8 @@ fn tables_fields_names() -> &'static HashMap<&'static str, Vec<&'static str>> {
vec![
"name",
"signature",
"args_count",
"return_type",
"class_name",
"is_method",
"is_virtual",
"is_pure_virtual",
"is_static",
"is_const",
"has_template",
"access_modifier",
"is_variadic",
"ast_function",
"source_loc",
],
);
Expand All @@ -104,8 +86,8 @@ pub fn create_clang_ql_environment() -> Environment {
tables_fields_types: tables_fields_types().to_owned(),
};

let std_signatures = standard_function_signatures();
let std_functions = standard_functions();
let std_signatures = clang_ql_functions_signatures();
let std_functions = clang_ql_functions();

let aggregation_signatures = aggregation_function_signatures();
let aggregation_functions = aggregation_functions();
Expand Down
24 changes: 24 additions & 0 deletions src/clang_ql/types/function.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use std::any::Any;

use gitql_ast::types::base::DataType;

#[derive(Clone)]
pub struct FunctionType;

impl DataType for FunctionType {
fn literal(&self) -> String {
"Function".to_string()
}

#[allow(clippy::borrowed_box)]
fn equals(&self, other: &Box<dyn DataType>) -> bool {
let self_type: Box<dyn DataType> = Box::new(FunctionType);
other.is_any()
|| other.is_variant_contains(&self_type)
|| other.as_any().downcast_ref::<FunctionType>().is_some()
}

fn as_any(&self) -> &dyn Any {
self
}
}
3 changes: 3 additions & 0 deletions src/clang_ql/types/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
mod source_location;
pub use source_location::SourceLocType;

mod function;
pub use function::FunctionType;
55 changes: 55 additions & 0 deletions src/clang_ql/values/function.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use clang_sys::CXCursor;
use gitql_core::values::base::Value;

use crate::clang_ql::types::FunctionType;

use super::FileLocation;

#[derive(Clone)]
pub struct FunctionNode {
pub name: String,
pub cursor: CXCursor,
pub parent: CXCursor,
pub signature: String,
pub return_type: String,
pub location: FileLocation,
}

#[derive(Clone)]
pub struct FunctionValue {
pub node: FunctionNode,
}

impl FunctionValue {
pub fn new(node: FunctionNode) -> Self {
FunctionValue { node }
}
}

impl Value for FunctionValue {
fn literal(&self) -> String {
self.node.signature.to_string()
}

fn equals(&self, other: &Box<dyn Value>) -> bool {
if let Some(other_fun) = other.as_any().downcast_ref::<FunctionValue>() {
return self.node.name.eq(&other_fun.node.name)
&& self.node.signature.eq(&other_fun.node.signature)
&& self.node.return_type.eq(&other_fun.node.return_type)
&& self.node.location.eq(&other_fun.node.location);
}
false
}

fn compare(&self, _other: &Box<dyn Value>) -> Option<std::cmp::Ordering> {
None
}

fn data_type(&self) -> Box<dyn gitql_ast::types::base::DataType> {
Box::new(FunctionType)
}

fn as_any(&self) -> &dyn std::any::Any {
self
}
}
4 changes: 4 additions & 0 deletions src/clang_ql/values/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
mod source_location;
pub use source_location::FileLocation;
pub use source_location::SourceLocValue;

mod function;
pub use function::FunctionNode;
pub use function::FunctionValue;
Loading

0 comments on commit 85cb18b

Please sign in to comment.