@@ -315,7 +315,7 @@ struct CountedOrSizedPointerThunkBuilder: PointerBoundsThunkBuilder {
315
315
}
316
316
317
317
func castIntToTargetType( expr: ExprSyntax , type: TypeSyntax ) -> ExprSyntax {
318
- if type. isSwiftInt {
318
+ if type. canRepresentBasicType ( type : Int . self ) {
319
319
return expr
320
320
}
321
321
return ExprSyntax ( " \( type) (exactly: \( expr) )! " )
@@ -717,3 +717,49 @@ public struct PointerBoundsMacro: PeerMacro {
717
717
}
718
718
}
719
719
}
720
+
721
+ // MARK: syntax utils
722
+ extension TypeSyntaxProtocol {
723
+ public var isSwiftCoreModule : Bool {
724
+ guard let identifierType = self . as ( IdentifierTypeSyntax . self) else {
725
+ return false
726
+ }
727
+ return identifierType. name. text == " Swift "
728
+ }
729
+
730
+ /// Check if this syntax could resolve to the type passed. Only supports types where the canonical type
731
+ /// can be named using only IdentifierTypeSyntax and MemberTypeSyntax. A non-exhaustive list of unsupported
732
+ /// types includes:
733
+ /// * array types
734
+ /// * function types
735
+ /// * optional types
736
+ /// * tuple types (including Void!)
737
+ /// The type syntax is allowed to use any level of qualified name for the type, e.g. Swift.Int.self
738
+ /// will match against both "Swift.Int" and "Int".
739
+ ///
740
+ /// - Parameter type: Type to check against. NB: if passing a type alias, the canonical type will be used.
741
+ /// - Returns: true if `self` spells out some suffix of the fully qualified name of `type`, otherwise false
742
+ public func canRepresentBasicType( type: Any . Type ) -> Bool {
743
+ let qualifiedTypeName = String ( reflecting: type)
744
+ var typeNames = qualifiedTypeName. split ( separator: " . " )
745
+ var currType : TypeSyntaxProtocol = self
746
+
747
+ while !typeNames. isEmpty {
748
+ let typeName = typeNames. popLast ( ) !
749
+ if let identifierType = currType. as ( IdentifierTypeSyntax . self) {
750
+ // It doesn't matter whether this is the final element of typeNames, because we don't know
751
+ // surrounding context - the Foo.Bar.Baz type can be referred to as `Baz` inside Foo.Bar
752
+ return identifierType. name. text == typeName
753
+ } else if let memberType = currType. as ( MemberTypeSyntax . self) {
754
+ if memberType. name. text != typeName {
755
+ return false
756
+ }
757
+ currType = memberType. baseType
758
+ } else {
759
+ return false
760
+ }
761
+ }
762
+
763
+ return false
764
+ }
765
+ }
0 commit comments