Skip to content

Commit

Permalink
[generator] Fix property accessor attributes when one accessor's iOS …
Browse files Browse the repository at this point in the history
…availability is different than the property itself. (xamarin#17298)

This PR handles two scenarios (fixed in separate commits):

Scenario 1:

* The property has different availability attributes than the containing type.
* The property's accessor(s) do not have availability attributes.

We'd generate the wrong availability attributes for the property accessors,
because we'd take the type's availability attributes and add them to the
accessors.

As for the fix: I can't really explain it. This code is rather impenetrable,
and the parameter names don't make much sense, but whatever I did seems to
work?

And it turns out this fix shows up in an existing test as well (the
generator's Bug35176 test), which I had to modify to remove the expectation of
(now redundant) availability attributes that we no longer produce.

Scenario 2:

* Type is available on iOS, tvOS.
* Property in the type is available on iOS (and not tvOS).
* Property accessor has explicit availability attributes for iOS.

Then the property accessor would get the availability attribute for tvOS from
the type, and not the (un)availability attribute from the property.

The fix is to make sure the parent context is the property (and not the type)
when processing availability attributes for the accessor.
  • Loading branch information
rolfbjarne authored Jan 25, 2023
1 parent d27667f commit a57695b
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 86 deletions.
2 changes: 1 addition & 1 deletion src/generator-enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ void GenerateEnum (Type type)
// skip value__ field
if (f.IsSpecialName)
continue;
PrintPlatformAttributes (f, is_enum: true);
PrintPlatformAttributes (f);
PrintObsoleteAttributes (f);
print ("{0} = {1},", f.Name, f.GetRawConstantValue ());
var fa = AttributeManager.GetCustomAttribute<FieldAttribute> (f);
Expand Down
13 changes: 7 additions & 6 deletions src/generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3677,15 +3677,16 @@ List<AvailabilityBaseAttribute> GetAllParentAttributes (MemberInfo context)
}
}

