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::Str(s) => SwiftExpr::SwiftLitExpr(SwiftLit::Str(s.clone())),
1175        }
1176    }
1177    /// Compile an LCNF expression to a list of Swift statements.
1178    ///
1179    /// The final statement is always a `return`.
1180    pub fn compile_expr(&self, expr: &LcnfExpr) -> Vec<SwiftStmt> {
1181        match expr {
1182            LcnfExpr::Return(arg) => vec![SwiftStmt::Return(Some(self.compile_arg(arg)))],
1183            LcnfExpr::Unreachable => {
1184                vec![SwiftStmt::ExprStmt(SwiftExpr::SwiftCall {
1185                    callee: Box::new(SwiftExpr::SwiftVar("ox_unreachable".to_string())),
1186                    args: Vec::new(),
1187                })]
1188            }
1189            LcnfExpr::TailCall(func, args) => {
1190                let callee = Box::new(self.compile_arg(func));
1191                let call_args = args
1192                    .iter()
1193                    .map(|a| (String::new(), self.compile_arg(a)))
1194                    .collect();
1195                vec![SwiftStmt::Return(Some(SwiftExpr::SwiftCall {
1196                    callee,
1197                    args: call_args,
1198                }))]
1199            }
1200            LcnfExpr::Let {
1201                id, value, body, ..
1202            } => {
1203                let var_name = format!("{}", id);
1204                let rhs = self.compile_let_value(value);
1205                let mut stmts = vec![SwiftStmt::Let {
1206                    name: var_name,
1207                    ty: None,
1208                    value: rhs,
1209                }];
1210                stmts.extend(self.compile_expr(body));
1211                stmts
1212            }
1213            LcnfExpr::Case {
1214                scrutinee,
1215                alts,
1216                default,
1217                ..
1218            } => {
1219                let subject = SwiftExpr::SwiftVar(format!("{}", scrutinee));
1220                let mut cases: Vec<SwiftCase> = alts
1221                    .iter()
1222                    .map(|alt| {
1223                        let pattern = format!(".ctor(tag: {}, _)", alt.ctor_tag);
1224                        let body = self.compile_expr(&alt.body);
1225                        SwiftCase { pattern, body }
1226                    })
1227                    .collect();
1228                if let Some(def) = default {
1229                    let def_body = self.compile_expr(def);
1230                    cases.push(SwiftCase {
1231                        pattern: "default".to_string(),
1232                        body: def_body,
1233                    });
1234                } else {
1235                    cases.push(SwiftCase {
1236                        pattern: "default".to_string(),
1237                        body: vec![SwiftStmt::ExprStmt(SwiftExpr::SwiftCall {
1238                            callee: Box::new(SwiftExpr::SwiftVar("ox_unreachable".to_string())),
1239                            args: Vec::new(),
1240                        })],
1241                    });
1242                }
1243                vec![SwiftStmt::Switch { subject, cases }]
1244            }
1245        }
1246    }
1247    /// Compile a let-value to a Swift expression.
1248    pub fn compile_let_value(&self, value: &LcnfLetValue) -> SwiftExpr {
1249        match value {
1250            LcnfLetValue::Lit(lit) => self.compile_lit(lit),
1251            LcnfLetValue::Erased => SwiftExpr::SwiftMember(
1252                Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1253                "erased".to_string(),
1254            ),
1255            LcnfLetValue::FVar(id) => SwiftExpr::SwiftVar(format!("{}", id)),
1256            LcnfLetValue::App(func, args) => {
1257                let callee = Box::new(self.compile_arg(func));
1258                let call_args = args
1259                    .iter()
1260                    .map(|a| (String::new(), self.compile_arg(a)))
1261                    .collect();
1262                SwiftExpr::SwiftCall {
1263                    callee,
1264                    args: call_args,
1265                }
1266            }
1267            LcnfLetValue::Ctor(name, tag, args) => {
1268                let tag_pair = (
1269                    "tag".to_string(),
1270                    SwiftExpr::SwiftLitExpr(SwiftLit::Int(*tag as i64)),
1271                );
1272                let field_exprs: Vec<SwiftExpr> =
1273                    args.iter().map(|a| self.compile_arg(a)).collect();
1274                let fields_array = SwiftExpr::SwiftArrayLit(field_exprs);
1275                let _ = name;
1276                SwiftExpr::SwiftCall {
1277                    callee: Box::new(SwiftExpr::SwiftMember(
1278                        Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1279                        "ctor".to_string(),
1280                    )),
1281                    args: vec![tag_pair, ("fields".to_string(), fields_array)],
1282                }
1283            }
1284            LcnfLetValue::Proj(_, idx, var) => {
1285                let base = SwiftExpr::SwiftMember(
1286                    Box::new(SwiftExpr::SwiftVar(format!("{}", var))),
1287                    "fields".to_string(),
1288                );
1289                SwiftExpr::SwiftSubscript(
1290                    Box::new(base),
1291                    Box::new(SwiftExpr::SwiftLitExpr(SwiftLit::Int(*idx as i64))),
1292                )
1293            }
1294            LcnfLetValue::Reset(var) => SwiftExpr::SwiftVar(format!("{}", var)),
1295            LcnfLetValue::Reuse(_, name, tag, args) => {
1296                let tag_pair = (
1297                    "tag".to_string(),
1298                    SwiftExpr::SwiftLitExpr(SwiftLit::Int(*tag as i64)),
1299                );
1300                let field_exprs: Vec<SwiftExpr> =
1301                    args.iter().map(|a| self.compile_arg(a)).collect();
1302                let fields_array = SwiftExpr::SwiftArrayLit(field_exprs);
1303                let _ = name;
1304                SwiftExpr::SwiftCall {
1305                    callee: Box::new(SwiftExpr::SwiftMember(
1306                        Box::new(SwiftExpr::SwiftVar("OxValue".to_string())),
1307                        "ctor".to_string(),
1308                    )),
1309                    args: vec![tag_pair, ("fields".to_string(), fields_array)],
1310                }
1311            }
1312        }
1313    }
1314    /// Compile a single LCNF function declaration to a [`SwiftFunc`].
1315    pub fn compile_decl(&self, decl: &LcnfFunDecl) -> SwiftFunc {
1316        let safe_name = Self::mangle_name(&decl.name.to_string());
1317        let params: Vec<SwiftParam> = decl
1318            .params
1319            .iter()
1320            .map(|p| {
1321                let pname = Self::mangle_name(&p.name);
1322                SwiftParam {
1323                    label: "_".to_string(),
1324                    name: pname,
1325                    ty: self.compile_lcnf_type(&p.ty),
1326                    default: None,
1327                    variadic: false,
1328                    inout: false,
1329                }
1330            })
1331            .collect();
1332        let body = self.compile_expr(&decl.body);
1333        let mut func = SwiftFunc::new(safe_name, SwiftType::SwiftNamed("OxValue".to_string()));
1334        func.params = params;
1335        func.body = body;
1336        func.is_public = self.emit_public;
1337        func
1338    }
1339    /// Map an LCNF type to the closest Swift type.
1340    pub fn compile_lcnf_type(&self, ty: &LcnfType) -> SwiftType {
1341        match ty {
1342            LcnfType::Nat | LcnfType::Unit | LcnfType::Erased | LcnfType::Irrelevant => {
1343                SwiftType::SwiftNamed("OxValue".to_string())
1344            }
1345            LcnfType::LcnfString => SwiftType::SwiftNamed("OxValue".to_string()),
1346            LcnfType::Object => SwiftType::SwiftNamed("OxValue".to_string()),
1347            LcnfType::Var(_) => SwiftType::SwiftNamed("OxValue".to_string()),
1348            LcnfType::Fun(params, ret) => {
1349                let p: Vec<SwiftType> = params.iter().map(|p| self.compile_lcnf_type(p)).collect();
1350                let r = Box::new(self.compile_lcnf_type(ret));
1351                SwiftType::SwiftFunc(p, r)
1352            }
1353            LcnfType::Ctor(_, _) => SwiftType::SwiftNamed("OxValue".to_string()),
1354        }
1355    }
1356    /// Compile a collection of LCNF declarations into a [`SwiftModule`].
1357    pub fn compile_module(&self, name: &str, decls: &[LcnfFunDecl]) -> SwiftModule {
1358        let mut module = SwiftModule::new(name);
1359        module.add_import("Foundation");
1360        for decl in decls {
1361            let func = self.compile_decl(decl);
1362            module.funcs.push(func);
1363        }
1364        module
1365    }
1366    /// Emit a [`SwiftModule`] to a Swift source string.
1367    pub fn emit_module(&self, module: &SwiftModule) -> String {
1368        module.codegen()
1369    }
1370    /// Emit a single [`SwiftFunc`] to a Swift source string.
1371    pub fn emit_func(&self, func: &SwiftFunc) -> String {
1372        func.codegen()
1373    }
1374    /// Emit a single [`SwiftTypeDecl`] to a Swift source string.
1375    pub fn emit_type_decl(&self, decl: &SwiftTypeDecl) -> String {
1376        decl.codegen()
1377    }
1378}
1379#[allow(dead_code)]
1380#[derive(Debug, Clone)]
1381pub struct SwiftPassConfig {
1382    pub phase: SwiftPassPhase,
1383    pub enabled: bool,
1384    pub max_iterations: u32,
1385    pub debug_output: bool,
1386    pub pass_name: String,
1387}
1388impl SwiftPassConfig {
1389    #[allow(dead_code)]
1390    pub fn new(name: impl Into<String>, phase: SwiftPassPhase) -> Self {
1391        SwiftPassConfig {
1392            phase,
1393            enabled: true,
1394            max_iterations: 10,
1395            debug_output: false,
1396            pass_name: name.into(),
1397        }
1398    }
1399    #[allow(dead_code)]
1400    pub fn disabled(mut self) -> Self {
1401        self.enabled = false;
1402        self
1403    }
1404    #[allow(dead_code)]
1405    pub fn with_debug(mut self) -> Self {
1406        self.debug_output = true;
1407        self
1408    }
1409    #[allow(dead_code)]
1410    pub fn max_iter(mut self, n: u32) -> Self {
1411        self.max_iterations = n;
1412        self
1413    }
1414}
1415/// A Swift enum declaration.
1416#[derive(Debug, Clone, PartialEq)]
1417pub struct SwiftEnumDecl {
1418    /// Enum name
1419    pub name: String,
1420    /// Enum cases
1421    pub cases: Vec<SwiftEnumCase>,
1422    /// Methods defined on this enum
1423    pub methods: Vec<SwiftFunc>,
1424    /// Protocol conformances / inheritance list
1425    pub conformances: Vec<SwiftConformance>,
1426    /// Whether `public`
1427    pub is_public: bool,
1428    /// Generic parameters
1429    pub generic_params: Vec<String>,
1430}
1431impl SwiftEnumDecl {
1432    /// Create a new empty enum.
1433    pub fn new(name: impl Into<String>) -> Self {
1434        SwiftEnumDecl {
1435            name: name.into(),
1436            cases: Vec::new(),
1437            methods: Vec::new(),
1438            conformances: Vec::new(),
1439            is_public: false,
1440            generic_params: Vec::new(),
1441        }
1442    }
1443    /// Emit as Swift source.
1444    pub fn codegen(&self) -> String {
1445        let vis = if self.is_public { "public " } else { "" };
1446        let generics = if self.generic_params.is_empty() {
1447            String::new()
1448        } else {
1449            format!("<{}>", self.generic_params.join(", "))
1450        };
1451        let conformances = if self.conformances.is_empty() {
1452            String::new()
1453        } else {
1454            format!(
1455                ": {}",
1456                self.conformances
1457                    .iter()
1458                    .map(|c| c.0.as_str())
1459                    .collect::<Vec<_>>()
1460                    .join(", ")
1461            )
1462        };
1463        let mut out = format!("{}enum {}{}{} {{\n", vis, self.name, generics, conformances);
1464        for case in &self.cases {
1465            out += &case.codegen();
1466            out += "\n";
1467        }
1468        for method in &self.methods {
1469            for line in method.codegen().lines() {
1470                out += "    ";
1471                out += line;
1472                out += "\n";
1473            }
1474        }
1475        out += "}\n";
1476        out
1477    }
1478}
1479#[allow(dead_code)]
1480#[derive(Debug, Clone, PartialEq)]
1481pub enum SwiftPassPhase {
1482    Analysis,
1483    Transformation,
1484    Verification,
1485    Cleanup,
1486}
1487impl SwiftPassPhase {
1488    #[allow(dead_code)]
1489    pub fn name(&self) -> &str {
1490        match self {
1491            SwiftPassPhase::Analysis => "analysis",
1492            SwiftPassPhase::Transformation => "transformation",
1493            SwiftPassPhase::Verification => "verification",
1494            SwiftPassPhase::Cleanup => "cleanup",
1495        }
1496    }
1497    #[allow(dead_code)]
1498    pub fn is_modifying(&self) -> bool {
1499        matches!(
1500            self,
1501            SwiftPassPhase::Transformation | SwiftPassPhase::Cleanup
1502        )
1503    }
1504}
1505#[allow(dead_code)]
1506#[derive(Debug, Clone)]
1507pub struct SwiftDepGraph {
1508    pub(super) nodes: Vec<u32>,
1509    pub(super) edges: Vec<(u32, u32)>,
1510}
1511impl SwiftDepGraph {
1512    #[allow(dead_code)]
1513    pub fn new() -> Self {
1514        SwiftDepGraph {
1515            nodes: Vec::new(),
1516            edges: Vec::new(),
1517        }
1518    }
1519    #[allow(dead_code)]
1520    pub fn add_node(&mut self, id: u32) {
1521        if !self.nodes.contains(&id) {
1522            self.nodes.push(id);
1523        }
1524    }
1525    #[allow(dead_code)]
1526    pub fn add_dep(&mut self, dep: u32, dependent: u32) {
1527        self.add_node(dep);
1528        self.add_node(dependent);
1529        self.edges.push((dep, dependent));
1530    }
1531    #[allow(dead_code)]
1532    pub fn dependents_of(&self, node: u32) -> Vec<u32> {
1533        self.edges
1534            .iter()
1535            .filter(|(d, _)| *d == node)
1536            .map(|(_, dep)| *dep)
1537            .collect()
1538    }
1539    #[allow(dead_code)]
1540    pub fn dependencies_of(&self, node: u32) -> Vec<u32> {
1541        self.edges
1542            .iter()
1543            .filter(|(_, dep)| *dep == node)
1544            .map(|(d, _)| *d)
1545            .collect()
1546    }
1547    #[allow(dead_code)]
1548    pub fn topological_sort(&self) -> Vec<u32> {
1549        let mut in_degree: std::collections::HashMap<u32, u32> = std::collections::HashMap::new();
1550        for &n in &self.nodes {
1551            in_degree.insert(n, 0);
1552        }
1553        for (_, dep) in &self.edges {
1554            *in_degree.entry(*dep).or_insert(0) += 1;
1555        }
1556        let mut queue: std::collections::VecDeque<u32> = self
1557            .nodes
1558            .iter()
1559            .filter(|&&n| in_degree[&n] == 0)
1560            .copied()
1561            .collect();
1562        let mut result = Vec::new();
1563        while let Some(node) = queue.pop_front() {
1564            result.push(node);
1565            for dep in self.dependents_of(node) {
1566                let cnt = in_degree.entry(dep).or_insert(0);
1567                *cnt = cnt.saturating_sub(1);
1568                if *cnt == 0 {
1569                    queue.push_back(dep);
1570                }
1571            }
1572        }
1573        result
1574    }
1575    #[allow(dead_code)]
1576    pub fn has_cycle(&self) -> bool {
1577        self.topological_sort().len() < self.nodes.len()
1578    }
1579}