diff --git a/SwiftReflector/NewClassCompiler.cs b/SwiftReflector/NewClassCompiler.cs index d6216d5d..a19358ae 100644 --- a/SwiftReflector/NewClassCompiler.cs +++ b/SwiftReflector/NewClassCompiler.cs @@ -5406,6 +5406,28 @@ WrappingResult WrapModuleContents ( } } + List GetBoundGenericsForAssociatedTypes (TypeDeclaration decl, ProtocolDeclaration proto, CSUsingPackages use) + { + var aliases = decl.TypeAliases; + var result = new List (); + var protoName = proto.ToFullyQualifiedName (); + foreach (var assoc in proto.AssociatedTypes) { + var possibleTypeName = $"{protoName}.{assoc.Name}"; + foreach (var alias in aliases) { + var namedTypeSpec = alias.TypeSpec as NamedTypeSpec; + if (namedTypeSpec == null) + throw new NotImplementedException ("You should never get an alias name that is not a NamedTypeSpec"); + var typeName = namedTypeSpec.NameWithoutModule; + if (typeName == assoc.Name || typeName == possibleTypeName) { + var ntb = TypeMapper.MapType (decl, alias.TargetTypeSpec, false); + var csType = ntb.ToCSType (use); + result.Add (csType.ToString ()); + } + } + } + return result; + } + void AddInheritedProtocols (TypeDeclaration decl, CSClass cl, ClassContents classContents, string trimmedLibPath, CSUsingPackages use, ErrorHandling errors) { @@ -5423,8 +5445,19 @@ void AddInheritedProtocols (TypeDeclaration decl, CSClass cl, ClassContents clas string itemName = null; if (iface.Namespace == typeof (SwiftError).Namespace && iface.TypeName == typeof (SwiftError).Name) itemName = "ISwiftError"; - else - itemName = iface.TypeName; + else { + var entity = TypeMapper.GetEntityForTypeSpec (inh.InheritedTypeSpec); + if (entity == null || entity.Type is ProtocolDeclaration proto && proto.AssociatedTypes.Count == 0) { + itemName = iface.TypeName; + } else { + var boundTypes = GetBoundGenericsForAssociatedTypes (decl, entity.Type as ProtocolDeclaration, use); + var sb = new StringBuilder (); + sb.Append (iface.TypeName).Append ('<'); + sb.Append (boundTypes.InterleaveCommas ()); + sb.Append ('>'); + itemName = sb.ToString (); + } + } return new CSIdentifier (itemName); })); diff --git a/SwiftReflector/SwiftInterfaceReflector/SwiftInterfaceReflector.cs b/SwiftReflector/SwiftInterfaceReflector/SwiftInterfaceReflector.cs index 6c0b9e28..2ef7f9e5 100644 --- a/SwiftReflector/SwiftInterfaceReflector/SwiftInterfaceReflector.cs +++ b/SwiftReflector/SwiftInterfaceReflector/SwiftInterfaceReflector.cs @@ -994,9 +994,6 @@ XElement HandleGenerics (Generic_parameter_clauseContext genericContext, Generic public override void ExitTypealias_declaration ([NotNull] Typealias_declarationContext context) { - // only care about top level typealiases - if (currentElement.Peek ().Name != kModule) - return; var name = UnTick (context.typealias_name ().GetText ()); var generics = context.generic_parameter_clause ()?.GetText () ?? ""; var targetType = context.typealias_assignment ().type ().GetText (); @@ -1004,8 +1001,19 @@ public override void ExitTypealias_declaration ([NotNull] Typealias_declarationC var map = new XElement (kTypeAlias, new XAttribute (kName, name + generics), new XAttribute (kAccessibility, access), new XAttribute (kType, targetType)); - if (access != null) - typeAliasMap.Add (map); + if (access != null) { + if (currentElement.Peek ().Name == kModule) { + typeAliasMap.Add (map); + } else { + var curr = currentElement.Peek (); + var aliaslist = curr.Element (kTypeAliases); + if (aliaslist == null) { + aliaslist = new XElement (kTypeAliases); + curr.Add (aliaslist); + } + aliaslist.Add (map); + } + } } XElement MakeConformanceWhere (string name, string from) diff --git a/SwiftReflector/SwiftXmlReflection/TypeDeclaration.cs b/SwiftReflector/SwiftXmlReflection/TypeDeclaration.cs index fe915562..bb9cef63 100644 --- a/SwiftReflector/SwiftXmlReflection/TypeDeclaration.cs +++ b/SwiftReflector/SwiftXmlReflection/TypeDeclaration.cs @@ -23,6 +23,7 @@ public TypeDeclaration () InnerEnums = new List (); Members = new List (); Inheritance = new List (); + TypeAliases = new List (); } public TypeKind Kind { get; set; } @@ -31,6 +32,7 @@ public TypeDeclaration () public List InnerClasses { get; set; } public List InnerStructs { get; set; } public List InnerEnums { get; set; } + public List TypeAliases { get; set; } public bool IsObjC { get; set; } public bool IsFinal { get; set; } public bool IsDeprecated { get; set; } @@ -167,6 +169,10 @@ protected virtual void GatherXObjects (List xobjects) xobjects.Add (new XElement ("members", memcontents.ToArray ())); List inherits = new List (Inheritance.Select (i => i.ToXElement ())); xobjects.Add (new XElement ("inherits", inherits.ToArray ())); + if (TypeAliases.Count > 0) { + var aliases = new List (TypeAliases.Select (a => a.ToXElement ())); + xobjects.Add (new XElement ("typealiases", aliases.ToArray ())); + } } #endregion @@ -205,6 +211,12 @@ public static TypeDeclaration TypeFromXElement (TypeAliasFolder folder, XElement select SwiftReflector.SwiftXmlReflection.Inheritance.FromXElement (folder, inherit) as Inheritance; decl.Inheritance.AddRange (inherits); } + var typealiases = elem.Element ("typealiases"); + if (typealiases != null) { + var aliases = from alias in typealiases.Elements () + select TypeAliasDeclaration.FromXElement (module.Name, alias); + decl.TypeAliases.AddRange (aliases); + } EnumDeclaration edecl = decl as EnumDeclaration; if (edecl != null) { var enumElements = (from enumElement in elem.Element ("elements").Elements () diff --git a/SwiftRuntimeLibrary.Mac/SwiftRuntimeLibrary.Mac.csproj b/SwiftRuntimeLibrary.Mac/SwiftRuntimeLibrary.Mac.csproj index 852428a4..c04bfda8 100644 --- a/SwiftRuntimeLibrary.Mac/SwiftRuntimeLibrary.Mac.csproj +++ b/SwiftRuntimeLibrary.Mac/SwiftRuntimeLibrary.Mac.csproj @@ -259,9 +259,6 @@ SwiftTypeRegistry.cs - - SwiftIteratorProtocol.cs - SwiftMarshal\SwiftProtocolConformanceDescriptor.cs @@ -289,6 +286,12 @@ SwiftMarshal\SwiftThrowsAttribute.cs + + ISwiftIteratorProtocol.cs + + + SwiftIteratorProtocolProxy.cs + diff --git a/SwiftRuntimeLibrary.iOS/SwiftRuntimeLibrary.iOS.csproj b/SwiftRuntimeLibrary.iOS/SwiftRuntimeLibrary.iOS.csproj index 03de2ec3..0f5f5ef9 100644 --- a/SwiftRuntimeLibrary.iOS/SwiftRuntimeLibrary.iOS.csproj +++ b/SwiftRuntimeLibrary.iOS/SwiftRuntimeLibrary.iOS.csproj @@ -264,9 +264,6 @@ SwiftTypeRegistry.cs - - SwiftIteratorProtocol.cs - SwiftMarshal\SwiftProtocolConformanceDescriptor.cs @@ -294,6 +291,12 @@ SwiftMarshal\SwiftThrowsAttribute.cs + + ISwiftIteratorProtocol.cs + + + SwiftIteratorProtocolProxy.cs + diff --git a/SwiftRuntimeLibrary/ISwiftIteratorProtocol.cs b/SwiftRuntimeLibrary/ISwiftIteratorProtocol.cs new file mode 100644 index 00000000..948f920b --- /dev/null +++ b/SwiftRuntimeLibrary/ISwiftIteratorProtocol.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Runtime.InteropServices; +using SwiftRuntimeLibrary; +using SwiftRuntimeLibrary.SwiftMarshal; +#if __IOS__ || __MACOS__ || __TVOS__ || __WATCHOS__ +using ObjCRuntime; +#endif +using System.Reflection; + +namespace SwiftRuntimeLibrary { + [SwiftProtocolType (typeof (SwiftIteratorProtocolProtocol<>), "libswiftCore.dylib", "$sStMp", true)] + [SwiftTypeName ("Swift.IteratorProtocol")] + public interface ISwiftIteratorProtocol { + SwiftOptional Next (); + } +} diff --git a/SwiftRuntimeLibrary/SwiftIteratorProtocol.cs b/SwiftRuntimeLibrary/SwiftIteratorProtocol.cs deleted file mode 100644 index 16502af1..00000000 --- a/SwiftRuntimeLibrary/SwiftIteratorProtocol.cs +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using SwiftRuntimeLibrary.SwiftMarshal; -#if !TOM_SWIFTY -using Foundation; -using ObjCRuntime; -#endif - -namespace SwiftRuntimeLibrary { - // this code is preliminary and is likely to change - // do not depend on this - - [SwiftProtocolType (typeof (SwiftIteratorProtocolProxy<>), SwiftCoreConstants.LibSwiftCore, "$sStMp", true)] - public interface IIteratorProtocol { - SwiftOptional Next (); - } - -#if __IOS__ - [MonoNativeFunctionWrapper] -#endif - delegate void NextFunc (IntPtr returnVal, IntPtr self); - - struct SwiftIteratorProtocolVtable { - [MarshalAs (UnmanagedType.FunctionPtr)] - public NextFunc func0; - } - - - public class SwiftIteratorProtocolProxy : SwiftNativeObject, IIteratorProtocol { - static SwiftIteratorProtocolProxy () - { - SetVTable (); - } - - static void SetVTable () - { - var vt = new SwiftIteratorProtocolVtable (); - vt.func0 = NextFuncReceiver; - IteratorProtocolPinvokes.SetVtable (ref vt, StructMarshal.Marshaler.Metatypeof (typeof (T))); - } - - static void NextFuncReceiver (IntPtr returnVal, IntPtr self) - { - var instance = SwiftObjectRegistry.Registry.CSObjectForSwiftObject> (self); - var result = instance.Next (); - StructMarshal.Marshaler.ToSwift (result, returnVal); - } - - IIteratorProtocol proxiedType; - - - public SwiftIteratorProtocolProxy (IIteratorProtocol proxiedType) - : base (IteratorProtocolPinvokes.NewIteratorProtocol (StructMarshal.Marshaler.Metatypeof (typeof (T))), - GetSwiftMetatype (), SwiftObjectRegistry.Registry) - { - this.proxiedType = proxiedType; - } - - SwiftIteratorProtocolProxy (IntPtr ptr, SwiftObjectRegistry registry) - : base (ptr, GetSwiftMetatype (), registry) - { - } - - ~SwiftIteratorProtocolProxy () - { - Dispose (false); - } - - public static SwiftIteratorProtocolProxy XamarinFactory (IntPtr p) - { - return new SwiftIteratorProtocolProxy (p, SwiftObjectRegistry.Registry); - } - - public static SwiftMetatype GetSwiftMetatype () - { - return IteratorProtocolPinvokes.IteratorProtocolMetadataAccessor (SwiftMetadataRequest.Complete, StructMarshal.Marshaler.Metatypeof (typeof (T))); - } - - #region IIteratorProtocol - public SwiftOptional Next () - { - if (proxiedType == null) - throw new NotSupportedException ("Non proxied types not supported yet"); - return proxiedType.Next (); - } - #endregion - } - - internal static class IteratorProtocolPinvokes { - [DllImport (SwiftCore.kXamGlue, EntryPoint = "$s7XamGlue19newIteratorProtocolAA27iteratorprotocol_xam_helperCyxGylF")] - public static extern IntPtr NewIteratorProtocol (SwiftMetatype metadata); - - [DllImport (SwiftCore.kXamGlue, EntryPoint = "$s7XamGlue20IteratorProtocolNext6retval4thisySpyxSgG_AA27iteratorprotocol_xam_helperCyxGtlF")] - public static extern void IteratorProtocolNext (IntPtr retval, IntPtr self, SwiftMetatype metadata); - - [DllImport (SwiftCore.kXamGlue, EntryPoint = "$s7XamGlue27iteratorprotocol_xam_helperCMa")] - public static extern SwiftMetatype IteratorProtocolMetadataAccessor (SwiftMetadataRequest request, SwiftMetatype mt); - - [DllImport (SwiftCore.kXamGlue, EntryPoint = "$s7XamGlue31iteratorprotocol_set_xam_vtableyySV_ypXptF")] - public static extern void SetVtable (ref SwiftIteratorProtocolVtable vtable, SwiftMetatype mt); - - [DllImport (SwiftCore.kXamGlue, EntryPoint = "$s7XamGlue13iterateThings3ret4thisySpySSG_AA27iteratorprotocol_xam_helperCySiGtF")] - public static extern void IterateThings (IntPtr ret, IntPtr self); - } - - public class EnumerableIterator : IIteratorProtocol { - IEnumerator enumerator; - public EnumerableIterator (IEnumerable enumerable) - { - this.enumerator = enumerable.GetEnumerator (); - } - - public SwiftOptional Next () - { - if (enumerator.MoveNext ()) { - return SwiftOptional.Some (enumerator.Current); - } else { - return SwiftOptional.None (); - } - } - } -} diff --git a/SwiftRuntimeLibrary/SwiftIteratorProtocolProxy.cs b/SwiftRuntimeLibrary/SwiftIteratorProtocolProxy.cs new file mode 100644 index 00000000..7faed34a --- /dev/null +++ b/SwiftRuntimeLibrary/SwiftIteratorProtocolProxy.cs @@ -0,0 +1,168 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Runtime.InteropServices; +using SwiftRuntimeLibrary.SwiftMarshal; +using System.Collections.Generic; +#if __IOS__ || __MACOS__ || __TVOS__ || __WATCHOS__ +using ObjCRuntime; +#endif +using System.Reflection; + +namespace SwiftRuntimeLibrary { + public class SwiftIteratorProtocolProtocol : + BaseAssociatedTypeProxy, ISwiftIteratorProtocol { + + static SwiftIteratorProtocol_xam_vtable xamVtableISwiftIteratorProtocol; + static IntPtr protocolWitnessTable; + ISwiftIteratorProtocol xamarinImpl; + + static SwiftIteratorProtocolProtocol () + { + XamSetVTable (); + } + + static IntPtr _XamSwiftIteratorProtocolProtocolCtorImpl () + { + IntPtr retvalIntPtr = IntPtr.Zero; + retvalIntPtr = NativeMethodsForSwiftIteratorProtocolProtocol.PI_SwiftIteratorProtocolProtocol (StructMarshal.Marshaler.Metatypeof (typeof (ATElement))); + return retvalIntPtr; + } + + public SwiftIteratorProtocolProtocol () : base (SwiftIteratorProtocolProtocol._XamSwiftIteratorProtocolProtocolCtorImpl (), + GetSwiftMetatype (), SwiftObjectRegistry.Registry) + { + } + + protected SwiftIteratorProtocolProtocol (IntPtr handle, + SwiftMetatype mt, SwiftObjectRegistry registry) : base (handle, mt, registry) + { + } + + public static object XamarinFactory (IntPtr p, Type [] genericTypes) + { + Type t = typeof (SwiftIteratorProtocolProtocol<>).MakeGenericType (genericTypes); + + ConstructorInfo ci = t.GetConstructor (BindingFlags.Instance | BindingFlags.NonPublic, null, + new Type [] { typeof(IntPtr), typeof(SwiftObjectRegistry)}, null); + return ci.Invoke (new object [] { p, SwiftObjectRegistry.Registry }); + } + + public static SwiftMetatype GetSwiftMetatype () + { + return NativeMethodsForSwiftIteratorProtocolProtocol.PIMetadataAccessor_SwiftIteratorProtocolProtocol (SwiftMetadataRequest.Complete, StructMarshal.Marshaler.Metatypeof (typeof (ATElement))); + } + + public SwiftIteratorProtocolProtocol (ISwiftIteratorProtocol actualImplementation) : this () + { + xamarinImpl = actualImplementation; + } + + public SwiftOptional Next () + { + if (xamarinImpl != null) { + return xamarinImpl.Next (); + } else { + unsafe { + SwiftOptional retval = new SwiftOptional (); + fixed (byte* retvalSwiftDataPtr = StructMarshal.Marshaler.PrepareValueType (retval)) { + IntPtr thisIntPtr = StructMarshal.RetainSwiftObject (this); + NativeMethodsForSwiftIteratorProtocolProtocol.PImethod_SwiftIteratorProtocolProtocolXamarin_SwiftIteratorProtocolProtocolDnext00000001 ((IntPtr)retvalSwiftDataPtr, thisIntPtr); + SwiftCore.Release (thisIntPtr); + return retval; + } + } + } + } + +#if __IOS__ || __MACOS__ || __TVOS__ || __WATCHOS__ + [MonoPInvokeCallback(typeof(SwiftIteratorProtocol_xam_vtable.Delfunc0))] +#endif + static void xamVtable_recv_Next_SwiftOptionalT0 (IntPtr xam_retval, IntPtr self) + { + SwiftOptional retval = SwiftObjectRegistry.Registry.CSObjectForSwiftObject> (self).Next (); + if (typeof (ISwiftObject).IsAssignableFrom (typeof (SwiftOptional))) { + Marshal.WriteIntPtr (xam_retval, ((ISwiftObject)retval).SwiftObject); + } else { + StructMarshal.Marshaler.ToSwift (typeof (SwiftOptional), retval, xam_retval); + } + } + + static void XamSetVTable () + { + xamVtableISwiftIteratorProtocol.func0 = xamVtable_recv_Next_SwiftOptionalT0; + unsafe { + byte* vtData = stackalloc byte [Marshal.SizeOf (xamVtableISwiftIteratorProtocol)]; + IntPtr vtPtr = new IntPtr (vtData); + Marshal.WriteIntPtr (vtPtr, Marshal.GetFunctionPointerForDelegate (xamVtableISwiftIteratorProtocol.func0)); + NativeMethodsForSwiftIteratorProtocolProtocol.SwiftXamSetVtable (vtPtr, + StructMarshal.Marshaler.Metatypeof (typeof (ATElement))); + } + } + + public static IntPtr ProtocolWitnessTable { + get { + if (protocolWitnessTable == IntPtr.Zero) { + protocolWitnessTable = SwiftCore.ProtocolWitnessTableFromFile (SwiftCore.kXamGlue, + "$s7XamGlue021SwiftIteratorProtocolE0CyxGStAAMc", GetSwiftMetatype ()); + } + return protocolWitnessTable; + } + } + } + + internal class NativeMethodsForSwiftIteratorProtocolProtocol { + [DllImport (SwiftCore.kXamGlue, EntryPoint = "$s7XamGlue029xamarin_SwiftIteratorProtocolF13Dnext000000016retval4thisySpyxSgG_AA0defF0CyxGtlF")] + internal static extern void PImethod_SwiftIteratorProtocolProtocolXamarin_SwiftIteratorProtocolProtocolDnext00000001 (IntPtr retval, IntPtr this0); + [DllImport (SwiftCore.kXamGlue, EntryPoint = "$s7XamGlue35setSwiftIteratorProtocol_xam_vtableyySV_ypXptF")] + internal static extern void SwiftXamSetVtable (IntPtr + vt, SwiftMetatype t0); + [DllImport (SwiftCore.kXamGlue, EntryPoint = "$s7XamGlue029xamarin_SwiftIteratorProtocolf6DSwifteF16Protocol00000002AA0defF0CyxGylF")] + internal static extern IntPtr PI_SwiftIteratorProtocolProtocol (SwiftMetatype mt); + [DllImport (SwiftCore.kXamGlue, EntryPoint = "$s7XamGlue021SwiftIteratorProtocolE0CMa")] + internal static extern SwiftMetatype PIMetadataAccessor_SwiftIteratorProtocolProtocol (SwiftMetadataRequest + request, SwiftMetatype mt0); + } + + internal struct SwiftIteratorProtocol_xam_vtable { + public delegate void Delfunc0 (IntPtr xam_retval, IntPtr self); + [MarshalAs (UnmanagedType.FunctionPtr)] + public Delfunc0 func0; + } + + public static class SwiftIteratorProtocolExtensions { + public static IEnumerable AsIEnumerable (this ISwiftIteratorProtocol iterator) + { + while (true) { + var element = iterator.Next (); + if (element.HasValue) + yield return element.Value; + else + break; + } + yield break; + } + + public static ISwiftIteratorProtocol AsISwiftIteratorProtocol (this IEnumerable iterator) + { + return new EnumerableAdapter (iterator); + } + } + + public sealed class EnumerableAdapter : ISwiftIteratorProtocol { + IEnumerator enumerator; + public EnumerableAdapter (IEnumerable enumerable) + { + enumerator = Exceptions.ThrowOnNull (enumerable, nameof (enumerable)).GetEnumerator (); + } + + public SwiftOptional Next () + { + if (enumerator.MoveNext ()) + return SwiftOptional.Some (enumerator.Current); + else + return SwiftOptional.None (); + } + } +} diff --git a/SwiftRuntimeLibrary/SwiftRuntimeLibrary.csproj b/SwiftRuntimeLibrary/SwiftRuntimeLibrary.csproj index 7c1af782..01cabe1c 100644 --- a/SwiftRuntimeLibrary/SwiftRuntimeLibrary.csproj +++ b/SwiftRuntimeLibrary/SwiftRuntimeLibrary.csproj @@ -110,7 +110,6 @@ - @@ -120,6 +119,8 @@ + + diff --git a/bindings/SwiftCore.xml b/bindings/SwiftCore.xml index a09283ef..38a0332f 100644 --- a/bindings/SwiftCore.xml +++ b/bindings/SwiftCore.xml @@ -151,6 +151,13 @@ + + + + + + + diff --git a/swiftglue/IteratorHelpers.swift b/swiftglue/IteratorHelpers.swift new file mode 100644 index 00000000..3c391dc4 --- /dev/null +++ b/swiftglue/IteratorHelpers.swift @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import Swift + +fileprivate var _vtable: [TypeCacheKey : SwiftIteratorProtocol_xam_vtable] + = [TypeCacheKey : SwiftIteratorProtocol_xam_vtable](); + +fileprivate struct SwiftIteratorProtocol_xam_vtable +{ + fileprivate var func0: (@convention(c)(UnsafeRawPointer, UnsafeRawPointer) -> ())?; +} + +public final class SwiftIteratorProtocolProtocol : IteratorProtocol +{ + private var _xamarinClassIsInitialized: Bool = false; + + public init() + { + } + + public func next() -> Optional + { + let vt: SwiftIteratorProtocol_xam_vtable = getSwiftIteratorProtocol_xam_vtable(T0.self)!; + + let retval = UnsafeMutablePointer>.allocate(capacity: 1); + vt.func0!(retval, toIntPtr(value: self)); + + let actualRetval = retval.move(); + retval.deallocate(); + return actualRetval; + } +} + +public func setSwiftIteratorProtocol_xam_vtable(_ uvt: UnsafeRawPointer, _ t0: Any.Type) +{ + let vt: UnsafePointer = fromIntPtr(ptr: uvt); + + _vtable[TypeCacheKey(types: ObjectIdentifier(t0))] = vt.pointee; +} + +fileprivate func getSwiftIteratorProtocol_xam_vtable(_ t0: Any.Type) -> SwiftIteratorProtocol_xam_vtable? +{ + return _vtable[TypeCacheKey(types: ObjectIdentifier(t0))]; +} + +public func xamarin_static_wrapper_IteratorProtocol_next(this: inout T0) -> + Optional where T0 : IteratorProtocol, T1 == T0.Element +{ + return this.next(); +} + +public func xamarin_XamWrappingFxamarin_static_wrapper_ProtocolTests_IteratorProtocol_next00000000 + (retval: UnsafeMutablePointer>, this: inout T0) + where T0 : IteratorProtocol, T1 == T0.Element +{ + retval.initialize(to: xamarin_static_wrapper_IteratorProtocol_next(this: &this)); +} + +public func xamarin_SwiftIteratorProtocolProtocolDnext00000001(retval: + UnsafeMutablePointer>, this: SwiftIteratorProtocolProtocol) +{ + retval.initialize(to: this.next()); +} + +public func xamarin_SwiftIteratorProtocolProtocolDSwiftIteratorProtocolProtocol00000002() + -> SwiftIteratorProtocolProtocol +{ + return SwiftIteratorProtocolProtocol(); +} diff --git a/swiftglue/iteratorprotocolhelpers.swift b/swiftglue/iteratorprotocolhelpers.swift deleted file mode 100644 index 1ae5adda..00000000 --- a/swiftglue/iteratorprotocolhelpers.swift +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -internal var iteratorprotocol_xam_helperVtableCache = [TypeCacheKey : iteratorprotocol_xam_vtable ] () - -internal struct iteratorprotocol_xam_vtable -{ - internal var func0: (@convention(c)(UnsafeRawPointer, UnsafeRawPointer)->())? -} - -internal func iteratorprotocol_get_xam_vtable(_ t0: Any.Type) -> iteratorprotocol_xam_vtable? -{ - return iteratorprotocol_xam_helperVtableCache[TypeCacheKey(types: ObjectIdentifier(t0))]; -} - -public class iteratorprotocol_xam_helper : IteratorProtocol { - private var _xamarinClassIsInitialized: Bool = false; - - public init () - { - _xamarinClassIsInitialized = true; - } - - public func next() -> Elem? { - let vt = iteratorprotocol_get_xam_vtable(Elem.self)! - let retval = UnsafeMutablePointer.allocate(capacity: 1) - vt.func0!(toIntPtr(value: retval), toIntPtr(value: self)) - let actualRetval = retval.move() - retval.deallocate(); - return actualRetval - } -} - -public func iteratorprotocol_set_xam_vtable (_ vt0: UnsafeRawPointer, _ t0: Any.Type) -{ - let vt: UnsafePointer = fromIntPtr(ptr: vt0) - - iteratorprotocol_xam_helperVtableCache [ TypeCacheKey(types: ObjectIdentifier(t0)) ] = vt.pointee -} - -public func newIteratorProtocol() -> iteratorprotocol_xam_helper -{ - return iteratorprotocol_xam_helper () -} - -public func anyIteratorProtocolNext(retval: UnsafeMutablePointer, this: UnsafeMutablePointer ) where T:IteratorProtocol -{ - retval.initialize(to: this.pointee.next()) -} - diff --git a/tests/tom-swifty-test/SwiftReflector/ProtocolConformanceTests.cs b/tests/tom-swifty-test/SwiftReflector/ProtocolConformanceTests.cs index 9c55a847..8f2edd74 100644 --- a/tests/tom-swifty-test/SwiftReflector/ProtocolConformanceTests.cs +++ b/tests/tom-swifty-test/SwiftReflector/ProtocolConformanceTests.cs @@ -12,7 +12,7 @@ public class ProtocolConformanceTests { [Test] public void CanGetProtocolConformanceDesc () { - // var nomDesc = SwiftProtocolTypeAttribute.DescriptorForType (typeof (IIteratorProtocol<>)); + // var nomDesc = SwiftProtocolTypeAttribute.DescriptorForType (typeof (ISwiftIteratorProtocol<>)); // var witTable = SwiftCore.ConformsToSwiftProtocol (StructMarshal.Marshaler.Metatypeof (typeof (SwiftIteratorProtocolProxy)), // nomDesc); // Console.WriteLine (confDesc != IntPtr.Zero); @@ -25,9 +25,9 @@ public func canGetProtocolConfDesc () { var witTableID = new CSIdentifier ("witTable"); var nomDecl = CSVariableDeclaration.VarLine (CSSimpleType.Var, nomDescID, - new CSFunctionCall ("SwiftProtocolTypeAttribute.DescriptorForType", false, new CSSimpleType ("IIteratorProtocol<>").Typeof ())); + new CSFunctionCall ("SwiftProtocolTypeAttribute.DescriptorForType", false, new CSSimpleType ("ISwiftIteratorProtocol<>").Typeof ())); - var metaTypeCall = new CSFunctionCall ("StructMarshal.Marshaler.Metatypeof", false, new CSSimpleType ("SwiftIteratorProtocolProxy").Typeof ()); + var metaTypeCall = new CSFunctionCall ("StructMarshal.Marshaler.Metatypeof", false, new CSSimpleType ("SwiftIteratorProtocolProtocol").Typeof ()); var confDescDecl = CSVariableDeclaration.VarLine (CSSimpleType.Var, witTableID, new CSFunctionCall ("SwiftCore.ConformsToSwiftProtocol", false, metaTypeCall, nomDescID)); var printer = CSFunctionCall.ConsoleWriteLine (witTableID.Dot (new CSIdentifier ("Handle")) != new CSIdentifier ("IntPtr.Zero")); @@ -41,7 +41,7 @@ public func canGetProtocolConfDesc () { [Test] public void CanGetProtocolConformanceDescMarshal () { - // var confDesc = StructMarshal.Marshaler.ProtocolConformanceof (typeof (IIteratorProtocol<>), + // var confDesc = StructMarshal.Marshaler.ProtocolConformanceof (typeof (ISwiftIteratorProtocol<>), // typeof (SwiftIteratorProtocolProxy); // Console.WriteLine (confDesc != IntPtr.Zero); @@ -51,8 +51,8 @@ public func canGetProtocolConfDescMarshal () { "; var confDescID = new CSIdentifier ("confDesc"); - var concreteType = new CSSimpleType ("SwiftIteratorProtocolProxy").Typeof (); - var ifaceType = new CSSimpleType ("IIteratorProtocol<>").Typeof (); + var concreteType = new CSSimpleType ("SwiftIteratorProtocolProtocol").Typeof (); + var ifaceType = new CSSimpleType ("ISwiftIteratorProtocol<>").Typeof (); var confDescDecl = CSVariableDeclaration.VarLine (CSSimpleType.Var, confDescID, new CSFunctionCall ("StructMarshal.Marshaler.ProtocolConformanceof", false, ifaceType, concreteType)); var printer = CSFunctionCall.ConsoleWriteLine (confDescID.Dot (new CSIdentifier ("Handle")) != new CSIdentifier ("IntPtr.Zero")); @@ -137,7 +137,7 @@ public func next () -> {swiftType}? {{ }} "; // var any = TopLevelEntities.BlindAssocFunc (); - // var types = StructMarshal.Marshaler.GetAssociatedTypes (any, typeof (IIteratorProtocol<>), 1); + // var types = StructMarshal.Marshaler.GetAssociatedTypes (any, typeof (ISwiftIteratorProtocol<>), 1); // Console.WriteLine (types[0].Name); var anyID = new CSIdentifier ("any"); @@ -145,7 +145,7 @@ public func next () -> {swiftType}? {{ var assocTypesID = new CSIdentifier ("assoc"); var typesID = new CSIdentifier ("types"); var typesDecl = CSVariableDeclaration.VarLine (typesID, new CSFunctionCall ("StructMarshal.Marshaler.GetAssociatedTypes", false, - anyID, new CSSimpleType ("IIteratorProtocol<>").Typeof (), CSConstant.Val (1))); + anyID, new CSSimpleType ("ISwiftIteratorProtocol<>").Typeof (), CSConstant.Val (1))); var printer = CSFunctionCall.ConsoleWriteLine (new CSIndexExpression (typesID, false, CSConstant.Val (0)).Dot (new CSIdentifier ("Name"))); var callingCode = CSCodeBlock.Create (anyDecl, typesDecl, printer); @@ -185,7 +185,7 @@ public func next () -> {swiftType}? {{ }} "; // var any = TopLevelEntities.BlindAssocFuncAny (); - // var types = StructMarshal.Marshaler.GetAssociateTypes (any.ObjectMetadata, typeof (IIteratorProtocol<>), 1); + // var types = StructMarshal.Marshaler.GetAssociateTypes (any.ObjectMetadata, typeof (ISwiftIteratorProtocol<>), 1); // Console.WriteLine (types[0].Name); var anyID = new CSIdentifier ("any"); @@ -193,7 +193,7 @@ public func next () -> {swiftType}? {{ var assocTypesID = new CSIdentifier ("assoc"); var typesID = new CSIdentifier ("tyypes"); var typesDecl = CSVariableDeclaration.VarLine (typesID, new CSFunctionCall ("StructMarshal.Marshaler.GetAssociatedTypes", false, - anyID.Dot (new CSIdentifier ("ObjectMetadata")), new CSSimpleType ("IIteratorProtocol<>").Typeof (), CSConstant.Val (1))); + anyID.Dot (new CSIdentifier ("ObjectMetadata")), new CSSimpleType ("ISwiftIteratorProtocol<>").Typeof (), CSConstant.Val (1))); var printer = CSFunctionCall.ConsoleWriteLine (new CSIndexExpression (typesID, false, CSConstant.Val (0)).Dot (new CSIdentifier ("Name"))); var callingCode = CSCodeBlock.Create (anyDecl, typesDecl, printer); diff --git a/tests/tom-swifty-test/SwiftReflector/ProtocolTests.cs b/tests/tom-swifty-test/SwiftReflector/ProtocolTests.cs index 5fcbd276..2942482d 100644 --- a/tests/tom-swifty-test/SwiftReflector/ProtocolTests.cs +++ b/tests/tom-swifty-test/SwiftReflector/ProtocolTests.cs @@ -38,7 +38,7 @@ void WrapSingleMethod (string type, string csType, string csReplacement, string CSLine invoker = CSFunctionCall.FunctionCallLine ("tester.DoIt", false, new CSIdentifier ("myOver")); CSCodeBlock callingCode = CSCodeBlock.Create (decl, decl1, invoker); - TestRunning.TestAndExecute (swiftCode, callingCode, expected, testName : $"WrapSingleMethod{type}", otherClass: overCS); + TestRunning.TestAndExecute (swiftCode, callingCode, expected, testName: $"WrapSingleMethod{type}", otherClass: overCS); } [Test] @@ -88,8 +88,8 @@ void WrapSingleSubscriptGetOnly (string type, string csType, string csReplacemen overCS.Inheritance.Add (new CSIdentifier ($"IMontyWSGO{type}")); CSParameterList overParams = new CSParameterList (); overParams.Add (new CSParameter (CSSimpleType.Int, "i")); - CSCodeBlock overBody = CSCodeBlock.Create (CSReturn.ReturnLine (new CSTernary(new CSIdentifier("i") == CSConstant.Val(0), - new CSIdentifier(csReplacement), new CSIdentifier(csAlt), false))); + CSCodeBlock overBody = CSCodeBlock.Create (CSReturn.ReturnLine (new CSTernary (new CSIdentifier ("i") == CSConstant.Val (0), + new CSIdentifier (csReplacement), new CSIdentifier (csAlt), false))); CSProperty overProp = new CSProperty (new CSSimpleType (csType), CSMethodKind.None, CSVisibility.Public, overBody, CSVisibility.Public, null, overParams); @@ -101,7 +101,7 @@ void WrapSingleSubscriptGetOnly (string type, string csType, string csReplacemen CSCodeBlock callingCode = CSCodeBlock.Create (decl, decl1, invoker); - TestRunning.TestAndExecute (swiftCode, callingCode, expected, testName : $"WrapSingleSubscriptGetOnly{type}", otherClass : overCS, + TestRunning.TestAndExecute (swiftCode, callingCode, expected, testName: $"WrapSingleSubscriptGetOnly{type}", otherClass: overCS, platform: PlatformName.macOS); } @@ -162,7 +162,7 @@ void WrapSinglePropertyGetOnly (string appendage, string type, string csType, st CSLine invoker = CSFunctionCall.FunctionCallLine ("tester.DoIt", false, new CSIdentifier ("myOver")); CSCodeBlock callingCode = CSCodeBlock.Create (decl, decl1, invoker); - TestRunning.TestAndExecute (swiftCode, callingCode, expected, testName : $"WrapSinglePropertyGetOnly{appendage}", otherClass : overCS); + TestRunning.TestAndExecute (swiftCode, callingCode, expected, testName: $"WrapSinglePropertyGetOnly{appendage}", otherClass: overCS); } [Test] @@ -221,7 +221,7 @@ void WrapSinglePropertyGetSetOnly (string type, string csType, string csVal, str CSLine invoker = CSFunctionCall.FunctionCallLine ("tester.DoIt", false, new CSIdentifier ("myOver")); CSCodeBlock callingCode = CSCodeBlock.Create (decl, decl1, initer, invoker); - TestRunning.TestAndExecute (swiftCode, callingCode, expected, testName : $"WrapSinglePropertyGetSetOnly{type}", otherClass : overCS); + TestRunning.TestAndExecute (swiftCode, callingCode, expected, testName: $"WrapSinglePropertyGetSetOnly{type}", otherClass: overCS); } [Test] @@ -283,9 +283,9 @@ void WrapSubscriptGetSetOnly (string type, string csType, string csVal, string s CSLine decl = CSVariableDeclaration.VarLine (new CSSimpleType ($"OverWSubSGO{type}"), "myOver", new CSFunctionCall ($"OverWSubSGO{type}", true)); CSLine decl1 = CSVariableDeclaration.VarLine (new CSSimpleType ($"TestMontyWSubSGO{type}"), "tester", new CSFunctionCall ($"TestMontyWSubSGO{type}", true)); CSLine invoker = CSFunctionCall.FunctionCallLine ("tester.DoIt", false, new CSIdentifier ("myOver")); - CSCodeBlock callingCode = CSCodeBlock .Create (decl, decl1, invoker); + CSCodeBlock callingCode = CSCodeBlock.Create (decl, decl1, invoker); - TestRunning.TestAndExecute (swiftCode, callingCode, expected, testName : $"WrapSubscriptGetSetOnly{type}", otherClass : overCS, + TestRunning.TestAndExecute (swiftCode, callingCode, expected, testName: $"WrapSubscriptGetSetOnly{type}", otherClass: overCS, platform: PlatformName.macOS); } @@ -326,7 +326,7 @@ public void WrapSubscriptPropGetSetString () } [Test] - [Ignore("Taking offline until protocols are redone")] + [Ignore ("Taking offline until protocols are redone")] public void CustomStringConvertibleTest () { var swiftCode = TestRunningCodeGenerator.kSwiftFileWriter + @@ -336,14 +336,14 @@ public void CustomStringConvertibleTest () var convertible = new CSClass (CSVisibility.Public, "MyConvert"); convertible.Inheritance.Add (new CSIdentifier ("ICustomStringConvertible")); - var getBody = CSCodeBlock.Create (CSReturn.ReturnLine (new CSFunctionCall("SwiftString.FromString", false, CSConstant.Val ("I did it!")))); + var getBody = CSCodeBlock.Create (CSReturn.ReturnLine (new CSFunctionCall ("SwiftString.FromString", false, CSConstant.Val ("I did it!")))); var declProp = new CSProperty (new CSSimpleType (typeof (SwiftString)), CSMethodKind.None, new CSIdentifier ("Description"), CSVisibility.Public, getBody, CSVisibility.Public, null); convertible.Properties.Add (declProp); var caller = CSFunctionCall.FunctionCallLine ("TopLevelEntities.PrintIt", false, new CSFunctionCall ("MyConvert", true)); var callingCode = CSCodeBlock.Create (caller); - TestRunning.TestAndExecute (swiftCode, callingCode, "I did it!", otherClass : convertible); + TestRunning.TestAndExecute (swiftCode, callingCode, "I did it!", otherClass: convertible); } [Test] @@ -533,7 +533,7 @@ public void ObjCRefProtocolArg () " @objc func Everything () -> Int {\n" + " return x\n" + " }\n" + - "}\n"+ + "}\n" + "public func makeIt (a: Int) -> LifeTheUniverseAnd {\n" + " return Liff(z: a)\n" + "}\n" + @@ -586,9 +586,9 @@ public init () { } var printIt = CSFunctionCall.ConsoleWriteLine (CSConstant.Val ("No smoke")); var callingCode = CSCodeBlock.Create (printIt); // expected errors: - // associated type + // associated type // equality constraint - // skipping FilmString (due to previous errors) + // skipping FilmString (due to previous errors) TestRunning.TestAndExecute (swiftCode, callingCode, "No smoke\n", expectedErrorCount: 1); } @@ -605,7 +605,7 @@ func doNothing () var getter = CSFunctionCall.FunctionCallLine ("SwiftProtocolTypeAttribute.DescriptorForType", false, new CSSimpleType ("IUseless").Typeof ()); var printer = CSFunctionCall.ConsoleWriteLine (CSConstant.Val ("OK")); - + var callingCode = CSCodeBlock.Create (getter, printer); TestRunning.TestAndExecute (swiftCode, callingCode, "OK\n"); } @@ -719,7 +719,7 @@ public func printSandwich (of: Bread, with: Filling) { public void BasicIterator () { var swiftCode = @" -public protocol MyIterator { +public protocol SwiftIteratorProtocol { associatedtype Element func next () -> Self.Element? } @@ -728,5 +728,78 @@ func next () -> Self.Element? var callingCode = CSCodeBlock.Create (printIt); TestRunning.TestAndExecute (swiftCode, callingCode, "Got here\n"); } + + + [Test] + public void IntIterator () + { + var swiftCode = @" +public class IntIterator : IteratorProtocol +{ + public typealias Element = Int + private var count:Int + private var curr = -1 + + public init (count:Int) + { + self.count = count + } + + public func next () -> Int? + { + if (count <= 0) { + return nil; + } + curr = curr + 1 + count = count - 1 + return curr + } +} +"; + // var it = new IntIterator (4); + // foreach (var value in it.AsEnumerable()) { + // Console.WriteLine (value); + // } + + var itId = new CSIdentifier ("it"); + var itDecl = CSVariableDeclaration.VarLine (itId, new CSFunctionCall ("IntIterator", true, + new CSCastExpression ("nint", CSConstant.Val (4)))); + + var valueId = new CSIdentifier ("value"); + var forEachBody = CSCodeBlock.Create (CSFunctionCall.ConsoleWriteLine (valueId)); + var forEach = new CSForEach (CSSimpleType.Var, valueId, new CSFunctionCall ($"{itId.Name}.AsIEnumerable", false), forEachBody); + + var callingCode = CSCodeBlock.Create (itDecl, forEach); + TestRunning.TestAndExecute (swiftCode, callingCode, "0\n1\n2\n3\n"); + } + + [Test] + [Ignore ("See issue - https://github.com/xamarin/binding-tools-for-swift/issues/767")] + public void TestCSIterator () + { + var swiftCode = @" +public func printIteratorToString(thing: inout T) -> String where T:IteratorProtocol { + var s = """"; + while let t = thing.next() { + print (t, to: &s) + } + return s +}"; + // var ints = new nint [] { 0, 1, 2, 3 }; + // var output = PrintIteratorToString(ints.AsISwiftIteratorProtocol ()); + // Console.Write(output); + + var intsId = new CSIdentifier ("ints"); + var intsDecl = CSVariableDeclaration.VarLine (intsId, + new CSArray1DInitialized ("nint", CSConstant.Val (0), CSConstant.Val (1), + CSConstant.Val (2), CSConstant.Val (3))); + var outId = new CSIdentifier ("output"); + var outDecl = CSVariableDeclaration.VarLine (outId, new CSFunctionCall ($"{intsId.Name}.AsISwiftIteratorProtocol", false)); + + var printer = CSFunctionCall.FunctionCallLine ("Console.Write", outId); + + var callingCode = CSCodeBlock.Create (intsDecl, outDecl, printer); + TestRunning.TestAndExecute (swiftCode, callingCode, "0\n1\n2\n3\n"); + } } }