Skip to main content

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 { verbose: false, colored: true }
80    }
81
82    /// Visualize C AST from source file
83    ///
84    /// # Errors
85    ///
86    /// Returns an error if the file cannot be read or parsed
87    pub fn visualize_c_ast(&self, file_path: &Path) -> Result<String> {
88        visualize_ast::visualize_c_ast(file_path, self.colored)
89    }
90
91    /// Visualize HIR (High-level IR) conversion
92    ///
93    /// # Errors
94    ///
95    /// Returns an error if the file cannot be read, parsed, or converted to HIR
96    pub fn visualize_hir(&self, file_path: &Path) -> Result<String> {
97        visualize_hir::visualize_hir(file_path, self.colored)
98    }
99
100    /// Visualize ownership inference graph
101    ///
102    /// # Errors
103    ///
104    /// Returns an error if the file cannot be analyzed
105    pub fn visualize_ownership(&self, file_path: &Path) -> Result<String> {
106        visualize_ownership::visualize_ownership_graph(file_path, self.colored)
107    }
108
109    /// Step through transpilation pipeline interactively
110    ///
111    /// # Errors
112    ///
113    /// Returns an error if the pipeline cannot be initialized
114    pub fn step_through(&self, file_path: &Path) -> Result<()> {
115        step_debugger::interactive_step_through(file_path, self.verbose);
116        Ok(())
117    }
118}
119
120#[cfg(test)]
121mod tests {
122    use super::*;
123    use std::io::Write;
124    use tempfile::NamedTempFile;
125
126    #[test]
127    fn test_debugger_creation() {
128        let debugger = Debugger::new();
129        assert!(!debugger.verbose);
130        assert!(debugger.colored);
131    }
132
133    #[test]
134    fn test_visualize_simple_c_function() {
135        let debugger = Debugger::new();
136
137        let mut temp_file = NamedTempFile::new().unwrap();
138        writeln!(temp_file, "int add(int a, int b) {{ return a + b; }}").unwrap();
139
140        let result = debugger.visualize_c_ast(temp_file.path());
141        assert!(result.is_ok(), "Should visualize simple C function");
142
143        let output = result.unwrap();
144        assert!(output.contains("Function"), "Should contain Function node");
145        assert!(output.contains("add"), "Should contain function name");
146    }
147}
148
149#[cfg(test)]
150mod coverage_tests;
151
152#[cfg(test)]
153mod debugger_coverage_tests;