TypeScript_Rust_Compiler/
types.rs

1//! Type mapping from TypeScript to Rust
2
3use crate::ast::*;
4use crate::error::Result;
5use std::collections::HashMap;
6
7/// Type mapper for converting TypeScript types to Rust types
8pub struct TypeMapper {
9    /// Mapping of TypeScript types to Rust types
10    type_mappings: HashMap<String, String>,
11    /// Generic type parameters
12    generics: Vec<String>,
13    /// Runtime support enabled
14    runtime: bool,
15}
16
17impl TypeMapper {
18    /// Create a new type mapper
19    pub fn new(runtime: bool) -> Self {
20        let mut type_mappings = HashMap::new();
21        
22        // Primitive type mappings
23        type_mappings.insert("string".to_string(), "String".to_string());
24        type_mappings.insert("number".to_string(), "f64".to_string());
25        type_mappings.insert("boolean".to_string(), "bool".to_string());
26        type_mappings.insert("void".to_string(), "()".to_string());
27        type_mappings.insert("never".to_string(), "!".to_string());
28        type_mappings.insert("any".to_string(), "Box<dyn Any>".to_string());
29        type_mappings.insert("unknown".to_string(), "Box<dyn Any>".to_string());
30        type_mappings.insert("null".to_string(), "Option<()>".to_string());
31        type_mappings.insert("undefined".to_string(), "Option<()>".to_string());
32        type_mappings.insert("object".to_string(), "Box<dyn Any>".to_string());
33        type_mappings.insert("symbol".to_string(), "Symbol".to_string());
34        type_mappings.insert("bigint".to_string(), "i64".to_string());
35
36        Self {
37            type_mappings,
38            generics: Vec::new(),
39            runtime,
40        }
41    }
42
43    /// Map a TypeScript type to Rust type
44    pub fn map_type(&mut self, ts_type: &Type) -> Result<String> {
45        match ts_type {
46            // Primitive types
47            Type::String => Ok("String".to_string()),
48            Type::Number => Ok("f64".to_string()),
49            Type::Boolean => Ok("bool".to_string()),
50            Type::Any => {
51                if self.runtime {
52                    Ok("Box<dyn Any>".to_string())
53                } else {
54                    Ok("serde_json::Value".to_string())
55                }
56            }
57            Type::Void => Ok("()".to_string()),
58            Type::Never => Ok("!".to_string()),
59            Type::Unknown => {
60                if self.runtime {
61                    Ok("Box<dyn Any>".to_string())
62                } else {
63                    Ok("serde_json::Value".to_string())
64                }
65            }
66            Type::Null => Ok("Option<()>".to_string()),
67            Type::Undefined => Ok("Option<()>".to_string()),
68            Type::Object => {
69                if self.runtime {
70                    Ok("Box<dyn Any>".to_string())
71                } else {
72                    Ok("serde_json::Value".to_string())
73                }
74            }
75            Type::Symbol => Ok("Symbol".to_string()),
76            Type::BigInt => Ok("i64".to_string()),
77
78            // Named types
79            Type::Named(name) => self.map_named_type(name),
80            Type::Qualified(qualified) => self.map_qualified_type(qualified),
81
82            // Generic types
83            Type::Generic(generic) => self.map_generic_type(generic),
84            Type::GenericNamed { name, type_parameters } => {
85                let rust_name = self.map_named_type(name)?;
86                if type_parameters.is_empty() {
87                    Ok(rust_name)
88                } else {
89                    let param_types: Result<Vec<String>> = type_parameters
90                        .iter()
91                        .map(|param| self.map_type(&Type::Named(param.name.clone())))
92                        .collect();
93                    let param_types = param_types?;
94                    Ok(format!("{}<{}>", rust_name, param_types.join(", ")))
95                }
96            }
97
98            // Union types
99            Type::Union(types) => self.map_union_type(types),
100
101            // Intersection types
102            Type::Intersection(types) => self.map_intersection_type(types),
103
104            // Array types
105            Type::Array(element_type) => {
106                let element_rust = self.map_type(element_type)?;
107                Ok(format!("Vec<{}>", element_rust))
108            }
109
110            // Tuple types
111            Type::Tuple(types) => self.map_tuple_type(types),
112
113            // Function types
114            Type::Function(func_type) => self.map_function_type(func_type),
115
116            // Object types
117            Type::ObjectType(obj_type) => self.map_object_type(obj_type),
118
119            // Index signatures
120            Type::IndexSignature(index_sig) => self.map_index_signature(index_sig),
121
122            // Mapped types
123            Type::Mapped(mapped) => self.map_mapped_type(mapped),
124
125            // Conditional types
126            Type::Conditional(conditional) => self.map_conditional_type(conditional),
127
128            // Template literal types
129            Type::TemplateLiteral(template) => self.map_template_literal_type(template),
130
131            // Parenthesized types
132            Type::Parenthesized(inner) => self.map_type(inner),
133
134            // Type queries
135            Type::TypeQuery(query) => self.map_type_query(query),
136
137            // Import types
138            Type::Import(import) => self.map_import_type(import),
139        }
140    }
141
142    /// Map named type
143    fn map_named_type(&self, name: &str) -> Result<String> {
144        if let Some(mapped) = self.type_mappings.get(name) {
145            Ok(mapped.clone())
146        } else {
147            // Convert to PascalCase for Rust structs/traits
148            Ok(self.to_pascal_case(name))
149        }
150    }
151
152    /// Map qualified type
153    fn map_qualified_type(&mut self, qualified: &QualifiedTypeName) -> Result<String> {
154        let left = self.map_type(&qualified.left)?;
155        Ok(format!("{}::{}", left, qualified.right))
156    }
157
158    /// Map generic type
159    fn map_generic_type(&mut self, generic: &GenericType) -> Result<String> {
160        let base_type = self.map_type(&generic.type_)?;
161        let type_args: Result<Vec<String>> = generic
162            .type_arguments
163            .iter()
164            .map(|t| self.map_type(t))
165            .collect();
166        let type_args = type_args?;
167        
168        if type_args.is_empty() {
169            Ok(base_type)
170        } else {
171            Ok(format!("{}<{}>", base_type, type_args.join(", ")))
172        }
173    }
174
175    /// Map union type
176    fn map_union_type(&mut self, types: &[Type]) -> Result<String> {
177        if types.is_empty() {
178            return Ok("()".to_string());
179        }
180
181        if types.len() == 1 {
182            return self.map_type(&types[0]);
183        }
184
185        // Convert union to enum
186        let mut enum_variants = Vec::new();
187        for (i, ts_type) in types.iter().enumerate() {
188            let rust_type = self.map_type(ts_type)?;
189            enum_variants.push(format!("Variant{}({})", i, rust_type));
190        }
191
192        Ok(format!("UnionType {{\n    {}\n}}", enum_variants.join(",\n    ")))
193    }
194
195    /// Map intersection type
196    fn map_intersection_type(&mut self, types: &[Type]) -> Result<String> {
197        if types.is_empty() {
198            return Ok("()".to_string());
199        }
200
201        if types.len() == 1 {
202            return self.map_type(&types[0]);
203        }
204
205        // Convert intersection to trait bounds
206        let rust_types: Result<Vec<String>> = types
207            .iter()
208            .map(|t| self.map_type(t))
209            .collect();
210        let rust_types = rust_types?;
211
212        Ok(format!("({})", rust_types.join(" + ")))
213    }
214
215    /// Map tuple type
216    fn map_tuple_type(&mut self, types: &[Type]) -> Result<String> {
217        if types.is_empty() {
218            return Ok("()".to_string());
219        }
220
221        let rust_types: Result<Vec<String>> = types
222            .iter()
223            .map(|t| self.map_type(t))
224            .collect();
225        let rust_types = rust_types?;
226
227        Ok(format!("({})", rust_types.join(", ")))
228    }
229
230    /// Map function type
231    fn map_function_type(&mut self, func_type: &FunctionType) -> Result<String> {
232        let params: Result<Vec<String>> = func_type
233            .parameters
234            .iter()
235            .map(|param| {
236                let param_type = if let Some(ref t) = param.type_ {
237                    self.map_type(t)?
238                } else {
239                    "Box<dyn Any>".to_string()
240                };
241                Ok(format!("{}: {}", param.name, param_type))
242            })
243            .collect();
244        let params = params?;
245
246        let return_type = self.map_type(&func_type.return_type)?;
247
248        Ok(format!("fn({}) -> {}", params.join(", "), return_type))
249    }
250
251    /// Map object type
252    fn map_object_type(&mut self, obj_type: &ObjectType) -> Result<String> {
253        let mut struct_fields = Vec::new();
254        
255        for member in &obj_type.members {
256            match member {
257                ObjectTypeMember::Property(prop) => {
258                    let field_type = if let Some(ref t) = prop.type_ {
259                        self.map_type(t)?
260                    } else {
261                        "Box<dyn Any>".to_string()
262                    };
263                    
264                    let field_name = if prop.optional {
265                        format!("{}: Option<{}>", prop.name, field_type)
266                    } else {
267                        format!("{}: {}", prop.name, field_type)
268                    };
269                    
270                    struct_fields.push(field_name);
271                }
272                ObjectTypeMember::Method(method) => {
273                    // Methods become associated functions
274                    let params: Result<Vec<String>> = method
275                        .parameters
276                        .iter()
277                        .map(|param| {
278                            let param_type = if let Some(ref t) = param.type_ {
279                                self.map_type(t)?
280                            } else {
281                                "Box<dyn Any>".to_string()
282                            };
283                            Ok(format!("{}: {}", param.name, param_type))
284                        })
285                        .collect();
286                    let params = params?;
287
288                    let return_type = if let Some(ref t) = method.return_type {
289                        self.map_type(t)?
290                    } else {
291                        "()".to_string()
292                    };
293
294                    struct_fields.push(format!(
295                        "fn {}({}) -> {}",
296                        method.name, params.join(", "), return_type
297                    ));
298                }
299                _ => {
300                    // Handle other member types as needed
301                }
302            }
303        }
304
305        Ok(format!("struct ObjectType {{\n    {}\n}}", struct_fields.join(",\n    ")))
306    }
307
308    /// Map index signature
309    fn map_index_signature(&mut self, index_sig: &IndexSignature) -> Result<String> {
310        let key_type = self.map_type(&index_sig.parameter.type_.as_ref().map_or(Type::String, |v| *v.clone()))?;
311        let value_type = self.map_type(&index_sig.type_)?;
312        Ok(format!("HashMap<{}, {}>", key_type, value_type))
313    }
314
315    /// Map mapped type
316    fn map_mapped_type(&mut self, mapped: &MappedType) -> Result<String> {
317        // Convert mapped type to generic struct
318        let key_type = self.map_type(&mapped.type_parameter.constraint.as_ref().map_or(Type::String, |v| *v.clone()))?;
319        let value_type = self.map_type(&mapped.type_)?;
320        Ok(format!("HashMap<{}, {}>", key_type, value_type))
321    }
322
323    /// Map conditional type
324    fn map_conditional_type(&mut self, conditional: &ConditionalType) -> Result<String> {
325        // Convert conditional type to trait with associated type
326        let check_type = self.map_type(&conditional.check_type)?;
327        let extends_type = self.map_type(&conditional.extends_type)?;
328        let _true_type = self.map_type(&conditional.true_type)?;
329        let _false_type = self.map_type(&conditional.false_type)?;
330
331        Ok(format!(
332            "trait ConditionalType {{\n    type Output: PartialEq<{}>;\n    fn condition<{}>() -> Self::Output;\n}}",
333            extends_type, check_type
334        ))
335    }
336
337    /// Map template literal type
338    fn map_template_literal_type(&mut self, template: &TemplateLiteralType) -> Result<String> {
339        // Convert template literal type to const generic or macro
340        Ok(format!("\"{}\"", template.head))
341    }
342
343    /// Map type query
344    fn map_type_query(&mut self, _query: &TypeQuery) -> Result<String> {
345        // Convert type query to associated type
346        Ok("TypeQuery".to_string())
347    }
348
349    /// Map import type
350    fn map_import_type(&mut self, import: &ImportType) -> Result<String> {
351        let base_type = self.map_type(&import.argument)?;
352        if let Some(ref qualifier) = import.qualifier {
353            Ok(format!("{}::{}", base_type, qualifier))
354        } else {
355            Ok(base_type)
356        }
357    }
358
359    /// Convert string to PascalCase
360    fn to_pascal_case(&self, s: &str) -> String {
361        let mut result = String::new();
362        let mut capitalize = true;
363        
364        for ch in s.chars() {
365            if ch == '_' || ch == '-' {
366                capitalize = true;
367            } else if capitalize {
368                result.push(ch.to_uppercase().next().unwrap_or(ch));
369                capitalize = false;
370            } else {
371                result.push(ch);
372            }
373        }
374        
375        result
376    }
377
378    /// Add generic type parameter
379    pub fn add_generic(&mut self, name: String) {
380        self.generics.push(name);
381    }
382
383    /// Get all generic type parameters
384    pub fn get_generics(&self) -> &[String] {
385        &self.generics
386    }
387
388    /// Clear generic type parameters
389    pub fn clear_generics(&mut self) {
390        self.generics.clear();
391    }
392}
393
394/// Type mapping utilities
395pub struct TypeMappingUtils;
396
397impl TypeMappingUtils {
398    /// Check if a TypeScript type is primitive
399    pub fn is_primitive(ts_type: &Type) -> bool {
400        matches!(
401            ts_type,
402            Type::String
403                | Type::Number
404                | Type::Boolean
405                | Type::Void
406                | Type::Never
407                | Type::Any
408                | Type::Unknown
409                | Type::Null
410                | Type::Undefined
411                | Type::Object
412                | Type::Symbol
413                | Type::BigInt
414        )
415    }
416
417    /// Check if a TypeScript type is nullable
418    pub fn is_nullable(ts_type: &Type) -> bool {
419        matches!(ts_type, Type::Null | Type::Undefined)
420    }
421
422    /// Check if a TypeScript type is optional
423    pub fn is_optional(_ts_type: &Type) -> bool {
424        // This would need to be determined from context
425        false
426    }
427
428    /// Get the underlying type for optional types
429    pub fn get_underlying_type(ts_type: &Type) -> &Type {
430        // This would need to be implemented based on the specific type
431        ts_type
432    }
433
434    /// Check if a TypeScript type needs runtime support
435    pub fn needs_runtime(ts_type: &Type) -> bool {
436        matches!(
437            ts_type,
438            Type::Any | Type::Unknown | Type::Object | Type::Union(_) | Type::Intersection(_)
439        )
440    }
441
442    /// Generate Rust imports for a type
443    pub fn generate_imports(ts_type: &Type) -> Vec<String> {
444        let mut imports = Vec::new();
445
446        match ts_type {
447            Type::Any | Type::Unknown | Type::Object => {
448                imports.push("use std::any::Any;".to_string());
449                imports.push("use std::boxed::Box;".to_string());
450            }
451            Type::Union(_) => {
452                imports.push("use serde::{Deserialize, Serialize};".to_string());
453            }
454            Type::Intersection(_) => {
455                imports.push("use std::ops::Add;".to_string());
456            }
457            Type::Array(_) => {
458                imports.push("use std::vec::Vec;".to_string());
459            }
460            Type::Tuple(_) => {
461                // Tuples don't need special imports
462            }
463            Type::Function(_) => {
464                imports.push("use std::boxed::Box;".to_string());
465            }
466            _ => {}
467        }
468
469        imports
470    }
471}