## Coverage Report

#### Created: 2025-09-08 21:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /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;