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 have a {nameof (SwiftImportAttribute)}, or declare a public, read-only `Body` property returning a concrete type of `{nameof (View)}`"); } BodyNullability = Nullability.Of(BodyProperty); BodySwiftType = SwiftType.Of(BodyProperty.PropertyType, BodyNullability) !; var thunkMetadata = (CustomViewMetadata *)fullMetadata; thunkMetadata->ThunkViewU = Metadata; thunkMetadata->ThunkViewT = BodySwiftType.Metadata; // Currently unused, so don't force allocation if it's a custom view //thunkMetadata->ThunkViewTViewConformance = swiftBodyType.ViewConformance; thunkMetadata->ThunkViewTViewConformance = null; // Proactively create View conformance. While generics that are explicitly constrained to View // have the conformance passed in, other cases, such as TupleView, look up the conformance // dynamically, so it's important to register it eagerly. ViewConformance = CreateViewConformance(); } catch { // Ensure we don't leak allocated unmanaged memory Dispose(true); throw; } }
static void AssertField(string fieldName, Nullability expected) { var fld = typeof(NullabilityTests).GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic) !; Assert.True(Nullability.Of(fld) == expected, fieldName); }
static void AssertFieldType(string fieldName) { var fld = GetField(fieldName); Assert.NotNull(SwiftType.Of(fld.FieldType, Nullability.Of(fld))); }
static void AssertField(string fieldName, Nullability expected) { var fld = GetField(fieldName); Assert.True(Nullability.Of(fld) == expected, fieldName); }