From 8bb69eb81ddf1fb90a47f02ee078da943438352c Mon Sep 17 00:00:00 2001
From: Jason Volk <jason@zemos.net>
Date: Thu, 25 Jul 2024 01:41:31 +0000
Subject: [PATCH] add simple ast dimension diagnostic

Signed-off-by: Jason Volk <jason@zemos.net>
---
 src/core/debug.rs   |  3 +++
 src/macros/debug.rs | 28 ++++++++++++++++++++++++++++
 src/macros/mod.rs   |  4 ++++
 3 files changed, 35 insertions(+)
 create mode 100644 src/macros/debug.rs

diff --git a/src/core/debug.rs b/src/core/debug.rs
index 5e52f399a..63f25d472 100644
--- a/src/core/debug.rs
+++ b/src/core/debug.rs
@@ -1,5 +1,8 @@
 use std::{any::Any, panic};
 
+/// Export debug proc_macros
+pub use conduit_macros::recursion_depth;
+
 /// Export all of the ancillary tools from here as well.
 pub use crate::utils::debug::*;
 
diff --git a/src/macros/debug.rs b/src/macros/debug.rs
new file mode 100644
index 000000000..5251fa179
--- /dev/null
+++ b/src/macros/debug.rs
@@ -0,0 +1,28 @@
+use std::cmp;
+
+use proc_macro::TokenStream;
+use syn::{parse_macro_input, AttributeArgs, Item};
+
+pub(super) fn recursion_depth(args: TokenStream, item_: TokenStream) -> TokenStream {
+	let item = item_.clone();
+	let item = parse_macro_input!(item as Item);
+	let _args = parse_macro_input!(args as AttributeArgs);
+
+	let mut best: usize = 0;
+	let mut count: usize = 0;
+	// think you'd find a fancy recursive ast visitor? think again
+	let tree = format!("{item:#?}");
+	for line in tree.lines() {
+		let trim = line.trim_start_matches(' ');
+		let diff = line.len().saturating_sub(trim.len());
+		let level = diff / 4;
+		best = cmp::max(level, best);
+		count = count.saturating_add(1);
+	}
+
+	println!("--- Recursion Diagnostic ---");
+	println!("DEPTH: {best}");
+	println!("LENGTH: {count}");
+
+	item_
+}
diff --git a/src/macros/mod.rs b/src/macros/mod.rs
index 94ea781e3..b01e5275a 100644
--- a/src/macros/mod.rs
+++ b/src/macros/mod.rs
@@ -1,5 +1,6 @@
 mod admin;
 mod cargo;
+mod debug;
 mod rustc;
 mod utils;
 
@@ -13,5 +14,8 @@ pub fn admin_command_dispatch(args: TokenStream, input: TokenStream) -> TokenStr
 #[proc_macro_attribute]
 pub fn cargo_manifest(args: TokenStream, input: TokenStream) -> TokenStream { cargo::manifest(args, input) }
 
+#[proc_macro_attribute]
+pub fn recursion_depth(args: TokenStream, input: TokenStream) -> TokenStream { debug::recursion_depth(args, input) }
+
 #[proc_macro]
 pub fn rustc_flags_capture(args: TokenStream) -> TokenStream { rustc::flags_capture(args) }
-- 
GitLab