/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 | 22 | pub fn transpile_method_call_refactored( |
13 | 22 | &self, |
14 | 22 | object: &Expr, |
15 | 22 | method: &str, |
16 | 22 | args: &[Expr], |
17 | 22 | ) -> Result<TokenStream> { |
18 | 22 | let obj_tokens = self.transpile_expr(object)?0 ; |
19 | 22 | let arg_tokens: Result<Vec<_>> = args.iter().map(|a| self16 .transpile_expr16 (a16 )).collect(); |
20 | 22 | let arg_tokens = arg_tokens?0 ; |
21 | | |
22 | | // Dispatch to specialized handlers based on method category |
23 | 22 | match method { |
24 | | // Iterator methods |
25 | 22 | "map" | "filter"21 | "reduce"20 | "fold"19 | "any"19 | "all"18 | "find"17 => |
26 | 6 | self.transpile_iterator_method(&obj_tokens, method, &arg_tokens), |
27 | | |
28 | | // HashMap/Dict methods |
29 | 16 | "get" | "contains_key"15 | "keys"14 | "values"14 | "items"14 | "entry"13 => |
30 | 3 | self.transpile_hashmap_method(&obj_tokens, method, &arg_tokens), |
31 | | |
32 | | // HashSet methods |
33 | 13 | "contains" | "union"12 | "intersection"11 | "difference"11 | "symmetric_difference"11 => |
34 | 2 | self.transpile_hashset_method(&obj_tokens, method, &arg_tokens), |
35 | | |
36 | | // Collection mutators |
37 | 11 | "insert" | "remove" | "clear" | "push" | "pop"10 | "append"9 | "extend"9 => |
38 | 2 | self.transpile_collection_mutator(&obj_tokens, method, &arg_tokens), |
39 | | |
40 | | // Collection accessors |
41 | 9 | "len" | "is_empty"8 | "iter"7 | "slice"7 | "first"7 | "last"7 => |
42 | 2 | self.transpile_collection_accessor(&obj_tokens, method, &arg_tokens), |
43 | | |
44 | | // String methods |
45 | 7 | "to_s" | "to_string" | "to_upper" | "to_lower"6 | "length"6 | |
46 | 6 | "trim" | "split"5 | "replace"4 | "starts_with"3 | "ends_with"3 => |
47 | 4 | self.transpile_string_method(&obj_tokens, method, &arg_tokens), |
48 | | |
49 | | // DataFrame methods |
50 | 3 | "select" | "groupby" | "agg" | "sort" | "mean" | "std" | "min" | "max" | |
51 | 3 | "sum" | "count" | "drop_nulls" | "fill_null" | "pivot" | "melt" | |
52 | 3 | "head" | "tail" | "sample" | "describe" => |
53 | 0 | self.transpile_dataframe_method_refactored(&obj_tokens, method, &arg_tokens), |
54 | | |
55 | | // Default: pass through |
56 | | _ => { |
57 | 3 | let method_ident = format_ident!("{}", method); |
58 | 3 | Ok(quote! { #obj_tokens.#method_ident(#(#arg_tokens),*) }) |
59 | | } |
60 | | } |
61 | 22 | } |
62 | | |
63 | | /// Handle iterator methods (complexity: ~10) |
64 | 6 | fn transpile_iterator_method( |
65 | 6 | &self, |
66 | 6 | obj: &TokenStream, |
67 | 6 | method: &str, |
68 | 6 | args: &[TokenStream], |
69 | 6 | ) -> Result<TokenStream> { |
70 | 6 | match method { |
71 | 6 | "map" => Ok(quote!1 { #obj.iter().map(#(#args),*).collect::<Vec<_>>() }), |
72 | 5 | "filter" => Ok(quote!1 { #obj.into_iter().filter(#(#args),*).collect::<Vec<_>>() }), |
73 | 4 | "reduce" => Ok(quote!1 { #obj.into_iter().reduce(#(#args),*) }), |
74 | 3 | "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 | 3 | "any" => Ok(quote!1 { #obj.iter().any(#(#args),*) }), |
83 | 2 | "all" => Ok(quote!1 { #obj.iter().all(#(#args),*) }), |
84 | 1 | "find" => Ok(quote! { #obj.iter().find(#(#args),*).cloned() }), |
85 | 0 | _ => unreachable!("Unknown iterator method: {}", method), |
86 | | } |
87 | 6 | } |
88 | | |
89 | | /// Handle HashMap/Dict methods (complexity: ~10) |
90 | 3 | fn transpile_hashmap_method( |
91 | 3 | &self, |
92 | 3 | obj: &TokenStream, |
93 | 3 | method: &str, |
94 | 3 | args: &[TokenStream], |
95 | 3 | ) -> Result<TokenStream> { |
96 | 3 | let method_ident = format_ident!("{}", method); |
97 | 3 | match method { |
98 | 3 | "get" => Ok(quote!1 { #obj.#method_ident(#(#args),*).cloned() }), |
99 | 2 | "items" => Ok(quote! { #obj.iter().map(|(k, v)| (k.clone(), v.clone())) })1 , |
100 | 1 | "contains_key" | "keys"0 | "values"0 | "entry"0 => |
101 | 1 | Ok(quote! { #obj.#method_ident(#(#args),*) }), |
102 | 0 | _ => unreachable!("Unknown HashMap method: {}", method), |
103 | | } |
104 | 3 | } |
105 | | |
106 | | /// Handle `HashSet` methods (complexity: ~12) |
107 | 2 | fn transpile_hashset_method( |
108 | 2 | &self, |
109 | 2 | obj: &TokenStream, |
110 | 2 | method: &str, |
111 | 2 | args: &[TokenStream], |
112 | 2 | ) -> Result<TokenStream> { |
113 | 2 | match method { |
114 | 2 | "contains" => { |
115 | 1 | let method_ident = format_ident!("{}", method); |
116 | 1 | Ok(quote! { #obj.#method_ident(#(#args),*) }) |
117 | | } |
118 | 1 | "union" | "intersection"0 | "difference"0 | "symmetric_difference"0 => { |
119 | 1 | if args.len() != 1 { |
120 | 0 | bail!("{} requires exactly 1 argument", method); |
121 | 1 | } |
122 | 1 | let other = &args[0]; |
123 | 1 | let method_ident = format_ident!("{}", method); |
124 | 1 | Ok(quote! { |
125 | 1 | { |
126 | 1 | use std::collections::HashSet; |
127 | 1 | #obj.#method_ident(&#other).cloned().collect::<HashSet<_>>() |
128 | 1 | } |
129 | 1 | }) |
130 | | } |
131 | 0 | _ => unreachable!("Unknown HashSet method: {}", method), |
132 | | } |
133 | 2 | } |
134 | | |
135 | | /// Handle collection mutator methods (complexity: ~5) |
136 | 2 | fn transpile_collection_mutator( |
137 | 2 | &self, |
138 | 2 | obj: &TokenStream, |
139 | 2 | method: &str, |
140 | 2 | args: &[TokenStream], |
141 | 2 | ) -> Result<TokenStream> { |
142 | 2 | let method_ident = format_ident!("{}", method); |
143 | 2 | Ok(quote! { #obj.#method_ident(#(#args),*) }) |
144 | 2 | } |
145 | | |
146 | | /// Handle collection accessor methods (complexity: ~10) |
147 | 2 | fn transpile_collection_accessor( |
148 | 2 | &self, |
149 | 2 | obj: &TokenStream, |
150 | 2 | method: &str, |
151 | 2 | args: &[TokenStream], |
152 | 2 | ) -> Result<TokenStream> { |
153 | 2 | match method { |
154 | 2 | "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 | 2 | "first" => Ok(quote! { #obj.first().cloned() })0 , |
163 | 2 | "last" => Ok(quote! { #obj.last().cloned() })0 , |
164 | | _ => { |
165 | 2 | let method_ident = format_ident!("{}", method); |
166 | 2 | Ok(quote! { #obj.#method_ident(#(#args),*) }) |
167 | | } |
168 | | } |
169 | 2 | } |
170 | | |
171 | | /// Handle string methods (complexity: ~12) |
172 | 4 | fn transpile_string_method( |
173 | 4 | &self, |
174 | 4 | obj: &TokenStream, |
175 | 4 | method: &str, |
176 | 4 | args: &[TokenStream], |
177 | 4 | ) -> Result<TokenStream> { |
178 | 4 | match method { |
179 | 4 | "to_s" | "to_string" => Ok(quote! { #obj })0 , |
180 | 4 | "to_upper" => Ok(quote!1 { #obj.to_uppercase(#(#args),*) }), |
181 | 3 | "to_lower" => Ok(quote!0 { #obj.to_lowercase(#(#args),*) }), |
182 | 3 | "length" => Ok(quote!0 { #obj.len(#(#args),*) }), |
183 | 3 | "trim" => Ok(quote!1 { #obj.trim(#(#args),*).to_string() }), |
184 | 2 | "split" => { |
185 | 1 | if args.is_empty() { |
186 | 0 | Ok(quote! { #obj.split_whitespace().map(String::from).collect::<Vec<_>>() }) |
187 | | } else { |
188 | 1 | Ok(quote! { #obj.split(#(#args),*).map(String::from).collect::<Vec<_>>() }) |
189 | | } |
190 | | } |
191 | 1 | "replace" => { |
192 | 1 | if args.len() != 2 { |
193 | 0 | bail!("replace requires exactly 2 arguments"); |
194 | 1 | } |
195 | 1 | 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 | 4 | } |
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; |