decy_debugger/
lib.rs

1//! Decy Interactive Debugger
2//!
3//! Deep integration with spydecy-debugger to provide introspective debugging
4//! capabilities for the Decy C-to-Rust transpiler.
5//!
6//! # Features
7//!
8//! - **C AST Visualization**: Display parsed C AST with colored tree view
9//! - **HIR Visualization**: Show High-level IR conversion from C
10//! - **Ownership Graph**: Visualize pointer ownership inference
11//! - **Dataflow Graph**: Display dataflow analysis results
12//! - **Step-through Debugging**: Step through transpilation pipeline
13//! - **Diff Viewer**: Compare input C vs output Rust
14//!
15//! # Architecture
16//!
17//! ```text
18//! C Source → Parser → AST → HIR → Analyzer → Codegen → Rust
19//!              ↓        ↓     ↓       ↓         ↓        ↓
20//!           [Debug] [Debug] [Debug] [Debug]  [Debug] [Debug]
21//! ```
22//!
23//! # Usage
24//!
25//! ```rust,no_run
26//! use decy_debugger::Debugger;
27//! use std::path::Path;
28//!
29//! # fn main() -> anyhow::Result<()> {
30//! let debugger = Debugger::new();
31//!
32//! // Visualize C AST
33//! let ast_output = debugger.visualize_c_ast(Path::new("example.c"))?;
34//! println!("{}", ast_output);
35//!
36//! // Show ownership graph
37//! let ownership_output = debugger.visualize_ownership(Path::new("example.c"))?;
38//! println!("{}", ownership_output);
39//! # Ok(())
40//! # }
41//! ```
42
43#![warn(missing_docs, clippy::all, clippy::pedantic)]
44#![deny(unsafe_code)]
45#![allow(
46    clippy::module_name_repetitions,
47    clippy::format_push_string,
48    clippy::str_to_string,
49    clippy::unwrap_used,
50    clippy::uninlined_format_args,
51    clippy::unnecessary_wraps,
52    clippy::too_many_lines
53)]
54
55pub mod step_debugger;
56pub mod visualize_ast;
57pub mod visualize_hir;
58pub mod visualize_ownership;
59
60use anyhow::Result;
61use std::path::Path;
62
63/// Main debugger interface for Decy transpiler
64///
65/// Provides introspective debugging capabilities by integrating with
66/// spydecy-debugger and adding C-specific visualizations.
67#[derive(Debug, Default)]
68pub struct Debugger {
69    /// Enable verbose output
70    pub verbose: bool,
71    /// Enable colored output (default: true)
72    pub colored: bool,
73}
74
75impl Debugger {
76    /// Create a new debugger instance
77    #[must_use]
78    pub fn new() -> Self {
79        Self {
80            verbose: false,
81            colored: true,
82        }
83    }
84
85    /// Visualize C AST from source file
86    ///
87    /// # Errors
88    ///
89    /// Returns an error if the file cannot be read or parsed
90    pub fn visualize_c_ast(&self, file_path: &Path) -> Result<String> {
91        visualize_ast::visualize_c_ast(file_path, self.colored)
92    }
93
94    /// Visualize HIR (High-level IR) conversion
95    ///
96    /// # Errors
97    ///
98    /// Returns an error if the file cannot be read, parsed, or converted to HIR
99    pub fn visualize_hir(&self, file_path: &Path) -> Result<String> {
100        visualize_hir::visualize_hir(file_path, self.colored)
101    }
102
103    /// Visualize ownership inference graph
104    ///
105    /// # Errors
106    ///
107    /// Returns an error if the file cannot be analyzed
108    pub fn visualize_ownership(&self, file_path: &Path) -> Result<String> {
109        visualize_ownership::visualize_ownership_graph(file_path, self.colored)
110    }
111
112    /// Step through transpilation pipeline interactively
113    ///
114    /// # Errors
115    ///
116    /// Returns an error if the pipeline cannot be initialized
117    pub fn step_through(&self, file_path: &Path) -> Result<()> {
118        step_debugger::interactive_step_through(file_path, self.verbose);
119        Ok(())
120    }
121}
122
123#[cfg(test)]
124mod tests {
125    use super::*;
126    use std::io::Write;
127    use tempfile::NamedTempFile;
128
129    #[test]
130    fn test_debugger_creation() {
131        let debugger = Debugger::new();
132        assert!(!debugger.verbose);
133        assert!(debugger.colored);
134    }
135
136    #[test]
137    fn test_visualize_simple_c_function() {
138        let debugger = Debugger::new();
139
140        let mut temp_file = NamedTempFile::new().unwrap();
141        writeln!(temp_file, "int add(int a, int b) {{ return a + b; }}").unwrap();
142
143        let result = debugger.visualize_c_ast(temp_file.path());
144        assert!(result.is_ok(), "Should visualize simple C function");
145
146        let output = result.unwrap();
147        assert!(output.contains("Function"), "Should contain Function node");
148        assert!(output.contains("add"), "Should contain function name");
149    }
150}