Skip to main content

swift_demangler/
types.rs

1//! Type representation for Swift symbols.
2//!
3//! This module provides semantic types for representing Swift types
4//! extracted from demangled symbols.
5
6use crate::helpers::NodeExt;
7use crate::raw::{Node, NodeKind};
8
9/// A reference to a Swift type.
10///
11/// This wraps a raw node and provides methods to extract type information.
12/// The type information is parsed lazily when accessed.
13#[derive(Clone, Copy)]
14pub struct TypeRef<'ctx> {
15    raw: Node<'ctx>,
16}
17
18impl<'ctx> TypeRef<'ctx> {
19    /// Create a TypeRef from a raw node.
20    pub fn new(raw: Node<'ctx>) -> Self {
21        Self { raw }
22    }
23
24    /// Get the underlying raw node.
25    pub fn raw(&self) -> Node<'ctx> {
26        self.raw
27    }
28
29    /// Get the kind of this type.
30    pub fn kind(&self) -> TypeKind<'ctx> {
31        self.classify()
32    }
33
34    /// Get a display string for this type.
35    pub fn display(&self) -> String {
36        self.raw.to_string()
37    }
38
39    /// Get generic arguments if this is a generic type.
40    ///
41    /// Returns an empty vector if this is not a generic type.
42    pub fn generic_args(&self) -> Vec<TypeRef<'ctx>> {
43        if let TypeKind::Named(named) = self.kind() {
44            named.generic_args()
45        } else {
46            Vec::new()
47        }
48    }
49
50    /// Check if this is a generic type.
51    pub fn is_generic(&self) -> bool {
52        if let TypeKind::Named(named) = self.kind() {
53            named.is_generic()
54        } else {
55            false
56        }
57    }
58
59    /// Helper for type wrappers that take child(0) and wrap in a TypeKind variant.
60    fn wrap_child<F>(&self, wrapper: F) -> TypeKind<'ctx>
61    where
62        F: FnOnce(Box<TypeRef<'ctx>>) -> TypeKind<'ctx>,
63    {
64        self.raw
65            .child(0)
66            .map(|inner| wrapper(Box::new(TypeRef::new(inner))))
67            .unwrap_or(TypeKind::Other(self.raw))
68    }
69
70    /// Helper for types that need to unwrap two layers (child(0).child(0)).
71    fn wrap_nested_child<F>(&self, wrapper: F) -> TypeKind<'ctx>
72    where
73        F: FnOnce(Box<TypeRef<'ctx>>) -> TypeKind<'ctx>,
74    {
75        self.raw
76            .child(0)
77            .and_then(|t| t.child(0))
78            .map(|inner| wrapper(Box::new(TypeRef::new(inner))))
79            .unwrap_or(TypeKind::Other(self.raw))
80    }
81
82    fn classify(&self) -> TypeKind<'ctx> {
83        match self.raw.kind() {
84            // Named types (classes, structs, enums, protocols, type aliases)
85            NodeKind::Class
86            | NodeKind::Structure
87            | NodeKind::Enum
88            | NodeKind::Protocol
89            | NodeKind::TypeAlias
90            | NodeKind::OtherNominalType => TypeKind::Named(NamedType { raw: self.raw }),
91
92            // Bound generic types
93            NodeKind::BoundGenericClass
94            | NodeKind::BoundGenericStructure
95            | NodeKind::BoundGenericEnum
96            | NodeKind::BoundGenericProtocol
97            | NodeKind::BoundGenericTypeAlias
98            | NodeKind::BoundGenericOtherNominalType => {
99                TypeKind::Named(NamedType { raw: self.raw })
100            }
101
102            // Function types
103            NodeKind::FunctionType
104            | NodeKind::NoEscapeFunctionType
105            | NodeKind::CFunctionPointer
106            | NodeKind::ThinFunctionType
107            | NodeKind::AutoClosureType
108            | NodeKind::EscapingAutoClosureType
109            | NodeKind::ObjCBlock
110            | NodeKind::EscapingObjCBlock
111            | NodeKind::ConcurrentFunctionType
112            | NodeKind::GlobalActorFunctionType
113            | NodeKind::DifferentiableFunctionType
114            | NodeKind::IsolatedAnyFunctionType
115            | NodeKind::NonIsolatedCallerFunctionType
116            | NodeKind::SendingResultFunctionType
117            | NodeKind::UncurriedFunctionType => TypeKind::Function(FunctionType { raw: self.raw }),
118
119            // SIL implementation function type (with detailed conventions)
120            NodeKind::ImplFunctionType => TypeKind::ImplFunction(ImplFunctionType::new(self.raw)),
121
122            // Tuple
123            NodeKind::Tuple => {
124                let elements = self
125                    .raw
126                    .children()
127                    .filter(|c| c.kind() == NodeKind::TupleElement)
128                    .map(TupleElement::new)
129                    .collect();
130                TypeKind::Tuple(elements)
131            }
132
133            // Optional types (sugared)
134            NodeKind::SugaredOptional => self.wrap_child(TypeKind::Optional),
135
136            // Array types (sugared)
137            NodeKind::SugaredArray => self.wrap_child(TypeKind::Array),
138
139            // Dictionary types (sugared)
140            NodeKind::SugaredDictionary => {
141                if let (Some(key), Some(value)) = (self.raw.child(0), self.raw.child(1)) {
142                    TypeKind::Dictionary {
143                        key: Box::new(TypeRef::new(key)),
144                        value: Box::new(TypeRef::new(value)),
145                    }
146                } else {
147                    TypeKind::Other(self.raw)
148                }
149            }
150
151            // Generic type parameters
152            NodeKind::DependentGenericParamType => {
153                let depth = self.raw.child(0).and_then(|c| c.index()).unwrap_or(0);
154                let index = self.raw.child(1).and_then(|c| c.index()).unwrap_or(0);
155                TypeKind::GenericParam { depth, index }
156            }
157
158            // Metatype
159            NodeKind::Metatype | NodeKind::ExistentialMetatype => {
160                if let Some(inner) = self.raw.child(0) {
161                    // The child might be a MetatypeRepresentation or the actual type
162                    let type_node = if inner.kind() == NodeKind::MetatypeRepresentation {
163                        self.raw.child(1)
164                    } else {
165                        Some(inner)
166                    };
167                    if let Some(t) = type_node {
168                        TypeKind::Metatype(Box::new(TypeRef::new(t)))
169                    } else {
170                        TypeKind::Other(self.raw)
171                    }
172                } else {
173                    TypeKind::Other(self.raw)
174                }
175            }
176
177            // Existential (protocols)
178            NodeKind::ProtocolList
179            | NodeKind::ProtocolListWithClass
180            | NodeKind::ProtocolListWithAnyObject => {
181                let protocols: Vec<_> = self
182                    .raw
183                    .descendants()
184                    .filter(|n| n.kind() == NodeKind::Protocol || n.kind() == NodeKind::Type)
185                    .map(TypeRef::new)
186                    .collect();
187                if protocols.is_empty() {
188                    // Empty protocol list represents `Any`
189                    TypeKind::Any
190                } else {
191                    TypeKind::Existential(protocols)
192                }
193            }
194
195            // Builtin types
196            NodeKind::BuiltinTypeName => {
197                let name = self.raw.text().unwrap_or("");
198                TypeKind::Builtin(name)
199            }
200
201            // Builtin fixed array
202            NodeKind::BuiltinFixedArray => {
203                // Structure: BuiltinFixedArray -> [Type -> size, Type -> element]
204                let mut children = self.raw.children();
205                let size = children
206                    .next()
207                    .and_then(|t| t.child(0))
208                    .and_then(|n| n.index())
209                    .map(|i| i as i64);
210                let element = children
211                    .next()
212                    .and_then(|t| t.child(0))
213                    .map(|n| Box::new(TypeRef::new(n)));
214                TypeKind::BuiltinFixedArray { size, element }
215            }
216
217            // InOut types
218            NodeKind::InOut => self.wrap_child(TypeKind::InOut),
219
220            // Ownership modifiers
221            NodeKind::Shared => self.wrap_child(TypeKind::Shared),
222            NodeKind::Owned => self.wrap_child(TypeKind::Owned),
223            NodeKind::Weak => self.wrap_nested_child(TypeKind::Weak),
224            NodeKind::Unowned => self.wrap_nested_child(TypeKind::Unowned),
225            NodeKind::Sending => self.wrap_child(TypeKind::Sending),
226            NodeKind::Isolated => self.wrap_child(TypeKind::Isolated),
227
228            // NoDerivative type wrapper (autodiff)
229            NodeKind::NoDerivative => self.wrap_child(TypeKind::NoDerivative),
230
231            // Variadic generic pack
232            NodeKind::Pack => {
233                let elements: Vec<_> = self
234                    .raw
235                    .children()
236                    .filter(|c| c.kind() == NodeKind::Type)
237                    .filter_map(|t| t.child(0))
238                    .map(TypeRef::new)
239                    .collect();
240                TypeKind::Pack(elements)
241            }
242
243            // Value generics (integer literals as generic arguments)
244            NodeKind::Integer => {
245                let value = self.raw.index().map(|i| i as i64).unwrap_or(0);
246                TypeKind::ValueGeneric(value)
247            }
248
249            // Compile-time literal type (macro-related)
250            NodeKind::CompileTimeLiteral => self.wrap_child(TypeKind::CompileTimeLiteral),
251
252            // Error type (invalid/failed demangling)
253            NodeKind::ErrorType => TypeKind::Error,
254
255            // Type wrapper node - unwrap and classify the inner type
256            NodeKind::Type => {
257                if let Some(inner) = self.raw.child(0) {
258                    TypeRef::new(inner).classify()
259                } else {
260                    TypeKind::Other(self.raw)
261                }
262            }
263
264            // Dynamic self
265            NodeKind::DynamicSelf => self.wrap_child(TypeKind::DynamicSelf),
266
267            // Constrained existential
268            NodeKind::ConstrainedExistential => self.wrap_child(TypeKind::ConstrainedExistential),
269
270            // Module - typically part of a qualified name
271            NodeKind::Module => TypeKind::Named(NamedType { raw: self.raw }),
272
273            // Dependent generic type - preserve generic signature if present
274            NodeKind::DependentGenericType => {
275                // Structure: DependentGenericType -> [DependentGenericSignature, Type -> inner]
276                let signature = self
277                    .raw
278                    .child_of_kind(NodeKind::DependentGenericSignature)
279                    .map(GenericSignature::new);
280
281                let inner = self
282                    .raw
283                    .child_of_kind(NodeKind::Type)
284                    .and_then(|t| t.child(0));
285
286                match (signature, inner) {
287                    (Some(sig), Some(inner_node)) => TypeKind::Generic {
288                        signature: sig,
289                        inner: Box::new(TypeRef::new(inner_node)),
290                    },
291                    (None, Some(inner_node)) => TypeRef::new(inner_node).kind(),
292                    _ => TypeKind::Other(self.raw),
293                }
294            }
295
296            // Associated type (T.AssociatedType)
297            NodeKind::DependentMemberType => {
298                // Structure: DependentMemberType -> [Type (base), DependentAssociatedTypeRef -> Identifier]
299                let base = self
300                    .raw
301                    .child_of_kind(NodeKind::Type)
302                    .and_then(|t| t.child(0))
303                    .map(|inner| Box::new(TypeRef::new(inner)));
304                let name = self
305                    .raw
306                    .child_of_kind(NodeKind::DependentAssociatedTypeRef)
307                    .and_then(|r| r.child_of_kind(NodeKind::Identifier))
308                    .and_then(|id| id.text());
309                if let Some(base) = base {
310                    TypeKind::AssociatedType { base, name }
311                } else {
312                    TypeKind::Other(self.raw)
313                }
314            }
315
316            // Opaque types (some Protocol)
317            NodeKind::OpaqueType => {
318                // Structure: OpaqueType -> [OpaqueReturnTypeOf -> Function, Index, TypeList]
319                let source = self
320                    .raw
321                    .child_of_kind(NodeKind::OpaqueReturnTypeOf)
322                    .map(OpaqueSource::from_opaque_return_type_of);
323                let index = self
324                    .raw
325                    .child_of_kind(NodeKind::Index)
326                    .and_then(|i| i.index());
327                TypeKind::Opaque { source, index }
328            }
329
330            NodeKind::OpaqueReturnType => {
331                // Structure: OpaqueReturnType -> [OpaqueReturnTypeParent]
332                // The parent contains the mangled name of the defining function
333                let source = self
334                    .raw
335                    .child_of_kind(NodeKind::OpaqueReturnTypeParent)
336                    .map(OpaqueSource::from_opaque_return_type_parent);
337                TypeKind::Opaque {
338                    source,
339                    index: None,
340                }
341            }
342
343            // SIL box types (captured values in closures)
344            NodeKind::SILBoxTypeWithLayout | NodeKind::SILBoxType => {
345                // Structure: SILBoxTypeWithLayout -> [SILBoxLayout, DependentGenericSignature?, TypeList?]
346                // SILBoxLayout -> [SILBoxMutableField | SILBoxImmutableField]
347                let mut fields = Vec::new();
348                let mut substitutions = Vec::new();
349
350                for child in self.raw.children() {
351                    match child.kind() {
352                        NodeKind::SILBoxLayout => {
353                            for field_node in child.children() {
354                                let is_mutable = field_node.kind() == NodeKind::SILBoxMutableField;
355                                if let Some(type_node) = field_node.child(0) {
356                                    let inner = if type_node.kind() == NodeKind::Type {
357                                        type_node.child(0).unwrap_or(type_node)
358                                    } else {
359                                        type_node
360                                    };
361                                    fields.push(SILBoxField {
362                                        type_ref: TypeRef::new(inner),
363                                        is_mutable,
364                                    });
365                                }
366                            }
367                        }
368                        NodeKind::TypeList => {
369                            for type_node in child.children() {
370                                if let Some(inner) = type_node.unwrap_if_kind(NodeKind::Type) {
371                                    substitutions.push(TypeRef::new(inner));
372                                }
373                            }
374                        }
375                        _ => {}
376                    }
377                }
378
379                TypeKind::SILBox {
380                    fields,
381                    substitutions,
382                }
383            }
384
385            // Fallback
386            _ => TypeKind::Other(self.raw),
387        }
388    }
389}
390
391impl std::fmt::Debug for TypeRef<'_> {
392    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
393        // Just delegate to the kind's debug representation
394        self.kind().fmt(f)
395    }
396}
397
398impl std::fmt::Display for TypeRef<'_> {
399    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
400        write!(f, "{}", self.display())
401    }
402}
403
404/// The kind of a Swift type.
405#[derive(Debug)]
406pub enum TypeKind<'ctx> {
407    /// A named type (class, struct, enum, protocol, type alias).
408    Named(NamedType<'ctx>),
409    /// A function type.
410    Function(FunctionType<'ctx>),
411    /// A SIL implementation function type (with detailed conventions).
412    ImplFunction(ImplFunctionType<'ctx>),
413    /// A tuple type.
414    Tuple(Vec<TupleElement<'ctx>>),
415    /// An optional type (`T?`).
416    Optional(Box<TypeRef<'ctx>>),
417    /// An array type (`[T]`).
418    Array(Box<TypeRef<'ctx>>),
419    /// A dictionary type (`[K: V]`).
420    Dictionary {
421        key: Box<TypeRef<'ctx>>,
422        value: Box<TypeRef<'ctx>>,
423    },
424    /// A generic type parameter.
425    GenericParam { depth: u64, index: u64 },
426    /// A metatype (`T.Type`).
427    Metatype(Box<TypeRef<'ctx>>),
428    /// An existential type (protocol composition).
429    Existential(Vec<TypeRef<'ctx>>),
430    /// The `Any` type (empty protocol composition).
431    Any,
432    /// A builtin type.
433    Builtin(&'ctx str),
434    /// A builtin fixed array type.
435    BuiltinFixedArray {
436        size: Option<i64>,
437        element: Option<Box<TypeRef<'ctx>>>,
438    },
439    /// An inout parameter type.
440    InOut(Box<TypeRef<'ctx>>),
441    /// A shared/borrowed parameter type (`__shared` / `borrowing`).
442    Shared(Box<TypeRef<'ctx>>),
443    /// An owned/consuming parameter type (`__owned` / `consuming`).
444    Owned(Box<TypeRef<'ctx>>),
445    /// A weak reference type.
446    Weak(Box<TypeRef<'ctx>>),
447    /// An unowned reference type.
448    Unowned(Box<TypeRef<'ctx>>),
449    /// A sending parameter/result type (for region-based isolation).
450    Sending(Box<TypeRef<'ctx>>),
451    /// An isolated parameter type (actor isolation).
452    Isolated(Box<TypeRef<'ctx>>),
453    /// A `@noDerivative` type (autodiff).
454    NoDerivative(Box<TypeRef<'ctx>>),
455    /// A variadic generic pack type.
456    Pack(Vec<TypeRef<'ctx>>),
457    /// A value generic parameter (integer literal as generic argument).
458    ValueGeneric(i64),
459    /// A compile-time literal type (macro-related).
460    CompileTimeLiteral(Box<TypeRef<'ctx>>),
461    /// Dynamic Self type.
462    DynamicSelf(Box<TypeRef<'ctx>>),
463    /// Constrained existential type.
464    ConstrainedExistential(Box<TypeRef<'ctx>>),
465    /// An associated type (`T.AssociatedType`).
466    AssociatedType {
467        base: Box<TypeRef<'ctx>>,
468        name: Option<&'ctx str>,
469    },
470    /// An opaque type (`some Protocol` return type).
471    Opaque {
472        /// Information about the function that defines this opaque type.
473        source: Option<OpaqueSource<'ctx>>,
474        /// The index of this opaque type (for multiple `some` returns).
475        index: Option<u64>,
476    },
477    /// A generic type with constraints (e.g., `<A where A: Protocol>(A) -> A.Mince`).
478    Generic {
479        /// The generic signature containing type parameters and constraints.
480        signature: GenericSignature<'ctx>,
481        /// The inner type being constrained.
482        inner: Box<TypeRef<'ctx>>,
483    },
484    /// An error type (invalid/failed demangling).
485    Error,
486    /// A SIL box type (captured values in closures).
487    SILBox {
488        /// The field types in the box.
489        fields: Vec<SILBoxField<'ctx>>,
490        /// Substituted types.
491        substitutions: Vec<TypeRef<'ctx>>,
492    },
493    /// Fallback for unhandled type kinds.
494    Other(Node<'ctx>),
495}
496
497/// A field in a SIL box type.
498#[derive(Debug)]
499pub struct SILBoxField<'ctx> {
500    /// The type of the field.
501    pub type_ref: TypeRef<'ctx>,
502    /// Whether the field is mutable.
503    pub is_mutable: bool,
504}
505
506/// Information about the source of an opaque return type.
507///
508/// This captures the defining function for a `some Protocol` return type.
509#[derive(Debug, Clone, Copy)]
510pub struct OpaqueSource<'ctx> {
511    /// The module containing the defining function.
512    pub module: Option<&'ctx str>,
513    /// The containing type (struct, class, enum) if this is a method.
514    pub containing_type: Option<&'ctx str>,
515    /// The name of the defining function.
516    pub name: Option<&'ctx str>,
517    /// The mangled name of the defining function (fallback for OpaqueReturnType).
518    pub mangled_name: Option<&'ctx str>,
519}
520
521impl<'ctx> OpaqueSource<'ctx> {
522    /// Create an OpaqueSource from an OpaqueReturnTypeOf node.
523    fn from_opaque_return_type_of(node: Node<'ctx>) -> Self {
524        // OpaqueReturnTypeOf -> Function -> [Structure/Class/Enum/Module, Identifier, ...]
525        let func_node = node.child_of_kind(NodeKind::Function);
526
527        let (module, containing_type, name) = if let Some(func) = func_node {
528            let module = func
529                .descendants()
530                .find(|d| d.kind() == NodeKind::Module)
531                .and_then(|m| m.text());
532
533            let containing_type = func
534                .children()
535                .find(|c| {
536                    matches!(
537                        c.kind(),
538                        NodeKind::Structure | NodeKind::Class | NodeKind::Enum | NodeKind::Protocol
539                    )
540                })
541                .and_then(|t| {
542                    t.child_of_kind(NodeKind::Identifier)
543                        .and_then(|id| id.text())
544                });
545
546            let name = func
547                .child_of_kind(NodeKind::Identifier)
548                .and_then(|id| id.text());
549
550            (module, containing_type, name)
551        } else {
552            (None, None, None)
553        };
554
555        Self {
556            module,
557            containing_type,
558            name,
559            mangled_name: None,
560        }
561    }
562
563    /// Create an OpaqueSource from an OpaqueReturnTypeParent node.
564    fn from_opaque_return_type_parent(node: Node<'ctx>) -> Self {
565        // OpaqueReturnTypeParent has a text field with the mangled name
566        Self {
567            module: None,
568            containing_type: None,
569            name: None,
570            mangled_name: node.text(),
571        }
572    }
573}
574
575/// A named Swift type (class, struct, enum, protocol, type alias).
576#[derive(Clone, Copy)]
577pub struct NamedType<'ctx> {
578    raw: Node<'ctx>,
579}
580
581impl<'ctx> NamedType<'ctx> {
582    /// Get the underlying raw node.
583    pub fn raw(&self) -> Node<'ctx> {
584        self.raw
585    }
586
587    /// Get the simple name of this type (without module qualification).
588    pub fn name(&self) -> Option<&'ctx str> {
589        // For bound generic types, the name is in the first child
590        match self.raw.kind() {
591            NodeKind::BoundGenericClass
592            | NodeKind::BoundGenericStructure
593            | NodeKind::BoundGenericEnum
594            | NodeKind::BoundGenericProtocol
595            | NodeKind::BoundGenericTypeAlias
596            | NodeKind::BoundGenericOtherNominalType => {
597                self.raw.child(0).and_then(Self::extract_name)
598            }
599            _ => Self::extract_name(self.raw),
600        }
601    }
602
603    fn extract_name(node: Node<'ctx>) -> Option<&'ctx str> {
604        // First check if this node has an Identifier child
605        for child in node.children() {
606            if child.kind() == NodeKind::Identifier {
607                return child.text();
608            }
609        }
610        // If this is a Type wrapper, unwrap it and recurse
611        if let Some(inner) = node.unwrap_if_kind(NodeKind::Type) {
612            return Self::extract_name(inner);
613        }
614        // Fall back to the node's own text
615        node.text()
616    }
617
618    /// Get the module containing this type.
619    pub fn module(&self) -> Option<&'ctx str> {
620        Self::find_module_in_node(self.raw)
621    }
622
623    fn find_module_in_node(node: Node<'ctx>) -> Option<&'ctx str> {
624        // For bound generic types, the module is in the first child (Type -> actual type)
625        let search_node = match node.kind() {
626            NodeKind::BoundGenericClass
627            | NodeKind::BoundGenericStructure
628            | NodeKind::BoundGenericEnum
629            | NodeKind::BoundGenericProtocol
630            | NodeKind::BoundGenericTypeAlias
631            | NodeKind::BoundGenericOtherNominalType => {
632                // Get the first child and unwrap Type if needed
633                node.child(0).unwrap_or(node)
634            }
635            NodeKind::Type => {
636                // Unwrap Type wrapper
637                return node.child(0).and_then(Self::find_module_in_node);
638            }
639            _ => node,
640        };
641
642        for child in search_node.children() {
643            if child.kind() == NodeKind::Module {
644                return child.text();
645            }
646            // Recurse into Type wrappers and nominal types
647            match child.kind() {
648                NodeKind::Type
649                | NodeKind::Class
650                | NodeKind::Structure
651                | NodeKind::Enum
652                | NodeKind::Protocol
653                | NodeKind::TypeAlias => {
654                    if let Some(module) = Self::find_module_in_node(child) {
655                        return Some(module);
656                    }
657                }
658                _ => {}
659            }
660        }
661        None
662    }
663
664    /// Get the full qualified name of this type.
665    pub fn full_name(&self) -> String {
666        self.raw.to_string()
667    }
668
669    /// Get the generic arguments if this is a bound generic type.
670    pub fn generic_args(&self) -> Vec<TypeRef<'ctx>> {
671        match self.raw.kind() {
672            NodeKind::BoundGenericClass
673            | NodeKind::BoundGenericStructure
674            | NodeKind::BoundGenericEnum
675            | NodeKind::BoundGenericProtocol
676            | NodeKind::BoundGenericTypeAlias
677            | NodeKind::BoundGenericOtherNominalType => {
678                // The generic arguments come after the first child (the base type)
679                // They're wrapped in a TypeList node
680                self.raw
681                    .child(1)
682                    .map(|type_list| {
683                        type_list
684                            .children()
685                            .filter(|c| c.kind() == NodeKind::Type)
686                            .map(|c| TypeRef::new(c.child(0).unwrap_or(c)))
687                            .collect()
688                    })
689                    .unwrap_or_default()
690            }
691            _ => Vec::new(),
692        }
693    }
694
695    /// Check if this is a class type (reference type, always a pointer at the ABI level).
696    pub fn is_class(&self) -> bool {
697        matches!(
698            self.raw.kind(),
699            NodeKind::Class | NodeKind::BoundGenericClass
700        )
701    }
702
703    /// Check if this is a bound generic type.
704    pub fn is_generic(&self) -> bool {
705        matches!(
706            self.raw.kind(),
707            NodeKind::BoundGenericClass
708                | NodeKind::BoundGenericStructure
709                | NodeKind::BoundGenericEnum
710                | NodeKind::BoundGenericProtocol
711                | NodeKind::BoundGenericTypeAlias
712                | NodeKind::BoundGenericOtherNominalType
713        )
714    }
715}
716
717impl std::fmt::Debug for NamedType<'_> {
718    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
719        let mut s = f.debug_struct("NamedType");
720        s.field("module", &self.module());
721        s.field("name", &self.name());
722        let args = self.generic_args();
723        if !args.is_empty() {
724            s.field("generic_args", &args);
725        }
726        s.finish()
727    }
728}
729
730/// A Swift function type.
731#[derive(Clone, Copy)]
732pub struct FunctionType<'ctx> {
733    raw: Node<'ctx>,
734}
735
736impl<'ctx> FunctionType<'ctx> {
737    /// Create a FunctionType from a raw node.
738    pub fn new(raw: Node<'ctx>) -> Self {
739        Self { raw }
740    }
741
742    /// Get the underlying raw node.
743    pub fn raw(&self) -> Node<'ctx> {
744        self.raw
745    }
746
747    /// Get the parameters of this function type.
748    pub fn parameters(&self) -> Vec<FunctionParam<'ctx>> {
749        // Function type structure: FunctionType -> ArgumentTuple -> Type -> Tuple/Type
750        // Or for single param: FunctionType -> ArgumentTuple -> Type -> actual_type
751        for child in self.raw.children() {
752            if child.kind() == NodeKind::ArgumentTuple {
753                return self.extract_params_from_argument_tuple(child);
754            }
755            // ImplFunctionType has ImplParameter children directly
756            if child.kind() == NodeKind::ImplParameter {
757                return self.extract_impl_params();
758            }
759        }
760        Vec::new()
761    }
762
763    fn extract_params_from_argument_tuple(
764        &self,
765        arg_tuple: Node<'ctx>,
766    ) -> Vec<FunctionParam<'ctx>> {
767        // ArgumentTuple -> Type -> (Tuple with TupleElements | single type)
768        let type_node = match arg_tuple.child(0) {
769            Some(n) if n.kind() == NodeKind::Type => n.child(0).unwrap_or(n),
770            Some(n) => n,
771            None => return Vec::new(),
772        };
773
774        if type_node.kind() == NodeKind::Tuple {
775            type_node
776                .children()
777                .filter(|c| c.kind() == NodeKind::TupleElement)
778                .map(FunctionParam::from_tuple_element)
779                .collect()
780        } else {
781            // Single parameter (or empty)
782            // Check if it's an empty tuple representation
783            if type_node.num_children() == 0 && type_node.text().is_none() {
784                Vec::new()
785            } else {
786                vec![FunctionParam {
787                    label: None,
788                    type_ref: TypeRef::new(type_node),
789                    is_variadic: false,
790                }]
791            }
792        }
793    }
794
795    fn extract_impl_params(&self) -> Vec<FunctionParam<'ctx>> {
796        self.raw
797            .children()
798            .filter(|c| c.kind() == NodeKind::ImplParameter)
799            .map(|c| {
800                let type_node = c
801                    .child_of_kind(NodeKind::Type)
802                    .and_then(|t| t.child(0))
803                    .unwrap_or(c);
804                FunctionParam {
805                    label: None,
806                    type_ref: TypeRef::new(type_node),
807                    is_variadic: false,
808                }
809            })
810            .collect()
811    }
812
813    /// Get the return type of this function.
814    pub fn return_type(&self) -> Option<TypeRef<'ctx>> {
815        for child in self.raw.children() {
816            if child.kind() == NodeKind::ReturnType {
817                // ReturnType -> Type -> actual_type
818                return child
819                    .child(0)
820                    .map(|t| TypeRef::new(t.child(0).unwrap_or(t)));
821            }
822            // ImplFunctionType has ImplResult
823            if child.kind() == NodeKind::ImplResult {
824                return child
825                    .child_of_kind(NodeKind::Type)
826                    .map(|t| TypeRef::new(t.child(0).unwrap_or(t)));
827            }
828        }
829        None
830    }
831
832    /// Check if this function is async.
833    pub fn is_async(&self) -> bool {
834        self.raw
835            .descendants()
836            .any(|n| n.kind() == NodeKind::AsyncAnnotation)
837    }
838
839    /// Check if this function throws.
840    pub fn is_throwing(&self) -> bool {
841        self.raw.descendants().any(|n| {
842            n.kind() == NodeKind::ThrowsAnnotation || n.kind() == NodeKind::TypedThrowsAnnotation
843        })
844    }
845
846    /// Get the thrown error type if this function has typed throws.
847    pub fn thrown_error_type(&self) -> Option<TypeRef<'ctx>> {
848        self.raw
849            .descendants()
850            .find(|n| n.kind() == NodeKind::TypedThrowsAnnotation)
851            .and_then(|n| n.child(0))
852            .map(TypeRef::new)
853    }
854
855    /// Get the calling convention of this function.
856    pub fn convention(&self) -> FunctionConvention {
857        match self.raw.kind() {
858            NodeKind::CFunctionPointer => FunctionConvention::C,
859            NodeKind::ObjCBlock | NodeKind::EscapingObjCBlock => FunctionConvention::Block,
860            NodeKind::ThinFunctionType => FunctionConvention::Thin,
861            _ => {
862                // Check for ImplFunctionConvention child
863                for child in self.raw.children() {
864                    if matches!(
865                        child.kind(),
866                        NodeKind::ImplFunctionConvention | NodeKind::ImplFunctionConventionName
867                    ) && let Some(text) = child.text()
868                    {
869                        return match text {
870                            "c" => FunctionConvention::C,
871                            "block" => FunctionConvention::Block,
872                            "thin" => FunctionConvention::Thin,
873                            _ => FunctionConvention::Swift,
874                        };
875                    }
876                }
877                FunctionConvention::Swift
878            }
879        }
880    }
881
882    /// Check if this function type escapes.
883    pub fn is_escaping(&self) -> bool {
884        !matches!(
885            self.raw.kind(),
886            NodeKind::NoEscapeFunctionType | NodeKind::AutoClosureType
887        )
888    }
889
890    /// Check if this is an autoclosure.
891    pub fn is_autoclosure(&self) -> bool {
892        matches!(
893            self.raw.kind(),
894            NodeKind::AutoClosureType | NodeKind::EscapingAutoClosureType
895        )
896    }
897
898    /// Check if this function has a sending result.
899    pub fn has_sending_result(&self) -> bool {
900        self.raw
901            .children()
902            .any(|c| c.kind() == NodeKind::SendingResultFunctionType)
903    }
904}
905
906impl std::fmt::Debug for FunctionType<'_> {
907    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
908        let mut s = f.debug_struct("FunctionType");
909        s.field("parameters", &self.parameters());
910        s.field("return_type", &self.return_type());
911        s.field("is_async", &self.is_async());
912        s.field("is_throwing", &self.is_throwing());
913        if self.has_sending_result() {
914            s.field("has_sending_result", &true);
915        }
916        s.field("convention", &self.convention());
917        s.finish()
918    }
919}
920
921/// A SIL implementation function type.
922///
923/// This represents a function type with detailed SIL-level information
924/// including calling conventions, parameter passing conventions, and ownership.
925#[derive(Clone, Copy)]
926pub struct ImplFunctionType<'ctx> {
927    raw: Node<'ctx>,
928}
929
930impl<'ctx> ImplFunctionType<'ctx> {
931    /// Create an ImplFunctionType from a raw node.
932    pub fn new(raw: Node<'ctx>) -> Self {
933        Self { raw }
934    }
935
936    /// Get the underlying raw node.
937    pub fn raw(&self) -> Node<'ctx> {
938        self.raw
939    }
940
941    /// Get the callee convention (e.g., "@callee_guaranteed", "@callee_owned").
942    pub fn callee_convention(&self) -> Option<&'ctx str> {
943        self.raw
944            .child_of_kind(NodeKind::ImplConvention)
945            .and_then(|c| c.text())
946    }
947
948    /// Get the parameters with their conventions.
949    pub fn parameters(&self) -> Vec<ImplParam<'ctx>> {
950        self.raw
951            .children()
952            .filter(|c| c.kind() == NodeKind::ImplParameter)
953            .map(ImplParam::new)
954            .collect()
955    }
956
957    /// Get the results with their conventions.
958    pub fn results(&self) -> Vec<ImplResult<'ctx>> {
959        self.raw
960            .children()
961            .filter(|c| c.kind() == NodeKind::ImplResult)
962            .map(ImplResult::new)
963            .collect()
964    }
965
966    /// Get the error result if present.
967    pub fn error_result(&self) -> Option<ImplResult<'ctx>> {
968        self.raw
969            .child_of_kind(NodeKind::ImplErrorResult)
970            .map(ImplResult::new)
971    }
972
973    /// Get the generic signature if this is a substituted function type.
974    pub fn generic_signature(&self) -> Option<GenericSignature<'ctx>> {
975        self.raw
976            .child_of_kind(NodeKind::DependentGenericSignature)
977            .map(GenericSignature::new)
978    }
979
980    /// Get the substitution types (the "for <...>" part).
981    pub fn substitutions(&self) -> Vec<TypeRef<'ctx>> {
982        // Look for ImplPatternSubstitutions or ImplInvocationSubstitutions
983        for child in self.raw.children() {
984            if child.kind() == NodeKind::ImplPatternSubstitutions
985                || child.kind() == NodeKind::ImplInvocationSubstitutions
986            {
987                return child
988                    .children()
989                    .filter(|c| c.kind() == NodeKind::Type)
990                    .filter_map(|t| t.child(0))
991                    .map(TypeRef::new)
992                    .collect();
993            }
994        }
995        Vec::new()
996    }
997
998    /// Check if this function is escaping.
999    pub fn is_escaping(&self) -> bool {
1000        self.raw
1001            .children()
1002            .any(|c| c.kind() == NodeKind::ImplEscaping)
1003    }
1004
1005    /// Check if this function has a sending result.
1006    pub fn has_sending_result(&self) -> bool {
1007        self.raw
1008            .children()
1009            .any(|c| c.kind() == NodeKind::ImplSendingResult)
1010    }
1011}
1012
1013impl std::fmt::Debug for ImplFunctionType<'_> {
1014    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1015        let mut s = f.debug_struct("ImplFunctionType");
1016        s.field("callee_convention", &self.callee_convention());
1017        s.field("is_escaping", &self.is_escaping());
1018        if self.has_sending_result() {
1019            s.field("has_sending_result", &true);
1020        }
1021        s.field("parameters", &self.parameters());
1022        s.field("results", &self.results());
1023        if let Some(err) = self.error_result() {
1024            s.field("error_result", &err);
1025        }
1026        if let Some(sig) = self.generic_signature() {
1027            s.field("generic_signature", &sig);
1028        }
1029        let subs = self.substitutions();
1030        if !subs.is_empty() {
1031            s.field("substitutions", &subs);
1032        }
1033        s.finish()
1034    }
1035}
1036
1037/// A parameter in a SIL implementation function type.
1038#[derive(Clone, Copy)]
1039pub struct ImplParam<'ctx> {
1040    raw: Node<'ctx>,
1041}
1042
1043impl<'ctx> ImplParam<'ctx> {
1044    fn new(raw: Node<'ctx>) -> Self {
1045        Self { raw }
1046    }
1047
1048    /// Get the convention (e.g., "@guaranteed", "@owned", "@in", "@inout").
1049    pub fn convention(&self) -> Option<&'ctx str> {
1050        self.raw
1051            .child_of_kind(NodeKind::ImplConvention)
1052            .and_then(|c| c.text())
1053    }
1054
1055    /// Get the type of this parameter.
1056    pub fn type_ref(&self) -> Option<TypeRef<'ctx>> {
1057        self.raw
1058            .child_of_kind(NodeKind::Type)
1059            .and_then(|t| t.child(0))
1060            .map(TypeRef::new)
1061    }
1062
1063    /// Check if this parameter has the "sending" attribute.
1064    pub fn is_sending(&self) -> bool {
1065        self.raw
1066            .children()
1067            .any(|c| c.kind() == NodeKind::ImplParameterSending)
1068    }
1069}
1070
1071impl std::fmt::Debug for ImplParam<'_> {
1072    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1073        let mut s = f.debug_struct("ImplParam");
1074        s.field("convention", &self.convention());
1075        if self.is_sending() {
1076            s.field("is_sending", &true);
1077        }
1078        s.field("type_ref", &self.type_ref());
1079        s.finish()
1080    }
1081}
1082
1083/// A result in a SIL implementation function type.
1084#[derive(Clone, Copy)]
1085pub struct ImplResult<'ctx> {
1086    raw: Node<'ctx>,
1087}
1088
1089impl<'ctx> ImplResult<'ctx> {
1090    fn new(raw: Node<'ctx>) -> Self {
1091        Self { raw }
1092    }
1093
1094    /// Get the convention (e.g., "@owned", "@out").
1095    pub fn convention(&self) -> Option<&'ctx str> {
1096        self.raw
1097            .child_of_kind(NodeKind::ImplConvention)
1098            .and_then(|c| c.text())
1099    }
1100
1101    /// Get the type of this result.
1102    pub fn type_ref(&self) -> Option<TypeRef<'ctx>> {
1103        self.raw
1104            .child_of_kind(NodeKind::Type)
1105            .and_then(|t| t.child(0))
1106            .map(TypeRef::new)
1107    }
1108}
1109
1110impl std::fmt::Debug for ImplResult<'_> {
1111    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1112        f.debug_struct("ImplResult")
1113            .field("convention", &self.convention())
1114            .field("type_ref", &self.type_ref())
1115            .finish()
1116    }
1117}
1118
1119/// A parameter in a function type.
1120#[derive(Debug)]
1121pub struct FunctionParam<'ctx> {
1122    /// The parameter label, if any.
1123    pub label: Option<&'ctx str>,
1124    /// The type of the parameter.
1125    pub type_ref: TypeRef<'ctx>,
1126    /// Whether this is a variadic parameter (T...).
1127    pub is_variadic: bool,
1128}
1129
1130impl<'ctx> FunctionParam<'ctx> {
1131    fn from_tuple_element(node: Node<'ctx>) -> Self {
1132        let mut label = None;
1133        let mut type_node = None;
1134        let mut is_variadic = false;
1135
1136        for child in node.children() {
1137            match child.kind() {
1138                NodeKind::TupleElementName => {
1139                    label = child.text();
1140                }
1141                NodeKind::Type => {
1142                    type_node = child.child(0).or(Some(child));
1143                }
1144                NodeKind::VariadicMarker => {
1145                    is_variadic = true;
1146                }
1147                _ => {
1148                    if type_node.is_none() {
1149                        type_node = Some(child);
1150                    }
1151                }
1152            }
1153        }
1154
1155        FunctionParam {
1156            label,
1157            type_ref: TypeRef::new(type_node.unwrap_or(node)),
1158            is_variadic,
1159        }
1160    }
1161}
1162
1163/// A tuple element.
1164#[derive(Clone, Copy)]
1165pub struct TupleElement<'ctx> {
1166    raw: Node<'ctx>,
1167}
1168
1169impl<'ctx> TupleElement<'ctx> {
1170    /// Create a TupleElement from a raw node.
1171    pub fn new(raw: Node<'ctx>) -> Self {
1172        Self { raw }
1173    }
1174
1175    /// Get the underlying raw node.
1176    pub fn raw(&self) -> Node<'ctx> {
1177        self.raw
1178    }
1179
1180    /// Get the label of this tuple element, if any.
1181    pub fn label(&self) -> Option<&'ctx str> {
1182        self.raw
1183            .child_of_kind(NodeKind::TupleElementName)
1184            .and_then(|c| c.text())
1185    }
1186
1187    /// Get the type of this tuple element.
1188    pub fn type_ref(&self) -> TypeRef<'ctx> {
1189        let type_node = self
1190            .raw
1191            .child_of_kind(NodeKind::Type)
1192            .and_then(|c| c.child(0))
1193            .unwrap_or(self.raw);
1194        TypeRef::new(type_node)
1195    }
1196
1197    /// Check if this is a variadic element (T...).
1198    pub fn is_variadic(&self) -> bool {
1199        self.raw
1200            .children()
1201            .any(|c| c.kind() == NodeKind::VariadicMarker)
1202    }
1203}
1204
1205impl std::fmt::Debug for TupleElement<'_> {
1206    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1207        f.debug_struct("TupleElement")
1208            .field("label", &self.label())
1209            .field("type", &self.type_ref())
1210            .field("is_variadic", &self.is_variadic())
1211            .finish()
1212    }
1213}
1214
1215/// The calling convention of a function type.
1216#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1217pub enum FunctionConvention {
1218    /// Swift calling convention (default).
1219    Swift,
1220    /// C calling convention (`@convention(c)`).
1221    C,
1222    /// Objective-C block calling convention (`@convention(block)`).
1223    Block,
1224    /// Thin function (no context).
1225    Thin,
1226}
1227
1228/// A generic signature describing generic parameters and their constraints.
1229#[derive(Clone, Copy)]
1230pub struct GenericSignature<'ctx> {
1231    raw: Node<'ctx>,
1232}
1233
1234impl<'ctx> GenericSignature<'ctx> {
1235    /// Create a GenericSignature from a raw DependentGenericSignature node.
1236    pub fn new(raw: Node<'ctx>) -> Self {
1237        Self { raw }
1238    }
1239
1240    /// Get the underlying raw node.
1241    pub fn raw(&self) -> Node<'ctx> {
1242        self.raw
1243    }
1244
1245    /// Get the number of generic parameters at each depth level.
1246    ///
1247    /// Returns a vector where index 0 is depth 0 params, index 1 is depth 1 params, etc.
1248    pub fn param_counts(&self) -> Vec<u64> {
1249        self.raw
1250            .children()
1251            .filter(|c| c.kind() == NodeKind::DependentGenericParamCount)
1252            .filter_map(|c| c.index())
1253            .collect()
1254    }
1255
1256    /// Get all generic requirements (constraints).
1257    pub fn requirements(&self) -> Vec<GenericRequirement<'ctx>> {
1258        self.raw
1259            .children()
1260            .filter_map(|c| match c.kind() {
1261                NodeKind::DependentGenericConformanceRequirement => {
1262                    Some(GenericRequirement::from_conformance_node(c))
1263                }
1264                NodeKind::DependentGenericSameTypeRequirement => {
1265                    Some(GenericRequirement::from_same_type_node(c))
1266                }
1267                NodeKind::DependentGenericLayoutRequirement => {
1268                    Some(GenericRequirement::from_layout_node(c))
1269                }
1270                _ => None,
1271            })
1272            .collect()
1273    }
1274}
1275
1276impl std::fmt::Debug for GenericSignature<'_> {
1277    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1278        f.debug_struct("GenericSignature")
1279            .field("param_counts", &self.param_counts())
1280            .field("requirements", &self.requirements())
1281            .finish()
1282    }
1283}
1284
1285/// A generic requirement (constraint) on a generic parameter.
1286#[derive(Clone, Copy)]
1287pub struct GenericRequirement<'ctx> {
1288    kind: GenericRequirementKind<'ctx>,
1289}
1290
1291impl<'ctx> GenericRequirement<'ctx> {
1292    fn from_conformance_node(node: Node<'ctx>) -> Self {
1293        // Structure: DependentGenericConformanceRequirement -> [Type (param), Type (protocol)]
1294        let mut children = node.children();
1295        let subject = children
1296            .next()
1297            .filter(|c| c.kind() == NodeKind::Type)
1298            .and_then(|c| c.child(0))
1299            .map(TypeRef::new);
1300        let constraint = children
1301            .next()
1302            .filter(|c| c.kind() == NodeKind::Type)
1303            .and_then(|c| c.child(0))
1304            .map(TypeRef::new);
1305
1306        Self {
1307            kind: GenericRequirementKind::Conformance {
1308                subject,
1309                constraint,
1310            },
1311        }
1312    }
1313
1314    fn from_same_type_node(node: Node<'ctx>) -> Self {
1315        // Structure: DependentGenericSameTypeRequirement -> [Type (first), Type (second)]
1316        let mut children = node.children();
1317        let first = children
1318            .next()
1319            .filter(|c| c.kind() == NodeKind::Type)
1320            .and_then(|c| c.child(0))
1321            .map(TypeRef::new);
1322        let second = children
1323            .next()
1324            .filter(|c| c.kind() == NodeKind::Type)
1325            .and_then(|c| c.child(0))
1326            .map(TypeRef::new);
1327
1328        Self {
1329            kind: GenericRequirementKind::SameType { first, second },
1330        }
1331    }
1332
1333    fn from_layout_node(node: Node<'ctx>) -> Self {
1334        // Structure: DependentGenericLayoutRequirement -> [Type (param), Identifier (layout)]
1335        let subject = node
1336            .child_of_kind(NodeKind::Type)
1337            .and_then(|c| c.child(0))
1338            .map(TypeRef::new);
1339        let layout = node
1340            .child_of_kind(NodeKind::Identifier)
1341            .and_then(|c| c.text());
1342
1343        Self {
1344            kind: GenericRequirementKind::Layout { subject, layout },
1345        }
1346    }
1347
1348    /// Get the kind of this requirement.
1349    pub fn kind(&self) -> &GenericRequirementKind<'ctx> {
1350        &self.kind
1351    }
1352
1353    /// Get a display string for this requirement.
1354    pub fn display(&self) -> String {
1355        match &self.kind {
1356            GenericRequirementKind::Conformance {
1357                subject,
1358                constraint,
1359            } => {
1360                let subj = subject.map(|s| s.display()).unwrap_or_else(|| "?".into());
1361                let cons = constraint
1362                    .map(|c| c.display())
1363                    .unwrap_or_else(|| "?".into());
1364                format!("{subj}: {cons}")
1365            }
1366            GenericRequirementKind::SameType { first, second } => {
1367                let f = first.map(|s| s.display()).unwrap_or_else(|| "?".into());
1368                let s = second.map(|s| s.display()).unwrap_or_else(|| "?".into());
1369                format!("{f} == {s}")
1370            }
1371            GenericRequirementKind::Layout { subject, layout } => {
1372                let subj = subject.map(|s| s.display()).unwrap_or_else(|| "?".into());
1373                let lay = layout.unwrap_or("?");
1374                format!("{subj}: {lay}")
1375            }
1376        }
1377    }
1378}
1379
1380impl std::fmt::Debug for GenericRequirement<'_> {
1381    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1382        match &self.kind {
1383            GenericRequirementKind::Conformance {
1384                subject,
1385                constraint,
1386            } => f
1387                .debug_struct("Conformance")
1388                .field("subject", subject)
1389                .field("constraint", constraint)
1390                .finish(),
1391            GenericRequirementKind::SameType { first, second } => f
1392                .debug_struct("SameType")
1393                .field("first", first)
1394                .field("second", second)
1395                .finish(),
1396            GenericRequirementKind::Layout { subject, layout } => f
1397                .debug_struct("Layout")
1398                .field("subject", subject)
1399                .field("layout", layout)
1400                .finish(),
1401        }
1402    }
1403}
1404
1405impl std::fmt::Display for GenericRequirement<'_> {
1406    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1407        write!(f, "{}", self.display())
1408    }
1409}
1410
1411/// The kind of generic requirement.
1412#[derive(Clone, Copy)]
1413pub enum GenericRequirementKind<'ctx> {
1414    /// A conformance requirement (`T: Protocol`).
1415    Conformance {
1416        subject: Option<TypeRef<'ctx>>,
1417        constraint: Option<TypeRef<'ctx>>,
1418    },
1419    /// A same-type requirement (`T == U` or `T == SomeType`).
1420    SameType {
1421        first: Option<TypeRef<'ctx>>,
1422        second: Option<TypeRef<'ctx>>,
1423    },
1424    /// A layout requirement (`T: _NativeClass`, etc.).
1425    Layout {
1426        subject: Option<TypeRef<'ctx>>,
1427        layout: Option<&'ctx str>,
1428    },
1429}
1430
1431#[cfg(test)]
1432mod tests {
1433    use super::*;
1434    use crate::raw::Context;
1435
1436    /// Parse a type mangling and return the inner type.
1437    /// For manglings like `_TtGSqSS_`, navigates Global -> TypeMangling -> Type -> actual_type
1438    fn parse_type<'ctx>(ctx: &'ctx Context, mangled: &str) -> Option<TypeRef<'ctx>> {
1439        let root = Node::parse(ctx, mangled)?;
1440        // Navigate: Global -> first Type node -> child
1441        root.descendants()
1442            .find(|n| n.kind() == NodeKind::Type)
1443            .and_then(|n| n.child(0))
1444            .map(TypeRef::new)
1445    }
1446
1447    #[test]
1448    fn test_simple_type() {
1449        let ctx = Context::new();
1450        // Swift.Int - this produces Global -> Structure directly
1451        let root = Node::parse(&ctx, "$sSi").unwrap();
1452        let type_ref = TypeRef::new(root.child(0).unwrap());
1453        assert!(matches!(type_ref.kind(), TypeKind::Named(_)));
1454    }
1455
1456    #[test]
1457    fn test_function_type() {
1458        let ctx = Context::new();
1459        // (Swift.Int) -> Swift.String
1460        let type_ref = parse_type(&ctx, "_TtFSiSS").expect("Should parse");
1461        if let TypeKind::Function(func) = type_ref.kind() {
1462            assert!(!func.is_async());
1463            assert!(!func.is_throwing());
1464            assert_eq!(func.convention(), FunctionConvention::Swift);
1465        } else {
1466            panic!("Expected function type, got {:?}", type_ref.kind());
1467        }
1468    }
1469
1470    #[test]
1471    fn test_optional_type() {
1472        let ctx = Context::new();
1473        // Swift.String? - produces BoundGenericEnum (Swift.Optional<String>)
1474        let type_ref = parse_type(&ctx, "_TtGSqSS_").expect("Should parse");
1475        // The classic mangling produces BoundGenericEnum, which we classify as Named
1476        // This is semantically correct - Optional is a named type
1477        if let TypeKind::Named(named) = type_ref.kind() {
1478            assert_eq!(named.name(), Some("Optional"));
1479            assert!(named.is_generic());
1480        } else {
1481            panic!(
1482                "Expected named type for Optional, got {:?}",
1483                type_ref.kind()
1484            );
1485        }
1486    }
1487
1488    #[test]
1489    fn test_array_type() {
1490        let ctx = Context::new();
1491        // [Swift.String] - produces BoundGenericStructure (Swift.Array<String>)
1492        let type_ref = parse_type(&ctx, "_TtGSaSS_").expect("Should parse");
1493        // The classic mangling produces BoundGenericStructure
1494        if let TypeKind::Named(named) = type_ref.kind() {
1495            assert_eq!(named.name(), Some("Array"));
1496            assert!(named.is_generic());
1497        } else {
1498            panic!("Expected named type for Array, got {:?}", type_ref.kind());
1499        }
1500    }
1501
1502    #[test]
1503    fn test_dictionary_type() {
1504        let ctx = Context::new();
1505        // [Swift.String : Swift.Int]
1506        let type_ref = parse_type(&ctx, "_TtGVs10DictionarySSSi_").expect("Should parse");
1507        // Produces BoundGenericStructure (Swift.Dictionary<String, Int>)
1508        if let TypeKind::Named(named) = type_ref.kind() {
1509            assert_eq!(named.name(), Some("Dictionary"));
1510            assert!(named.is_generic());
1511            let args = named.generic_args();
1512            assert_eq!(args.len(), 2);
1513        } else {
1514            panic!(
1515                "Expected named type for Dictionary, got {:?}",
1516                type_ref.kind()
1517            );
1518        }
1519    }
1520
1521    #[test]
1522    fn test_c_function_pointer() {
1523        let ctx = Context::new();
1524        // @convention(c) (Swift.Int) -> Swift.UInt
1525        let type_ref = parse_type(&ctx, "_TtcSiSu").expect("Should parse");
1526        if let TypeKind::Function(func) = type_ref.kind() {
1527            assert_eq!(func.convention(), FunctionConvention::C);
1528        } else {
1529            panic!("Expected function type, got {:?}", type_ref.kind());
1530        }
1531    }
1532
1533    #[test]
1534    fn test_block_type() {
1535        let ctx = Context::new();
1536        // @convention(block) (Swift.Int) -> Swift.UInt
1537        let type_ref = parse_type(&ctx, "_TtbSiSu").expect("Should parse");
1538        if let TypeKind::Function(func) = type_ref.kind() {
1539            assert_eq!(func.convention(), FunctionConvention::Block);
1540        } else {
1541            panic!("Expected function type, got {:?}", type_ref.kind());
1542        }
1543    }
1544
1545    #[test]
1546    fn test_tuple_type() {
1547        let ctx = Context::new();
1548        // (Swift.Int, Swift.UInt)
1549        let type_ref = parse_type(&ctx, "_TtTSiSu_").expect("Should parse");
1550        if let TypeKind::Tuple(elements) = type_ref.kind() {
1551            assert_eq!(elements.len(), 2);
1552        } else {
1553            panic!("Expected tuple type, got {:?}", type_ref.kind());
1554        }
1555    }
1556
1557    #[test]
1558    fn test_labeled_tuple() {
1559        let ctx = Context::new();
1560        // (foo: Swift.Int, bar: Swift.UInt)
1561        let type_ref = parse_type(&ctx, "_TtT3fooSi3barSu_").expect("Should parse");
1562        if let TypeKind::Tuple(elements) = type_ref.kind() {
1563            assert_eq!(elements.len(), 2);
1564            assert_eq!(elements[0].label(), Some("foo"));
1565            assert_eq!(elements[1].label(), Some("bar"));
1566        } else {
1567            panic!("Expected tuple type, got {:?}", type_ref.kind());
1568        }
1569    }
1570
1571    #[test]
1572    fn test_metatype() {
1573        let ctx = Context::new();
1574        // Swift.Int.Type
1575        let type_ref = parse_type(&ctx, "_TtMSi").expect("Should parse");
1576        assert!(
1577            matches!(type_ref.kind(), TypeKind::Metatype(_)),
1578            "Expected metatype, got {:?}",
1579            type_ref.kind()
1580        );
1581    }
1582
1583    #[test]
1584    fn test_inout_type() {
1585        let ctx = Context::new();
1586        // inout Swift.Int
1587        let type_ref = parse_type(&ctx, "_TtRSi").expect("Should parse");
1588        assert!(
1589            matches!(type_ref.kind(), TypeKind::InOut(_)),
1590            "Expected inout type, got {:?}",
1591            type_ref.kind()
1592        );
1593    }
1594
1595    #[test]
1596    fn test_named_type_generic_args() {
1597        let ctx = Context::new();
1598        // Swift.Optional<Swift.String>
1599        let type_ref = parse_type(&ctx, "_TtGSqSS_").expect("Should parse");
1600        if let TypeKind::Named(named) = type_ref.kind() {
1601            let args = named.generic_args();
1602            assert_eq!(args.len(), 1);
1603            // The argument should be String
1604            assert!(args[0].display().contains("String"));
1605        } else {
1606            panic!("Expected named type");
1607        }
1608    }
1609}