AvailabilityBaseAttribute [] GetPlatformAttributesToPrint (MemberInfo mi, Type type, MemberInfo inlinedType)
AvailabilityBaseAttribute [] GetPlatformAttributesToPrint (MemberInfo mi, MemberInfo context, MemberInfo inlinedType)
{
// Attributes are directly on the member
List<AvailabilityBaseAttribute> memberAvailability = AttributeManager.GetCustomAttributes<AvailabilityBaseAttribute> (mi).ToList ();

// Due to differences between Xamarin and NET6 availability attributes, we have to synthesize many duplicates for NET6
// See https://github.com/xamarin/xamarin-macios/issues/10170 for details
#if NET
MemberInfo context = type ?? FindContainingContext (mi);
if (context is null)
context = FindContainingContext (mi);
// Attributes on the _target_ context, the class itself or the target of the protocol inlining
List<AvailabilityBaseAttribute> parentContextAvailability = GetAllParentAttributes (context);
// (Optional) Attributes from the inlined protocol type itself
Expand Down Expand Up @@ -3761,16 +3762,16 @@ AvailabilityBaseAttribute [] GetPlatformAttributesToPrint (MemberInfo mi, Type t
return memberAvailability.ToArray ();
}

public bool PrintPlatformAttributes (MemberInfo mi, Type type = null, bool is_enum = false)
public bool PrintPlatformAttributes (MemberInfo mi, Type inlinedType = null)
{
bool printed = false;
if (mi == null)
return printed;

AvailabilityBaseAttribute [] type_ca = null;

foreach (var availability in GetPlatformAttributesToPrint (mi, is_enum ? mi.DeclaringType : type, is_enum ? null : mi.DeclaringType)) {
var t = type ?? (mi as TypeInfo) ?? mi.DeclaringType;
foreach (var availability in GetPlatformAttributesToPrint (mi, null, inlinedType)) {
var t = inlinedType ?? (mi as TypeInfo) ?? mi.DeclaringType;
if (type_ca == null) {
if (t != null)
type_ca = AttributeManager.GetCustomAttributes<AvailabilityBaseAttribute> (t);
Expand Down Expand Up @@ -5289,7 +5290,7 @@ void PrintPropertyAttributes (PropertyInfo pi, Type type, bool skipTypeInjection
PrintPlatformAttributes (pi.DeclaringType, type);
}
} else {
PrintPlatformAttributes (pi, type);
PrintPlatformAttributes (pi);
}

foreach (var sa in AttributeManager.GetCustomAttributes<ThreadSafeAttribute> (pi))
Expand Down
59 changes: 0 additions & 59 deletions tests/cecil-tests/ApiAvailabilityTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,7 @@ public void FindMissingObsoleteAttributes ()
"AppKit.NSCursor.IsSetOnMouseExited()",
"AppKit.NSCursor.SetOnMouseEntered(System.Boolean)",
"AppKit.NSCursor.SetOnMouseExited(System.Boolean)",
"AppKit.NSImage.get_Flipped()",
"AppKit.NSImage.get_ImageFileTypes()",
"AppKit.NSImage.ImageUnfilteredFileTypes()",
"AppKit.NSImage.set_Flipped(System.Boolean)",
"AppKit.NSToolbarItem.get_MaxSize()",
"AppKit.NSToolbarItem.get_MinSize()",
"AppKit.NSToolbarItem.set_MaxSize(CoreGraphics.CGSize)",
"AppKit.NSToolbarItem.set_MinSize(CoreGraphics.CGSize)",
"AudioToolbox.AudioFormatFlags AudioToolbox.AudioStreamBasicDescription::AudioFormatFlagsAudioUnitCanonical",
"AudioToolbox.AudioFormatProperty AudioToolbox.AudioFormatProperty::HardwareCodecCapabilities",
"AudioToolbox.AudioSessionActiveFlags",
Expand All @@ -110,23 +103,8 @@ public void FindMissingObsoleteAttributes ()
"AudioUnit.AUGraph",
"AudioUnit.SpatialMixerRenderingFlags AudioUnit.SpatialMixerRenderingFlags::DistanceAttenuation",
"AVFoundation.AVAssetDownloadUrlSession.GetAssetDownloadTask(AVFoundation.AVUrlAsset, Foundation.NSUrl, Foundation.NSDictionary)",
"AVFoundation.AVCaptureConnection.get_SupportsVideoMaxFrameDuration()",
"AVFoundation.AVCaptureConnection.get_SupportsVideoMinFrameDuration()",
"AVFoundation.AVCaptureConnection.get_VideoMaxFrameDuration()",
"AVFoundation.AVCaptureConnection.get_VideoMinFrameDuration()",
"AVFoundation.AVCaptureConnection.set_VideoMaxFrameDuration(CoreMedia.CMTime)",
"AVFoundation.AVCaptureConnection.set_VideoMinFrameDuration(CoreMedia.CMTime)",
"AVFoundation.AVCaptureDevice.get_FlashMode()",
"AVFoundation.AVCaptureDevice.IsFlashModeSupported(AVFoundation.AVCaptureFlashMode)",
"AVFoundation.AVCaptureDevice.set_FlashMode(AVFoundation.AVCaptureFlashMode)",
"AVFoundation.AVCaptureFlashMode AVFoundation.AVCaptureDevice::FlashMode()",
"AVFoundation.AVCapturePhotoSettings.get_AutoDualCameraFusionEnabled()",
"AVFoundation.AVCapturePhotoSettings.get_DualCameraDualPhotoDeliveryEnabled()",
"AVFoundation.AVCapturePhotoSettings.set_AutoDualCameraFusionEnabled(System.Boolean)",
"AVFoundation.AVCapturePhotoSettings.set_DualCameraDualPhotoDeliveryEnabled(System.Boolean)",
"AVFoundation.AVCaptureResolvedPhotoSettings.get_DualCameraFusionEnabled()",
"AVFoundation.AVCaptureVideoDataOutput.get_MinFrameDuration()",
"AVFoundation.AVCaptureVideoDataOutput.set_MinFrameDuration(CoreMedia.CMTime)",
"CFNetwork.CFHTTPStream",
"CoreBluetooth.CBCentralManagerState",
"CoreBluetooth.CBPeripheralManagerState",
Expand Down Expand Up @@ -190,34 +168,23 @@ public void FindMissingObsoleteAttributes ()
"GameController.GCMicroGamepadSnapshotData.ToNSData()",
"GameController.GCMicroGamepadSnapShotDataV100",
"GameKit.GKVoiceChatService",
"HealthKit.HKActivitySummary.get_AppleExerciseTimeGoal()",
"HealthKit.HKActivitySummary.get_AppleStandHoursGoal()",
"HealthKit.HKActivitySummary.set_AppleExerciseTimeGoal(HealthKit.HKQuantity)",
"HealthKit.HKActivitySummary.set_AppleStandHoursGoal(HealthKit.HKQuantity)",
"HealthKit.HKAnchoredObjectQuery..ctor(HealthKit.HKSampleType, Foundation.NSPredicate, System.UIntPtr, System.UIntPtr, HealthKit.HKAnchoredObjectResultHandler)",
"HealthKit.HKCategoryValueOvulationTestResult HealthKit.HKCategoryValueOvulationTestResult::Positive",
"HealthKit.HKCumulativeQuantitySeriesSample",
"HealthKit.HKCumulativeQuantitySeriesSample.get_Sum()",
"HealthKit.HKHealthStore.GetDateOfBirth(out Foundation.NSError&)",
"HealthKit.HKHealthStore.SplitTotalEnergy(HealthKit.HKQuantity, Foundation.NSDate, Foundation.NSDate, System.Action`3<HealthKit.HKQuantity,HealthKit.HKQuantity,Foundation.NSError>)",
"HealthKit.HKObject.get_Source()",
"HealthKit.HKQuantity HealthKit.HKActivitySummary::AppleExerciseTimeGoal()",
"HealthKit.HKQuantity HealthKit.HKActivitySummary::AppleStandHoursGoal()",
"HealthKit.HKQuantity HealthKit.HKCumulativeQuantitySeriesSample::Sum()",
"HealthKit.HKQuantityAggregationStyle HealthKit.HKQuantityAggregationStyle::Discrete",
"HealthKit.HKQuantitySeriesSampleQuery..ctor(HealthKit.HKQuantitySample, HealthKit.HKQuantitySeriesSampleQueryQuantityDelegate)",
"HealthKit.HKQuery.get_SampleType()",
"HealthKit.HKSampleType HealthKit.HKQuery::SampleType()",
"HealthKit.HKSource HealthKit.HKObject::Source()",
"HealthKit.HKUnit HealthKit.HKUnit::Calorie()",
"HealthKit.HKUnit.get_Calorie()",
"HealthKit.HKVerifiableClinicalRecord.get_JwsRepresentation()",
"HealthKit.HKWorkoutActivityType HealthKit.HKWorkoutActivityType::DanceInspiredTraining",
"HealthKit.HKWorkoutActivityType HealthKit.HKWorkoutActivityType::MixedMetabolicCardioTraining",
"HealthKit.HKWorkoutEvent.Create(HealthKit.HKWorkoutEventType, Foundation.NSDate)",
"HealthKit.HKWorkoutEvent.Create(HealthKit.HKWorkoutEventType, Foundation.NSDate, Foundation.NSDictionary)",
"HealthKit.HKWorkoutEvent.Create(HealthKit.HKWorkoutEventType, Foundation.NSDate, HealthKit.HKMetadata)",
"HealthKit.HKWorkoutEvent.get_Date()",
"HomeKit.HMEventTrigger.CreatePredicateForEvaluatingTriggerOccurringAfterSignificantEvent(HomeKit.HMSignificantEvent, Foundation.NSDateComponents)",
"HomeKit.HMEventTrigger.CreatePredicateForEvaluatingTriggerOccurringBeforeSignificantEvent(HomeKit.HMSignificantEvent, Foundation.NSDateComponents)",
"Intents.INCallRecord..ctor(System.String, Foundation.NSDate, Intents.INPerson, Intents.INCallRecordType, Intents.INCallCapability, System.Nullable`1<System.Double>, System.Nullable`1<System.Boolean>, System.Nullable`1<System.Int32>)",
Expand All @@ -228,7 +195,6 @@ public void FindMissingObsoleteAttributes ()
"Intents.INSetProfileInCarIntent..ctor(Foundation.NSNumber, System.String, System.Nullable`1<System.Boolean>)",
"Intents.INSetSeatSettingsInCarIntent..ctor(System.Nullable`1<System.Boolean>, System.Nullable`1<System.Boolean>, System.Nullable`1<System.Boolean>, Intents.INCarSeat, Foundation.NSNumber, Intents.INRelativeSetting)",
"Intents.INStartCallIntent..ctor(Intents.INCallAudioRoute, Intents.INCallDestinationType, Intents.INPerson[], Intents.INCallRecordType, Intents.INCallCapability)",
"Intents.INStartCallIntent.get_RecordTypeForRedialing()",
"MapKit.MKOverlayView",
"MapKit.MKPinAnnotationColor",
"MediaPlayer.MPMoviePlayerController",
Expand All @@ -237,11 +203,7 @@ public void FindMissingObsoleteAttributes ()
"MediaPlayer.MPVolumeSettings.AlertIsVisible()",
"MediaPlayer.MPVolumeSettings.AlertShow()",
"Metal.IMTLResource Metal.MTLTextureWrapper::RootResource()",
"Metal.MTLTextureWrapper.get_RootResource()",
"MetalPerformanceShaders.MPSCnnConvolution.get_Neuron()",
"MetalPerformanceShaders.MPSCnnConvolutionDescriptor.get_Neuron()",
"MetalPerformanceShaders.MPSCnnConvolutionDescriptor.GetConvolutionDescriptor(System.UIntPtr, System.UIntPtr, System.UIntPtr, System.UIntPtr, MetalPerformanceShaders.MPSCnnNeuron)",
"MetalPerformanceShaders.MPSCnnConvolutionDescriptor.set_Neuron(MetalPerformanceShaders.MPSCnnNeuron)",
"MetalPerformanceShaders.MPSCnnFullyConnected..ctor(Metal.IMTLDevice, MetalPerformanceShaders.MPSCnnConvolutionDescriptor, System.Single[], System.Single[], MetalPerformanceShaders.MPSCnnConvolutionFlags)",
"MetalPerformanceShaders.MPSCnnNeuron MetalPerformanceShaders.MPSCnnConvolution::Neuron()",
"MetalPerformanceShaders.MPSCnnNeuron MetalPerformanceShaders.MPSCnnConvolutionDescriptor::Neuron()",
Expand All @@ -253,15 +215,8 @@ public void FindMissingObsoleteAttributes ()
"MobileCoreServices.UTType.get_UniversalSceneDescriptionMobile()",
"MobileCoreServices.UTType.IsDeclared(System.String)",
"MobileCoreServices.UTType.IsDynamic(System.String)",
"NetworkExtension.NEFilterProviderConfiguration.get_FilterBrowsers()",
"NetworkExtension.NEFilterProviderConfiguration.set_FilterBrowsers(System.Boolean)",
"PassKit.PKAddShareablePassConfiguration.get_ProvisioningPolicyIdentifier()",
"PassKit.PKShareablePassMetadata..ctor(System.String, System.String, CoreGraphics.CGImage, System.String, System.String, System.String, System.String, System.String, System.Boolean)",
"PassKit.PKShareablePassMetadata..ctor(System.String, System.String, System.String, CoreGraphics.CGImage, System.String, System.String)",
"PassKit.PKShareablePassMetadata.get_LocalizedDescription()",
"PassKit.PKShareablePassMetadata.get_OwnerDisplayName()",
"PassKit.PKShareablePassMetadata.get_PassThumbnailImage()",
"PassKit.PKShareablePassMetadata.get_TemplateIdentifier()",
"Security.Authorization.ExecuteWithPrivileges(System.String, Security.AuthorizationFlags, System.String[])",
"Security.SecAccessible Security.SecAccessible::Always",
"Security.SecAccessible Security.SecAccessible::AlwaysThisDeviceOnly",
Expand Down Expand Up @@ -290,18 +245,12 @@ public void FindMissingObsoleteAttributes ()
"Security.SslContext.SetSessionStrengthPolicy(Security.SslSessionStrengthPolicy)",
"Security.SslContext.SetSessionTickets(System.Boolean)",
"Security.SslProtocol Security.SecProtocolMetadata::NegotiatedProtocolVersion()",
"Speech.SFSpeechRecognitionRequest.get_InteractionIdentifier()",
"Speech.SFSpeechRecognitionRequest.set_InteractionIdentifier(System.String)",
"Speech.SFTranscription.get_AveragePauseDuration()",
"Speech.SFTranscription.get_SpeakingRate()",
"Speech.SFTranscriptionSegment.get_VoiceAnalytics()",
"Speech.SFVoiceAnalytics Speech.SFTranscriptionSegment::VoiceAnalytics()",
"StoreKit.SKCloudServiceController.RequestPersonalizationToken(System.String, System.Action`2<Foundation.NSString,Foundation.NSError>)",
"StoreKit.SKCloudServiceController.RequestPersonalizationTokenAsync(System.String)",
"StoreKit.SKDownload.DeleteContentForProduct(System.String)",
"StoreKit.SKDownload.GetContentUrlForProduct(System.String)",
"StoreKit.SKMutablePayment.PaymentWithProduct(System.String)",
"StoreKit.SKProduct.get_ContentVersion()",
"StoreKit.SKStoreReviewController.RequestReview()",
"System.Boolean AppKit.NSImage::Flipped()",
"System.Boolean AVFoundation.AVCaptureConnection::SupportsVideoMaxFrameDuration()",
Expand Down Expand Up @@ -332,8 +281,6 @@ public void FindMissingObsoleteAttributes ()
"SystemConfiguration.CaptiveNetwork.TryGetSupportedInterfaces(out System.String[]&)",
"UIKit.UIGestureRecognizer UIKit.UIScrollView::DirectionalPressGestureRecognizer()",
"UIKit.UIGraphicsRendererFormat UIKit.UIGraphicsRendererFormat::DefaultFormat()",
"UIKit.UIGraphicsRendererFormat.get_DefaultFormat()",
"UIKit.UIScrollView.get_DirectionalPressGestureRecognizer()",
"UIKit.UIStringDrawing.DrawString(System.String, CoreGraphics.CGPoint, System.Runtime.InteropServices.NFloat, UIKit.UIFont, System.Runtime.InteropServices.NFloat, System.Runtime.InteropServices.NFloat&, UIKit.UILineBreakMode, UIKit.UIBaselineAdjustment)",
"UIKit.UIStringDrawing.DrawString(System.String, CoreGraphics.CGPoint, System.Runtime.InteropServices.NFloat, UIKit.UIFont, System.Runtime.InteropServices.NFloat, UIKit.UILineBreakMode, UIKit.UIBaselineAdjustment)",
"UIKit.UIStringDrawing.DrawString(System.String, CoreGraphics.CGPoint, System.Runtime.InteropServices.NFloat, UIKit.UIFont, UIKit.UILineBreakMode)",
Expand All @@ -346,12 +293,6 @@ public void FindMissingObsoleteAttributes ()
"UIKit.UIStringDrawing.StringSize(System.String, UIKit.UIFont, CoreGraphics.CGSize, UIKit.UILineBreakMode)",
"UIKit.UIStringDrawing.StringSize(System.String, UIKit.UIFont, System.Runtime.InteropServices.NFloat, System.Runtime.InteropServices.NFloat&, System.Runtime.InteropServices.NFloat, UIKit.UILineBreakMode)",
"UIKit.UIStringDrawing.StringSize(System.String, UIKit.UIFont, System.Runtime.InteropServices.NFloat, UIKit.UILineBreakMode)",
"UserNotifications.UNMutableNotificationContent.get_SummaryArgument()",
"UserNotifications.UNMutableNotificationContent.get_SummaryArgumentCount()",
"UserNotifications.UNMutableNotificationContent.set_SummaryArgument(System.String)",
"UserNotifications.UNMutableNotificationContent.set_SummaryArgumentCount(System.UIntPtr)",
"UserNotifications.UNNotificationContent.get_SummaryArgument()",
"UserNotifications.UNNotificationContent.get_SummaryArgumentCount()",
};

// This test verifies that the SupportedOSPlatform and UnavailableOSPlatform/ObsoletedOSplatform attributes are consistent.
Expand Down
2 changes: 2 additions & 0 deletions tests/common/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,8 @@ static string GetSdkNuGetName (ApplePlatform platform)
return "Microsoft.watchOS.Sdk";
case ApplePlatform.MacOSX:
return "Microsoft.macOS.Sdk";
case ApplePlatform.MacCatalyst:
return "Microsoft.MacCatalyst.Sdk";
default:
throw new InvalidOperationException (platform.ToString ());
}
Expand Down
2 changes: 2 additions & 0 deletions tests/common/Profile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public static ApplePlatform AsPlatform (this Profile profile)
case Profile.macOSMobile:
case Profile.macOSSystem:
return ApplePlatform.MacOSX;
case Profile.MacCatalyst:
return ApplePlatform.MacCatalyst;
case Profile.None:
default:
throw new NotImplementedException (profile.ToString ());
Expand Down
Loading

0 comments on commit a57695b

Please sign in to comment.