diff --git a/src/AppKit/NSAccessibility.cs b/src/AppKit/NSAccessibility.cs index 5ca6531326..5efc92dacc 100644 --- a/src/AppKit/NSAccessibility.cs +++ b/src/AppKit/NSAccessibility.cs @@ -221,7 +221,6 @@ namespace AppKit return NSArray.ArrayFromHandle (handle); } - [Mac (10, 9)] [DllImport (Constants.AppKitLibrary)] static extern bool NSAccessibilitySetMayContainProtectedContent (bool flag); diff --git a/src/CoreMedia/CMSync.cs b/src/CoreMedia/CMSync.cs index 92b5a90a5a..0ffe46989d 100644 --- a/src/CoreMedia/CMSync.cs +++ b/src/CoreMedia/CMSync.cs @@ -456,19 +456,19 @@ namespace CoreMedia { return new CMClock (ptr, deprecated); } - [iOS (9,0)][Mac (10,11), Watch (6,0)] + [iOS (9,0)][Mac (10,11)] [DllImport(Constants.CoreMediaLibrary)] static extern unsafe /* CMTimebaseRef */ IntPtr CMTimebaseCopyMasterTimebase (/* CMTimebaseRef */ IntPtr timebase); - [iOS (9,0)][Mac (10,11), Watch (6,0)] + [iOS (9,0)][Mac (10,11)] [DllImport(Constants.CoreMediaLibrary)] static extern unsafe /* CMClockRef */ IntPtr CMTimebaseCopyMasterClock (/* CMTimebaseRef */ IntPtr timebase); - [iOS (9,0)][Mac (10,11), Watch (6,0)] + [iOS (9,0)][Mac (10,11)] [DllImport(Constants.CoreMediaLibrary)] static extern unsafe IntPtr /* void* */ CMTimebaseCopyMaster (/* CMTimebaseRef */ IntPtr timebase); - [iOS (9,0)][Mac (10,11), Watch (6,0)] + [iOS (9,0)][Mac (10,11)] [DllImport(Constants.CoreMediaLibrary)] static extern unsafe /* CMClockRef */ IntPtr CMTimebaseCopyUltimateMasterClock (/* CMTimebaseRef */ IntPtr timebase); #endif diff --git a/src/CoreTelephony/CoreTelephony.cs b/src/CoreTelephony/CoreTelephony.cs index 05af383ddb..723402b2a4 100644 --- a/src/CoreTelephony/CoreTelephony.cs +++ b/src/CoreTelephony/CoreTelephony.cs @@ -6,28 +6,24 @@ namespace CoreTelephony { public partial class CTCall { #if !COREBUILD - [Deprecated (PlatformName.iOS, 10, 0, message : Constants.UseCallKitInstead)] public string StateDialing { get { return Dlfcn.SlowGetStringConstant (Constants.CoreTelephonyLibrary, "CTCallStateDialing"); } } - [Deprecated (PlatformName.iOS, 10, 0, message : Constants.UseCallKitInstead)] public string StateIncoming { get { return Dlfcn.SlowGetStringConstant (Constants.CoreTelephonyLibrary, "CTCallStateIncoming"); } } - [Deprecated (PlatformName.iOS, 10, 0, message : Constants.UseCallKitInstead)] public string StateConnected { get { return Dlfcn.SlowGetStringConstant (Constants.CoreTelephonyLibrary, "CTCallStateConnected"); } } - [Deprecated (PlatformName.iOS, 10, 0, message : Constants.UseCallKitInstead)] public string StateDisconnected { get { return Dlfcn.SlowGetStringConstant (Constants.CoreTelephonyLibrary, "CTCallStateDisconnected"); diff --git a/src/GameController/GCExtendedGamepadSnapshot.cs b/src/GameController/GCExtendedGamepadSnapshot.cs index d7bb99123f..7d7546b608 100644 --- a/src/GameController/GCExtendedGamepadSnapshot.cs +++ b/src/GameController/GCExtendedGamepadSnapshot.cs @@ -115,9 +115,6 @@ namespace GameController { [TV (12, 2), Mac (10, 14, 4), iOS (12, 2)] bool RightThumbstickButton; - [Deprecated (PlatformName.MacOSX, 10, 15, message: "Use 'GCController.GetExtendedGamepadController()' instead.")] - [Deprecated (PlatformName.iOS, 13, 0, message: "Use 'GCController.GetExtendedGamepadController()' instead.")] - [Deprecated (PlatformName.TvOS, 13, 0, message: "Use 'GCController.GetExtendedGamepadController()' instead.")] [DllImport (Constants.GameControllerLibrary)] [TV (12, 2), Mac (10, 14, 4), iOS (12, 2)] static extern /* NSData * __nullable */ IntPtr NSDataFromGCExtendedGamepadSnapshotData ( @@ -134,28 +131,17 @@ namespace GameController { public partial class GCExtendedGamepadSnapshot { // GCExtendedGamepadSnapshot.h - [Deprecated (PlatformName.MacOSX, 10, 15, message: "Use 'GCController.GetExtendedGamepadController()' instead.")] - [Deprecated (PlatformName.iOS, 13, 0, message: "Use 'GCController.GetExtendedGamepadController()' instead.")] - [Deprecated (PlatformName.TvOS, 13, 0, message: "Use 'GCController.GetExtendedGamepadController()' instead.")] [DllImport (Constants.GameControllerLibrary)] static extern bool GCExtendedGamepadSnapShotDataV100FromNSData ( /* GCExtendedGamepadSnapShotDataV100 * __nullable */ out GCExtendedGamepadSnapShotDataV100 snapshotData, /* NSData * __nullable */ IntPtr data); - - [Deprecated (PlatformName.MacOSX, 10, 15, message: "Use 'GCController.GetExtendedGamepadController()' instead.")] - [Deprecated (PlatformName.iOS, 13, 0, message: "Use 'GCController.GetExtendedGamepadController()' instead.")] - [Deprecated (PlatformName.TvOS, 13, 0, message: "Use 'GCController.GetExtendedGamepadController()' instead.")] [DllImport (Constants.GameControllerLibrary)] [TV (12, 2), Mac (10, 14, 4), iOS (12, 2)] static extern bool GCExtendedGamepadSnapshotDataFromNSData ( /* GCExtendedGamepadSnapshotData * __nullable */ out GCExtendedGamepadSnapshotData snapshotData, /* NSData * __nullable */ IntPtr data); - - [Deprecated (PlatformName.iOS, 12, 2, message: "Use 'TryGetExtendedSnapShotData' instead.")] - [Deprecated (PlatformName.MacOSX, 10, 14, 4, message: "Use 'TryGetExtendedSnapShotData' instead.")] - [Deprecated (PlatformName.TvOS, 12, 2, message: "Use 'TryGetExtendedSnapShotData' instead.")] public static bool TryGetSnapShotData (NSData data, out GCExtendedGamepadSnapShotDataV100 snapshotData) { return GCExtendedGamepadSnapShotDataV100FromNSData (out snapshotData, data == null ? IntPtr.Zero : data.Handle); diff --git a/src/GameController/GCGamepadSnapshot.cs b/src/GameController/GCGamepadSnapshot.cs index 8e3f0c2783..0bfa366c54 100644 --- a/src/GameController/GCGamepadSnapshot.cs +++ b/src/GameController/GCGamepadSnapshot.cs @@ -40,9 +40,6 @@ namespace GameController { public float /* float_t = float */ LeftShoulder; public float /* float_t = float */ RightShoulder; - [Deprecated (PlatformName.MacOSX, 10, 15, message: "Use 'GCExtendedGamepad' instead.")] - [Deprecated (PlatformName.iOS, 13, 0, message: "Use 'GCExtendedGamepad' instead.")] - [Deprecated (PlatformName.TvOS, 13, 0, message: "Use 'GCExtendedGamepad' instead.")] [DllImport (Constants.GameControllerLibrary)] static extern /* NSData * __nullable */ IntPtr NSDataFromGCGamepadSnapShotDataV100 ( /* GCGamepadSnapShotDataV100 * __nullable */ ref GCGamepadSnapShotDataV100 snapshotData); @@ -57,9 +54,6 @@ namespace GameController { public partial class GCGamepadSnapshot { // GCGamepadSnapshot.h - [Deprecated (PlatformName.MacOSX, 10, 15, message: "Use 'GCExtendedGamepad' instead.")] - [Deprecated (PlatformName.iOS, 13, 0, message: "Use 'GCExtendedGamepad' instead.")] - [Deprecated (PlatformName.TvOS, 13, 0, message: "Use 'GCExtendedGamepad' instead.")] [DllImport (Constants.GameControllerLibrary)] static extern bool GCGamepadSnapShotDataV100FromNSData ( /* GCGamepadSnapShotDataV100 * __nullable */ out GCGamepadSnapShotDataV100 snapshotData, diff --git a/src/GameController/GCMicroGamepadSnapshot.cs b/src/GameController/GCMicroGamepadSnapshot.cs index 11a21a30f3..29907eba29 100644 --- a/src/GameController/GCMicroGamepadSnapshot.cs +++ b/src/GameController/GCMicroGamepadSnapshot.cs @@ -67,9 +67,6 @@ namespace GameController { public float /* float_t = float */ ButtonA; public float /* float_t = float */ ButtonX; - [Deprecated (PlatformName.MacOSX, 10, 15, message: "Use 'GCController.GetMicroGamepadController()' instead.")] - [Deprecated (PlatformName.iOS, 13, 0, message: "Use 'GCController.GetMicroGamepadController()' instead.")] - [Deprecated (PlatformName.TvOS, 13, 0, message: "Use 'GCController.GetMicroGamepadController()' instead.")] [DllImport (Constants.GameControllerLibrary)] [TV (12, 2), Mac (10, 14, 4), iOS (12, 2)] static extern /* NSData * __nullable */ IntPtr NSDataFromGCMicroGamepadSnapshotData ( diff --git a/src/MediaPlayer/MPPlayableContentDelegate.cs b/src/MediaPlayer/MPPlayableContentDelegate.cs index 5b3614fbdf..2143b5fcde 100644 --- a/src/MediaPlayer/MPPlayableContentDelegate.cs +++ b/src/MediaPlayer/MPPlayableContentDelegate.cs @@ -26,7 +26,6 @@ namespace MediaPlayer { #if !XAMCORE_4_0 public partial class MPPlayableContentDataSource : NSObject { - [Unavailable (PlatformName.MacOSX, PlatformArchitecture.All)] [iOS (10, 0)] [Obsolete ("Use 'MPPlayableContentDataSource_Extensions.GetContentItemAsync' instead.")] public unsafe virtual Task GetContentItemAsync (string identifier) diff --git a/src/Metal/MTLResourceStateCommandEncoder.cs b/src/Metal/MTLResourceStateCommandEncoder.cs index 7fa4d45c7c..e9054f8622 100644 --- a/src/Metal/MTLResourceStateCommandEncoder.cs +++ b/src/Metal/MTLResourceStateCommandEncoder.cs @@ -16,7 +16,7 @@ namespace Metal { public static partial class MTLResourceStateCommandEncoder_Extensions { - [NoMac, NoTV, iOS (13,0)] + [NoMac, NoTV] public static void Update (this IMTLResourceStateCommandEncoder This, IMTLTexture texture, MTLSparseTextureMappingMode mode, MTLRegion[] regions, nuint[] mipLevels, nuint[] slices) { if (texture == null) diff --git a/src/MetalPerformanceShaders/MPSKernel.cs b/src/MetalPerformanceShaders/MPSKernel.cs index 005564eeed..4564243dd5 100644 --- a/src/MetalPerformanceShaders/MPSKernel.cs +++ b/src/MetalPerformanceShaders/MPSKernel.cs @@ -20,11 +20,9 @@ namespace MetalPerformanceShaders { } [DllImport (Constants.MetalPerformanceShadersLibrary)] - [Introduced (PlatformName.MacCatalyst, 13, 0)] [TV (13,0), Mac (10,15), iOS (13,0)] static extern /* id _Nullable */ IntPtr MPSGetPreferredDevice (nuint options); - [Introduced (PlatformName.MacCatalyst, 13, 0)] [TV (13,0), Mac (10,15), iOS (13,0)] public static IMTLDevice GetPreferredDevice (MPSDeviceOptions options) { @@ -72,11 +70,11 @@ namespace MetalPerformanceShaders { #if !COREBUILD public partial class MPSImage { - [iOS (13,0), TV (12,0), Mac (10,15)][Introduced (PlatformName.MacCatalyst, 13, 0)] + [iOS (13,0), TV (12,0), Mac (10,15)] [DllImport (Constants.MetalPerformanceShadersLibrary)] static extern MPSImageType MPSGetImageType (IntPtr image); - [iOS (13,0), TV (12,0), Mac (10,15)][Introduced (PlatformName.MacCatalyst, 13, 0)] + [iOS (13,0), TV (12,0), Mac (10,15)] public MPSImageType ImageType => MPSGetImageType (Handle); } diff --git a/src/MetalPerformanceShaders/MPSStateBatch.cs b/src/MetalPerformanceShaders/MPSStateBatch.cs index 3b9fcc59a8..c633dc9fb5 100644 --- a/src/MetalPerformanceShaders/MPSStateBatch.cs +++ b/src/MetalPerformanceShaders/MPSStateBatch.cs @@ -44,13 +44,11 @@ namespace MetalPerformanceShaders { MPSStateBatchSynchronize (stateBatch.Handle, commandBuffer.Handle); } - [Introduced (PlatformName.MacCatalyst, 13, 0)] [iOS (12,0), TV (12,0), Mac (10,14)] [DllImport (Constants.MetalPerformanceShadersLibrary)] static extern nuint MPSStateBatchResourceSize (IntPtr batch); // Using 'NSArray' instead of `MPSState[]` because array 'Handle' matters. - [Introduced (PlatformName.MacCatalyst, 13, 0)] [iOS (12,0), TV (12,0), Mac (10,14)] public static nuint GetResourceSize (NSArray stateBatch) { diff --git a/src/Network/NWProtocolDefinition.cs b/src/Network/NWProtocolDefinition.cs index 1548e38069..acada3aedb 100644 --- a/src/Network/NWProtocolDefinition.cs +++ b/src/Network/NWProtocolDefinition.cs @@ -91,7 +91,7 @@ namespace Network { [TV (13,0), Mac (10,15), iOS (13,0)] public static NWProtocolDefinition CreateWebSocketDefinition () => new NWProtocolDefinition (nw_protocol_copy_ws_definition (), owns: true); - [Watch (6,0), TV (13,0), Mac (10,15)] + [TV (13,0), Mac (10,15)] [DllImport (Constants.NetworkLibrary)] static extern unsafe OS_nw_protocol_definition nw_framer_create_definition (string identifier, NWFramerCreateFlags flags, ref BlockLiteral start_handler); delegate NWFramerStartResult nw_framer_create_definition_t (IntPtr block, IntPtr framer); diff --git a/src/QTKit/QTCompat.cs b/src/QTKit/QTCompat.cs index 32f4db284f..674374c21a 100644 --- a/src/QTKit/QTCompat.cs +++ b/src/QTKit/QTCompat.cs @@ -115,7 +115,6 @@ namespace QTKit { get { return default(Foundation.NSString); } } - [ObjCRuntime.Obsoleted (ObjCRuntime.PlatformName.MacOSX, 10,15, message: ObjCRuntime.Constants.MacOS32bitsUnavailable)] public static class Notifications : System.Object { public static Foundation.NSObject ObserveAttributeDidChange (System.EventHandler handler) { @@ -353,7 +352,6 @@ namespace QTKit { get { return default(Foundation.NSString); } } - [ObjCRuntime.Obsoleted (ObjCRuntime.PlatformName.MacOSX, 10,15, message: ObjCRuntime.Constants.MacOS32bitsUnavailable)] public static class Notifications : System.Object { public static Foundation.NSObject ObserveAttributeDidChange (System.EventHandler handler) { @@ -1786,7 +1784,6 @@ namespace QTKit { get { return default(Foundation.NSString); } } - [ObjCRuntime.Obsoleted (ObjCRuntime.PlatformName.MacOSX, 10,15, message: ObjCRuntime.Constants.MacOS32bitsUnavailable)] public static class Notifications : System.Object { public static Foundation.NSObject ObserveApertureModeDidChange (System.EventHandler handler) { @@ -2884,7 +2881,6 @@ namespace QTKit { get { return default(Foundation.NSString); } } - [ObjCRuntime.Obsoleted (ObjCRuntime.PlatformName.MacOSX, 10,15, message: ObjCRuntime.Constants.MacOS32bitsUnavailable)] public static class Notifications : System.Object { public static Foundation.NSObject ObserveRuntimeError (System.EventHandler handler) { diff --git a/src/Security/SecAccessControl.cs b/src/Security/SecAccessControl.cs index a79a60b205..dabfb7e8a2 100644 --- a/src/Security/SecAccessControl.cs +++ b/src/Security/SecAccessControl.cs @@ -123,7 +123,6 @@ namespace Security { public SecAccessible Accessible { get; private set; } public SecAccessControlCreateFlags Flags { get; private set; } - [Mac (10,10)][iOS (8,0)] [DllImport (Constants.SecurityLibrary)] extern static IntPtr SecAccessControlCreateWithFlags (IntPtr allocator, /* CFTypeRef */ IntPtr protection, /* SecAccessControlCreateFlags */ nint flags, out IntPtr error); #endif diff --git a/src/Security/SecSharedCredential.cs b/src/Security/SecSharedCredential.cs index ce242c1daf..141dae7444 100644 --- a/src/Security/SecSharedCredential.cs +++ b/src/Security/SecSharedCredential.cs @@ -13,7 +13,6 @@ namespace Security { public static partial class SecSharedCredential { [DllImport (Constants.SecurityLibrary)] - [Introduced (PlatformName.MacCatalyst, 14, 0)] extern static void SecAddSharedWebCredential (IntPtr /* CFStringRef */ fqdn, IntPtr /* CFStringRef */ account, IntPtr /* CFStringRef */ password, IntPtr /* void (^completionHandler)( CFErrorRef error) ) */ completionHandler); @@ -34,7 +33,6 @@ namespace Security { } } - [Introduced (PlatformName.MacCatalyst, 14, 0)] [BindingImpl (BindingImplOptions.Optimizable)] public static void AddSharedWebCredential (string domainName, string account, string password, Action handler) { @@ -137,11 +135,9 @@ namespace Security { } } - [Introduced (PlatformName.MacCatalyst, 14, 0)] [DllImport (Constants.SecurityLibrary)] extern static IntPtr /* CFStringRef */ SecCreateSharedWebCredentialPassword (); - [Introduced (PlatformName.MacCatalyst, 14, 0)] public static string CreateSharedWebCredentialPassword () { var handle = SecCreateSharedWebCredentialPassword (); diff --git a/src/StoreKit/SKAdNetworkCompat.cs b/src/StoreKit/SKAdNetworkCompat.cs index d168b51268..030f1c5a80 100644 --- a/src/StoreKit/SKAdNetworkCompat.cs +++ b/src/StoreKit/SKAdNetworkCompat.cs @@ -32,7 +32,6 @@ namespace StoreKit { protected internal SKAdNetwork (IntPtr handle) : base (handle) { } [Obsolete ("Throws a 'NotSupportedException'.")] - [Unavailable (PlatformName.TvOS)] public static void RegisterAppForAdNetworkAttribution () => throw new NotSupportedException (); } } diff --git a/src/authenticationservices.cs b/src/authenticationservices.cs index 19c6086253..12923caa26 100644 --- a/src/authenticationservices.cs +++ b/src/authenticationservices.cs @@ -49,9 +49,15 @@ namespace AuthenticationServices { } [Partial] +#if TVOS || WATCH + // The associated enum is not generated (which is normal) + // without this define the attributes would be duplicated + // on other platforms (where the enum exists) + [NoTV][NoWatch] +#endif interface ASExtensionErrorCodeExtensions { - [NoWatch, NoTV, NoMac, iOS (14,0)] + [NoMac, iOS (14,0)] [Field ("ASExtensionLocalizedFailureReasonErrorKey")] NSString LocalizedFailureReasonErrorKey { get; } } diff --git a/src/avfoundation.cs b/src/avfoundation.cs index ea0cb3dc2a..16e3172a64 100644 --- a/src/avfoundation.cs +++ b/src/avfoundation.cs @@ -13500,7 +13500,6 @@ namespace AVFoundation { [Export ("processContentKeyResponseError:")] void Process (NSError error); - [NoWatch] [Deprecated (PlatformName.iOS, 11, 2, message: "Use the 'NSError' overload instead.")] [Export ("respondByRequestingPersistableContentKeyRequest"), NoWatch, NoTV, NoMac] void RespondByRequestingPersistableContentKeyRequest (); diff --git a/src/foundation.cs b/src/foundation.cs index 91130e9d2b..cb301ed4c3 100644 --- a/src/foundation.cs +++ b/src/foundation.cs @@ -4004,7 +4004,6 @@ namespace Foundation #if !XAMCORE_3_0 // now exposed with the corresponding EABluetoothAccessoryPickerError enum [NoMac, NoTV, NoWatch] - [NoTV] [Field ("EABluetoothAccessoryPickerErrorDomain", "ExternalAccessory")] NSString EABluetoothAccessoryPickerErrorDomain { get; } @@ -6536,35 +6535,35 @@ namespace Foundation string AsString (); [iOS (9,0), Mac(10,11)] - [Export ("rangeOfScheme"), Mac(10,11)] + [Export ("rangeOfScheme")] NSRange RangeOfScheme { get; } [iOS (9,0), Mac(10,11)] - [Export ("rangeOfUser"), Mac(10,11)] + [Export ("rangeOfUser")] NSRange RangeOfUser { get; } [iOS (9,0), Mac(10,11)] - [Export ("rangeOfPassword"), Mac(10,11)] + [Export ("rangeOfPassword")] NSRange RangeOfPassword { get; } [iOS (9,0), Mac(10,11)] - [Export ("rangeOfHost"), Mac(10,11)] + [Export ("rangeOfHost")] NSRange RangeOfHost { get; } [iOS (9,0), Mac(10,11)] - [Export ("rangeOfPort"), Mac(10,11)] + [Export ("rangeOfPort")] NSRange RangeOfPort { get; } [iOS (9,0), Mac(10,11)] - [Export ("rangeOfPath"), Mac(10,11)] + [Export ("rangeOfPath")] NSRange RangeOfPath { get; } [iOS (9,0), Mac(10,11)] - [Export ("rangeOfQuery"), Mac(10,11)] + [Export ("rangeOfQuery")] NSRange RangeOfQuery { get; } [iOS (9,0), Mac(10,11)] - [Export ("rangeOfFragment"), Mac(10,11)] + [Export ("rangeOfFragment")] NSRange RangeOfFragment { get; } [Watch (4, 0), TV (11, 0), Mac (10, 13), iOS (11, 0)] diff --git a/src/generator-filters.cs b/src/generator-filters.cs index 7e5cc80a4b..0705074865 100644 --- a/src/generator-filters.cs +++ b/src/generator-filters.cs @@ -117,7 +117,7 @@ public partial class Generator { } // properties - GenerateProperties (type); + GenerateProperties (type, type); // protocols GenerateProtocolProperties (type, new HashSet ()); @@ -146,14 +146,14 @@ public partial class Generator { print (""); print ($"// {pname} protocol members "); - GenerateProperties (i, type); + GenerateProperties (i, type, fromProtocol: true); // also include base interfaces/protocols GenerateProtocolProperties (i, processed); } } - void GenerateProperties (Type type, Type originalType = null) + void GenerateProperties (Type type, Type originalType = null, bool fromProtocol = false) { foreach (var p in type.GetProperties (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (p.IsUnavailable (this)) @@ -162,7 +162,13 @@ public partial class Generator { continue; print (""); - PrintPropertyAttributes (p, originalType); + + // an export will be present (only) if it's defined in a protocol + var export = AttributeManager.GetCustomAttribute (p); + + // this is a bit special since CoreImage filter protocols are much newer than the our generated, key-based bindings + // so we do not want to advertise the protocol versions since most properties would be incorrectly advertised + PrintPropertyAttributes (p, originalType, skipTypeInjection: export != null); print_generated_code (); var ptype = p.PropertyType.Name; @@ -189,7 +195,7 @@ public partial class Generator { case "CIColor": case "CIImage": // protocol-based bindings have annotations - but the older, key-based, versions did not - if (originalType == null) + if (!fromProtocol) nullable = true; break; } @@ -198,9 +204,6 @@ public partial class Generator { print ("public {0}{1} {2} {{", ptype, nullable ? "?" : "", p.Name); indent++; - // an export will be present (only) if it's defined in a protocol - var export = AttributeManager.GetCustomAttribute (p); - var name = AttributeManager.GetCustomAttribute (p)?.Name; // we can skip the name when it's identical to a protocol selector if (name == null) { diff --git a/src/generator.cs b/src/generator.cs index db505a8a4f..800f147618 100644 --- a/src/generator.cs +++ b/src/generator.cs @@ -3217,40 +3217,41 @@ public partial class Generator : IMemberGatherer { return false; } - public void PrintPlatformAttributes (MemberInfo mi, Type type = null) + public bool PrintPlatformAttributes (MemberInfo mi, Type type = null) { + bool printed = false; if (mi == null) - return; + return printed; - AvailabilityBaseAttribute[] type_ca = null; + AvailabilityBaseAttribute [] type_ca = null; foreach (var availability in AttributeManager.GetCustomAttributes (mi)) { + var t = type ?? (mi as TypeInfo) ?? mi.DeclaringType; if (type_ca == null) { - if (mi.DeclaringType != null) - type_ca = AttributeManager.GetCustomAttributes (type ?? mi.DeclaringType); + if (t != null) + type_ca = AttributeManager.GetCustomAttributes (t); else type_ca = Array.Empty (); } - // type has nothing, anything on member should be generated - if (type_ca.Length == 0) { - print (availability.ToString ()); - continue; - } - if (Duplicated (availability, type_ca)) + // if we're comparing to something else (than ourself) then don't generate duplicate attributes + if ((mi != t) && Duplicated (availability, type_ca)) continue; switch (availability.AvailabilityKind) { case AvailabilityKind.Unavailable: // an unavailable member can override type-level attribute print (availability.ToString ()); + printed = true; break; default: // can't introduce or deprecate/obsolete a member on a type that is not available if (IsUnavailable (type_ca, availability.Platform)) continue; print (availability.ToString ()); + printed = true; break; } } + return printed; } static bool IsUnavailable (IEnumerable customAttributes, PlatformName platform) @@ -3312,23 +3313,6 @@ public partial class Generator : IMemberGatherer { } } - public void PrintPlatformAttributesIfInlined (MemberInformation minfo) - { - if (minfo == null) - return; - - // check if it is an inlined property (e.g. from a protocol) - bool isInlined = minfo.type != minfo.property.DeclaringType; - - // we must avoid duplication of availability so we will only print - // if the property has no Availability - bool propHasNoInfo = !AttributeManager.HasAttribute (minfo.property) - && (minfo.property.GetGetMethod () == null || !AttributeManager.HasAttribute (minfo.property.GetGetMethod ())); - - if (isInlined && propHasNoInfo) - PrintPlatformAttributes (minfo.property.DeclaringType); - } - public string SelectorField (string s, bool ignore_inline_directive = false) { string name; @@ -4740,7 +4724,7 @@ public partial class Generator : IMemberGatherer { } } - void PrintPropertyAttributes (PropertyInfo pi, Type type = null) + void PrintPropertyAttributes (PropertyInfo pi, Type type, bool skipTypeInjection = false) { foreach (var oa in AttributeManager.GetCustomAttributes (pi)) { print ("[Obsolete (\"{0}\", {1})]", oa.Message, oa.IsError ? "true" : "false"); @@ -4759,7 +4743,17 @@ public partial class Generator : IMemberGatherer { print ("[DebuggerBrowsable (DebuggerBrowsableState.Never)]"); } - PrintPlatformAttributes (pi, type); + // if we inline properties (e.g. from a protocol) + // we must look if the type has an [Availability] attribute + if (type != pi.DeclaringType) { + // print, if not duplicated from the type (being inlined into), the property availability + if (!PrintPlatformAttributes (pi, type) && !skipTypeInjection) { + // print, if not duplicated from the type (being inlined into), the property declaring type (protocol) availability + PrintPlatformAttributes (pi.DeclaringType, type); + } + } else { + PrintPlatformAttributes (pi, type); + } foreach (var sa in AttributeManager.GetCustomAttributes (pi)) print (sa.Safe ? "[ThreadSafe]" : "[ThreadSafe (false)]"); @@ -4802,7 +4796,7 @@ public partial class Generator : IMemberGatherer { if (wrap != null){ print_generated_code (); - PrintPropertyAttributes (pi); + PrintPropertyAttributes (pi, minfo.type); PrintAttributes (pi, preserve:true, advice:true); print ("{0} {1}{2}{3} {4}{5} {{", mod, @@ -4881,11 +4875,7 @@ public partial class Generator : IMemberGatherer { } print_generated_code (); - PrintPropertyAttributes (pi); - - // when we inline properties (e.g. from a protocol) - // we must look if the type has an [Availability] attribute - PrintPlatformAttributesIfInlined (minfo); + PrintPropertyAttributes (pi, minfo.type); PrintAttributes (pi, preserve:true, advice:true, bindAs:true); @@ -4950,7 +4940,9 @@ public partial class Generator : IMemberGatherer { var ba = GetBindAttribute (getter); string sel = ba != null ? ba.Selector : export.Selector; - PrintAttributes (pi, platform:true); + // print availability separately since we could be inlining + PrintPlatformAttributes (pi, type); + PrintAttributes (pi, platform:false); if (!minfo.is_sealed || !minfo.is_wrapper) { PrintDelegateProxy (pi.GetGetMethod ()); @@ -5014,7 +5006,10 @@ public partial class Generator : IMemberGatherer { } PrintBlockProxy (pi.PropertyType); - PrintAttributes (pi, platform:true); + + // print availability separately since we could be inlining + PrintPlatformAttributes (pi, type); + PrintAttributes (pi, platform: false); if (not_implemented_attr == null && (!minfo.is_sealed || !minfo.is_wrapper)) PrintExport (minfo, sel, export.ArgumentSemantic); @@ -5839,7 +5834,6 @@ public partial class Generator : IMemberGatherer { var mod = string.Empty; PrintMethodAttributes (minfo); - PrintPlatformAttributes (mi); print_generated_code (); PrintDelegateProxy (minfo); PrintExport (minfo); diff --git a/src/scenekit.cs b/src/scenekit.cs index 4c1dcddd4e..8fb9d667a9 100644 --- a/src/scenekit.cs +++ b/src/scenekit.cs @@ -404,7 +404,7 @@ namespace SceneKit { [Mac (10,9)] [Export ("projectionTransform")] - SCNMatrix4 ProjectionTransform { get; [Mac (10,9)] set; } + SCNMatrix4 ProjectionTransform { get; set; } [Mac (10,9)] [Export ("automaticallyAdjustsZRange")] diff --git a/src/xkit.cs b/src/xkit.cs index 70a23525ee..6fd90ddf4c 100644 --- a/src/xkit.cs +++ b/src/xkit.cs @@ -936,7 +936,6 @@ namespace UIKit { [Deprecated (PlatformName.iOS, 13, 0, message: "Please use 'UsesDefaultHyphenation' or 'NSParagraphStyle.HyphenationFactor' instead.")] [Deprecated (PlatformName.WatchOS, 6, 0, message: "Please use 'UsesDefaultHyphenation' or 'NSParagraphStyle.HyphenationFactor' instead.")] [Deprecated (PlatformName.TvOS, 13, 0, message: "Please use 'UsesDefaultHyphenation' or 'NSParagraphStyle.HyphenationFactor' instead.")] - [Unavailable (PlatformName.MacCatalyst)] [Advice ("This API is not available when using UIKit on macOS.")] [NoMacCatalyst] [Export ("hyphenationFactor")] diff --git a/tests/generator/BGenTests.cs b/tests/generator/BGenTests.cs index bae840bb8e..9c0c366699 100644 --- a/tests/generator/BGenTests.cs +++ b/tests/generator/BGenTests.cs @@ -220,7 +220,7 @@ namespace GeneratorTests .Union (allTypes.SelectMany ((type) => type.Properties)); var preserves = allMembers.Sum ((v) => v.CustomAttributes.Count ((ca) => ca.AttributeType.Name == "IntroducedAttribute")); - Assert.AreEqual (8, preserves, "Introduced attribute count"); // If you modified code that generates IntroducedAttributes please update the attribute count + Assert.AreEqual (10, preserves, "Introduced attribute count"); // If you modified code that generates IntroducedAttributes please update the attribute count } [Test] diff --git a/tests/introspection/ApiAvailabilityTest.cs b/tests/introspection/ApiAvailabilityTest.cs index 4c3de4379a..d7d4904d29 100644 --- a/tests/introspection/ApiAvailabilityTest.cs +++ b/tests/introspection/ApiAvailabilityTest.cs @@ -20,6 +20,7 @@ // using System; +using System.Collections.Generic; using System.Reflection; using NUnit.Framework; using ObjCRuntime; @@ -259,5 +260,56 @@ namespace Introspection { } AssertIfErrors ("{0} API with mixed [Unavailable] and availability attributes", Errors); } + + static HashSet member_level = new HashSet (); + + void CheckDupes (MemberInfo m, Type t, ISet type_level) + { + member_level.Clear (); + foreach (var a in m.GetCustomAttributes (false)) { + var s = String.Empty; + if (a is AvailabilityBaseAttribute aa) + s = aa.ToString (); + if (s.Length > 0) { + if (type_level.Contains (s)) + AddErrorLine ($"[FAIL] Both '{t}' and '{m}' are marked with `{s}`."); + if (member_level.Contains (s)) + AddErrorLine ($"[FAIL] '{m}' is decorated more than once with `{s}`."); + else + member_level.Add (s); + } + } + } + + [Test] + public void Duplicates () + { + HashSet type_level = new HashSet (); + //LogProgress = true; + Errors = 0; + foreach (Type t in Assembly.GetTypes ()) { + if (LogProgress) + Console.WriteLine ($"T: {t}"); + + type_level.Clear (); + foreach (var a in t.GetCustomAttributes (false)) { + if (a is AvailabilityBaseAttribute aa) + type_level.Add (aa.ToString ()); + } + + foreach (var p in t.GetProperties (BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) { + if (LogProgress) + Console.WriteLine ($"P: {p}"); + CheckDupes (p, t, type_level); + } + + foreach (var m in t.GetMembers (BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) { + if (LogProgress) + Console.WriteLine ($"M: {m}"); + CheckDupes (m, t, type_level); + } + } + AssertIfErrors ("{0} API with members duplicating type-level attributes", Errors); + } } }