Skip to main content

oxilean_codegen/swift_backend/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use crate::lcnf::*;
6
7use super::functions::OXILEAN_SWIFT_RUNTIME;
8
9use super::functions::*;
10use std::collections::{HashMap, HashSet, VecDeque};
11
12#[allow(dead_code)]
13#[derive(Debug, Clone)]
14pub struct SwiftDominatorTree {
15    pub idom: Vec<Option<u32>>,
16    pub dom_children: Vec<Vec<u32>>,
17    pub dom_depth: Vec<u32>,
18}
19impl SwiftDominatorTree {
20    #[allow(dead_code)]
21    pub fn new(size: usize) -> Self {
22        SwiftDominatorTree {
23            idom: vec![None; size],
24            dom_children: vec![Vec::new(); size],
25            dom_depth: vec![0; size],
26        }
27    }
28    #[allow(dead_code)]
29    pub fn set_idom(&mut self, node: usize, idom: u32) {
30        self.idom[node] = Some(idom);
31    }
32    #[allow(dead_code)]
33    pub fn dominates(&self, a: usize, b: usize) -> bool {
34        if a == b {
35            return true;
36        }
37        let mut cur = b;
38        loop {
39            match self.idom[cur] {
40                Some(parent) if parent as usize == a => return true,
41                Some(parent) if parent as usize == cur => return false,
42                Some(parent) => cur = parent as usize,
43                None => return false,
44            }
45        }
46    }
47    #[allow(dead_code)]
48    pub fn depth(&self, node: usize) -> u32 {
49        self.dom_depth.get(node).copied().unwrap_or(0)
50    }
51}
52/// A Swift struct declaration.
53#[derive(Debug, Clone, PartialEq)]
54pub struct SwiftStructDecl {
55    /// Struct name
56    pub name: String,
57    /// Fields (stored properties)
58    pub fields: Vec<SwiftField>,
59    /// Methods
60    pub methods: Vec<SwiftFunc>,
61    /// Protocol conformances
62    pub conformances: Vec<SwiftConformance>,
63    /// Whether `public`
64    pub is_public: bool,
65    /// Generic parameters
66    pub generic_params: Vec<String>,
67}
68impl SwiftStructDecl {
69    /// Create a new empty struct.
70    pub fn new(name: impl Into<String>) -> Self {
71        SwiftStructDecl {
72            name: name.into(),
73            fields: Vec::new(),
74            methods: Vec::new(),
75            conformances: Vec::new(),
76            is_public: false,
77            generic_params: Vec::new(),
78        }
79    }
80    /// Emit as Swift source.
81    pub fn codegen(&self) -> String {
82        let vis = if self.is_public { "public " } else { "" };
83        let generics = if self.generic_params.is_empty() {
84            String::new()
85        } else {
86            format!("<{}>", self.generic_params.join(", "))
87        };
88        let conformances = if self.conformances.is_empty() {
89            String::new()
90        } else {
91            format!(
92                ": {}",
93                self.conformances
94                    .iter()
95                    .map(|c| c.0.as_str())
96                    .collect::<Vec<_>>()
97                    .join(", ")
98            )
99        };
100        let mut out = format!(
101            "{}struct {}{}{} {{\n",
102            vis, self.name, generics, conformances
103        );
104        for field in &self.fields {
105            out += &field.codegen();
106            out += "\n";
107        }
108        for method in &self.methods {
109            for line in method.codegen().lines() {
110                out += "    ";
111                out += line;
112                out += "\n";
113            }
114        }
115        out += "}\n";
116        out
117    }
118}
119/// A Swift function (or method) declaration.
120#[derive(Debug, Clone, PartialEq)]
121pub struct SwiftFunc {
122    /// Function name
123    pub name: String,
124    /// Parameter list
125    pub params: Vec<SwiftParam>,
126    /// Return type (defaults to Void)
127    pub return_type: SwiftType,
128    /// Function body statements
129    pub body: Vec<SwiftStmt>,
130    /// Whether the function is `public`
131    pub is_public: bool,
132    /// Whether the function is `private`
133    pub is_private: bool,
134    /// Whether the function can `throw`
135    pub throws: bool,
136    /// Whether the function is `async`
137    pub is_async: bool,
138    /// Whether the function is `static`
139    pub is_static: bool,
140    /// Whether the function is `mutating`
141    pub is_mutating: bool,
142    /// Generic type parameters: `<T: Equatable, U>`
143    pub generic_params: Vec<String>,
144    /// Where clause
145    pub where_clause: Option<String>,
146}
147impl SwiftFunc {
148    /// Create a minimal function with the given name and return type.
149    pub fn new(name: impl Into<String>, return_type: SwiftType) -> Self {
150        SwiftFunc {
151            name: name.into(),
152            params: Vec::new(),
153            return_type,
154            body: Vec::new(),
155            is_public: false,
156            is_private: false,
157            throws: false,
158            is_async: false,
159            is_static: false,
160            is_mutating: false,
161            generic_params: Vec::new(),
162            where_clause: None,
163        }
164    }
165    /// Emit the function as a Swift source string.
166    pub fn codegen(&self) -> String {
167        let mut out = String::new();
168        if self.is_public {
169            out += "public ";
170        } else if self.is_private {
171            out += "private ";
172        }
173        if self.is_static {
174            out += "static ";
175        }
176        if self.is_mutating {
177            out += "mutating ";
178        }
179        out += "func ";
180        out += &self.name;
181        if !self.generic_params.is_empty() {
182            out += "<";
183            out += &self.generic_params.join(", ");
184            out += ">";
185        }
186        out += "(";
187        for (i, p) in self.params.iter().enumerate() {
188            if i > 0 {
189                out += ", ";
190            }
191            out += &p.to_string();
192        }
193        out += ")";
194        if self.is_async {
195            out += " async";
196        }
197        if self.throws {
198            out += " throws";
199        }
200        if self.return_type != SwiftType::SwiftVoid {
201            out += &format!(" -> {}", self.return_type);
202        }
203        if let Some(ref wh) = self.where_clause {
204            out += &format!(" where {}", wh);
205        }
206        out += " {\n";
207        out += &emit_block(&self.body, 4);
208        if !self.body.is_empty() {
209            out += "\n";
210        }
211        out += "}\n";
212        out
213    }
214}
215/// A conformance / protocol conformance constraint.
216#[derive(Debug, Clone, PartialEq)]
217pub struct SwiftConformance(pub String);
218#[allow(dead_code)]
219pub struct SwiftPassRegistry {
220    pub(super) configs: Vec<SwiftPassConfig>,
221    pub(super) stats: std::collections::HashMap<String, SwiftPassStats>,
222}
223impl SwiftPassRegistry {
224    #[allow(dead_code)]
225    pub fn new() -> Self {
226        SwiftPassRegistry {
227            configs: Vec::new(),
228            stats: std::collections::HashMap::new(),
229        }
230    }
231    #[allow(dead_code)]
232    pub fn register(&mut self, config: SwiftPassConfig) {
233        self.stats
234            .insert(config.pass_name.clone(), SwiftPassStats::new());
235        self.configs.push(config);
236    }
237    #[allow(dead_code)]
238    pub fn enabled_passes(&self) -> Vec<&SwiftPassConfig> {
239        self.configs.iter().filter(|c| c.enabled).collect()
240    }
241    #[allow(dead_code)]
242    pub fn get_stats(&self, name: &str) -> Option<&SwiftPassStats> {
243        self.stats.get(name)
244    }
245    #[allow(dead_code)]
246    pub fn total_passes(&self) -> usize {
247        self.configs.len()
248    }
249    #[allow(dead_code)]
250    pub fn enabled_count(&self) -> usize {
251        self.enabled_passes().len()
252    }
253    #[allow(dead_code)]
254    pub fn update_stats(&mut self, name: &str, changes: u64, time_ms: u64, iter: u32) {
255        if let Some(stats) = self.stats.get_mut(name) {
256            stats.record_run(changes, time_ms, iter);
257        }
258    }
259}
260#[allow(dead_code)]
261#[derive(Debug, Clone)]
262pub struct SwiftCacheEntry {
263    pub key: String,
264    pub data: Vec<u8>,
265    pub timestamp: u64,
266    pub valid: bool,
267}
268/// A Swift source module (one `.swift` file or a logical unit).
269#[derive(Debug, Clone, PartialEq)]
270pub struct SwiftModule {
271    /// Module/file name (without `.swift` extension)
272    pub name: String,
273    /// `import` statements
274    pub imports: Vec<String>,
275    /// Top-level type declarations
276    pub types: Vec<SwiftTypeDecl>,
277    /// Top-level function declarations
278    pub funcs: Vec<SwiftFunc>,
279    /// Extensions
280    pub extensions: Vec<SwiftExtension>,
281    /// Global `let`/`var` declarations emitted verbatim
282    pub globals: Vec<SwiftStmt>,
283}
284impl SwiftModule {
285    /// Create a new empty module.
286    pub fn new(name: impl Into<String>) -> Self {
287        SwiftModule {
288            name: name.into(),
289            imports: Vec::new(),
290            types: Vec::new(),
291            funcs: Vec::new(),
292            extensions: Vec::new(),
293            globals: Vec::new(),
294        }
295    }
296    /// Add an import (deduplicating).
297    pub fn add_import(&mut self, module: impl Into<String>) {
298        let m = module.into();
299        if !self.imports.contains(&m) {
300            self.imports.push(m);
301        }
302    }
303    /// Emit the complete Swift source for this module.
304    pub fn codegen(&self) -> String {
305        let mut out = String::new();
306        out += &format!("// OxiLean-generated Swift module: {}\n", self.name);
307        out += OXILEAN_SWIFT_RUNTIME;
308        out += "\n";
309        for imp in &self.imports {
310            out += &format!("import {}\n", imp);
311        }
312        if !self.imports.is_empty() {
313            out += "\n";
314        }
315        for g in &self.globals {
316            out += &format!("{}\n", emit_stmt(g, 0));
317        }
318        if !self.globals.is_empty() {
319            out += "\n";
320        }
321        for ty in &self.types {
322            out += &ty.codegen();
323            out += "\n";
324        }
325        for func in &self.funcs {
326            out += &func.codegen();
327            out += "\n";
328        }
329        for ext in &self.extensions {
330            out += &ext.codegen();
331            out += "\n";
332        }
333        out
334    }
335}
336/// A `case` arm in a switch statement.
337#[derive(Debug, Clone, PartialEq)]
338pub struct SwiftCase {
339    /// Pattern string (e.g. `".some(let x)"`, `"0"`, `"default"`)
340    pub pattern: String,
341    /// Body statements for this case
342    pub body: Vec<SwiftStmt>,
343}
344#[allow(dead_code)]
345pub struct SwiftConstantFoldingHelper;
346impl SwiftConstantFoldingHelper {
347    #[allow(dead_code)]
348    pub fn fold_add_i64(a: i64, b: i64) -> Option<i64> {
349        a.checked_add(b)
350    }
351    #[allow(dead_code)]
352    pub fn fold_sub_i64(a: i64, b: i64) -> Option<i64> {
353        a.checked_sub(b)
354    }
355    #[allow(dead_code)]
356    pub fn fold_mul_i64(a: i64, b: i64) -> Option<i64> {
357        a.checked_mul(b)
358    }
359    #[allow(dead_code)]
360    pub fn fold_div_i64(a: i64, b: i64) -> Option<i64> {
361        if b == 0 {
362            None
363        } else {
364            a.checked_div(b)
365        }
366    }
367    #[allow(dead_code)]
368    pub fn fold_add_f64(a: f64, b: f64) -> f64 {
369        a + b
370    }
371    #[allow(dead_code)]
372    pub fn fold_mul_f64(a: f64, b: f64) -> f64 {
373        a * b
374    }
375    #[allow(dead_code)]
376    pub fn fold_neg_i64(a: i64) -> Option<i64> {
377        a.checked_neg()
378    }
379    #[allow(dead_code)]
380    pub fn fold_not_bool(a: bool) -> bool {
381        !a
382    }
383    #[allow(dead_code)]
384    pub fn fold_and_bool(a: bool, b: bool) -> bool {
385        a && b
386    }
387    #[allow(dead_code)]
388    pub fn fold_or_bool(a: bool, b: bool) -> bool {
389        a || b
390    }
391    #[allow(dead_code)]
392    pub fn fold_shl_i64(a: i64, b: u32) -> Option<i64> {
393        a.checked_shl(b)
394    }
395    #[allow(dead_code)]
396    pub fn fold_shr_i64(a: i64, b: u32) -> Option<i64> {
397        a.checked_shr(b)
398    }
399    #[allow(dead_code)]
400    pub fn fold_rem_i64(a: i64, b: i64) -> Option<i64> {
401        if b == 0 {
402            None
403        } else {
404            Some(a % b)
405        }
406    }
407    #[allow(dead_code)]
408    pub fn fold_bitand_i64(a: i64, b: i64) -> i64 {
409        a & b
410    }
411    #[allow(dead_code)]
412    pub fn fold_bitor_i64(a: i64, b: i64) -> i64 {
413        a | b
414    }
415    #[allow(dead_code)]
416    pub fn fold_bitxor_i64(a: i64, b: i64) -> i64 {
417        a ^ b
418    }
419    #[allow(dead_code)]
420    pub fn fold_bitnot_i64(a: i64) -> i64 {
421        !a
422    }
423}
424/// Swift expression for code generation.
425#[derive(Debug, Clone, PartialEq)]
426pub enum SwiftExpr {
427    /// A literal value: `42`, `"hello"`, `true`, `nil`
428    SwiftLitExpr(SwiftLit),
429    /// A variable or identifier: `x`, `myVar`, `MyType`
430    SwiftVar(String),
431    /// A function/method call: `f(a, b)`
432    SwiftCall {
433        /// The function or method being called
434        callee: Box<SwiftExpr>,
435        /// Labeled arguments: `(label, expr)` — label is empty for unlabeled
436        args: Vec<(String, SwiftExpr)>,
437    },
438    /// Binary operator: `lhs + rhs`, `a == b`
439    SwiftBinOp {
440        op: String,
441        lhs: Box<SwiftExpr>,
442        rhs: Box<SwiftExpr>,
443    },
444    /// Member access: `obj.field`
445    SwiftMember(Box<SwiftExpr>, String),
446    /// Subscript: `arr[idx]`
447    SwiftSubscript(Box<SwiftExpr>, Box<SwiftExpr>),
448    /// Unary prefix operator: `!x`, `-n`
449    SwiftUnary(String, Box<SwiftExpr>),
450    /// Ternary conditional: `cond ? then : else`
451    SwiftTernary(Box<SwiftExpr>, Box<SwiftExpr>, Box<SwiftExpr>),
452    /// Closure expression: `{ params in body }`
453    SwiftClosure {
454        /// Parameter names with optional types
455        params: Vec<(String, Option<SwiftType>)>,
456        /// Return type annotation
457        return_type: Option<SwiftType>,
458        /// Body statements
459        body: Vec<SwiftStmt>,
460    },
461    /// Switch expression (Swift 5.9+): `switch x { case .a: expr }`
462    SwiftSwitchExpr {
463        /// The scrutinee
464        subject: Box<SwiftExpr>,
465        /// Arms: `(pattern_str, result_expr)`
466        arms: Vec<(String, SwiftExpr)>,
467    },
468    /// Optional chaining: `obj?.field`
469    SwiftOptionalChain(Box<SwiftExpr>, String),
470    /// Force unwrap: `expr!`
471    SwiftForceUnwrap(Box<SwiftExpr>),
472    /// Array literal: `[a, b, c]`
473    SwiftArrayLit(Vec<SwiftExpr>),
474    /// Dictionary literal: `[k1: v1, k2: v2]`
475    SwiftDictLit(Vec<(SwiftExpr, SwiftExpr)>),
476    /// Tuple literal: `(a, b)`
477    SwiftTupleLit(Vec<SwiftExpr>),
478    /// Type cast: `expr as Type`
479    SwiftAs(Box<SwiftExpr>, SwiftType),
480    /// Try expression: `try expr`
481    SwiftTry(Box<SwiftExpr>),
482    /// Await expression: `await expr`
483    SwiftAwait(Box<SwiftExpr>),
484    /// Self reference
485    SwiftSelf,
486    /// Super reference
487    SwiftSuper,
488}
489#[allow(dead_code)]
490#[derive(Debug, Clone)]
491pub struct SwiftWorklist {
492    pub(super) items: std::collections::VecDeque<u32>,
493    pub(super) in_worklist: std::collections::HashSet<u32>,
494}
495impl SwiftWorklist {
496    #[allow(dead_code)]
497    pub fn new() -> Self {
498        SwiftWorklist {
499            items: std::collections::VecDeque::new(),
500            in_worklist: std::collections::HashSet::new(),
501        }
502    }
503    #[allow(dead_code)]
504    pub fn push(&mut self, item: u32) -> bool {
505        if self.in_worklist.insert(item) {
506            self.items.push_back(item);
507            true
508        } else {
509            false
510        }
511    }
512    #[allow(dead_code)]
513    pub fn pop(&mut self) -> Option<u32> {
514        let item = self.items.pop_front()?;
515        self.in_worklist.remove(&item);
516        Some(item)
517    }
518    #[allow(dead_code)]
519    pub fn is_empty(&self) -> bool {
520        self.items.is_empty()
521    }
522    #[allow(dead_code)]
523    pub fn len(&self) -> usize {
524        self.items.len()
525    }
526    #[allow(dead_code)]
527    pub fn contains(&self, item: u32) -> bool {
528        self.in_worklist.contains(&item)
529    }
530}
531/// Swift literal values.
532#[derive(Debug, Clone, PartialEq)]
533pub enum SwiftLit {
534    /// Integer literal: `42`, `-7`
535    Int(i64),
536    /// Boolean literal: `true` or `false`
537    Bool(bool),
538    /// String literal: `"hello"`
539    Str(String),
540    /// `nil` literal
541    Nil,
542    /// Float/Double literal: `3.14`
543    Float(f64),
544}
545/// A Swift class declaration.
546#[derive(Debug, Clone, PartialEq)]
547pub struct SwiftClassDecl {
548    /// Class name
549    pub name: String,
550    /// Superclass (if any)
551    pub superclass: Option<String>,
552    /// Fields
553    pub fields: Vec<SwiftField>,
554    /// Methods
555    pub methods: Vec<SwiftFunc>,
556    /// Protocol conformances
557    pub conformances: Vec<SwiftConformance>,
558    /// Whether `public`
559    pub is_public: bool,
560    /// Whether `final`
561    pub is_final: bool,
562    /// Generic parameters
563    pub generic_params: Vec<String>,
564}
565impl SwiftClassDecl {
566    /// Create a new class.
567    pub fn new(name: impl Into<String>) -> Self {
568        SwiftClassDecl {
569            name: name.into(),
570            superclass: None,
571            fields: Vec::new(),
572            methods: Vec::new(),
573            conformances: Vec::new(),
574            is_public: false,
575            is_final: false,
576            generic_params: Vec::new(),
577        }
578    }
579    /// Emit as Swift source.
580    pub fn codegen(&self) -> String {
581        let vis = if self.is_public { "public " } else { "" };
582        let final_ = if self.is_final { "final " } else { "" };
583        let generics = if self.generic_params.is_empty() {
584            String::new()
585        } else {
586            format!("<{}>", self.generic_params.join(", "))
587        };
588        let mut inherit = Vec::new();
589        if let Some(ref sc) = self.superclass {
590            inherit.push(sc.clone());
591        }
592        for c in &self.conformances {
593            inherit.push(c.0.clone());
594        }
595        let inherit_str = if inherit.is_empty() {
596            String::new()
597        } else {
598            format!(": {}", inherit.join(", "))
599        };
600        let mut out = format!(
601            "{}{}class {}{}{} {{\n",
602            vis, final_, self.name, generics, inherit_str
603        );
604        for field in &self.fields {
605            out += &field.codegen();
606            out += "\n";
607        }
608        for method in &self.methods {
609            for line in method.codegen().lines() {
610                out += "    ";
611                out += line;
612                out += "\n";
613            }
614        }
615        out += "}\n";
616        out
617    }
618}
619#[allow(dead_code)]
620#[derive(Debug, Clone)]
621pub struct SwiftLivenessInfo {
622    pub live_in: Vec<std::collections::HashSet<u32>>,
623    pub live_out: Vec<std::collections::HashSet<u32>>,
624    pub defs: Vec<std::collections::HashSet<u32>>,
625    pub uses: Vec<std::collections::HashSet<u32>>,
626}
627impl SwiftLivenessInfo {
628    #[allow(dead_code)]
629    pub fn new(block_count: usize) -> Self {
630        SwiftLivenessInfo {
631            live_in: vec![std::collections::HashSet::new(); block_count],
632            live_out: vec![std::collections::HashSet::new(); block_count],
633            defs: vec![std::collections::HashSet::new(); block_count],
634            uses: vec![std::collections::HashSet::new(); block_count],
635        }
636    }
637    #[allow(dead_code)]
638    pub fn add_def(&mut self, block: usize, var: u32) {
639        if block < self.defs.len() {
640            self.defs[block].insert(var);
641        }
642    }
643    #[allow(dead_code)]
644    pub fn add_use(&mut self, block: usize, var: u32) {
645        if block < self.uses.len() {
646            self.uses[block].insert(var);
647        }
648    }
649    #[allow(dead_code)]
650    pub fn is_live_in(&self, block: usize, var: u32) -> bool {
651        self.live_in
652            .get(block)
653            .map(|s| s.contains(&var))
654            .unwrap_or(false)
655    }
656    #[allow(dead_code)]
657    pub fn is_live_out(&self, block: usize, var: u32) -> bool {
658        self.live_out
659            .get(block)
660            .map(|s| s.contains(&var))
661            .unwrap_or(false)
662    }
663}
664/// Swift type representation for type-directed code generation.
665#[derive(Debug, Clone, PartialEq, Eq, Hash)]
666pub enum SwiftType {
667    /// `Int` — platform-native signed integer
668    SwiftInt,
669    /// `Bool` — boolean
670    SwiftBool,
671    /// `String` — Unicode string
672    SwiftString,
673    /// `Double` — 64-bit floating-point
674    SwiftDouble,
675    /// `Float` — 32-bit floating-point
676    SwiftFloat,
677    /// `Void` — unit / no value
678    SwiftVoid,
679    /// `[T]` — array of T
680    SwiftArray(Box<SwiftType>),
681    /// `[K: V]` — dictionary
682    SwiftDict(Box<SwiftType>, Box<SwiftType>),
683    /// `T?` — optional
684    SwiftOptional(Box<SwiftType>),
685    /// `(A, B, ...)` — tuple
686    SwiftTuple(Vec<SwiftType>),
687    /// `(A, B) -> R` — function type
688    SwiftFunc(Vec<SwiftType>, Box<SwiftType>),
689    /// Named enum type
690    SwiftEnum(String),
691    /// Named struct type
692    SwiftStruct(String),
693    /// Named class type
694    SwiftClass(String),
695    /// Named protocol type
696    SwiftProtocol(String),
697    /// Generic type: `Array<T>`, `Result<T, E>`, etc.
698    SwiftGeneric(String, Vec<SwiftType>),
699    /// `Any` — existential any
700    SwiftAny,
701    /// `AnyObject` — class-constrained any
702    SwiftAnyObject,
703    /// `Never` — uninhabited type
704    SwiftNever,
705    /// Raw named type (user-supplied string)
706    SwiftNamed(String),
707}
708/// An enum case declaration.
709#[derive(Debug, Clone, PartialEq)]
710pub struct SwiftEnumCase {
711    /// Case name
712    pub name: String,
713    /// Associated value types (empty for bare cases)
714    pub associated: Vec<SwiftType>,
715    /// Raw value (for raw-value enums)
716    pub raw_value: Option<SwiftLit>,
717}
718impl SwiftEnumCase {
719    /// A bare enum case with no associated value.
720    pub fn bare(name: impl Into<String>) -> Self {
721        SwiftEnumCase {
722            name: name.into(),
723            associated: Vec::new(),
724            raw_value: None,
725        }
726    }
727    /// An enum case with associated values.
728    pub fn with_values(name: impl Into<String>, values: Vec<SwiftType>) -> Self {
729        SwiftEnumCase {
730            name: name.into(),
731            associated: values,
732            raw_value: None,
733        }
734    }
735    /// Emit as Swift source.
736    pub fn codegen(&self) -> String {
737        let mut out = format!("    case {}", self.name);
738        if !self.associated.is_empty() {
739            out += "(";
740            for (i, t) in self.associated.iter().enumerate() {
741                if i > 0 {
742                    out += ", ";
743                }
744                out += &t.to_string();
745            }
746            out += ")";
747        }
748        if let Some(ref rv) = self.raw_value {
749            out += &format!(" = {}", rv);
750        }
751        out
752    }
753}
754/// A field in a Swift struct or class.
755#[derive(Debug, Clone, PartialEq)]
756pub struct SwiftField {
757    /// Field name
758    pub name: String,
759    /// Field type
760    pub ty: SwiftType,
761    /// Whether the field is `var` (mutable) vs `let` (immutable)
762    pub mutable: bool,
763    /// Whether the field is `public`
764    pub is_public: bool,
765    /// Default value expression
766    pub default: Option<SwiftExpr>,
767}
768impl SwiftField {
769    /// Create an immutable field.
770    pub fn new_let(name: impl Into<String>, ty: SwiftType) -> Self {
771        SwiftField {
772            name: name.into(),
773            ty,
774            mutable: false,
775            is_public: false,
776            default: None,
777        }
778    }
779    /// Create a mutable field.
780    pub fn new_var(name: impl Into<String>, ty: SwiftType) -> Self {
781        SwiftField {
782            name: name.into(),
783            ty,
784            mutable: true,
785            is_public: false,
786            default: None,
787        }
788    }
789    /// Emit as Swift source.
790    pub fn codegen(&self) -> String {
791        let vis = if self.is_public { "public " } else { "" };
792        let kw = if self.mutable { "var" } else { "let" };
793        let default = self
794            .default
795            .as_ref()
796            .map(|v| format!(" = {}", v))
797            .unwrap_or_default();
798        format!("    {}{} {}: {}{}", vis, kw, self.name, self.ty, default)
799    }
800}
801/// A parameter in a Swift function declaration.
802#[derive(Debug, Clone, PartialEq)]
803pub struct SwiftParam {
804    /// External label (use `_` for unlabeled)
805    pub label: String,
806    /// Internal parameter name
807    pub name: String,
808    /// Parameter type
809    pub ty: SwiftType,
810    /// Default value expression
811    pub default: Option<SwiftExpr>,
812    /// Whether the parameter is variadic (`...`)
813    pub variadic: bool,
814    /// Whether the parameter is `inout`
815    pub inout: bool,
816}
817impl SwiftParam {
818    /// Create a simple labeled parameter.
819    pub fn new(name: impl Into<String>, ty: SwiftType) -> Self {
820        SwiftParam {
821            label: String::new(),
822            name: name.into(),
823            ty,
824            default: None,
825            variadic: false,
826            inout: false,
827        }
828    }
829    /// Create a parameter with separate external label and internal name.
830    pub fn labeled(label: impl Into<String>, name: impl Into<String>, ty: SwiftType) -> Self {
831        SwiftParam {
832            label: label.into(),
833            name: name.into(),
834            ty,
835            default: None,
836            variadic: false,
837            inout: false,
838        }
839    }
840}
841/// Swift statement for code generation.
842#[derive(Debug, Clone, PartialEq)]
843pub enum SwiftStmt {
844    /// `let name: Type = expr`
845    Let {
846        name: String,
847        ty: Option<SwiftType>,
848        value: SwiftExpr,
849    },
850    /// `var name: Type = expr`
851    Var {
852        name: String,
853        ty: Option<SwiftType>,
854        value: Option<SwiftExpr>,
855    },
856    /// `target = expr`
857    Assign { target: SwiftExpr, value: SwiftExpr },
858    /// `return expr?`
859    Return(Option<SwiftExpr>),
860    /// `if cond { then } else { else }`
861    If {
862        cond: SwiftExpr,
863        then_body: Vec<SwiftStmt>,
864        else_body: Vec<SwiftStmt>,
865    },
866    /// `if let name = expr { ... } else { ... }`
867    IfLet {
868        name: String,
869        value: SwiftExpr,
870        then_body: Vec<SwiftStmt>,
871        else_body: Vec<SwiftStmt>,
872    },
873    /// `guard cond else { ... }`
874    Guard {
875        cond: SwiftExpr,
876        else_body: Vec<SwiftStmt>,
877    },
878    /// `switch subject { case ... }`
879    Switch {
880        subject: SwiftExpr,
881        cases: Vec<SwiftCase>,
882    },
883    /// `for name in collection { body }`
884    For {
885        name: String,
886        collection: SwiftExpr,
887        body: Vec<SwiftStmt>,
888    },
889    /// `while cond { body }`
890    While {
891        cond: SwiftExpr,
892        body: Vec<SwiftStmt>,
893    },
894    /// `throw expr`
895    Throw(SwiftExpr),
896    /// `break`
897    Break,
898    /// `continue`
899    Continue,
900    /// Bare expression statement
901    ExprStmt(SwiftExpr),
902    /// A raw block of statements: `{ stmts }`
903    Block(Vec<SwiftStmt>),
904    /// A raw string inserted verbatim (for runtime preamble, etc.)
905    Raw(String),
906}
907/// Discriminated union of all Swift type declarations.
908#[derive(Debug, Clone, PartialEq)]
909pub enum SwiftTypeDecl {
910    Enum(SwiftEnumDecl),
911    Struct(SwiftStructDecl),
912    Class(SwiftClassDecl),
913}
914impl SwiftTypeDecl {
915    /// Emit as Swift source.
916    pub fn codegen(&self) -> String {
917        match self {
918            SwiftTypeDecl::Enum(e) => e.codegen(),
919            SwiftTypeDecl::Struct(s) => s.codegen(),
920            SwiftTypeDecl::Class(c) => c.codegen(),
921        }
922    }
923}
924#[allow(dead_code)]
925#[derive(Debug, Clone, Default)]
926pub struct SwiftPassStats {
927    pub total_runs: u32,
928    pub successful_runs: u32,
929    pub total_changes: u64,
930    pub time_ms: u64,
931    pub iterations_used: u32,
932}
933impl SwiftPassStats {
934    #[allow(dead_code)]
935    pub fn new() -> Self {
936        Self::default()
937    }
938    #[allow(dead_code)]
939    pub fn record_run(&mut self, changes: u64, time_ms: u64, iterations: u32) {
940        self.total_runs += 1;
941        self.successful_runs += 1;
942        self.total_changes += changes;
943        self.time_ms += time_ms;
944        self.iterations_used = iterations;
945    }
946    #[allow(dead_code)]
947    pub fn average_changes_per_run(&self) -> f64 {
948        if self.total_runs == 0 {
949            return 0.0;
950        }
951        self.total_changes as f64 / self.total_runs as f64
952    }
953    #[allow(dead_code)]
954    pub fn success_rate(&self) -> f64 {
955        if self.total_runs == 0 {
956            return 0.0;
957        }
958        self.successful_runs as f64 / self.total_runs as f64
959    }
960    #[allow(dead_code)]
961    pub fn format_summary(&self) -> String {
962        format!(
963            "Runs: {}/{}, Changes: {}, Time: {}ms",
964            self.successful_runs, self.total_runs, self.total_changes, self.time_ms
965        )
966    }
967}
968#[allow(dead_code)]
969#[derive(Debug, Clone)]
970pub struct SwiftAnalysisCache {
971    pub(super) entries: std::collections::HashMap<String, SwiftCacheEntry>,
972    pub(super) max_size: usize,
973    pub(super) hits: u64,
974    pub(super) misses: u64,
975}
976impl SwiftAnalysisCache {
977    #[allow(dead_code)]
978    pub fn new(max_size: usize) -> Self {
979        SwiftAnalysisCache {
980            entries: std::collections::HashMap::new(),
981            max_size,
982            hits: 0,
983            misses: 0,
984        }
985    }
986    #[allow(dead_code)]
987    pub fn get(&mut self, key: &str) -> Option<&SwiftCacheEntry> {
988        if self.entries.contains_key(key) {
989            self.hits += 1;
990            self.entries.get(key)
991        } else {
992            self.misses += 1;
993            None
994        }
995    }
996    #[allow(dead_code)]
997    pub fn insert(&mut self, key: String, data: Vec<u8>) {
998        if self.entries.len() >= self.max_size {
999            if let Some(oldest) = self.entries.keys().next().cloned() {
1000                self.entries.remove(&oldest);
1001            }
1002        }
1003        self.entries.insert(
1004            key.clone(),
1005            SwiftCacheEntry {
1006                key,
1007                data,
1008                timestamp: 0,
1009                valid: true,
1010            },
1011        );
1012    }
1013    #[allow(dead_code)]
1014    pub fn invalidate(&mut self, key: &str) {
1015        if let Some(entry) = self.entries.get_mut(key) {
1016            entry.valid = false;
1017        }
1018    }
1019    #[allow(dead_code)]
1020    pub fn clear(&mut self) {
1021        self.entries.clear();
1022    }
1023    #[allow(dead_code)]
1024    pub fn hit_rate(&self) -> f64 {
1025        let total = self.hits + self.misses;
1026        if total == 0 {
1027            return 0.0;
1028        }
1029        self.hits as f64 / total as f64
1030    }
1031    #[allow(dead_code)]
1032    pub fn size(&self) -> usize {
1033        self.entries.len()
1034    }
1035}
1036/// A Swift `extension` declaration.
1037#[derive(Debug, Clone, PartialEq)]
1038pub struct SwiftExtension {
1039    /// The type being extended
1040    pub target: String,
1041    /// Additional conformances added by this extension
1042    pub conformances: Vec<SwiftConformance>,
1043    /// Methods added
1044    pub methods: Vec<SwiftFunc>,
1045    /// Where clause
1046    pub where_clause: Option<String>,
1047}
1048impl SwiftExtension {
1049    /// Create a new extension.
1050    pub fn new(target: impl Into<String>) -> Self {
1051        SwiftExtension {
1052            target: target.into(),
1053            conformances: Vec::new(),
1054            methods: Vec::new(),
1055            where_clause: None,
1056        }
1057    }
1058    /// Emit as Swift source.
1059    pub fn codegen(&self) -> String {
1060        let conformances = if self.conformances.is_empty() {
1061            String::new()
1062        } else {
1063            format!(
1064                ": {}",
1065                self.conformances
1066                    .iter()
1067                    .map(|c| c.0.as_str())
1068                    .collect::<Vec<_>>()
1069                    .join(", ")
1070            )
1071        };
1072        let where_str = self
1073            .where_clause
1074            .as_ref()
1075            .map(|w| format!(" where {}", w))
1076            .unwrap_or_default();
1077        let mut out = format!(
1078            "extension {}{}{} {{\n",
1079            self.target, conformances, where_str
1080        );
1081        for method in &self.methods {
1082            for line in method.codegen().lines() {
1083                out += "    ";
1084                out += line;
1085                out += "\n";
1086            }
1087        }
1088        out += "}\n";
1089        out
1090    }
1091}
1092/// Swift code generation backend.
1093///
1094/// Compiles LCNF declarations/expressions to valid Swift source code.
1095/// Entry points:
1096/// - [`SwiftBackend::compile_module`] — compile a complete `LcnfDecl` collection
1097/// - [`SwiftBackend::compile_decl`]   — compile a single `LcnfDecl`
1098/// - [`SwiftBackend::compile_expr`]   — compile an `LcnfExpr`
1099/// - [`SwiftBackend::mangle_name`]    — escape an OxiLean identifier for Swift
1100pub struct SwiftBackend {
1101    /// Fresh variable counter for temporaries
1102    pub(super) var_counter: u64,
1103    /// Whether to emit public declarations
1104    pub emit_public: bool,
1105    /// Whether to emit inline comments
1106    pub emit_comments: bool,
1107}
1108impl SwiftBackend {
1109    /// Create a new backend with default settings.
1110    pub fn new() -> Self {
1111        SwiftBackend {
1112            var_counter: 0,
1113            emit_public: true,
1114            emit_comments: true,
1115        }
1116    }
1117    /// Allocate a fresh temporary variable name.
1118    pub fn fresh_var(&mut self) -> String {
1119        let n = self.var_counter;
1120        self.var_counter += 1;
1121        format!("_ox{}", n)
1122    }
1123    /// Mangle an OxiLean name into a valid Swift identifier.
1124    ///
1125    /// Rules:
1126    /// 1. Empty input → `"ox_empty"`
1127    /// 2. Swift keywords → prefixed with `ox_`
1128    /// 3. Leading digit → prefixed with `ox_`
1129    /// 4. Non-alphanumeric / non-underscore characters → replaced with `_`
1130    pub fn mangle_name(name: &str) -> String {
1131        if name.is_empty() {
1132            return "ox_empty".to_string();
1133        }
1134        let sanitized: String = name
1135            .chars()
1136            .map(|c| {
1137                if c.is_alphanumeric() || c == '_' {
1138                    c
1139                } else {
1140                    '_'
1141                }
1142            })
1143            .collect();
1144        let sanitized = if sanitized.starts_with(|c: char| c.is_ascii_digit()) {
1145            format!("ox_{}", sanitized)
1146        } else {
1147            sanitized
1148        };
1149        if is_swift_keyword(&sanitized) {
1150            format!("ox_{}", sanitized)
1151        } else {
1152            sanitized
1153        }
1154    }
1155    /// Compile an LCNF argument to a Swift expression.
1156    pub fn compile_arg(&self, arg: &LcnfArg) -> SwiftExpr {
1157        match arg {
1158            LcnfArg::Var(id) => SwiftExpr::SwiftVar(format!("{}", id)),
1159            LcnfArg::Lit(lit) => self.compile_lit(lit),
1160            LcnfArg::Erased => SwiftExpr::SwiftMember(
1161                Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1162                "erased".to_string(),
1163            ),
1164            LcnfArg::Type(_) => SwiftExpr::SwiftMember(
1165                Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1166                "erased".to_string(),
1167            ),
1168        }
1169    }
1170    /// Compile an LCNF literal to a Swift expression.
1171    pub fn compile_lit(&self, lit: &LcnfLit) -> SwiftExpr {
1172        match lit {
1173            LcnfLit::Nat(n) => SwiftExpr::SwiftLitExpr(SwiftLit::Int(*n as i64)),
1174            LcnfLit::Int(i) => SwiftExpr::SwiftLitExpr(SwiftLit::Int(*i)),
1175            LcnfLit::Str(s) => SwiftExpr::SwiftLitExpr(SwiftLit::Str(s.clone())),
1176        }
1177    }
1178    /// Compile an LCNF expression to a list of Swift statements.
1179    ///
1180    /// The final statement is always a `return`.
1181    pub fn compile_expr(&self, expr: &LcnfExpr) -> Vec<SwiftStmt> {
1182        match expr {
1183            LcnfExpr::Return(arg) => vec![SwiftStmt::Return(Some(self.compile_arg(arg)))],
1184            LcnfExpr::Unreachable => {
1185                vec![SwiftStmt::ExprStmt(SwiftExpr::SwiftCall {
1186                    callee: Box::new(SwiftExpr::SwiftVar("ox_unreachable".to_string())),
1187                    args: Vec::new(),
1188                })]
1189            }
1190            LcnfExpr::TailCall(func, args) => {
1191                let callee = Box::new(self.compile_arg(func));
1192                let call_args = args
1193                    .iter()
1194                    .map(|a| (String::new(), self.compile_arg(a)))
1195                    .collect();
1196                vec![SwiftStmt::Return(Some(SwiftExpr::SwiftCall {
1197                    callee,
1198                    args: call_args,
1199                }))]
1200            }
1201            LcnfExpr::Let {
1202                id, value, body, ..
1203            } => {
1204                let var_name = format!("{}", id);
1205                let rhs = self.compile_let_value(value);
1206                let mut stmts = vec![SwiftStmt::Let {
1207                    name: var_name,
1208                    ty: None,
1209                    value: rhs,
1210                }];
1211                stmts.extend(self.compile_expr(body));
1212                stmts
1213            }
1214            LcnfExpr::Case {
1215                scrutinee,
1216                alts,
1217                default,
1218                ..
1219            } => {
1220                let subject = SwiftExpr::SwiftVar(format!("{}", scrutinee));
1221                let mut cases: Vec<SwiftCase> = alts
1222                    .iter()
1223                    .map(|alt| {
1224                        let pattern = format!(".ctor(tag: {}, _)", alt.ctor_tag);
1225                        let body = self.compile_expr(&alt.body);
1226                        SwiftCase { pattern, body }
1227                    })
1228                    .collect();
1229                if let Some(def) = default {
1230                    let def_body = self.compile_expr(def);
1231                    cases.push(SwiftCase {
1232                        pattern: "default".to_string(),
1233                        body: def_body,
1234                    });
1235                } else {
1236                    cases.push(SwiftCase {
1237                        pattern: "default".to_string(),
1238                        body: vec![SwiftStmt::ExprStmt(SwiftExpr::SwiftCall {
1239                            callee: Box::new(SwiftExpr::SwiftVar("ox_unreachable".to_string())),
1240                            args: Vec::new(),
1241                        })],
1242                    });
1243                }
1244                vec![SwiftStmt::Switch { subject, cases }]
1245            }
1246        }
1247    }
1248    /// Compile a let-value to a Swift expression.
1249    pub fn compile_let_value(&self, value: &LcnfLetValue) -> SwiftExpr {
1250        match value {
1251            LcnfLetValue::Lit(lit) => self.compile_lit(lit),
1252            LcnfLetValue::Erased => SwiftExpr::SwiftMember(
1253                Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1254                "erased".to_string(),
1255            ),
1256            LcnfLetValue::FVar(id) => SwiftExpr::SwiftVar(format!("{}", id)),
1257            LcnfLetValue::App(func, args) => {
1258                let callee = Box::new(self.compile_arg(func));
1259                let call_args = args
1260                    .iter()
1261                    .map(|a| (String::new(), self.compile_arg(a)))
1262                    .collect();
1263                SwiftExpr::SwiftCall {
1264                    callee,
1265                    args: call_args,
1266                }
1267            }
1268            LcnfLetValue::Ctor(name, tag, args) => {
1269                let tag_pair = (
1270                    "tag".to_string(),
1271                    SwiftExpr::SwiftLitExpr(SwiftLit::Int(*tag as i64)),
1272                );
1273                let field_exprs: Vec<SwiftExpr> =
1274                    args.iter().map(|a| self.compile_arg(a)).collect();
1275                let fields_array = SwiftExpr::SwiftArrayLit(field_exprs);
1276                let _ = name;
1277                SwiftExpr::SwiftCall {
1278                    callee: Box::new(SwiftExpr::SwiftMember(
1279                        Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1280                        "ctor".to_string(),
1281                    )),
1282                    args: vec![tag_pair, ("fields".to_string(), fields_array)],
1283                }
1284            }
1285            LcnfLetValue::Proj(_, idx, var) => {
1286                let base = SwiftExpr::SwiftMember(
1287                    Box::new(SwiftExpr::SwiftVar(format!("{}", var))),
1288                    "fields".to_string(),
1289                );
1290                SwiftExpr::SwiftSubscript(
1291                    Box::new(base),
1292                    Box::new(SwiftExpr::SwiftLitExpr(SwiftLit::Int(*idx as i64))),
1293                )
1294            }
1295            LcnfLetValue::Reset(var) => SwiftExpr::SwiftVar(format!("{}", var)),
1296            LcnfLetValue::Reuse(_, name, tag, args) => {
1297                let tag_pair = (
1298                    "tag".to_string(),
1299                    SwiftExpr::SwiftLitExpr(SwiftLit::Int(*tag as i64)),
1300                );
1301                let field_exprs: Vec<SwiftExpr> =
1302                    args.iter().map(|a| self.compile_arg(a)).collect();
1303                let fields_array = SwiftExpr::SwiftArrayLit(field_exprs);
1304                let _ = name;
1305                SwiftExpr::SwiftCall {
1306                    callee: Box::new(SwiftExpr::SwiftMember(
1307                        Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1308                        "ctor".to_string(),
1309                    )),
1310                    args: vec![tag_pair, ("fields".to_string(), fields_array)],
1311                }
1312            }
1313        }
1314    }
1315    /// Compile a single LCNF function declaration to a [`SwiftFunc`].
1316    pub fn compile_decl(&self, decl: &LcnfFunDecl) -> SwiftFunc {
1317        let safe_name = Self::mangle_name(&decl.name.to_string());
1318        let params: Vec<SwiftParam> = decl
1319            .params
1320            .iter()
1321            .map(|p| {
1322                let pname = Self::mangle_name(&p.name);
1323                SwiftParam {
1324                    label: "_".to_string(),
1325                    name: pname,
1326                    ty: self.compile_lcnf_type(&p.ty),
1327                    default: None,
1328                    variadic: false,
1329                    inout: false,
1330                }
1331            })
1332            .collect();
1333        let body = self.compile_expr(&decl.body);
1334        let mut func = SwiftFunc::new(safe_name, SwiftType::SwiftNamed("OxValue".to_string()));
1335        func.params = params;
1336        func.body = body;
1337        func.is_public = self.emit_public;
1338        func
1339    }
1340    /// Map an LCNF type to the closest Swift type.
1341    pub fn compile_lcnf_type(&self, ty: &LcnfType) -> SwiftType {
1342        match ty {
1343            LcnfType::Nat
1344            | LcnfType::Int
1345            | LcnfType::Unit
1346            | LcnfType::Erased
1347            | LcnfType::Irrelevant => SwiftType::SwiftNamed("OxValue".to_string()),
1348            LcnfType::LcnfString => SwiftType::SwiftNamed("OxValue".to_string()),
1349            LcnfType::Object => SwiftType::SwiftNamed("OxValue".to_string()),
1350            LcnfType::Var(_) => SwiftType::SwiftNamed("OxValue".to_string()),
1351            LcnfType::Fun(params, ret) => {
1352                let p: Vec<SwiftType> = params.iter().map(|p| self.compile_lcnf_type(p)).collect();
1353                let r = Box::new(self.compile_lcnf_type(ret));
1354                SwiftType::SwiftFunc(p, r)
1355            }
1356            LcnfType::Ctor(_, _) => SwiftType::SwiftNamed("OxValue".to_string()),
1357        }
1358    }
1359    /// Compile a collection of LCNF declarations into a [`SwiftModule`].
1360    pub fn compile_module(&self, name: &str, decls: &[LcnfFunDecl]) -> SwiftModule {
1361        let mut module = SwiftModule::new(name);
1362        module.add_import("Foundation");
1363        for decl in decls {
1364            let func = self.compile_decl(decl);
1365            module.funcs.push(func);
1366        }
1367        module
1368    }
1369    /// Emit a [`SwiftModule`] to a Swift source string.
1370    pub fn emit_module(&self, module: &SwiftModule) -> String {
1371        module.codegen()
1372    }
1373    /// Emit a single [`SwiftFunc`] to a Swift source string.
1374    pub fn emit_func(&self, func: &SwiftFunc) -> String {
1375        func.codegen()
1376    }
1377    /// Emit a single [`SwiftTypeDecl`] to a Swift source string.
1378    pub fn emit_type_decl(&self, decl: &SwiftTypeDecl) -> String {
1379        decl.codegen()
1380    }
1381}
1382#[allow(dead_code)]
1383#[derive(Debug, Clone)]
1384pub struct SwiftPassConfig {
1385    pub phase: SwiftPassPhase,
1386    pub enabled: bool,
1387    pub max_iterations: u32,
1388    pub debug_output: bool,
1389    pub pass_name: String,
1390}
1391impl SwiftPassConfig {
1392    #[allow(dead_code)]
1393    pub fn new(name: impl Into<String>, phase: SwiftPassPhase) -> Self {
1394        SwiftPassConfig {
1395            phase,
1396            enabled: true,
1397            max_iterations: 10,
1398            debug_output: false,
1399            pass_name: name.into(),
1400        }
1401    }
1402    #[allow(dead_code)]
1403    pub fn disabled(mut self) -> Self {
1404        self.enabled = false;
1405        self
1406    }
1407    #[allow(dead_code)]
1408    pub fn with_debug(mut self) -> Self {
1409        self.debug_output = true;
1410        self
1411    }
1412    #[allow(dead_code)]
1413    pub fn max_iter(mut self, n: u32) -> Self {
1414        self.max_iterations = n;
1415        self
1416    }
1417}
1418/// A Swift enum declaration.
1419#[derive(Debug, Clone, PartialEq)]
1420pub struct SwiftEnumDecl {
1421    /// Enum name
1422    pub name: String,
1423    /// Enum cases
1424    pub cases: Vec<SwiftEnumCase>,
1425    /// Methods defined on this enum
1426    pub methods: Vec<SwiftFunc>,
1427    /// Protocol conformances / inheritance list
1428    pub conformances: Vec<SwiftConformance>,
1429    /// Whether `public`
1430    pub is_public: bool,
1431    /// Generic parameters
1432    pub generic_params: Vec<String>,
1433}
1434impl SwiftEnumDecl {
1435    /// Create a new empty enum.
1436    pub fn new(name: impl Into<String>) -> Self {
1437        SwiftEnumDecl {
1438            name: name.into(),
1439            cases: Vec::new(),
1440            methods: Vec::new(),
1441            conformances: Vec::new(),
1442            is_public: false,
1443            generic_params: Vec::new(),
1444        }
1445    }
1446    /// Emit as Swift source.
1447    pub fn codegen(&self) -> String {
1448        let vis = if self.is_public { "public " } else { "" };
1449        let generics = if self.generic_params.is_empty() {
1450            String::new()
1451        } else {
1452            format!("<{}>", self.generic_params.join(", "))
1453        };
1454        let conformances = if self.conformances.is_empty() {
1455            String::new()
1456        } else {
1457            format!(
1458                ": {}",
1459                self.conformances
1460                    .iter()
1461                    .map(|c| c.0.as_str())
1462                    .collect::<Vec<_>>()
1463                    .join(", ")
1464            )
1465        };
1466        let mut out = format!("{}enum {}{}{} {{\n", vis, self.name, generics, conformances);
1467        for case in &self.cases {
1468            out += &case.codegen();
1469            out += "\n";
1470        }
1471        for method in &self.methods {
1472            for line in method.codegen().lines() {
1473                out += "    ";
1474                out += line;
1475                out += "\n";
1476            }
1477        }
1478        out += "}\n";
1479        out
1480    }
1481}
1482#[allow(dead_code)]
1483#[derive(Debug, Clone, PartialEq)]
1484pub enum SwiftPassPhase {
1485    Analysis,
1486    Transformation,
1487    Verification,
1488    Cleanup,
1489}
1490impl SwiftPassPhase {
1491    #[allow(dead_code)]
1492    pub fn name(&self) -> &str {
1493        match self {
1494            SwiftPassPhase::Analysis => "analysis",
1495            SwiftPassPhase::Transformation => "transformation",
1496            SwiftPassPhase::Verification => "verification",
1497            SwiftPassPhase::Cleanup => "cleanup",
1498        }
1499    }
1500    #[allow(dead_code)]
1501    pub fn is_modifying(&self) -> bool {
1502        matches!(
1503            self,
1504            SwiftPassPhase::Transformation | SwiftPassPhase::Cleanup
1505        )
1506    }
1507}
1508#[allow(dead_code)]
1509#[derive(Debug, Clone)]
1510pub struct SwiftDepGraph {
1511    pub(super) nodes: Vec<u32>,
1512    pub(super) edges: Vec<(u32, u32)>,
1513}
1514impl SwiftDepGraph {
1515    #[allow(dead_code)]
1516    pub fn new() -> Self {
1517        SwiftDepGraph {
1518            nodes: Vec::new(),
1519            edges: Vec::new(),
1520        }
1521    }
1522    #[allow(dead_code)]
1523    pub fn add_node(&mut self, id: u32) {
1524        if !self.nodes.contains(&id) {
1525            self.nodes.push(id);
1526        }
1527    }
1528    #[allow(dead_code)]
1529    pub fn add_dep(&mut self, dep: u32, dependent: u32) {
1530        self.add_node(dep);
1531        self.add_node(dependent);
1532        self.edges.push((dep, dependent));
1533    }
1534    #[allow(dead_code)]
1535    pub fn dependents_of(&self, node: u32) -> Vec<u32> {
1536        self.edges
1537            .iter()
1538            .filter(|(d, _)| *d == node)
1539            .map(|(_, dep)| *dep)
1540            .collect()
1541    }
1542    #[allow(dead_code)]
1543    pub fn dependencies_of(&self, node: u32) -> Vec<u32> {
1544        self.edges
1545            .iter()
1546            .filter(|(_, dep)| *dep == node)
1547            .map(|(d, _)| *d)
1548            .collect()
1549    }
1550    #[allow(dead_code)]
1551    pub fn topological_sort(&self) -> Vec<u32> {
1552        let mut in_degree: std::collections::HashMap<u32, u32> = std::collections::HashMap::new();
1553        for &n in &self.nodes {
1554            in_degree.insert(n, 0);
1555        }
1556        for (_, dep) in &self.edges {
1557            *in_degree.entry(*dep).or_insert(0) += 1;
1558        }
1559        let mut queue: std::collections::VecDeque<u32> = self
1560            .nodes
1561            .iter()
1562            .filter(|&&n| in_degree[&n] == 0)
1563            .copied()
1564            .collect();
1565        let mut result = Vec::new();
1566        while let Some(node) = queue.pop_front() {
1567            result.push(node);
1568            for dep in self.dependents_of(node) {
1569                let cnt = in_degree.entry(dep).or_insert(0);
1570                *cnt = cnt.saturating_sub(1);
1571                if *cnt == 0 {
1572                    queue.push_back(dep);
1573                }
1574            }
1575        }
1576        result
1577    }
1578    #[allow(dead_code)]
1579    pub fn has_cycle(&self) -> bool {
1580        self.topological_sort().len() < self.nodes.len()
1581    }
1582}