/home/noah/src/ruchy/src/backend/transpiler/method_call_refactored.rs
Line | Count | Source |
1 | | //! Refactored method call transpilation with reduced complexity |
2 | | //! Original complexity: 58, Target: <20 per function |
3 | | |
4 | | use crate::backend::Transpiler; |
5 | | use crate::frontend::ast::Expr; |
6 | | use anyhow::{bail, Result}; |
7 | | use proc_macro2::TokenStream; |
8 | | use quote::{quote, format_ident}; |
9 | | |
10 | | impl Transpiler { |
11 | | /// Main dispatcher for method calls (complexity: ~15) |
12 | 0 | pub fn transpile_method_call_refactored( |
13 | 0 | &self, |
14 | 0 | object: &Expr, |
15 | 0 | method: &str, |
16 | 0 | args: &[Expr], |
17 | 0 | ) -> Result<TokenStream> { |
18 | 0 | let obj_tokens = self.transpile_expr(object)?; |
19 | 0 | let arg_tokens: Result<Vec<_>> = args.iter().map(|a| self.transpile_expr(a)).collect(); |
20 | 0 | let arg_tokens = arg_tokens?; |
21 | | |
22 | | // Dispatch to specialized handlers based on method category |
23 | 0 | match method { |
24 | | // Iterator methods |
25 | 0 | "map" | "filter" | "reduce" | "fold" | "any" | "all" | "find" => |
26 | 0 | self.transpile_iterator_method(&obj_tokens, method, &arg_tokens), |
27 | | |
28 | | // HashMap/Dict methods |
29 | 0 | "get" | "contains_key" | "keys" | "values" | "items" | "entry" => |
30 | 0 | self.transpile_hashmap_method(&obj_tokens, method, &arg_tokens), |
31 | | |
32 | | // HashSet methods |
33 | 0 | "contains" | "union" | "intersection" | "difference" | "symmetric_difference" => |
34 | 0 | self.transpile_hashset_method(&obj_tokens, method, &arg_tokens), |
35 | | |
36 | | // Collection mutators |
37 | 0 | "insert" | "remove" | "clear" | "push" | "pop" | "append" | "extend" => |
38 | 0 | self.transpile_collection_mutator(&obj_tokens, method, &arg_tokens), |
39 | | |
40 | | // Collection accessors |
41 | 0 | "len" | "is_empty" | "iter" | "slice" | "first" | "last" => |
42 | 0 | self.transpile_collection_accessor(&obj_tokens, method, &arg_tokens), |
43 | | |
44 | | // String methods |
45 | 0 | "to_s" | "to_string" | "to_upper" | "to_lower" | "length" | |
46 | 0 | "trim" | "split" | "replace" | "starts_with" | "ends_with" => |
47 | 0 | self.transpile_string_method(&obj_tokens, method, &arg_tokens), |
48 | | |
49 | | // DataFrame methods |
50 | 0 | "select" | "groupby" | "agg" | "sort" | "mean" | "std" | "min" | "max" | |
51 | 0 | "sum" | "count" | "drop_nulls" | "fill_null" | "pivot" | "melt" | |
52 | 0 | "head" | "tail" | "sample" | "describe" => |
53 | 0 | self.transpile_dataframe_method_refactored(&obj_tokens, method, &arg_tokens), |
54 | | |
55 | | // Default: pass through |
56 | | _ => { |
57 | 0 | let method_ident = format_ident!("{}", method); |
58 | 0 | Ok(quote! { #obj_tokens.#method_ident(#(#arg_tokens),*) }) |
59 | | } |
60 | | } |
61 | 0 | } |
62 | | |
63 | | /// Handle iterator methods (complexity: ~10) |
64 | 0 | fn transpile_iterator_method( |
65 | 0 | &self, |
66 | 0 | obj: &TokenStream, |
67 | 0 | method: &str, |
68 | 0 | args: &[TokenStream], |
69 | 0 | ) -> Result<TokenStream> { |
70 | 0 | match method { |
71 | 0 | "map" => Ok(quote! { #obj.iter().map(#(#args),*).collect::<Vec<_>>() }), |
72 | 0 | "filter" => Ok(quote! { #obj.into_iter().filter(#(#args),*).collect::<Vec<_>>() }), |
73 | 0 | "reduce" => Ok(quote! { #obj.into_iter().reduce(#(#args),*) }), |
74 | 0 | "fold" => { |
75 | 0 | if args.len() != 2 { |
76 | 0 | bail!("fold requires exactly 2 arguments"); |
77 | 0 | } |
78 | 0 | let init = &args[0]; |
79 | 0 | let func = &args[1]; |
80 | 0 | Ok(quote! { #obj.into_iter().fold(#init, #func) }) |
81 | | } |
82 | 0 | "any" => Ok(quote! { #obj.iter().any(#(#args),*) }), |
83 | 0 | "all" => Ok(quote! { #obj.iter().all(#(#args),*) }), |
84 | 0 | "find" => Ok(quote! { #obj.iter().find(#(#args),*).cloned() }), |
85 | 0 | _ => unreachable!("Unknown iterator method: {}", method), |
86 | | } |
87 | 0 | } |
88 | | |
89 | | /// Handle HashMap/Dict methods (complexity: ~10) |
90 | 0 | fn transpile_hashmap_method( |
91 | 0 | &self, |
92 | 0 | obj: &TokenStream, |
93 | 0 | method: &str, |
94 | 0 | args: &[TokenStream], |
95 | 0 | ) -> Result<TokenStream> { |
96 | 0 | let method_ident = format_ident!("{}", method); |
97 | 0 | match method { |
98 | 0 | "get" => Ok(quote! { #obj.#method_ident(#(#args),*).cloned() }), |
99 | 0 | "items" => Ok(quote! { #obj.iter().map(|(k, v)| (k.clone(), v.clone())) }), |
100 | 0 | "contains_key" | "keys" | "values" | "entry" => |
101 | 0 | Ok(quote! { #obj.#method_ident(#(#args),*) }), |
102 | 0 | _ => unreachable!("Unknown HashMap method: {}", method), |
103 | | } |
104 | 0 | } |
105 | | |
106 | | /// Handle `HashSet` methods (complexity: ~12) |
107 | 0 | fn transpile_hashset_method( |
108 | 0 | &self, |
109 | 0 | obj: &TokenStream, |
110 | 0 | method: &str, |
111 | 0 | args: &[TokenStream], |
112 | 0 | ) -> Result<TokenStream> { |
113 | 0 | match method { |
114 | 0 | "contains" => { |
115 | 0 | let method_ident = format_ident!("{}", method); |
116 | 0 | Ok(quote! { #obj.#method_ident(#(#args),*) }) |
117 | | } |
118 | 0 | "union" | "intersection" | "difference" | "symmetric_difference" => { |
119 | 0 | if args.len() != 1 { |
120 | 0 | bail!("{} requires exactly 1 argument", method); |
121 | 0 | } |
122 | 0 | let other = &args[0]; |
123 | 0 | let method_ident = format_ident!("{}", method); |
124 | 0 | Ok(quote! { |
125 | 0 | { |
126 | 0 | use std::collections::HashSet; |
127 | 0 | #obj.#method_ident(&#other).cloned().collect::<HashSet<_>>() |
128 | 0 | } |
129 | 0 | }) |
130 | | } |
131 | 0 | _ => unreachable!("Unknown HashSet method: {}", method), |
132 | | } |
133 | 0 | } |
134 | | |
135 | | /// Handle collection mutator methods (complexity: ~5) |
136 | 0 | fn transpile_collection_mutator( |
137 | 0 | &self, |
138 | 0 | obj: &TokenStream, |
139 | 0 | method: &str, |
140 | 0 | args: &[TokenStream], |
141 | 0 | ) -> Result<TokenStream> { |
142 | 0 | let method_ident = format_ident!("{}", method); |
143 | 0 | Ok(quote! { #obj.#method_ident(#(#args),*) }) |
144 | 0 | } |
145 | | |
146 | | /// Handle collection accessor methods (complexity: ~10) |
147 | 0 | fn transpile_collection_accessor( |
148 | 0 | &self, |
149 | 0 | obj: &TokenStream, |
150 | 0 | method: &str, |
151 | 0 | args: &[TokenStream], |
152 | 0 | ) -> Result<TokenStream> { |
153 | 0 | match method { |
154 | 0 | "slice" => { |
155 | 0 | if args.len() != 2 { |
156 | 0 | bail!("slice requires exactly 2 arguments"); |
157 | 0 | } |
158 | 0 | let start = &args[0]; |
159 | 0 | let end = &args[1]; |
160 | 0 | Ok(quote! { #obj[#start..#end].to_vec() }) |
161 | | } |
162 | 0 | "first" => Ok(quote! { #obj.first().cloned() }), |
163 | 0 | "last" => Ok(quote! { #obj.last().cloned() }), |
164 | | _ => { |
165 | 0 | let method_ident = format_ident!("{}", method); |
166 | 0 | Ok(quote! { #obj.#method_ident(#(#args),*) }) |
167 | | } |
168 | | } |
169 | 0 | } |
170 | | |
171 | | /// Handle string methods (complexity: ~12) |
172 | 0 | fn transpile_string_method( |
173 | 0 | &self, |
174 | 0 | obj: &TokenStream, |
175 | 0 | method: &str, |
176 | 0 | args: &[TokenStream], |
177 | 0 | ) -> Result<TokenStream> { |
178 | 0 | match method { |
179 | 0 | "to_s" | "to_string" => Ok(quote! { #obj }), |
180 | 0 | "to_upper" => Ok(quote! { #obj.to_uppercase(#(#args),*) }), |
181 | 0 | "to_lower" => Ok(quote! { #obj.to_lowercase(#(#args),*) }), |
182 | 0 | "length" => Ok(quote! { #obj.len(#(#args),*) }), |
183 | 0 | "trim" => Ok(quote! { #obj.trim(#(#args),*).to_string() }), |
184 | 0 | "split" => { |
185 | 0 | if args.is_empty() { |
186 | 0 | Ok(quote! { #obj.split_whitespace().map(String::from).collect::<Vec<_>>() }) |
187 | | } else { |
188 | 0 | Ok(quote! { #obj.split(#(#args),*).map(String::from).collect::<Vec<_>>() }) |
189 | | } |
190 | | } |
191 | 0 | "replace" => { |
192 | 0 | if args.len() != 2 { |
193 | 0 | bail!("replace requires exactly 2 arguments"); |
194 | 0 | } |
195 | 0 | Ok(quote! { #obj.replace(#(#args),*) }) |
196 | | } |
197 | 0 | "starts_with" | "ends_with" => { |
198 | 0 | let method_ident = format_ident!("{}", method); |
199 | 0 | Ok(quote! { #obj.#method_ident(#(#args),*) }) |
200 | | } |
201 | 0 | _ => unreachable!("Unknown string method: {}", method), |
202 | | } |
203 | 0 | } |
204 | | |
205 | | /// Handle `DataFrame` methods (complexity: ~5) |
206 | 0 | fn transpile_dataframe_method_refactored( |
207 | 0 | &self, |
208 | 0 | obj: &TokenStream, |
209 | 0 | method: &str, |
210 | 0 | args: &[TokenStream], |
211 | 0 | ) -> Result<TokenStream> { |
212 | 0 | let method_ident = format_ident!("{}", method); |
213 | 0 | Ok(quote! { #obj.#method_ident(#(#args),*) }) |
214 | 0 | } |
215 | | } |
216 | | #[cfg(test)] |
217 | | #[path = "method_call_refactored_tests.rs"] |
218 | | mod tests; |