public void NullableFieldConvertsToSwiftOptional(Type viewType) { var sty = SwiftType.Of(viewType) as CustomViewType; Assert.NotNull(sty); Assert.Equal(1, sty !.NativeFields.Count); Assert.False(sty.NativeFields [0].Nullability.IsNullable); Assert.True(sty.NativeFields [0].Nullability [0].IsNullable); var gargs = sty.NativeFields [0].SwiftType.GenericArguments; Assert.NotNull(gargs); Assert.Equal(1, gargs !.Count); unsafe { Assert.Equal("Optional", gargs [0].Metadata->TypeDescriptor->Name); } }
/// <summary> /// Returns a <see cref="SwiftHandle"/> bridging the given object to Swift. /// </summary> /// <remarks> /// The returned <see cref="SwiftHandle"/> must be disposed when no longer needed. /// </remarks> /// <param name="obj">The managed object to bridge to Swift</param> /// <param name="nullability">Determines whether to bridge the value to Swift /// as an Optional value. If <typeparamref name="T"/> is identified as a known /// nullable wrapper, such as <see cref="Nullable"/>, then the value is bridged /// as an Optional regardless of the value of this parameter.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="obj"/> is /// <c>null</c>, <typeparamref name="T"/> is not a known nullable wrapper type, /// and <paramref name="nullability"/> returns <c>false</c> from <see cref="Nullability.IsNullable"/>.</exception> /// <exception cref="ArgumentException">Thrown when the type <typeparamref name="T"/> cannot /// be directly bridged to Swift</exception> public static unsafe SwiftHandle GetSwiftHandle <T> (this T obj, Nullability nullability = default) { var type = typeof(T); var swiftType = SwiftType.Of(type, nullability); if (swiftType == null && obj != null) { type = obj.GetType(); swiftType = SwiftType.Of(type, nullability); } if (swiftType == null) { throw new ArgumentException($"Type '{type}' cannot be bridged to Swift"); } // Nullable types are bridged to Swift optionals if (nullability.IsNullable || Nullability.IsReifiedNullable(type)) { if (Nullability.IsNull(obj)) { var underlyingType = Nullability.GetUnderlyingType(type); var underlyingSwiftType = SwiftType.Of(underlyingType, nullability.Strip()) !; return(Optional.Wrap(null, swiftType, underlyingSwiftType)); } else { var unwrapped = Nullability.Unwrap(obj); using (var unwrappedHandle = unwrapped.GetSwiftHandle(nullability.Strip())) return(Optional.Wrap(unwrappedHandle.Pointer, swiftType, unwrappedHandle.SwiftType)); } } else if (obj is null) { throw new ArgumentNullException(nameof(obj)); } return(obj switch { ISwiftValue swiftValue => swiftValue.GetSwiftHandle(), string val => new SwiftHandle(new Swift.String(val), swiftType, destroyOnDispose: true), _ when type.IsPrimitive => new SwiftHandle(obj, swiftType), _ => throw new NotImplementedException(type.ToString()) });
protected virtual ProtocolWitnessTable *CreateViewConformance() { viewConformanceDesc = (ViewProtocolConformanceDescriptor *)Marshal.AllocHGlobal(sizeof(ViewProtocolConformanceDescriptor)); // zero everything first *viewConformanceDesc = default; viewConformanceDesc->Populate(Metadata->TypeDescriptor); var bodySwiftType = SwiftType.Of(BodyProperty.PropertyType) !; var bodyConformance = bodySwiftType.GetProtocolConformance(SwiftUILib.ViewProtocol); var witnessTable = SwiftCoreLib.GetProtocolWitnessTable(&viewConformanceDesc->ConformanceDescriptor, Metadata, null); viewConformanceDesc->FixupAndRegister( witnessTable, bodyConformance, bodySwiftType.Metadata, SwiftGlueLib.BodyProtocolWitness); return(witnessTable); }
internal CustomViewType(Type customViewType) : base(customViewType, MetadataKinds.Struct) { try { BodyProperty = customViewType.GetProperty("Body__", BindingFlags.NonPublic | BindingFlags.Instance) ?? customViewType.GetProperty("Body", BindingFlags.Public | BindingFlags.Instance); if (BodyProperty is null || !BodyProperty.CanRead || BodyProperty.CanWrite || !BodyProperty.PropertyType.IsSubclassOf(typeof(View))) { throw new ArgumentException($"View implementations must either override ViewType, or declare a public, read-only `Body` property returning a concrete type of `{nameof (View)}`"); } var thunkMetadata = (CustomViewMetadata *)fullMetadata; thunkMetadata->ThunkViewU = Metadata; thunkMetadata->ThunkViewT = SwiftType.Of(BodyProperty.PropertyType) !.Metadata; // Currently unused, so don't force allocation if it's a custom view //thunkMetadata->ThunkViewTViewConformance = swiftBodyType.ViewConformance; thunkMetadata->ThunkViewTViewConformance = null; } catch { // Ensure we don't leak allocated unmanaged memory Dispose(true); throw; } }
public static ModifiedBackground <TView, TBackground> Background <TView, TBackground> (this TView view, TBackground background) where TView : View where TBackground : View { var opaqueBackgroundMetadata = SwiftType.Of(typeof(ModifiedBackground <TView, TBackground>)) !; var result = TaggedPointer.AllocHGlobal(opaqueBackgroundMetadata.NativeDataSize); try { using (var viewHandle = view.GetSwiftHandle()) using (var backgroundHandle = background.GetSwiftHandle()) { var viewType = viewHandle.SwiftType; var backgroundType = backgroundHandle.SwiftType; // Note : When passing 2 generic parameters (in this case TView and TBackground) the order is IMPORTANT. The order is Generic1Pointer, Generic2Pointer, Generic1Metadata, Generic2Metadata, Generic1Prototcol, Generic2Prototcol ViewBackground(result.Pointer, viewHandle.Pointer, backgroundHandle.Pointer, viewType.Metadata, backgroundType.Metadata, viewType.GetProtocolConformance(SwiftUILib.ViewProtocol), backgroundType.GetProtocolConformance(SwiftUILib.ViewProtocol)); return(new ModifiedBackground <TView, TBackground> (result)); } } catch { result.Dispose(); throw; } }
public TLFieldOffset(string mangledName, SwiftName module, SwiftClassType classType, bool direct, SwiftName ident, SwiftType type, ulong offset) : base(CoreCompoundType.FieldOffset, mangledName, module, classType, offset) { IsDirect = direct; Identifier = ident; FieldType = type; }
static bool IsProperty(SwiftType signature, SwiftClassType cl) { return(signature is SwiftPropertyType); }
public String Copy() => SwiftType.Of(typeof(string)) !.Transfer(in this, TransferFuncType.InitWithCopy);
public TLMetadataDescriptor(SwiftType ofType, bool isBuiltIn, string mangledName, SwiftName module, ulong offset) : base(CoreCompoundType.MetadataDescriptor, mangledName, module, offset) { OfType = Ex.ThrowOnNull(ofType, nameof(ofType)); IsBuiltIn = isBuiltIn; }
static bool IsStaticProperty(SwiftType signature, SwiftClassType classType) { SwiftPropertyType pt = signature as SwiftPropertyType; return(pt != null && pt.IsStatic); }
static bool IsStaticMethod(SwiftType signature, SwiftClassType cl) { return(signature is SwiftStaticFunctionType); }
public TLUnsafeMutableAddressor(string mangledName, SwiftName module, SwiftClassType classType, SwiftName ident, SwiftType ofType, ulong offset) : base(CoreCompoundType.UnsafeMutableAddressor, mangledName, module, classType, offset) { Name = Ex.ThrowOnNull(ident, nameof(ident)); OfType = Ex.ThrowOnNull(ofType, nameof(ofType)); }
static bool IsPrivateProperty(SwiftType signature, SwiftClassType cl) { SwiftPropertyType pt = signature as SwiftPropertyType; return(pt != null && pt.IsPrivate); }
public TLVariable(string mangledName, SwiftName module, SwiftClassType classType, SwiftName ident, SwiftType ofType, bool isStatic, ulong offset, SwiftType extensionOn = null) : this(CoreCompoundType.Variable, mangledName, module, classType, ident, ofType, isStatic, offset, extensionOn) { }
public static void StoreTag(this SwiftType wrappedType, void *ptr, Tag tag) => wrappedType.StoreEnumTagSinglePayload(ptr, (int)tag, EmptyCases);
protected override void InitNativeData(void *handle) { // Using TransferFuncType.InitWithTake here in case we leak. using (var dataHandle = Data.GetSwiftHandle()) SwiftType.Transfer(handle, dataHandle.Pointer, TransferFuncType.InitWithTake); }
static void AssertFieldType(string fieldName) { var fld = GetField(fieldName); Assert.NotNull(SwiftType.Of(fld.FieldType, Nullability.Of(fld))); }
protected TLVariable(CoreCompoundType type, string mangledName, SwiftName module, SwiftClassType classType, SwiftName ident, SwiftType ofType, bool isStatic, ulong offset, SwiftType extensionOn) : base(type, mangledName, module, classType, offset) { Name = Ex.ThrowOnNull(ident, nameof(ident)); OfType = Ex.ThrowOnNull(ofType, nameof(ofType)); IsStatic = isStatic; ExtensionOn = extensionOn; }
static bool IsSubscript(SwiftType signature, SwiftClassType cl) { SwiftPropertyType prop = signature as SwiftPropertyType; return(prop != null && prop.IsSubscript); }
public TLPropertyDescriptor(string mangledName, SwiftName module, SwiftClassType classType, SwiftName ident, SwiftType ofType, bool isStatic, ulong offset, SwiftType extensionOn = null) : base(CoreCompoundType.PropertyDescriptor, mangledName, module, classType, ident, ofType, isStatic, offset, extensionOn) { }