Skip to content

Commit

Permalink
macro helper
Browse files Browse the repository at this point in the history
  • Loading branch information
dcodesdev committed Jun 8, 2024
1 parent 337f0d6 commit 0cd3344
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 8 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 crates/syntest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ edition = "2021"

[dependencies]
anyhow = "1.0.86"
proc-macro2 = "1.0.85"
syn = { version = "2.0.66", features = ["full", "extra-traits"] }
66 changes: 58 additions & 8 deletions crates/syntest/src/mac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,42 @@ pub struct Mac {
file: Rc<syn::File>,
}

#[derive(Debug)]
pub struct MacroDetails {
pub name: String,
pub tokens: Vec<String>,
}

impl Mac {
pub fn new(file: Rc<syn::File>) -> Self {
Self { file }
}

pub fn check_println_usage(&self, fn_name: &str) -> bool {
let mut found = false;
pub fn macros(&self, fn_name: &str) -> Vec<MacroDetails> {
let mut macros = Vec::new();

self.func_stmts(fn_name, |_, stmt| {
if let Stmt::Macro(macro_stmt) = stmt {
let mac = &macro_stmt.mac;

if mac.path.segments.iter().any(|seg| seg.ident == "println") {
found = true;
}
mac.path.segments.iter().for_each(|seg| {
let macro_name = seg.ident.to_string();
let tokens = mac
.tokens
.clone()
.into_iter()
.map(|token| token.to_string())
.collect();

macros.push(MacroDetails {
name: macro_name,
tokens,
});
});
}
});

found
macros
}
}

Expand All @@ -41,7 +59,7 @@ mod tests {
use crate::Syntest;

#[test]
fn test_macro_usage() {
fn test_list_macros() {
let content = r#"
pub fn test_fn() {
let my_local_int = 42;
Expand All @@ -50,13 +68,45 @@ mod tests {
let re_assigned = my_local_int + another_local_int * 2 / 2 - 2;
println!("Result: {}", re_assigned);
println!("Second macro");
return re_assigned;
}
"#;

let mac = Syntest::from_code(content).unwrap().mac;

assert!(mac.check_println_usage("test_fn"));
let macros = mac.macros("test_fn");

assert_eq!(macros.len(), 2);

match &macros[..] {
[first, second] => {
// Testing the first one
assert_eq!(first.name, "println");
first
.tokens
.iter()
.enumerate()
.for_each(|(i, token)| match i {
0 => assert_eq!(token, "\"Result: {}\""),
1 => assert_eq!(token, ","),
2 => assert_eq!(token, "re_assigned"),
_ => panic!("Unexpected token"),
});

// Testing the second one
assert_eq!(second.name, "println");
second
.tokens
.iter()
.enumerate()
.for_each(|(i, token)| match i {
0 => assert_eq!(token, "\"Second macro\""),
_ => panic!("Unexpected token"),
});
}
_ => panic!("Expected two macros"),
}
}
}
21 changes: 21 additions & 0 deletions crates/syntest/src/var.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use proc_macro2::TokenTree;
use std::fmt::Display;

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -44,10 +45,30 @@ pub enum Value {
Float(f64),
Char(char),
Bool(bool),
Vec(Vec<Value>),
Closure,
Other,
}

impl From<TokenTree> for Value {
fn from(value: TokenTree) -> Self {
match value {
TokenTree::Group(group) => {
let mut tokens = Vec::new();

for token in group.stream() {
tokens.push(Value::from(token));
}

Value::Vec(tokens)
}
TokenTree::Ident(ident) => Value::Str(ident.to_string()),
TokenTree::Literal(lit) => Value::Str(lit.to_string()),
TokenTree::Punct(punct) => Value::Char(punct.as_char()),
}
}
}

impl LocalVariable {
pub fn is_used(&self) -> bool {
match self {
Expand Down

0 comments on commit 0cd3344

Please sign in to comment.