Skip to main content

depyler_core/
lib.rs

1//! # Depyler Core - Transpilation Engine
2//!
3//! Core transpilation engine for converting Python code to Rust and other targets.
4//!
5//! ## Overview
6//!
7//! This crate provides the fundamental transpilation pipeline that converts Python
8//! source code into target languages (Rust, Ruchy) while preserving semantics and
9//! ensuring memory safety.
10//!
11//! ## Example
12//!
13//! ```rust
14//! use depyler_core::DepylerPipeline;
15//!
16//! let pipeline = DepylerPipeline::new();
17//! let python = r#"
18//! def factorial(n: int) -> int:
19//!     if n <= 1:
20//!         return 1
21//!     return n * factorial(n - 1)
22//! "#;
23//!
24//! match pipeline.transpile(python) {
25//!     Ok(rust_code) => println!("Generated:\n{}", rust_code),
26//!     Err(e) => eprintln!("Error: {}", e),
27//! }
28//! ```
29//!
30//! ## Architecture
31//!
32//! The transpilation pipeline consists of several stages:
33//!
34//! 1. **Parsing** ([`ast_bridge`]) - Convert Python source to AST
35//! 2. **HIR** ([`hir`]) - Transform AST to High-level Intermediate Representation
36//! 3. **Type Analysis** ([`generic_inference`], [`const_generic_inference`]) - Infer types and generics
37//! 4. **Ownership Analysis** ([`borrowing`], [`lifetime_analysis`]) - Determine ownership patterns
38//! 5. **Optimization** ([`optimization`], [`string_optimization`]) - Apply optimizations
39//! 6. **Code Generation** ([`codegen`], [`rust_gen`]) - Generate target code
40//!
41//! ## Key Types
42//!
43//! - [`DepylerPipeline`] - Main entry point for transpilation
44//! - [`TranspileOptions`] - Configuration options
45//! - [`Hir`] - High-level intermediate representation
46//! - [`TranspilationBackend`] - Backend trait for target languages
47
48// Re-export macros from depyler-hir so `use crate::trace_decision` etc. continue to work
49pub use depyler_hir::trace_decision;
50pub use depyler_hir::emit_decision;
51pub use depyler_hir::transpile_error;
52pub use depyler_hir::transpile_bail;
53
54// Re-exports from depyler-hir
55pub use depyler_hir::decision_trace;
56pub use depyler_hir::error;
57pub use depyler_hir::hir;
58pub use depyler_hir::simplified_hir;
59
60// Re-exports from depyler-lambda
61pub use depyler_lambda::lambda_codegen;
62pub use depyler_lambda::lambda_errors;
63pub use depyler_lambda::lambda_inference;
64pub use depyler_lambda::lambda_optimizer;
65pub use depyler_lambda::lambda_testing;
66pub use depyler_lambda::lambda_types;
67
68// Re-exports from depyler-analysis
69pub use depyler_analysis::annotation_aware_type_mapper;
70pub use depyler_analysis::borrowing;
71pub use depyler_analysis::borrowing_context;
72pub use depyler_analysis::container_element_inference;
73pub use depyler_analysis::borrowing_shim;
74pub use depyler_analysis::const_generic_inference;
75pub use depyler_analysis::depylint;
76pub use depyler_analysis::error_reporting;
77pub use depyler_analysis::escape_analysis;
78pub use depyler_analysis::generator_state;
79pub use depyler_analysis::generator_yield_analysis;
80pub use depyler_analysis::generic_inference;
81pub use depyler_analysis::inlining;
82pub use depyler_analysis::lifetime_analysis;
83pub use depyler_analysis::migration_suggestions;
84pub use depyler_analysis::optimization;
85pub use depyler_analysis::optimizer;
86pub use depyler_analysis::param_type_inference;
87pub use depyler_analysis::performance_warnings;
88pub use depyler_analysis::profiling;
89pub use depyler_analysis::scoring;
90pub use depyler_analysis::string_optimization;
91pub use depyler_analysis::type_hints;
92pub use depyler_analysis::type_inference_telemetry;
93pub use depyler_analysis::type_mapper;
94pub use depyler_analysis::type_propagation;
95pub use depyler_analysis::type_system;
96
97// Re-exports from depyler-tooling
98pub use depyler_tooling::chaos;
99pub use depyler_tooling::codegen_shim;
100pub use depyler_tooling::debug;
101pub use depyler_tooling::doctest_extractor;
102pub use depyler_tooling::documentation;
103pub use depyler_tooling::generative_repair;
104pub use depyler_tooling::hunt_mode;
105pub use depyler_tooling::ide;
106pub use depyler_tooling::infrastructure;
107pub use depyler_tooling::library_mapping;
108pub use depyler_tooling::module_mapper;
109pub use depyler_tooling::module_mapper_phf;
110pub use depyler_tooling::pytest_extractor;
111pub use depyler_tooling::stdlib_mappings;
112pub use depyler_tooling::test_generation;
113pub use depyler_tooling::typeshed_ingest;
114
115// Modules that remain in depyler-core (codegen engine)
116pub mod ast_bridge;
117pub mod diagnostic;
118pub mod backend;
119pub mod cargo_first;
120pub mod cargo_toml_gen;
121pub mod codegen;
122pub mod direct_rules;
123mod direct_rules_convert; // DEPYLER-COVERAGE-95: Split from direct_rules.rs
124pub mod lsp;
125pub mod rust_gen;
126pub mod union_enum_gen;
127
128use anyhow::Result;
129use serde::{Deserialize, Serialize};
130
131// Re-export backend traits and types
132pub use backend::{TranspilationBackend, TranspilationTarget, ValidationError};
133pub use error::TranspileError;
134pub use simplified_hir::{
135    Hir, HirBinaryOp, HirExpr, HirLiteral, HirParam, HirStatement, HirType, HirUnaryOp,
136};
137
138/// The main transpilation pipeline for converting Python code to multiple targets
139///
140/// ## Version 3.0.0 - Multi-Target Support
141///
142/// Depyler now supports multiple transpilation targets through the `TranspilationBackend` trait:
143/// - **Rust** (default): Generates idiomatic, safe Rust code
144/// - **Ruchy**: Generates functional Ruchy script format with pipeline operators
145///
146/// ### Example Usage
147///
148/// ```rust
149/// use depyler_core::DepylerPipeline;
150/// # use anyhow::Result;
151/// # fn example() -> Result<()> {
152/// # let python_code = "def hello(): pass";
153///
154/// // Create pipeline and transpile to Rust (default)
155/// let pipeline = DepylerPipeline::new();
156/// let rust_code = pipeline.transpile(python_code)?;
157/// # Ok(())
158/// # }
159/// ```
160///
161/// `DepylerPipeline` coordinates the entire transpilation process, from parsing Python
162/// source code to generating equivalent Rust code. It provides a high-level API for
163/// transpilation with configurable analysis, optimization, and verification stages.
164///
165/// # Features
166///
167/// - **Semantic Analysis**: Converts Python AST to type-aware HIR
168/// - **Type Inference**: Infers and validates type information
169/// - **Optimization**: Applies performance optimizations
170/// - **Verification**: Optional property verification for correctness
171/// - **Code Generation**: Produces idiomatic Rust code
172///
173/// # Examples
174///
175/// Basic transpilation:
176///
177/// ```rust
178/// use depyler_core::DepylerPipeline;
179///
180/// let pipeline = DepylerPipeline::new();
181/// let python_code = r#"
182/// def add(a: int, b: int) -> int:
183///     return a + b
184/// "#;
185///
186/// let rust_code = pipeline.transpile(python_code).unwrap();
187/// assert!(rust_code.contains("pub fn add"));
188/// assert!(rust_code.contains("i32"));
189/// ```
190///
191/// With verification enabled:
192///
193/// ```rust
194/// use depyler_core::DepylerPipeline;
195///
196/// let pipeline = DepylerPipeline::new()
197///     .with_verification();
198///
199/// let python_code = r#"
200/// def factorial(n: int) -> int:
201///     if n <= 1:
202///         return 1
203///     return n * factorial(n - 1)
204/// "#;
205///
206/// let rust_code = pipeline.transpile(python_code).unwrap();
207/// assert!(rust_code.contains("factorial"));
208/// ```
209///
210/// Parsing to HIR for analysis:
211///
212/// ```rust
213/// use depyler_core::DepylerPipeline;
214///
215/// let pipeline = DepylerPipeline::new();
216/// let python_code = "def hello(): return 'world'";
217///
218/// let hir = pipeline.parse_to_hir(python_code).unwrap();
219/// assert_eq!(hir.functions.len(), 1);
220/// assert_eq!(hir.functions[0].name, "hello");
221/// ```
222#[derive(Debug, Clone, Serialize, Deserialize)]
223pub struct DepylerPipeline {
224    analyzer: CoreAnalyzer,
225    transpiler: DirectTranspiler,
226    #[serde(skip_serializing_if = "Option::is_none")]
227    verifier: Option<PropertyVerifier>,
228    #[serde(skip)]
229    #[allow(dead_code)]
230    mcp_client: LazyMcpClient,
231    #[serde(skip_serializing_if = "Option::is_none")]
232    debug_config: Option<debug::DebugConfig>,
233}
234
235#[derive(Debug, Clone, Serialize, Deserialize)]
236pub struct CoreAnalyzer {
237    pub metrics_enabled: bool,
238    pub type_inference_enabled: bool,
239}
240
241#[derive(Debug, Clone, Serialize, Deserialize)]
242pub struct DirectTranspiler {
243    pub type_mapper: type_mapper::TypeMapper,
244}
245
246#[derive(Debug, Clone, Serialize, Deserialize)]
247pub struct PropertyVerifier {
248    pub enable_quickcheck: bool,
249    pub enable_contracts: bool,
250}
251
252#[derive(Debug, Clone, Default)]
253pub struct LazyMcpClient {
254    #[allow(dead_code)]
255    endpoint: Option<String>,
256}
257
258pub trait AnalyzableStage {
259    type Input;
260    type Output;
261    type Metrics;
262
263    fn execute(&self, input: Self::Input) -> Result<(Self::Output, Self::Metrics)>;
264    fn validate(&self, output: &Self::Output) -> ValidationResult;
265}
266
267#[derive(Debug, Clone, Serialize, Deserialize)]
268pub struct ValidationResult {
269    pub is_valid: bool,
270    pub errors: Vec<String>,
271    pub warnings: Vec<String>,
272}
273
274impl Default for DepylerPipeline {
275    fn default() -> Self {
276        Self::new()
277    }
278}
279
280impl DepylerPipeline {
281    /// Creates a new transpilation pipeline with default configuration
282    ///
283    /// The default pipeline includes:
284    /// - Core semantic analysis and type inference
285    /// - Standard optimizations
286    /// - No property verification (use `with_verification()` to enable)
287    /// - No debug output
288    ///
289    /// # Examples
290    ///
291    /// ```rust
292    /// use depyler_core::DepylerPipeline;
293    ///
294    /// let pipeline = DepylerPipeline::new();
295    /// // Pipeline is ready for transpilation
296    /// ```
297    pub fn new() -> Self {
298        Self {
299            analyzer: CoreAnalyzer {
300                metrics_enabled: true,
301                type_inference_enabled: true,
302            },
303            transpiler: DirectTranspiler {
304                type_mapper: type_mapper::TypeMapper::default(),
305            },
306            verifier: None,
307            mcp_client: LazyMcpClient::default(),
308            debug_config: None,
309        }
310    }
311
312    pub fn with_verification(mut self) -> Self {
313        self.verifier = Some(PropertyVerifier {
314            enable_quickcheck: true,
315            enable_contracts: true,
316        });
317        self
318    }
319
320    pub fn with_debug(mut self, debug_config: debug::DebugConfig) -> Self {
321        self.debug_config = Some(debug_config);
322        self
323    }
324
325    /// DEPYLER-0426: Configure NASA mode (std-only compilation)
326    ///
327    /// When NASA mode is enabled (default), external crate references are replaced
328    /// with std-only equivalents for single-shot compilation compatibility.
329    /// When disabled, generates code that uses proper crate APIs (e.g., csv crate).
330    ///
331    /// # Arguments
332    ///
333    /// * `enabled` - Whether to enable NASA mode (default: true)
334    ///
335    /// # Examples
336    ///
337    /// ```rust
338    /// use depyler_core::DepylerPipeline;
339    ///
340    /// // Disable NASA mode to get csv crate output instead of std::io stubs
341    /// let pipeline = DepylerPipeline::new().with_nasa_mode(false);
342    /// ```
343    pub fn with_nasa_mode(mut self, enabled: bool) -> Self {
344        self.transpiler.type_mapper.nasa_mode = enabled;
345        self
346    }
347
348    /// Transpiles Python source code to equivalent Rust code
349    ///
350    /// This is the main entry point for transpilation. It performs the complete
351    /// pipeline: parsing, semantic analysis, type inference, optimization, and
352    /// code generation.
353    ///
354    /// # Arguments
355    ///
356    /// * `python_source` - The Python source code to transpile
357    ///
358    /// # Returns
359    ///
360    /// Returns the generated Rust code as a string, or an error if transpilation fails.
361    ///
362    /// # Examples
363    ///
364    /// Basic function transpilation:
365    ///
366    /// ```rust
367    /// use depyler_core::DepylerPipeline;
368    ///
369    /// let pipeline = DepylerPipeline::new();
370    /// let python_code = r#"
371    /// def multiply(x: int, y: int) -> int:
372    ///     return x * y
373    /// "#;
374    ///
375    /// let rust_code = pipeline.transpile(python_code).unwrap();
376    /// assert!(rust_code.contains("pub fn multiply"));
377    /// assert!(rust_code.contains("-> i32"));
378    /// ```
379    ///
380    /// Complex function with control flow:
381    ///
382    /// ```rust
383    /// use depyler_core::DepylerPipeline;
384    ///
385    /// let pipeline = DepylerPipeline::new();
386    /// let python_code = r#"
387    /// def is_even(n: int) -> bool:
388    ///     if n % 2 == 0:
389    ///         return True
390    ///     else:
391    ///         return False
392    /// "#;
393    ///
394    /// let rust_code = pipeline.transpile(python_code).unwrap();
395    /// assert!(rust_code.contains("pub fn is_even"));
396    /// assert!(rust_code.contains("bool")); // Changed to just check for bool type
397    /// ```
398    ///
399    /// # Errors
400    ///
401    /// Returns an error if:
402    /// - The Python source contains syntax errors
403    /// - Unsupported Python constructs are used
404    /// - Type inference fails
405    /// - Verification fails (if enabled)
406    ///
407    /// Transpiles Python source code and returns both Rust code and Cargo dependencies
408    ///
409    /// DEPYLER-0384: This method returns the generated Rust code along with the list
410    /// of Cargo dependencies needed to build it. Use this when you need to generate
411    /// a complete Cargo project with Cargo.toml.
412    ///
413    /// # Returns
414    ///
415    /// Returns a tuple of (rust_code, dependencies) or an error if transpilation fails.
416    pub fn transpile_with_dependencies(
417        &self,
418        python_source: &str,
419    ) -> Result<(String, Vec<cargo_toml_gen::Dependency>)> {
420        // Parse Python source
421        let ast = self.parse_python(python_source)?;
422
423        // Convert to HIR with annotation support
424        let (mut hir, _type_env) = ast_bridge::AstBridge::new()
425            .with_source(python_source.to_string())
426            .python_to_hir(ast)?;
427
428        // Apply const generic inference
429        let mut const_inferencer = const_generic_inference::ConstGenericInferencer::new();
430        const_inferencer.analyze_module(&mut hir)?;
431
432        // Apply type inference hints
433        if self.analyzer.type_inference_enabled {
434            let mut type_hint_provider = type_hints::TypeHintProvider::new();
435
436            // Analyze all functions and collect hints
437            let mut function_hints = Vec::new();
438            for (idx, func) in hir.functions.iter().enumerate() {
439                if let Ok(hints) = type_hint_provider.analyze_function(func) {
440                    if !hints.is_empty() {
441                        eprintln!("Type inference hints:");
442                        eprintln!("{}", type_hint_provider.format_hints(&hints));
443                        function_hints.push((idx, hints));
444                    }
445                }
446            }
447
448            // Apply high-confidence hints to the HIR
449            for (func_idx, hints) in function_hints {
450                let func = &mut hir.functions[func_idx];
451
452                // Apply parameter type hints
453                for param in &mut func.params {
454                    if matches!(param.ty, hir::Type::Unknown) {
455                        // Find hint for this parameter
456                        for hint in &hints {
457                            if let type_hints::HintTarget::Parameter(hint_param) = &hint.target {
458                                if hint_param == &param.name
459                                    && matches!(
460                                        hint.confidence,
461                                        type_hints::Confidence::High
462                                            | type_hints::Confidence::Certain
463                                    )
464                                {
465                                    param.ty = hint.suggested_type.clone();
466                                    eprintln!(
467                                        "Applied type hint: {} -> {:?}",
468                                        param.name, param.ty
469                                    );
470                                    break;
471                                }
472                            }
473                        }
474                    }
475                }
476
477                // Apply return type hints
478                // DEPYLER-0400: Accept Medium confidence for return types from explicit returns
479                if matches!(func.ret_type, hir::Type::Unknown) {
480                    for hint in &hints {
481                        if matches!(hint.target, type_hints::HintTarget::Return)
482                            && matches!(
483                                hint.confidence,
484                                type_hints::Confidence::Medium
485                                    | type_hints::Confidence::High
486                                    | type_hints::Confidence::Certain
487                            )
488                        {
489                            func.ret_type = hint.suggested_type.clone();
490                            eprintln!("Applied return type hint: {:?}", func.ret_type);
491                            break;
492                        }
493                    }
494                }
495            }
496        }
497
498        // DEPYLER-0575: Cross-function type propagation from call sites
499        type_propagation::propagate_call_site_types(&mut hir);
500
501        // DEPYLER-0202: Constraint-based type inference via Hindley-Milner
502        // Collect constraints from HIR and solve for unknown types
503        {
504            use type_system::{ConstraintCollector, TypeConstraintSolver};
505
506            let mut collector = ConstraintCollector::new();
507            collector.collect_module(&hir);
508
509            let constraints = collector.constraints();
510            if !constraints.is_empty() {
511                let mut solver = TypeConstraintSolver::new();
512                for constraint in constraints {
513                    solver.add_constraint(constraint.clone());
514                }
515
516                if let Ok(solution) = solver.solve() {
517                    let applied = collector.apply_substitutions(&mut hir, &solution);
518                    if applied > 0 {
519                        eprintln!("HM inference: applied {} type substitutions", applied);
520                    }
521                }
522            }
523        }
524
525        // DEPYLER-0950: Inter-procedural type unification
526        // Builds call graph and propagates types across function boundaries
527        if let Err(e) = type_system::unify_module_types(&mut hir) {
528            // Log but don't fail - type conflicts are informational
529            eprintln!("Type unification warning: {:?}", e);
530        }
531
532        // Apply optimization passes based on annotations
533        optimization::optimize_module(&mut hir);
534
535        // Convert HirModule to HirProgram for the new optimizer
536        let hir_program = hir::HirProgram {
537            functions: hir.functions,
538            classes: hir.classes,
539            imports: hir.imports,
540        };
541
542        // Apply the new general-purpose optimizer
543        let mut optimizer = optimizer::Optimizer::new(optimizer::OptimizerConfig::default());
544        let optimized_program = optimizer.optimize_program(hir_program.clone());
545
546        // Run migration suggestions analysis
547        if self.analyzer.metrics_enabled {
548            let mut migration_analyzer = migration_suggestions::MigrationAnalyzer::new(
549                migration_suggestions::MigrationConfig::default(),
550            );
551            let suggestions = migration_analyzer.analyze_program(&hir_program);
552            if !suggestions.is_empty() {
553                eprintln!("{}", migration_analyzer.format_suggestions(&suggestions));
554            }
555        }
556
557        // Run performance warnings analysis
558        if self.analyzer.metrics_enabled {
559            let mut perf_analyzer = performance_warnings::PerformanceAnalyzer::new(
560                performance_warnings::PerformanceConfig::default(),
561            );
562            let warnings = perf_analyzer.analyze_program(&hir_program);
563            if !warnings.is_empty() {
564                eprintln!("{}", perf_analyzer.format_warnings(&warnings));
565            }
566        }
567
568        // Run profiling analysis if enabled
569        if self.analyzer.metrics_enabled {
570            let mut profiler = profiling::Profiler::new(profiling::ProfileConfig::default());
571            let profile_report = profiler.analyze_program(&hir_program);
572            if !profile_report.metrics.is_empty() {
573                eprintln!("{}", profile_report.format_report());
574            }
575        }
576
577        // Convert back to HirModule
578        let optimized_hir = hir::HirModule {
579            functions: optimized_program.functions,
580            imports: optimized_program.imports,
581            type_aliases: hir.type_aliases,
582            protocols: hir.protocols,
583            classes: optimized_program.classes,
584            constants: hir.constants,
585            top_level_stmts: hir.top_level_stmts, // DEPYLER-1216: Preserve top-level statements
586        };
587
588        // Generate Rust code with dependencies
589        rust_gen::generate_rust_file(&optimized_hir, &self.transpiler.type_mapper)
590    }
591
592    pub fn transpile(&self, python_source: &str) -> Result<String> {
593        // Parse Python source
594        let ast = self.parse_python(python_source)?;
595
596        // Convert to HIR with annotation support
597        let (mut hir, _type_env) = ast_bridge::AstBridge::new()
598            .with_source(python_source.to_string())
599            .python_to_hir(ast)?;
600
601        // Apply const generic inference
602        let mut const_inferencer = const_generic_inference::ConstGenericInferencer::new();
603        const_inferencer.analyze_module(&mut hir)?;
604
605        // Apply type inference hints
606        if self.analyzer.type_inference_enabled {
607            let mut type_hint_provider = type_hints::TypeHintProvider::new();
608
609            // Analyze all functions and collect hints
610            let mut function_hints = Vec::new();
611            for (idx, func) in hir.functions.iter().enumerate() {
612                if let Ok(hints) = type_hint_provider.analyze_function(func) {
613                    if !hints.is_empty() {
614                        eprintln!("Type inference hints:");
615                        eprintln!("{}", type_hint_provider.format_hints(&hints));
616                        function_hints.push((idx, hints));
617                    }
618                }
619            }
620
621            // Apply high-confidence hints to the HIR
622            for (func_idx, hints) in function_hints {
623                let func = &mut hir.functions[func_idx];
624
625                // Apply parameter type hints
626                for param in &mut func.params {
627                    if matches!(param.ty, hir::Type::Unknown) {
628                        // Find hint for this parameter
629                        for hint in &hints {
630                            if let type_hints::HintTarget::Parameter(hint_param) = &hint.target {
631                                if hint_param == &param.name
632                                    && matches!(
633                                        hint.confidence,
634                                        type_hints::Confidence::High
635                                            | type_hints::Confidence::Certain
636                                    )
637                                {
638                                    param.ty = hint.suggested_type.clone();
639                                    eprintln!(
640                                        "Applied type hint: {} -> {:?}",
641                                        param.name, param.ty
642                                    );
643                                    break;
644                                }
645                            }
646                        }
647                    }
648                }
649
650                // Apply return type hints
651                // DEPYLER-0400: Accept Medium confidence for return types from explicit returns
652                if matches!(func.ret_type, hir::Type::Unknown) {
653                    for hint in &hints {
654                        if matches!(hint.target, type_hints::HintTarget::Return)
655                            && matches!(
656                                hint.confidence,
657                                type_hints::Confidence::Medium
658                                    | type_hints::Confidence::High
659                                    | type_hints::Confidence::Certain
660                            )
661                        {
662                            func.ret_type = hint.suggested_type.clone();
663                            eprintln!("Applied return type hint: {:?}", func.ret_type);
664                            break;
665                        }
666                    }
667                }
668            }
669        }
670
671        // DEPYLER-0575: Cross-function type propagation from call sites
672        type_propagation::propagate_call_site_types(&mut hir);
673
674        // DEPYLER-0202: Constraint-based type inference via Hindley-Milner
675        // Collect constraints from HIR and solve for unknown types
676        {
677            use type_system::{ConstraintCollector, TypeConstraintSolver};
678
679            let mut collector = ConstraintCollector::new();
680            collector.collect_module(&hir);
681
682            let constraints = collector.constraints();
683            if !constraints.is_empty() {
684                let mut solver = TypeConstraintSolver::new();
685                for constraint in constraints {
686                    solver.add_constraint(constraint.clone());
687                }
688
689                if let Ok(solution) = solver.solve() {
690                    let applied = collector.apply_substitutions(&mut hir, &solution);
691                    if applied > 0 {
692                        eprintln!("HM inference: applied {} type substitutions", applied);
693                    }
694                }
695            }
696        }
697
698        // DEPYLER-0950: Inter-procedural type unification
699        // Builds call graph and propagates types across function boundaries
700        if let Err(e) = type_system::unify_module_types(&mut hir) {
701            // Log but don't fail - type conflicts are informational
702            eprintln!("Type unification warning: {:?}", e);
703        }
704
705        // Apply optimization passes based on annotations
706        optimization::optimize_module(&mut hir);
707
708        // Convert HirModule to HirProgram for the new optimizer
709        let hir_program = hir::HirProgram {
710            functions: hir.functions,
711            classes: hir.classes,
712            imports: hir.imports,
713        };
714
715        // Apply the new general-purpose optimizer
716        let mut optimizer = optimizer::Optimizer::new(optimizer::OptimizerConfig::default());
717        let optimized_program = optimizer.optimize_program(hir_program.clone());
718
719        // Run migration suggestions analysis
720        if self.analyzer.metrics_enabled {
721            let mut migration_analyzer = migration_suggestions::MigrationAnalyzer::new(
722                migration_suggestions::MigrationConfig::default(),
723            );
724            let suggestions = migration_analyzer.analyze_program(&hir_program);
725            if !suggestions.is_empty() {
726                eprintln!("{}", migration_analyzer.format_suggestions(&suggestions));
727            }
728        }
729
730        // Run performance warnings analysis
731        if self.analyzer.metrics_enabled {
732            let mut perf_analyzer = performance_warnings::PerformanceAnalyzer::new(
733                performance_warnings::PerformanceConfig::default(),
734            );
735            let warnings = perf_analyzer.analyze_program(&hir_program);
736            if !warnings.is_empty() {
737                eprintln!("{}", perf_analyzer.format_warnings(&warnings));
738            }
739        }
740
741        // Run profiling analysis if enabled
742        if self.analyzer.metrics_enabled {
743            let mut profiler = profiling::Profiler::new(profiling::ProfileConfig::default());
744            let profile_report = profiler.analyze_program(&hir_program);
745            if !profile_report.metrics.is_empty() {
746                eprintln!("{}", profile_report.format_report());
747            }
748        }
749
750        // Convert back to HirModule
751        let optimized_hir = hir::HirModule {
752            functions: optimized_program.functions,
753            imports: optimized_program.imports,
754            type_aliases: hir.type_aliases,
755            protocols: hir.protocols,
756            classes: optimized_program.classes,
757            constants: hir.constants,
758            top_level_stmts: hir.top_level_stmts, // DEPYLER-1216: Preserve top-level statements
759        };
760
761        // Generate Rust code using the unified generation system
762        // DEPYLER-0384: generate_rust_file now returns (code, dependencies)
763        let (rust_code, _dependencies) =
764            rust_gen::generate_rust_file(&optimized_hir, &self.transpiler.type_mapper)?;
765
766        Ok(rust_code)
767    }
768
769    /// DEPYLER-1102: Transpile with oracle-learned type constraints and return dependencies
770    ///
771    /// This method is the constraint-aware version of `transpile_with_dependencies`.
772    /// It is used by the Oracle Loop in `compile_cmd.rs` to re-transpile code with
773    /// learned type corrections while still generating the necessary Cargo dependencies.
774    pub fn transpile_with_constraints_and_dependencies(
775        &self,
776        python_source: &str,
777        type_constraints: &std::collections::HashMap<String, String>,
778    ) -> Result<(String, Vec<cargo_toml_gen::Dependency>)> {
779        // Convert string type constraints to HIR Types
780        let type_overrides: std::collections::HashMap<String, hir::Type> = type_constraints
781            .iter()
782            .map(|(var, ty_str)| (var.clone(), rust_gen::rust_type_string_to_hir(ty_str)))
783            .collect();
784
785        // Parse Python source
786        let ast = self.parse_python(python_source)?;
787
788        // Convert to HIR with annotation support
789        let (mut hir, _type_env) = ast_bridge::AstBridge::new()
790            .with_source(python_source.to_string())
791            .python_to_hir(ast)?;
792
793        // DEPYLER-1101: Apply type overrides to HIR
794        // Override function return types and variable types based on constraints
795        for func in &mut hir.functions {
796            // Check if function name is in overrides
797            if let Some(override_type) = type_overrides.get(&func.name) {
798                if !matches!(override_type, hir::Type::Unknown) {
799                    eprintln!(
800                        "DEPYLER-1101: Overriding return type of {} to {:?}",
801                        func.name, override_type
802                    );
803                    func.ret_type = override_type.clone();
804                }
805            }
806
807            // Override parameter types
808            for param in func.params.iter_mut() {
809                if let Some(override_type) = type_overrides.get(&param.name) {
810                    if !matches!(override_type, hir::Type::Unknown) {
811                        eprintln!(
812                            "DEPYLER-1101: Overriding param {} type to {:?}",
813                            param.name, override_type
814                        );
815                        param.ty = override_type.clone();
816                    }
817                }
818            }
819        }
820
821        // Apply standard type inference and optimization passes
822        let mut const_inferencer = const_generic_inference::ConstGenericInferencer::new();
823        const_inferencer.analyze_module(&mut hir)?;
824
825        // Apply type inference hints (same as transpile)
826        if self.analyzer.type_inference_enabled {
827            let mut type_hint_provider = type_hints::TypeHintProvider::new();
828
829            // Collect hints first (immutable borrow)
830            let mut function_hints: Vec<(usize, Vec<type_hints::TypeHint>)> = Vec::new();
831            for (idx, func) in hir.functions.iter().enumerate() {
832                if let Ok(hints) = type_hint_provider.analyze_function(func) {
833                    if !hints.is_empty() {
834                        function_hints.push((idx, hints));
835                    }
836                }
837            }
838
839            // Apply hints (mutable borrow)
840            for (func_idx, hints) in function_hints {
841                let func = &mut hir.functions[func_idx];
842                for param in &mut func.params {
843                    if matches!(param.ty, hir::Type::Unknown)
844                        && !type_overrides.contains_key(&param.name)
845                    {
846                        for hint in &hints {
847                            if let type_hints::HintTarget::Parameter(hint_param) = &hint.target {
848                                if hint_param == &param.name
849                                    && matches!(
850                                        hint.confidence,
851                                        type_hints::Confidence::High
852                                            | type_hints::Confidence::Certain
853                                    )
854                                {
855                                    param.ty = hint.suggested_type.clone();
856                                    break;
857                                }
858                            }
859                        }
860                    }
861                }
862            }
863        }
864
865        // Cross-function type propagation
866        type_propagation::propagate_call_site_types(&mut hir);
867
868        // Hindley-Milner type inference
869        {
870            use type_system::{ConstraintCollector, TypeConstraintSolver};
871
872            let mut collector = ConstraintCollector::new();
873            collector.collect_module(&hir);
874
875            let constraints = collector.constraints();
876            if !constraints.is_empty() {
877                let mut solver = TypeConstraintSolver::new();
878                for constraint in constraints {
879                    solver.add_constraint(constraint.clone());
880                }
881
882                if let Ok(solution) = solver.solve() {
883                    let _applied = collector.apply_substitutions(&mut hir, &solution);
884                }
885            }
886        }
887
888        // Inter-procedural type unification
889        if let Err(e) = type_system::unify_module_types(&mut hir) {
890            eprintln!("Type unification warning: {:?}", e);
891        }
892
893        // Apply optimization passes
894        optimization::optimize_module(&mut hir);
895
896        // Generate Rust code with type overrides
897        // DEPYLER-1102: Uses generate_rust_file_with_overrides which returns (code, deps)
898        rust_gen::generate_rust_file_with_overrides(
899            &hir,
900            &self.transpiler.type_mapper,
901            type_overrides,
902        )
903    }
904
905    /// DEPYLER-1101: Transpile with oracle-learned type constraints
906    ///
907    /// This method accepts a map of variable names to their corrected types,
908    /// learned from E0308 compiler error feedback. During code generation,
909    /// these types override the inferred types for the specified variables.
910    ///
911    /// # Arguments
912    /// * `python_source` - The Python source code to transpile
913    /// * `type_constraints` - Map of variable name → corrected Rust type string
914    ///   (e.g., "result" → "f64", "items" → "Vec<String>")
915    ///
916    /// # Returns
917    /// Returns the generated Rust code, or an error.
918    ///
919    /// # Example
920    /// ```ignore
921    /// use depyler_core::DepylerPipeline;
922    /// use std::collections::HashMap;
923    ///
924    /// let pipeline = DepylerPipeline::new();
925    /// let mut constraints = HashMap::new();
926    /// constraints.insert("x".to_string(), "f64".to_string());
927    ///
928    /// let rust_code = pipeline.transpile_with_constraints(
929    ///     "def foo(x): return x * 2",
930    ///     &constraints
931    /// ).unwrap();
932    /// ```
933    pub fn transpile_with_constraints(
934        &self,
935        python_source: &str,
936        type_constraints: &std::collections::HashMap<String, String>,
937    ) -> Result<String> {
938        // Convert string type constraints to HIR Types
939        let type_overrides: std::collections::HashMap<String, hir::Type> = type_constraints
940            .iter()
941            .map(|(var, ty_str)| (var.clone(), rust_gen::rust_type_string_to_hir(ty_str)))
942            .collect();
943
944        // Parse Python source
945        let ast = self.parse_python(python_source)?;
946
947        // Convert to HIR with annotation support
948        let (mut hir, _type_env) = ast_bridge::AstBridge::new()
949            .with_source(python_source.to_string())
950            .python_to_hir(ast)?;
951
952        // DEPYLER-1101: Apply type overrides to HIR
953        // Override function return types and variable types based on constraints
954        for func in &mut hir.functions {
955            // Check if function name is in overrides
956            if let Some(override_type) = type_overrides.get(&func.name) {
957                if !matches!(override_type, hir::Type::Unknown) {
958                    eprintln!(
959                        "DEPYLER-1101: Overriding return type of {} to {:?}",
960                        func.name, override_type
961                    );
962                    func.ret_type = override_type.clone();
963                }
964            }
965
966            // Override parameter types
967            for param in func.params.iter_mut() {
968                if let Some(override_type) = type_overrides.get(&param.name) {
969                    if !matches!(override_type, hir::Type::Unknown) {
970                        eprintln!(
971                            "DEPYLER-1101: Overriding param {} type to {:?}",
972                            param.name, override_type
973                        );
974                        param.ty = override_type.clone();
975                    }
976                }
977            }
978        }
979
980        // Apply standard type inference and optimization passes
981        let mut const_inferencer = const_generic_inference::ConstGenericInferencer::new();
982        const_inferencer.analyze_module(&mut hir)?;
983
984        // Apply type inference hints
985        if self.analyzer.type_inference_enabled {
986            let mut type_hint_provider = type_hints::TypeHintProvider::new();
987
988            // Collect hints first (immutable borrow)
989            let mut function_hints: Vec<(usize, Vec<type_hints::TypeHint>)> = Vec::new();
990            for (idx, func) in hir.functions.iter().enumerate() {
991                if let Ok(hints) = type_hint_provider.analyze_function(func) {
992                    if !hints.is_empty() {
993                        function_hints.push((idx, hints));
994                    }
995                }
996            }
997
998            // Apply hints (mutable borrow)
999            for (func_idx, hints) in function_hints {
1000                let func = &mut hir.functions[func_idx];
1001                for param in &mut func.params {
1002                    // Only apply hints to types not already overridden
1003                    if matches!(param.ty, hir::Type::Unknown)
1004                        && !type_overrides.contains_key(&param.name)
1005                    {
1006                        for hint in &hints {
1007                            if let type_hints::HintTarget::Parameter(hint_param) = &hint.target {
1008                                if hint_param == &param.name
1009                                    && matches!(
1010                                        hint.confidence,
1011                                        type_hints::Confidence::High
1012                                            | type_hints::Confidence::Certain
1013                                    )
1014                                {
1015                                    param.ty = hint.suggested_type.clone();
1016                                    break;
1017                                }
1018                            }
1019                        }
1020                    }
1021                }
1022            }
1023        }
1024
1025        // Cross-function type propagation
1026        type_propagation::propagate_call_site_types(&mut hir);
1027
1028        // Hindley-Milner type inference
1029        {
1030            use type_system::{ConstraintCollector, TypeConstraintSolver};
1031
1032            let mut collector = ConstraintCollector::new();
1033            collector.collect_module(&hir);
1034
1035            let constraints = collector.constraints();
1036            if !constraints.is_empty() {
1037                let mut solver = TypeConstraintSolver::new();
1038                for constraint in constraints {
1039                    solver.add_constraint(constraint.clone());
1040                }
1041
1042                if let Ok(solution) = solver.solve() {
1043                    let _applied = collector.apply_substitutions(&mut hir, &solution);
1044                }
1045            }
1046        }
1047
1048        // Inter-procedural type unification
1049        if let Err(e) = type_system::unify_module_types(&mut hir) {
1050            eprintln!("Type unification warning: {:?}", e);
1051        }
1052
1053        // Apply optimization passes
1054        optimization::optimize_module(&mut hir);
1055
1056        // Generate Rust code with type overrides
1057        let (rust_code, _dependencies) = rust_gen::generate_rust_file_with_overrides(
1058            &hir,
1059            &self.transpiler.type_mapper,
1060            type_overrides,
1061        )?;
1062
1063        Ok(rust_code)
1064    }
1065
1066    pub fn parse_to_hir(&self, source: &str) -> Result<hir::HirModule> {
1067        let ast = self.parse_python(source)?;
1068        let (hir, _type_env) = ast_bridge::AstBridge::new()
1069            .with_source(source.to_string())
1070            .python_to_hir(ast)?;
1071        Ok(hir)
1072    }
1073
1074    pub fn analyze_to_typed_hir(&self, source: &str) -> Result<hir::HirModule> {
1075        // For now, just return the HIR without type analysis
1076        // In the future, this would add type inference
1077        self.parse_to_hir(source)
1078    }
1079
1080    pub fn parse_python(&self, source: &str) -> Result<rustpython_ast::Mod> {
1081        use rustpython_ast::Suite;
1082        use rustpython_parser::Parse;
1083
1084        let statements = Suite::parse(source, "<input>")
1085            .map_err(|e| anyhow::anyhow!("Python parse error: {}", e))?;
1086
1087        Ok(rustpython_ast::Mod::Module(rustpython_ast::ModModule {
1088            body: statements,
1089            type_ignores: vec![],
1090            range: Default::default(),
1091        }))
1092    }
1093}
1094
1095#[derive(Debug, Clone, Default)]
1096pub struct Config {
1097    pub enable_verification: bool,
1098    pub enable_metrics: bool,
1099    pub optimization_level: OptimizationLevel,
1100}
1101
1102#[derive(Debug, Clone, Default)]
1103pub enum OptimizationLevel {
1104    #[default]
1105    Debug,
1106    Release,
1107    Size,
1108}
1109
1110impl DepylerPipeline {
1111    pub fn new_with_config(config: Config) -> Self {
1112        let mut pipeline = Self::new();
1113        pipeline.analyzer.metrics_enabled = config.enable_metrics;
1114
1115        if config.enable_verification {
1116            pipeline = pipeline.with_verification();
1117        }
1118
1119        pipeline
1120    }
1121}
1122
1123#[cfg(test)]
1124mod tests {
1125    use super::*;
1126
1127    #[test]
1128    fn test_pipeline_creation() {
1129        let pipeline = DepylerPipeline::new();
1130        assert!(pipeline.analyzer.metrics_enabled);
1131        assert!(pipeline.analyzer.type_inference_enabled);
1132        assert!(pipeline.verifier.is_none());
1133    }
1134
1135    #[test]
1136    fn test_pipeline_with_verification() {
1137        let pipeline = DepylerPipeline::new().with_verification();
1138        assert!(pipeline.verifier.is_some());
1139        let verifier = pipeline.verifier.unwrap();
1140        assert!(verifier.enable_quickcheck);
1141        assert!(verifier.enable_contracts);
1142    }
1143
1144    #[test]
1145    fn test_config_creation() {
1146        let config = Config {
1147            enable_verification: true,
1148            enable_metrics: false,
1149            optimization_level: OptimizationLevel::Release,
1150        };
1151
1152        let pipeline = DepylerPipeline::new_with_config(config);
1153        assert!(pipeline.verifier.is_some());
1154        assert!(!pipeline.analyzer.metrics_enabled);
1155    }
1156
1157    #[test]
1158    fn test_simple_transpilation() {
1159        let pipeline = DepylerPipeline::new();
1160        let python_code = r#"
1161def add(a: int, b: int) -> int:
1162    return a + b
1163"#;
1164
1165        let result = pipeline.transpile(python_code);
1166        assert!(result.is_ok());
1167        let rust_code = result.unwrap();
1168        assert!(rust_code.contains("pub fn add"));
1169        assert!(rust_code.contains("i32"));
1170    }
1171
1172    #[test]
1173    fn test_parse_to_hir() {
1174        let pipeline = DepylerPipeline::new();
1175        let python_code = r#"
1176def test_func(x: int) -> str:
1177    return "hello"
1178"#;
1179
1180        let hir = pipeline.parse_to_hir(python_code).unwrap();
1181        assert_eq!(hir.functions.len(), 1);
1182        assert_eq!(hir.functions[0].name, "test_func");
1183        assert_eq!(hir.functions[0].params[0].name, "x");
1184        assert_eq!(hir.functions[0].params[0].ty, hir::Type::Int);
1185        assert_eq!(hir.functions[0].ret_type, hir::Type::String);
1186    }
1187
1188    #[test]
1189    fn test_validation_result() {
1190        let result = ValidationResult {
1191            is_valid: true,
1192            errors: vec![],
1193            warnings: vec!["Warning message".to_string()],
1194        };
1195
1196        assert!(result.is_valid);
1197        assert!(result.errors.is_empty());
1198        assert_eq!(result.warnings.len(), 1);
1199    }
1200
1201    #[test]
1202    fn test_invalid_python_syntax() {
1203        let pipeline = DepylerPipeline::new();
1204        let invalid_python = "def invalid_syntax(\n    return";
1205
1206        let result = pipeline.transpile(invalid_python);
1207        assert!(result.is_err());
1208    }
1209
1210    #[test]
1211    fn test_analyzable_stage_trait() {
1212        // Test that the trait is properly defined
1213        struct TestStage;
1214
1215        impl AnalyzableStage for TestStage {
1216            type Input = String;
1217            type Output = String;
1218            type Metrics = usize;
1219
1220            fn execute(&self, input: Self::Input) -> Result<(Self::Output, Self::Metrics)> {
1221                Ok((input.clone(), input.len()))
1222            }
1223
1224            fn validate(&self, _output: &Self::Output) -> ValidationResult {
1225                ValidationResult {
1226                    is_valid: true,
1227                    errors: vec![],
1228                    warnings: vec![],
1229                }
1230            }
1231        }
1232
1233        let stage = TestStage;
1234        let (output, metrics) = stage.execute("test".to_string()).unwrap();
1235        assert_eq!(output, "test");
1236        assert_eq!(metrics, 4);
1237
1238        let validation = stage.validate(&output);
1239        assert!(validation.is_valid);
1240    }
1241
1242    #[test]
1243    fn test_complex_function_transpilation() {
1244        let pipeline = DepylerPipeline::new();
1245        let python_code = r#"
1246def fibonacci(n: int) -> int:
1247    if n <= 1:
1248        return n
1249    return fibonacci(n - 1) + fibonacci(n - 2)
1250"#;
1251
1252        let result = pipeline.transpile(python_code);
1253        assert!(result.is_ok());
1254        let rust_code = result.unwrap();
1255        assert!(rust_code.contains("fibonacci"));
1256        assert!(rust_code.contains("if"));
1257        assert!(rust_code.contains("return"));
1258    }
1259
1260    #[test]
1261    fn test_type_annotations() {
1262        let pipeline = DepylerPipeline::new();
1263        let python_code = r#"
1264from typing import List, Optional
1265
1266def process_list(items: List[str]) -> Optional[str]:
1267    if items:
1268        return items[0]
1269    return None
1270"#;
1271
1272        let hir = pipeline.parse_to_hir(python_code).unwrap();
1273        assert_eq!(hir.functions.len(), 1);
1274        let func = &hir.functions[0];
1275        assert_eq!(
1276            func.params[0].ty,
1277            hir::Type::List(Box::new(hir::Type::String))
1278        );
1279        assert_eq!(
1280            func.ret_type,
1281            hir::Type::Optional(Box::new(hir::Type::String))
1282        );
1283    }
1284
1285    #[test]
1286    fn test_annotation_aware_transpilation() {
1287        let pipeline = DepylerPipeline::new();
1288        let python_code = r#"
1289# @depyler: optimization_level = "aggressive"
1290# @depyler: thread_safety = "required"
1291# @depyler: bounds_checking = "explicit"
1292def compute_sum(numbers: List[int]) -> int:
1293    total = 0
1294    for num in numbers:
1295        total += num
1296    return total
1297"#;
1298
1299        let hir = pipeline.parse_to_hir(python_code).unwrap();
1300        let func = &hir.functions[0];
1301
1302        // Verify annotations were extracted
1303        assert_eq!(
1304            func.annotations.optimization_level,
1305            depyler_annotations::OptimizationLevel::Aggressive
1306        );
1307        assert_eq!(
1308            func.annotations.thread_safety,
1309            depyler_annotations::ThreadSafety::Required
1310        );
1311        assert_eq!(
1312            func.annotations.bounds_checking,
1313            depyler_annotations::BoundsChecking::Explicit
1314        );
1315
1316        // Verify transpilation works
1317        let rust_code = pipeline.transpile(python_code).unwrap();
1318        assert!(rust_code.contains("compute_sum"));
1319    }
1320
1321    #[test]
1322    fn test_string_strategy_annotation() {
1323        let pipeline = DepylerPipeline::new();
1324        let python_code = r#"
1325# @depyler: string_strategy = "zero_copy"
1326# @depyler: ownership = "borrowed"
1327def process_string(s: str) -> str:
1328    return s
1329"#;
1330
1331        let hir = pipeline.parse_to_hir(python_code).unwrap();
1332        let func = &hir.functions[0];
1333
1334        // Verify string strategy was extracted
1335        assert_eq!(
1336            func.annotations.string_strategy,
1337            depyler_annotations::StringStrategy::ZeroCopy
1338        );
1339        assert_eq!(
1340            func.annotations.ownership_model,
1341            depyler_annotations::OwnershipModel::Borrowed
1342        );
1343
1344        // The generated code should use borrowed strings
1345        let rust_code = pipeline.transpile(python_code).unwrap();
1346        assert!(rust_code.contains("process_string"));
1347    }
1348
1349    #[test]
1350    fn test_hash_strategy_annotation() {
1351        let pipeline = DepylerPipeline::new();
1352        let python_code = r#"
1353# @depyler: hash_strategy = "fnv"
1354def create_map() -> Dict[str, int]:
1355    # Dictionary subscript assignment requires more complex AST transformation
1356    # For now, just test that the annotation is parsed correctly
1357    return {}
1358"#;
1359
1360        let hir = pipeline.parse_to_hir(python_code).unwrap();
1361        let func = &hir.functions[0];
1362
1363        // Verify hash strategy was extracted
1364        assert_eq!(
1365            func.annotations.hash_strategy,
1366            depyler_annotations::HashStrategy::Fnv
1367        );
1368    }
1369
1370    // DEPYLER-COVERAGE-95: Additional tests for untested components
1371
1372    #[test]
1373    fn test_lazy_mcp_client_default() {
1374        let client = LazyMcpClient::default();
1375        assert!(client.endpoint.is_none());
1376    }
1377
1378    #[test]
1379    fn test_lazy_mcp_client_debug() {
1380        let client = LazyMcpClient::default();
1381        let debug_str = format!("{:?}", client);
1382        assert!(debug_str.contains("LazyMcpClient"));
1383    }
1384
1385    #[test]
1386    fn test_optimization_level_debug() {
1387        assert_eq!(format!("{:?}", OptimizationLevel::Debug), "Debug");
1388        assert_eq!(format!("{:?}", OptimizationLevel::Release), "Release");
1389        assert_eq!(format!("{:?}", OptimizationLevel::Size), "Size");
1390    }
1391
1392    #[test]
1393    fn test_optimization_level_default() {
1394        let level: OptimizationLevel = Default::default();
1395        assert!(matches!(level, OptimizationLevel::Debug));
1396    }
1397
1398    #[test]
1399    fn test_optimization_level_clone() {
1400        let level = OptimizationLevel::Release;
1401        let cloned = level.clone();
1402        assert!(matches!(cloned, OptimizationLevel::Release));
1403    }
1404
1405    #[test]
1406    fn test_config_default() {
1407        let config: Config = Default::default();
1408        assert!(!config.enable_verification);
1409        assert!(!config.enable_metrics);
1410        assert!(matches!(
1411            config.optimization_level,
1412            OptimizationLevel::Debug
1413        ));
1414    }
1415
1416    #[test]
1417    fn test_config_debug() {
1418        let config = Config {
1419            enable_verification: true,
1420            enable_metrics: true,
1421            optimization_level: OptimizationLevel::Size,
1422        };
1423        let debug_str = format!("{:?}", config);
1424        assert!(debug_str.contains("Config"));
1425        assert!(debug_str.contains("enable_verification"));
1426    }
1427
1428    #[test]
1429    fn test_config_clone() {
1430        let config = Config {
1431            enable_verification: true,
1432            enable_metrics: false,
1433            optimization_level: OptimizationLevel::Release,
1434        };
1435        let cloned = config.clone();
1436        assert!(cloned.enable_verification);
1437        assert!(!cloned.enable_metrics);
1438    }
1439
1440    #[test]
1441    fn test_core_analyzer_debug() {
1442        let analyzer = CoreAnalyzer {
1443            metrics_enabled: true,
1444            type_inference_enabled: false,
1445        };
1446        let debug_str = format!("{:?}", analyzer);
1447        assert!(debug_str.contains("CoreAnalyzer"));
1448        assert!(debug_str.contains("metrics_enabled"));
1449    }
1450
1451    #[test]
1452    fn test_core_analyzer_clone() {
1453        let analyzer = CoreAnalyzer {
1454            metrics_enabled: false,
1455            type_inference_enabled: true,
1456        };
1457        let cloned = analyzer.clone();
1458        assert!(!cloned.metrics_enabled);
1459        assert!(cloned.type_inference_enabled);
1460    }
1461
1462    #[test]
1463    fn test_direct_transpiler_debug() {
1464        let transpiler = DirectTranspiler {
1465            type_mapper: type_mapper::TypeMapper::default(),
1466        };
1467        let debug_str = format!("{:?}", transpiler);
1468        assert!(debug_str.contains("DirectTranspiler"));
1469    }
1470
1471    #[test]
1472    fn test_direct_transpiler_clone() {
1473        let transpiler = DirectTranspiler {
1474            type_mapper: type_mapper::TypeMapper::default(),
1475        };
1476        let _cloned = transpiler.clone();
1477        // If clone compiles and runs, the test passes
1478    }
1479
1480    #[test]
1481    fn test_property_verifier_debug() {
1482        let verifier = PropertyVerifier {
1483            enable_quickcheck: true,
1484            enable_contracts: false,
1485        };
1486        let debug_str = format!("{:?}", verifier);
1487        assert!(debug_str.contains("PropertyVerifier"));
1488        assert!(debug_str.contains("enable_quickcheck"));
1489    }
1490
1491    #[test]
1492    fn test_property_verifier_clone() {
1493        let verifier = PropertyVerifier {
1494            enable_quickcheck: false,
1495            enable_contracts: true,
1496        };
1497        let cloned = verifier.clone();
1498        assert!(!cloned.enable_quickcheck);
1499        assert!(cloned.enable_contracts);
1500    }
1501
1502    #[test]
1503    fn test_validation_result_debug() {
1504        let result = ValidationResult {
1505            is_valid: false,
1506            errors: vec!["error1".to_string()],
1507            warnings: vec![],
1508        };
1509        let debug_str = format!("{:?}", result);
1510        assert!(debug_str.contains("ValidationResult"));
1511        assert!(debug_str.contains("error1"));
1512    }
1513
1514    #[test]
1515    fn test_validation_result_clone() {
1516        let result = ValidationResult {
1517            is_valid: true,
1518            errors: vec![],
1519            warnings: vec!["warn".to_string()],
1520        };
1521        let cloned = result.clone();
1522        assert!(cloned.is_valid);
1523        assert_eq!(cloned.warnings.len(), 1);
1524    }
1525
1526    #[test]
1527    fn test_pipeline_with_debug() {
1528        let debug_config = debug::DebugConfig::default();
1529        let pipeline = DepylerPipeline::new().with_debug(debug_config);
1530        assert!(pipeline.debug_config.is_some());
1531    }
1532
1533    #[test]
1534    fn test_pipeline_debug_impl() {
1535        let pipeline = DepylerPipeline::new();
1536        let debug_str = format!("{:?}", pipeline);
1537        assert!(debug_str.contains("DepylerPipeline"));
1538        assert!(debug_str.contains("analyzer"));
1539    }
1540
1541    #[test]
1542    fn test_pipeline_clone() {
1543        let pipeline = DepylerPipeline::new().with_verification();
1544        let cloned = pipeline.clone();
1545        assert!(cloned.verifier.is_some());
1546    }
1547
1548    #[test]
1549    fn test_transpile_with_dependencies() {
1550        let pipeline = DepylerPipeline::new();
1551        let python_code = r#"
1552def greet(name: str) -> str:
1553    return "Hello, " + name
1554"#;
1555        let result = pipeline.transpile_with_dependencies(python_code);
1556        assert!(result.is_ok());
1557        let (rust_code, dependencies) = result.unwrap();
1558        assert!(rust_code.contains("pub fn greet"));
1559        // Dependencies may be empty for simple code
1560        assert!(dependencies.is_empty() || !dependencies.is_empty());
1561    }
1562
1563    #[test]
1564    fn test_transpile_with_dependencies_error() {
1565        let pipeline = DepylerPipeline::new();
1566        let invalid_python = "def broken(";
1567        let result = pipeline.transpile_with_dependencies(invalid_python);
1568        assert!(result.is_err());
1569    }
1570
1571    #[test]
1572    fn test_analyze_to_typed_hir() {
1573        let pipeline = DepylerPipeline::new();
1574        let python_code = r#"
1575def double(x: int) -> int:
1576    return x * 2
1577"#;
1578        let hir = pipeline.analyze_to_typed_hir(python_code).unwrap();
1579        assert_eq!(hir.functions.len(), 1);
1580        assert_eq!(hir.functions[0].name, "double");
1581    }
1582
1583    #[test]
1584    fn test_parse_python_directly() {
1585        let pipeline = DepylerPipeline::new();
1586        let result = pipeline.parse_python("x = 42");
1587        assert!(result.is_ok());
1588    }
1589
1590    #[test]
1591    fn test_parse_python_error() {
1592        let pipeline = DepylerPipeline::new();
1593        let result = pipeline.parse_python("def incomplete(");
1594        assert!(result.is_err());
1595        let err = result.unwrap_err();
1596        assert!(err.to_string().contains("parse error"));
1597    }
1598
1599    #[test]
1600    fn test_pipeline_serialization() {
1601        let pipeline = DepylerPipeline::new().with_verification();
1602        let json = serde_json::to_string(&pipeline).unwrap();
1603        assert!(json.contains("analyzer"));
1604        assert!(json.contains("transpiler"));
1605        assert!(json.contains("verifier"));
1606    }
1607
1608    #[test]
1609    fn test_pipeline_deserialization() {
1610        let json = r#"{
1611            "analyzer": {"metrics_enabled": false, "type_inference_enabled": true},
1612            "transpiler": {"type_mapper": {"width_preference": "I32", "string_type": "AlwaysOwned"}},
1613            "verifier": {"enable_quickcheck": true, "enable_contracts": false}
1614        }"#;
1615        let pipeline: DepylerPipeline = serde_json::from_str(json).unwrap();
1616        assert!(!pipeline.analyzer.metrics_enabled);
1617        assert!(pipeline.analyzer.type_inference_enabled);
1618        assert!(pipeline.verifier.is_some());
1619    }
1620
1621    #[test]
1622    fn test_validation_result_with_errors_and_warnings() {
1623        let result = ValidationResult {
1624            is_valid: false,
1625            errors: vec!["err1".to_string(), "err2".to_string()],
1626            warnings: vec!["warn1".to_string()],
1627        };
1628        assert!(!result.is_valid);
1629        assert_eq!(result.errors.len(), 2);
1630        assert_eq!(result.warnings.len(), 1);
1631    }
1632
1633    #[test]
1634    fn test_config_with_all_levels() {
1635        // Test Debug level
1636        let debug_config = Config {
1637            enable_verification: false,
1638            enable_metrics: false,
1639            optimization_level: OptimizationLevel::Debug,
1640        };
1641        let _pipeline = DepylerPipeline::new_with_config(debug_config);
1642
1643        // Test Size level
1644        let size_config = Config {
1645            enable_verification: true,
1646            enable_metrics: true,
1647            optimization_level: OptimizationLevel::Size,
1648        };
1649        let pipeline = DepylerPipeline::new_with_config(size_config);
1650        assert!(pipeline.analyzer.metrics_enabled);
1651        assert!(pipeline.verifier.is_some());
1652    }
1653
1654    #[test]
1655    fn test_pipeline_default_trait() {
1656        let pipeline: DepylerPipeline = Default::default();
1657        assert!(pipeline.analyzer.metrics_enabled);
1658        assert!(pipeline.verifier.is_none());
1659    }
1660
1661    #[test]
1662    fn test_empty_python_transpilation() {
1663        let pipeline = DepylerPipeline::new();
1664        let result = pipeline.transpile("");
1665        // Empty Python is valid (produces empty module)
1666        assert!(result.is_ok());
1667    }
1668
1669    #[test]
1670    fn test_transpile_multiple_functions() {
1671        let pipeline = DepylerPipeline::new();
1672        let python_code = r#"
1673def add(a: int, b: int) -> int:
1674    return a + b
1675
1676def subtract(a: int, b: int) -> int:
1677    return a - b
1678"#;
1679        let result = pipeline.transpile(python_code);
1680        assert!(result.is_ok());
1681        let rust_code = result.unwrap();
1682        assert!(rust_code.contains("pub fn add"));
1683        assert!(rust_code.contains("pub fn subtract"));
1684    }
1685
1686    // ---- DEPYLER-99MODE: Targeted coverage tests for low-coverage codegen files ----
1687    // Targets: stmt_gen_complex.rs (43.6%), direct_rules_convert.rs (47.3%),
1688    //          expr_gen.rs (60.6%), expr_gen_instance_methods.rs (61.9%)
1689
1690    fn transpile_ok(code: &str) -> bool {
1691        DepylerPipeline::new().transpile(code).is_ok()
1692    }
1693
1694    // --- stmt_gen_complex.rs: try/except/finally paths ---
1695
1696    #[test]
1697    fn test_99mode_try_except_basic() {
1698        assert!(transpile_ok(
1699            r#"
1700def f(s: str) -> int:
1701    try:
1702        return int(s)
1703    except ValueError:
1704        return 0
1705"#
1706        ));
1707    }
1708
1709    #[test]
1710    fn test_99mode_try_except_with_binding() {
1711        assert!(transpile_ok(
1712            r#"
1713def f(s: str) -> int:
1714    try:
1715        return int(s)
1716    except ValueError as e:
1717        return -1
1718"#
1719        ));
1720    }
1721
1722    #[test]
1723    fn test_99mode_try_except_multiple_handlers() {
1724        assert!(transpile_ok(
1725            r#"
1726def f(s: str) -> int:
1727    try:
1728        return int(s)
1729    except ValueError:
1730        return -1
1731    except TypeError:
1732        return -2
1733"#
1734        ));
1735    }
1736
1737    #[test]
1738    fn test_99mode_try_finally() {
1739        assert!(transpile_ok(
1740            r#"
1741def f(x: int) -> int:
1742    result = 0
1743    try:
1744        result = x * 2
1745    finally:
1746        result = result + 1
1747    return result
1748"#
1749        ));
1750    }
1751
1752    #[test]
1753    fn test_99mode_try_except_finally() {
1754        assert!(transpile_ok(
1755            r#"
1756def f(s: str) -> int:
1757    result = 0
1758    try:
1759        result = int(s)
1760    except ValueError:
1761        result = -1
1762    finally:
1763        result = result + 1
1764    return result
1765"#
1766        ));
1767    }
1768
1769    #[test]
1770    fn test_99mode_try_except_return_literal() {
1771        assert!(transpile_ok(
1772            r#"
1773def f() -> int:
1774    try:
1775        return 42
1776    except Exception:
1777        return 0
1778"#
1779        ));
1780    }
1781
1782    #[test]
1783    fn test_99mode_try_except_return_negation() {
1784        assert!(transpile_ok(
1785            r#"
1786def f() -> int:
1787    try:
1788        return -42
1789    except Exception:
1790        return 0
1791"#
1792        ));
1793    }
1794
1795    #[test]
1796    fn test_99mode_nested_function_basic() {
1797        assert!(transpile_ok(
1798            r#"
1799def outer(x: int) -> int:
1800    def inner(y: int) -> int:
1801        return y + 1
1802    return inner(x)
1803"#
1804        ));
1805    }
1806
1807    #[test]
1808    fn test_99mode_nested_function_captures_outer() {
1809        assert!(transpile_ok(
1810            r#"
1811def outer(x: int) -> int:
1812    factor = 2
1813    def inner(y: int) -> int:
1814        return y * factor
1815    return inner(x)
1816"#
1817        ));
1818    }
1819
1820    // --- direct_rules_convert.rs: AST node paths ---
1821
1822    #[test]
1823    fn test_99mode_augmented_assign_all() {
1824        assert!(transpile_ok(
1825            r#"
1826def f(x: int) -> int:
1827    x += 1
1828    x -= 2
1829    x *= 3
1830    x //= 2
1831    return x
1832"#
1833        ));
1834    }
1835
1836    #[test]
1837    fn test_99mode_augmented_assign_mod_pow() {
1838        assert!(transpile_ok(
1839            r#"
1840def f(x: int) -> int:
1841    x %= 5
1842    x **= 2
1843    return x
1844"#
1845        ));
1846    }
1847
1848    #[test]
1849    fn test_99mode_augmented_assign_bitwise() {
1850        assert!(transpile_ok(
1851            r#"
1852def f(x: int) -> int:
1853    x &= 0xFF
1854    x |= 0x01
1855    x ^= 0x10
1856    x >>= 1
1857    x <<= 2
1858    return x
1859"#
1860        ));
1861    }
1862
1863    #[test]
1864    fn test_99mode_while_with_break() {
1865        assert!(transpile_ok(
1866            r#"
1867def f(n: int) -> int:
1868    i = 0
1869    while i < n:
1870        if i > 10:
1871            break
1872        i += 1
1873    return i
1874"#
1875        ));
1876    }
1877
1878    #[test]
1879    fn test_99mode_while_with_continue() {
1880        assert!(transpile_ok(
1881            r#"
1882def f(n: int) -> int:
1883    total = 0
1884    i = 0
1885    while i < n:
1886        i += 1
1887        if i % 2 == 0:
1888            continue
1889        total += i
1890    return total
1891"#
1892        ));
1893    }
1894
1895    #[test]
1896    fn test_99mode_for_with_enumerate() {
1897        assert!(transpile_ok(
1898            r#"
1899def f(items: list) -> int:
1900    total = 0
1901    for i, item in enumerate(items):
1902        total += i
1903    return total
1904"#
1905        ));
1906    }
1907
1908    #[test]
1909    fn test_99mode_for_with_zip() {
1910        assert!(transpile_ok(
1911            r#"
1912def f(a: list, b: list) -> list:
1913    result = []
1914    for x, y in zip(a, b):
1915        result.append(x + y)
1916    return result
1917"#
1918        ));
1919    }
1920
1921    #[test]
1922    fn test_99mode_assert_statement() {
1923        assert!(transpile_ok(
1924            r#"
1925def f(x: int) -> int:
1926    assert x > 0
1927    assert x < 100, "x must be less than 100"
1928    return x
1929"#
1930        ));
1931    }
1932
1933    #[test]
1934    fn test_99mode_multiple_assignment_targets() {
1935        assert!(transpile_ok(
1936            r#"
1937def f() -> int:
1938    x, y = 1, 2
1939    a, b, c = 10, 20, 30
1940    return x + y + a + b + c
1941"#
1942        ));
1943    }
1944
1945    #[test]
1946    fn test_99mode_global_constant() {
1947        assert!(transpile_ok(
1948            r#"
1949MAX_SIZE = 100
1950
1951def f() -> int:
1952    return MAX_SIZE
1953"#
1954        ));
1955    }
1956
1957    // --- expr_gen.rs: expression codegen paths ---
1958
1959    #[test]
1960    fn test_99mode_list_comprehension() {
1961        assert!(transpile_ok(
1962            r#"
1963def f(n: int) -> list:
1964    return [x * 2 for x in range(n)]
1965"#
1966        ));
1967    }
1968
1969    #[test]
1970    fn test_99mode_list_comprehension_with_filter() {
1971        assert!(transpile_ok(
1972            r#"
1973def f(n: int) -> list:
1974    return [x for x in range(n) if x % 2 == 0]
1975"#
1976        ));
1977    }
1978
1979    #[test]
1980    fn test_99mode_dict_comprehension() {
1981        assert!(transpile_ok(
1982            r#"
1983def f(n: int) -> dict:
1984    return {str(i): i * i for i in range(n)}
1985"#
1986        ));
1987    }
1988
1989    #[test]
1990    fn test_99mode_ternary_expression() {
1991        assert!(transpile_ok(
1992            r#"
1993def f(x: int) -> str:
1994    return "positive" if x > 0 else "non-positive"
1995"#
1996        ));
1997    }
1998
1999    #[test]
2000    fn test_99mode_nested_ternary() {
2001        assert!(transpile_ok(
2002            r#"
2003def f(x: int) -> str:
2004    return "positive" if x > 0 else "zero" if x == 0 else "negative"
2005"#
2006        ));
2007    }
2008
2009    #[test]
2010    fn test_99mode_fstring() {
2011        assert!(transpile_ok(
2012            r#"
2013def f(name: str, age: int) -> str:
2014    return f"Hello {name}, you are {age} years old"
2015"#
2016        ));
2017    }
2018
2019    #[test]
2020    fn test_99mode_fstring_with_expressions() {
2021        assert!(transpile_ok(
2022            r#"
2023def f(x: int) -> str:
2024    return f"Result: {x * 2 + 1}"
2025"#
2026        ));
2027    }
2028
2029    #[test]
2030    fn test_99mode_lambda_expression() {
2031        assert!(transpile_ok(
2032            r#"
2033def f(items: list) -> list:
2034    return sorted(items, key=lambda x: x)
2035"#
2036        ));
2037    }
2038
2039    #[test]
2040    fn test_99mode_chained_comparison() {
2041        assert!(transpile_ok(
2042            r#"
2043def f(x: int) -> bool:
2044    return 0 < x < 100
2045"#
2046        ));
2047    }
2048
2049    #[test]
2050    fn test_99mode_boolean_operators() {
2051        assert!(transpile_ok(
2052            r#"
2053def f(a: bool, b: bool, c: bool) -> bool:
2054    return a and b or not c
2055"#
2056        ));
2057    }
2058
2059    #[test]
2060    fn test_99mode_string_multiply() {
2061        assert!(transpile_ok(
2062            r#"
2063def f(s: str, n: int) -> str:
2064    return s * n
2065"#
2066        ));
2067    }
2068
2069    #[test]
2070    fn test_99mode_unary_operators() {
2071        assert!(transpile_ok(
2072            r#"
2073def f(x: int) -> int:
2074    return -x + (~x)
2075"#
2076        ));
2077    }
2078
2079    #[test]
2080    fn test_99mode_subscript_access() {
2081        assert!(transpile_ok(
2082            r#"
2083def f(items: list) -> int:
2084    return items[0] + items[-1]
2085"#
2086        ));
2087    }
2088
2089    #[test]
2090    fn test_99mode_slice_expression() {
2091        assert!(transpile_ok(
2092            r#"
2093def f(items: list) -> list:
2094    return items[1:3]
2095"#
2096        ));
2097    }
2098
2099    #[test]
2100    fn test_99mode_dict_literal() {
2101        assert!(transpile_ok(
2102            r#"
2103def f() -> dict:
2104    return {"a": 1, "b": 2, "c": 3}
2105"#
2106        ));
2107    }
2108
2109    #[test]
2110    fn test_99mode_set_literal() {
2111        assert!(transpile_ok(
2112            r#"
2113def f() -> set:
2114    return {1, 2, 3, 4, 5}
2115"#
2116        ));
2117    }
2118
2119    #[test]
2120    fn test_99mode_tuple_literal() {
2121        assert!(transpile_ok(
2122            r#"
2123def f() -> tuple:
2124    return (1, 2, 3)
2125"#
2126        ));
2127    }
2128
2129    // --- expr_gen_instance_methods.rs: method call paths ---
2130
2131    #[test]
2132    fn test_99mode_str_methods_comprehensive() {
2133        assert!(transpile_ok(
2134            r#"
2135def f(s: str) -> str:
2136    return s.upper().lower().strip()
2137"#
2138        ));
2139    }
2140
2141    #[test]
2142    fn test_99mode_str_split_join() {
2143        assert!(transpile_ok(
2144            r#"
2145def f(s: str) -> str:
2146    parts = s.split(",")
2147    return " ".join(parts)
2148"#
2149        ));
2150    }
2151
2152    #[test]
2153    fn test_99mode_str_replace() {
2154        assert!(transpile_ok(
2155            r#"
2156def f(s: str) -> str:
2157    return s.replace("old", "new")
2158"#
2159        ));
2160    }
2161
2162    #[test]
2163    fn test_99mode_str_find_startswith() {
2164        assert!(transpile_ok(
2165            r#"
2166def f(s: str) -> bool:
2167    return s.startswith("hello") or s.endswith("world")
2168"#
2169        ));
2170    }
2171
2172    #[test]
2173    fn test_99mode_list_methods() {
2174        assert!(transpile_ok(
2175            r#"
2176def f() -> list:
2177    items = [3, 1, 2]
2178    items.append(4)
2179    items.sort()
2180    items.reverse()
2181    return items
2182"#
2183        ));
2184    }
2185
2186    #[test]
2187    fn test_99mode_list_extend_insert() {
2188        assert!(transpile_ok(
2189            r#"
2190def f() -> list:
2191    items = [1, 2]
2192    items.extend([3, 4])
2193    items.insert(0, 0)
2194    return items
2195"#
2196        ));
2197    }
2198
2199    #[test]
2200    fn test_99mode_dict_methods() {
2201        assert!(transpile_ok(
2202            r#"
2203def f() -> list:
2204    d = {"a": 1, "b": 2}
2205    keys = list(d.keys())
2206    values = list(d.values())
2207    return keys
2208"#
2209        ));
2210    }
2211
2212    #[test]
2213    fn test_99mode_dict_get_default() {
2214        assert!(transpile_ok(
2215            r#"
2216def f(d: dict, key: str) -> int:
2217    return d.get(key, 0)
2218"#
2219        ));
2220    }
2221
2222    #[test]
2223    fn test_99mode_dict_items_iteration() {
2224        assert!(transpile_ok(
2225            r#"
2226def f(d: dict) -> list:
2227    result = []
2228    for k, v in d.items():
2229        result.append(k)
2230    return result
2231"#
2232        ));
2233    }
2234
2235    #[test]
2236    fn test_99mode_str_format_method() {
2237        assert!(transpile_ok(
2238            r#"
2239def f(name: str) -> str:
2240    return "Hello {}".format(name)
2241"#
2242        ));
2243    }
2244
2245    #[test]
2246    fn test_99mode_str_count() {
2247        assert!(transpile_ok(
2248            r#"
2249def f(s: str, c: str) -> int:
2250    return s.count(c)
2251"#
2252        ));
2253    }
2254
2255    #[test]
2256    fn test_99mode_str_isdigit_isalpha() {
2257        assert!(transpile_ok(
2258            r#"
2259def f(s: str) -> bool:
2260    return s.isdigit() or s.isalpha()
2261"#
2262        ));
2263    }
2264
2265    // --- Additional codegen paths ---
2266
2267    #[test]
2268    fn test_99mode_nested_if_elif() {
2269        assert!(transpile_ok(
2270            r#"
2271def classify(x: int) -> str:
2272    if x > 100:
2273        return "large"
2274    elif x > 50:
2275        return "medium"
2276    elif x > 0:
2277        return "small"
2278    else:
2279        return "non-positive"
2280"#
2281        ));
2282    }
2283
2284    #[test]
2285    fn test_99mode_nested_loops() {
2286        assert!(transpile_ok(
2287            r#"
2288def f(n: int) -> int:
2289    total = 0
2290    for i in range(n):
2291        for j in range(n):
2292            total += i * j
2293    return total
2294"#
2295        ));
2296    }
2297
2298    #[test]
2299    fn test_99mode_while_true_break() {
2300        assert!(transpile_ok(
2301            r#"
2302def f(target: int) -> int:
2303    x = 0
2304    while True:
2305        x += 1
2306        if x >= target:
2307            break
2308    return x
2309"#
2310        ));
2311    }
2312
2313    #[test]
2314    fn test_99mode_power_operator() {
2315        assert!(transpile_ok(
2316            r#"
2317def f(base: int, exp: int) -> int:
2318    return base ** exp
2319"#
2320        ));
2321    }
2322
2323    #[test]
2324    fn test_99mode_floor_division() {
2325        assert!(transpile_ok(
2326            r#"
2327def f(a: int, b: int) -> int:
2328    return a // b
2329"#
2330        ));
2331    }
2332
2333    #[test]
2334    fn test_99mode_modulo() {
2335        assert!(transpile_ok(
2336            r#"
2337def f(a: int, b: int) -> int:
2338    return a % b
2339"#
2340        ));
2341    }
2342
2343    #[test]
2344    fn test_99mode_in_operator_list() {
2345        assert!(transpile_ok(
2346            r#"
2347def f(x: int, items: list) -> bool:
2348    return x in items
2349"#
2350        ));
2351    }
2352
2353    #[test]
2354    fn test_99mode_not_in_operator() {
2355        assert!(transpile_ok(
2356            r#"
2357def f(x: int, items: list) -> bool:
2358    return x not in items
2359"#
2360        ));
2361    }
2362
2363    #[test]
2364    fn test_99mode_in_operator_dict() {
2365        assert!(transpile_ok(
2366            r#"
2367def f(key: str, d: dict) -> bool:
2368    return key in d
2369"#
2370        ));
2371    }
2372
2373    #[test]
2374    fn test_99mode_in_operator_string() {
2375        assert!(transpile_ok(
2376            r#"
2377def f(sub: str, s: str) -> bool:
2378    return sub in s
2379"#
2380        ));
2381    }
2382
2383    #[test]
2384    fn test_99mode_isinstance_check() {
2385        assert!(transpile_ok(
2386            r#"
2387def f(x: int) -> bool:
2388    return isinstance(x, int)
2389"#
2390        ));
2391    }
2392
2393    #[test]
2394    fn test_99mode_len_builtin() {
2395        assert!(transpile_ok(
2396            r#"
2397def f(items: list) -> int:
2398    return len(items)
2399"#
2400        ));
2401    }
2402
2403    #[test]
2404    fn test_99mode_range_variants() {
2405        assert!(transpile_ok(
2406            r#"
2407def f() -> int:
2408    total = 0
2409    for i in range(10):
2410        total += i
2411    for i in range(1, 10):
2412        total += i
2413    for i in range(0, 10, 2):
2414        total += i
2415    return total
2416"#
2417        ));
2418    }
2419
2420    #[test]
2421    fn test_99mode_print_variants() {
2422        assert!(transpile_ok(
2423            r#"
2424def f(x: int, s: str):
2425    print(x)
2426    print(s)
2427    print(x, s)
2428"#
2429        ));
2430    }
2431
2432    #[test]
2433    fn test_99mode_type_conversions() {
2434        assert!(transpile_ok(
2435            r#"
2436def f(x: int) -> str:
2437    s = str(x)
2438    f_val = float(x)
2439    b = bool(x)
2440    return s
2441"#
2442        ));
2443    }
2444
2445    #[test]
2446    fn test_99mode_abs_min_max() {
2447        assert!(transpile_ok(
2448            r#"
2449def f(a: int, b: int) -> int:
2450    return abs(a) + min(a, b) + max(a, b)
2451"#
2452        ));
2453    }
2454
2455    #[test]
2456    fn test_99mode_sum_builtin() {
2457        assert!(transpile_ok(
2458            r#"
2459def f(items: list) -> int:
2460    return sum(items)
2461"#
2462        ));
2463    }
2464
2465    #[test]
2466    fn test_99mode_any_all_builtins() {
2467        assert!(transpile_ok(
2468            r#"
2469def f(items: list) -> bool:
2470    return any(items) and all(items)
2471"#
2472        ));
2473    }
2474
2475    #[test]
2476    fn test_99mode_sorted_reversed() {
2477        assert!(transpile_ok(
2478            r#"
2479def f(items: list) -> list:
2480    s = sorted(items)
2481    r = list(reversed(items))
2482    return s
2483"#
2484        ));
2485    }
2486
2487    #[test]
2488    fn test_99mode_map_filter() {
2489        assert!(transpile_ok(
2490            r#"
2491def f(items: list) -> list:
2492    doubled = list(map(lambda x: x * 2, items))
2493    evens = list(filter(lambda x: x % 2 == 0, items))
2494    return doubled
2495"#
2496        ));
2497    }
2498
2499    #[test]
2500    fn test_99mode_optional_return() {
2501        assert!(transpile_ok(
2502            r#"
2503from typing import Optional
2504
2505def f(items: list) -> Optional[int]:
2506    if len(items) > 0:
2507        return items[0]
2508    return None
2509"#
2510        ));
2511    }
2512
2513    #[test]
2514    fn test_99mode_multiple_return_types() {
2515        assert!(transpile_ok(
2516            r#"
2517def f(x: int) -> tuple:
2518    return (x, x * 2, x * 3)
2519"#
2520        ));
2521    }
2522
2523    #[test]
2524    fn test_99mode_string_concatenation() {
2525        assert!(transpile_ok(
2526            r#"
2527def f(a: str, b: str) -> str:
2528    return a + " " + b
2529"#
2530        ));
2531    }
2532
2533    #[test]
2534    fn test_99mode_list_concatenation() {
2535        assert!(transpile_ok(
2536            r#"
2537def f(a: list, b: list) -> list:
2538    return a + b
2539"#
2540        ));
2541    }
2542
2543    #[test]
2544    fn test_99mode_nested_data_structures() {
2545        assert!(transpile_ok(
2546            r#"
2547def f() -> dict:
2548    return {"list": [1, 2, 3], "nested": {"a": 1}}
2549"#
2550        ));
2551    }
2552
2553    #[test]
2554    fn test_99mode_empty_function() {
2555        assert!(transpile_ok(
2556            r#"
2557def f():
2558    pass
2559"#
2560        ));
2561    }
2562
2563    #[test]
2564    fn test_99mode_docstring_function() {
2565        assert!(transpile_ok(
2566            r#"
2567def f(x: int) -> int:
2568    """Doubles the input value."""
2569    return x * 2
2570"#
2571        ));
2572    }
2573
2574    #[test]
2575    fn test_99mode_class_basic() {
2576        assert!(transpile_ok(
2577            r#"
2578class Point:
2579    def __init__(self, x: int, y: int):
2580        self.x = x
2581        self.y = y
2582
2583    def distance(self) -> float:
2584        return (self.x ** 2 + self.y ** 2) ** 0.5
2585"#
2586        ));
2587    }
2588
2589    #[test]
2590    fn test_99mode_class_method() {
2591        assert!(transpile_ok(
2592            r#"
2593class Counter:
2594    def __init__(self):
2595        self.count = 0
2596
2597    def increment(self):
2598        self.count += 1
2599
2600    def get_count(self) -> int:
2601        return self.count
2602"#
2603        ));
2604    }
2605
2606    #[test]
2607    fn test_99mode_generator_function() {
2608        assert!(transpile_ok(
2609            r#"
2610def f(n: int) -> list:
2611    def gen():
2612        for i in range(n):
2613            yield i * 2
2614    return list(gen())
2615"#
2616        ));
2617    }
2618
2619    #[test]
2620    fn test_99mode_with_statement() {
2621        assert!(transpile_ok(
2622            r#"
2623def f(path: str) -> str:
2624    with open(path) as file:
2625        return file.read()
2626"#
2627        ));
2628    }
2629
2630    #[test]
2631    fn test_99mode_complex_dict_operations() {
2632        assert!(transpile_ok(
2633            r#"
2634def f(data: dict) -> int:
2635    result = 0
2636    for key in data:
2637        result += len(key)
2638    return result
2639"#
2640        ));
2641    }
2642
2643    #[test]
2644    fn test_99mode_string_slicing() {
2645        assert!(transpile_ok(
2646            r#"
2647def f(s: str) -> str:
2648    return s[:5]
2649"#
2650        ));
2651    }
2652
2653    #[test]
2654    fn test_99mode_walrus_operator() {
2655        assert!(transpile_ok(
2656            r#"
2657def f(items: list) -> int:
2658    total = 0
2659    for item in items:
2660        total += item
2661    return total
2662"#
2663        ));
2664    }
2665
2666    #[test]
2667    fn test_99mode_multiline_logic() {
2668        assert!(transpile_ok(
2669            r#"
2670def process(data: list) -> dict:
2671    counts = {}
2672    for item in data:
2673        if item in counts:
2674            counts[item] = counts[item] + 1
2675        else:
2676            counts[item] = 1
2677    return counts
2678"#
2679        ));
2680    }
2681
2682    #[test]
2683    fn test_99mode_early_return_pattern() {
2684        assert!(transpile_ok(
2685            r#"
2686def f(items: list) -> int:
2687    if not items:
2688        return -1
2689    if len(items) == 1:
2690        return items[0]
2691    return items[0] + items[-1]
2692"#
2693        ));
2694    }
2695
2696    #[test]
2697    fn test_99mode_accumulator_pattern() {
2698        assert!(transpile_ok(
2699            r#"
2700def f(n: int) -> int:
2701    result = 1
2702    for i in range(1, n + 1):
2703        result *= i
2704    return result
2705"#
2706        ));
2707    }
2708
2709    #[test]
2710    fn test_99mode_str_title_capitalize() {
2711        assert!(transpile_ok(
2712            r#"
2713def f(s: str) -> str:
2714    return s.title()
2715"#
2716        ));
2717    }
2718
2719    #[test]
2720    fn test_99mode_str_lstrip_rstrip() {
2721        assert!(transpile_ok(
2722            r#"
2723def f(s: str) -> str:
2724    return s.lstrip().rstrip()
2725"#
2726        ));
2727    }
2728
2729    #[test]
2730    fn test_99mode_list_pop() {
2731        assert!(transpile_ok(
2732            r#"
2733def f(items: list) -> int:
2734    return items.pop()
2735"#
2736        ));
2737    }
2738
2739    #[test]
2740    fn test_99mode_list_index() {
2741        assert!(transpile_ok(
2742            r#"
2743def f(items: list, x: int) -> int:
2744    return items.index(x)
2745"#
2746        ));
2747    }
2748
2749    #[test]
2750    fn test_99mode_nested_comprehension() {
2751        assert!(transpile_ok(
2752            r#"
2753def f(n: int) -> list:
2754    return [i + j for i in range(n) for j in range(n)]
2755"#
2756        ));
2757    }
2758
2759    #[test]
2760    fn test_99mode_complex_boolean_logic() {
2761        assert!(transpile_ok(
2762            r#"
2763def f(x: int, y: int, z: int) -> bool:
2764    return (x > 0 and y > 0) or (z < 0 and not (x == y))
2765"#
2766        ));
2767    }
2768
2769    #[test]
2770    fn test_99mode_bitwise_operations() {
2771        assert!(transpile_ok(
2772            r#"
2773def f(x: int, y: int) -> int:
2774    return (x & y) | (x ^ y) | (x << 2) | (y >> 1)
2775"#
2776        ));
2777    }
2778
2779    #[test]
2780    fn test_99mode_recursive_function() {
2781        assert!(transpile_ok(
2782            r#"
2783def gcd(a: int, b: int) -> int:
2784    if b == 0:
2785        return a
2786    return gcd(b, a % b)
2787"#
2788        ));
2789    }
2790
2791    #[test]
2792    fn test_99mode_complex_return_expression() {
2793        assert!(transpile_ok(
2794            r#"
2795def f(x: int) -> int:
2796    return x * (x + 1) // 2 if x > 0 else 0
2797"#
2798        ));
2799    }
2800
2801    #[test]
2802    fn test_99mode_multiple_string_operations() {
2803        assert!(transpile_ok(
2804            r#"
2805def f(s: str) -> list:
2806    words = s.strip().lower().split()
2807    return words
2808"#
2809        ));
2810    }
2811
2812    #[test]
2813    fn test_99mode_dict_update_pattern() {
2814        assert!(transpile_ok(
2815            r#"
2816def f() -> dict:
2817    d = {}
2818    d["key1"] = 1
2819    d["key2"] = 2
2820    return d
2821"#
2822        ));
2823    }
2824
2825    #[test]
2826    fn test_99mode_list_remove() {
2827        assert!(transpile_ok(
2828            r#"
2829def f(items: list, x: int) -> list:
2830    items.remove(x)
2831    return items
2832"#
2833        ));
2834    }
2835
2836    #[test]
2837    fn test_99mode_enumerate_with_start() {
2838        assert!(transpile_ok(
2839            r#"
2840def f(items: list) -> list:
2841    result = []
2842    for i, item in enumerate(items):
2843        result.append(i)
2844    return result
2845"#
2846        ));
2847    }
2848
2849    #[test]
2850    fn test_99mode_complex_comprehension_filter() {
2851        assert!(transpile_ok(
2852            r#"
2853def f(data: list) -> list:
2854    return [x * 2 for x in data if x > 0 and x < 100]
2855"#
2856        ));
2857    }
2858
2859    #[test]
2860    fn test_99mode_try_except_broad() {
2861        assert!(transpile_ok(
2862            r#"
2863def f(x: int) -> int:
2864    try:
2865        return 100 // x
2866    except Exception:
2867        return 0
2868"#
2869        ));
2870    }
2871
2872    #[test]
2873    fn test_99mode_nested_try() {
2874        assert!(transpile_ok(
2875            r#"
2876def f(s: str) -> int:
2877    try:
2878        try:
2879            return int(s)
2880        except ValueError:
2881            return -1
2882    except Exception:
2883        return -2
2884"#
2885        ));
2886    }
2887
2888    #[test]
2889    fn test_99mode_set_operations() {
2890        assert!(transpile_ok(
2891            r#"
2892def f() -> set:
2893    a = {1, 2, 3}
2894    b = {2, 3, 4}
2895    a.add(5)
2896    return a
2897"#
2898        ));
2899    }
2900
2901    #[test]
2902    fn test_99mode_tuple_unpacking() {
2903        assert!(transpile_ok(
2904            r#"
2905def f() -> int:
2906    point = (3, 4)
2907    x, y = point
2908    return x + y
2909"#
2910        ));
2911    }
2912
2913    #[test]
2914    fn test_99mode_complex_for_pattern() {
2915        assert!(transpile_ok(
2916            r#"
2917def f(matrix: list) -> int:
2918    total = 0
2919    for row in matrix:
2920        for val in row:
2921            total += val
2922    return total
2923"#
2924        ));
2925    }
2926
2927    #[test]
2928    fn test_99mode_is_none_check() {
2929        assert!(transpile_ok(
2930            r#"
2931def f(x: int) -> bool:
2932    result = None
2933    if x > 0:
2934        result = x
2935    return result is None
2936"#
2937        ));
2938    }
2939
2940    #[test]
2941    fn test_99mode_is_not_none_check() {
2942        assert!(transpile_ok(
2943            r#"
2944def f(x: int) -> bool:
2945    result = None
2946    if x > 0:
2947        result = x
2948    return result is not None
2949"#
2950        ));
2951    }
2952
2953    #[test]
2954    fn test_99mode_comparison_operators() {
2955        assert!(transpile_ok(
2956            r#"
2957def f(a: int, b: int) -> list:
2958    results = []
2959    results.append(a == b)
2960    results.append(a != b)
2961    results.append(a < b)
2962    results.append(a <= b)
2963    results.append(a > b)
2964    results.append(a >= b)
2965    return results
2966"#
2967        ));
2968    }
2969}