use tree_sitter::{Language, Query, QueryError};
pub struct CppQueries {
pub classes: Query,
pub functions: Query,
pub calls: Query,
}
impl CppQueries {
pub fn new(language: &Language) -> Result<Self, QueryError> {
Ok(Self {
classes: Query::new(language, CLASS_QUERY)?,
functions: Query::new(language, FUNCTION_QUERY)?,
calls: Query::new(language, CALL_QUERY)?,
})
}
}
const CLASS_QUERY: &str = r"
; Class specifiers: class Foo { ... };
(class_specifier
name: (type_identifier) @class.name) @class
; Struct specifiers: struct Foo { ... };
(struct_specifier
name: (type_identifier) @class.name) @class
; Class specifier inside template declaration
(template_declaration
(class_specifier
name: (type_identifier) @class.name) @class) @template_class
; Struct specifier inside template declaration
(template_declaration
(struct_specifier
name: (type_identifier) @class.name) @class) @template_struct
";
const FUNCTION_QUERY: &str = r"
; Function definitions (free functions and methods)
(function_definition
declarator: (function_declarator
declarator: [(identifier) (field_identifier)] @func.name)) @func
; Methods declared inside classes/structs without inline bodies
(field_declaration
declarator: (function_declarator
declarator: [(field_identifier) (identifier)] @func.name)) @func
; Template function declarations
(template_declaration
(function_definition
declarator: (function_declarator
declarator: (identifier) @func.name)) @func) @template_func
";
const CALL_QUERY: &str = r"
[
; Direct function calls: foo()
(call_expression
function: (identifier) @call.name) @call
; Qualified/scoped function calls: std::move()
(call_expression
function: (qualified_identifier) @call.name) @call
; Member function calls: object.method()
(call_expression
function: (field_expression
field: [(field_identifier) (identifier)] @call.method)) @call
]
";
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_queries_compile() {
let language = tree_sitter_cpp::LANGUAGE.into();
let queries = CppQueries::new(&language);
assert!(queries.is_ok(), "Cpp queries should compile successfully");
}
#[test]
fn test_class_query_compiles() {
let language = tree_sitter_cpp::LANGUAGE.into();
let query = Query::new(&language, CLASS_QUERY);
assert!(query.is_ok(), "CLASS_QUERY should compile");
}
#[test]
fn test_function_query_compiles() {
let language = tree_sitter_cpp::LANGUAGE.into();
let query = Query::new(&language, FUNCTION_QUERY);
assert!(query.is_ok(), "FUNCTION_QUERY should compile");
}
#[test]
fn test_call_query_compiles() {
let language = tree_sitter_cpp::LANGUAGE.into();
let query = Query::new(&language, CALL_QUERY);
assert!(query.is_ok(), "CALL_QUERY should compile");
}
}