1pub use depyler_hir::trace_decision;
50pub use depyler_hir::emit_decision;
51pub use depyler_hir::transpile_error;
52pub use depyler_hir::transpile_bail;
53
54pub use depyler_hir::decision_trace;
56pub use depyler_hir::error;
57pub use depyler_hir::hir;
58pub use depyler_hir::simplified_hir;
59
60pub 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
68pub 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
97pub 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
115pub 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; pub mod lsp;
125pub mod rust_gen;
126pub mod union_enum_gen;
127
128use anyhow::Result;
129use serde::{Deserialize, Serialize};
130
131pub 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#[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 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 pub fn with_nasa_mode(mut self, enabled: bool) -> Self {
344 self.transpiler.type_mapper.nasa_mode = enabled;
345 self
346 }
347
348 pub fn transpile_with_dependencies(
417 &self,
418 python_source: &str,
419 ) -> Result<(String, Vec<cargo_toml_gen::Dependency>)> {
420 let ast = self.parse_python(python_source)?;
422
423 let (mut hir, _type_env) = ast_bridge::AstBridge::new()
425 .with_source(python_source.to_string())
426 .python_to_hir(ast)?;
427
428 let mut const_inferencer = const_generic_inference::ConstGenericInferencer::new();
430 const_inferencer.analyze_module(&mut hir)?;
431
432 if self.analyzer.type_inference_enabled {
434 let mut type_hint_provider = type_hints::TypeHintProvider::new();
435
436 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 for (func_idx, hints) in function_hints {
450 let func = &mut hir.functions[func_idx];
451
452 for param in &mut func.params {
454 if matches!(param.ty, hir::Type::Unknown) {
455 for hint in &hints {
457 if let type_hints::HintTarget::Parameter(hint_param) = &hint.target {
458 if hint_param == ¶m.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 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 type_propagation::propagate_call_site_types(&mut hir);
500
501 {
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 if let Err(e) = type_system::unify_module_types(&mut hir) {
528 eprintln!("Type unification warning: {:?}", e);
530 }
531
532 optimization::optimize_module(&mut hir);
534
535 let hir_program = hir::HirProgram {
537 functions: hir.functions,
538 classes: hir.classes,
539 imports: hir.imports,
540 };
541
542 let mut optimizer = optimizer::Optimizer::new(optimizer::OptimizerConfig::default());
544 let optimized_program = optimizer.optimize_program(hir_program.clone());
545
546 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 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 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 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, };
587
588 rust_gen::generate_rust_file(&optimized_hir, &self.transpiler.type_mapper)
590 }
591
592 pub fn transpile(&self, python_source: &str) -> Result<String> {
593 let ast = self.parse_python(python_source)?;
595
596 let (mut hir, _type_env) = ast_bridge::AstBridge::new()
598 .with_source(python_source.to_string())
599 .python_to_hir(ast)?;
600
601 let mut const_inferencer = const_generic_inference::ConstGenericInferencer::new();
603 const_inferencer.analyze_module(&mut hir)?;
604
605 if self.analyzer.type_inference_enabled {
607 let mut type_hint_provider = type_hints::TypeHintProvider::new();
608
609 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 for (func_idx, hints) in function_hints {
623 let func = &mut hir.functions[func_idx];
624
625 for param in &mut func.params {
627 if matches!(param.ty, hir::Type::Unknown) {
628 for hint in &hints {
630 if let type_hints::HintTarget::Parameter(hint_param) = &hint.target {
631 if hint_param == ¶m.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 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 type_propagation::propagate_call_site_types(&mut hir);
673
674 {
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 if let Err(e) = type_system::unify_module_types(&mut hir) {
701 eprintln!("Type unification warning: {:?}", e);
703 }
704
705 optimization::optimize_module(&mut hir);
707
708 let hir_program = hir::HirProgram {
710 functions: hir.functions,
711 classes: hir.classes,
712 imports: hir.imports,
713 };
714
715 let mut optimizer = optimizer::Optimizer::new(optimizer::OptimizerConfig::default());
717 let optimized_program = optimizer.optimize_program(hir_program.clone());
718
719 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 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 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 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, };
760
761 let (rust_code, _dependencies) =
764 rust_gen::generate_rust_file(&optimized_hir, &self.transpiler.type_mapper)?;
765
766 Ok(rust_code)
767 }
768
769 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 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 let ast = self.parse_python(python_source)?;
787
788 let (mut hir, _type_env) = ast_bridge::AstBridge::new()
790 .with_source(python_source.to_string())
791 .python_to_hir(ast)?;
792
793 for func in &mut hir.functions {
796 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 for param in func.params.iter_mut() {
809 if let Some(override_type) = type_overrides.get(¶m.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 let mut const_inferencer = const_generic_inference::ConstGenericInferencer::new();
823 const_inferencer.analyze_module(&mut hir)?;
824
825 if self.analyzer.type_inference_enabled {
827 let mut type_hint_provider = type_hints::TypeHintProvider::new();
828
829 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 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(¶m.name)
845 {
846 for hint in &hints {
847 if let type_hints::HintTarget::Parameter(hint_param) = &hint.target {
848 if hint_param == ¶m.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 type_propagation::propagate_call_site_types(&mut hir);
867
868 {
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 if let Err(e) = type_system::unify_module_types(&mut hir) {
890 eprintln!("Type unification warning: {:?}", e);
891 }
892
893 optimization::optimize_module(&mut hir);
895
896 rust_gen::generate_rust_file_with_overrides(
899 &hir,
900 &self.transpiler.type_mapper,
901 type_overrides,
902 )
903 }
904
905 pub fn transpile_with_constraints(
934 &self,
935 python_source: &str,
936 type_constraints: &std::collections::HashMap<String, String>,
937 ) -> Result<String> {
938 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 let ast = self.parse_python(python_source)?;
946
947 let (mut hir, _type_env) = ast_bridge::AstBridge::new()
949 .with_source(python_source.to_string())
950 .python_to_hir(ast)?;
951
952 for func in &mut hir.functions {
955 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 for param in func.params.iter_mut() {
968 if let Some(override_type) = type_overrides.get(¶m.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 let mut const_inferencer = const_generic_inference::ConstGenericInferencer::new();
982 const_inferencer.analyze_module(&mut hir)?;
983
984 if self.analyzer.type_inference_enabled {
986 let mut type_hint_provider = type_hints::TypeHintProvider::new();
987
988 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 for (func_idx, hints) in function_hints {
1000 let func = &mut hir.functions[func_idx];
1001 for param in &mut func.params {
1002 if matches!(param.ty, hir::Type::Unknown)
1004 && !type_overrides.contains_key(¶m.name)
1005 {
1006 for hint in &hints {
1007 if let type_hints::HintTarget::Parameter(hint_param) = &hint.target {
1008 if hint_param == ¶m.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 type_propagation::propagate_call_site_types(&mut hir);
1027
1028 {
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 if let Err(e) = type_system::unify_module_types(&mut hir) {
1050 eprintln!("Type unification warning: {:?}", e);
1051 }
1052
1053 optimization::optimize_module(&mut hir);
1055
1056 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 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 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 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 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 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 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 assert_eq!(
1365 func.annotations.hash_strategy,
1366 depyler_annotations::HashStrategy::Fnv
1367 );
1368 }
1369
1370 #[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 }
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 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 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 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 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 fn transpile_ok(code: &str) -> bool {
1691 DepylerPipeline::new().transpile(code).is_ok()
1692 }
1693
1694 #[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 #[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 #[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 #[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 #[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}