-
Notifications
You must be signed in to change notification settings - Fork 517
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[cecil-tests] Add two more tests. (#21625)
Add two more Cecil tests: * Verify that we don't call the NSObject.Handle setter, we're supposed to call NSObject.InitializeHandle instead (which throws an exception if the handle is null), * Verify that we never call the base class' default constructor (very easy mistake to make) in manually bound constructors - we're supposed to call the overload that takes an `NSObjectFlag` parameter instead.
- Loading branch information
1 parent
1a7def0
commit 98bee4d
Showing
5 changed files
with
332 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using System.Collections.Generic; | ||
|
||
#nullable enable | ||
|
||
namespace Cecil.Tests { | ||
public partial class ConstructorTest { | ||
static HashSet<string> knownFailuresNonDefaultCtorDoesNotCallBaseDefaultCtor = new HashSet<string> { | ||
"AppKit.ActionDispatcher::.ctor(System.EventHandler)", | ||
"AppKit.NSAlertDidEndDispatcher::.ctor(System.Action`1<System.IntPtr>)", | ||
"AppKit.NSGradient::.ctor(AppKit.NSColor[],System.Single[],AppKit.NSColorSpace)", | ||
"AppKit.NSImage::.ctor(Foundation.NSData,System.Boolean)", | ||
"AppKit.NSImage::.ctor(System.String,System.Boolean)", | ||
"AppKit.NSTextContainer::.ctor(CoreGraphics.CGSize,System.Boolean)", | ||
"AVFoundation.AVAudioRecorder::.ctor(Foundation.NSUrl,AVFoundation.AudioSettings,Foundation.NSError&)", | ||
"AVFoundation.AVAudioRecorder::.ctor(Foundation.NSUrl,AVFoundation.AVAudioFormat,Foundation.NSError&)", | ||
"AVFoundation.InternalAVAudioSessionDelegate::.ctor(AVFoundation.AVAudioSession)", | ||
"CarPlay.CPListSection::.ctor(CarPlay.CPListItem[],System.String,System.String)", | ||
"CarPlay.CPListSection::.ctor(CarPlay.CPListItem[])", | ||
"CloudKit.CKSyncEngineFetchChangesScope::.ctor(Foundation.NSSet`1<CloudKit.CKRecordZoneID>,System.Boolean)", | ||
"CloudKit.CKSyncEngineSendChangesScope::.ctor(Foundation.NSSet`1<CloudKit.CKRecordZoneID>,System.Boolean)", | ||
"CloudKit.CKUserIdentityLookupInfo::.ctor(System.String,System.Int32)", | ||
"CoreAnimation.CALayer::.ctor(CoreAnimation.CALayer)", | ||
"Foundation.InternalNSNotificationHandler::.ctor(Foundation.NSNotificationCenter,System.Action`1<Foundation.NSNotification>)", | ||
"Foundation.NSActionDispatcher::.ctor(System.Action)", | ||
"Foundation.NSAppleEventDescriptor::.ctor(Foundation.NSAppleEventDescriptorType)", | ||
"Foundation.NSAsyncActionDispatcher::.ctor(System.Action)", | ||
"Foundation.NSAsyncSynchronizationContextDispatcher::.ctor(System.Threading.SendOrPostCallback,System.Object)", | ||
"Foundation.NSAttributedString::.ctor(Foundation.NSData,Foundation.NSAttributedStringDataType,Foundation.NSDictionary&)", | ||
"Foundation.NSHttpCookie::.ctor(System.Net.Cookie)", | ||
"Foundation.NSHttpCookie::.ctor(System.String,System.String,System.String,System.String)", | ||
"Foundation.NSMutableArray`1::.ctor(TValue[])", | ||
"Foundation.NSObject::.ctor(Foundation.NSObjectFlag)", | ||
"Foundation.NSObject::.ctor(ObjCRuntime.NativeHandle,System.Boolean)", | ||
"Foundation.NSString::.ctor(System.String,System.Int32,System.Int32)", | ||
"Foundation.NSString::.ctor(System.String)", | ||
"Foundation.NSSynchronizationContextDispatcher::.ctor(System.Threading.SendOrPostCallback,System.Object)", | ||
"Foundation.NSThread::.ctor(Foundation.NSObject,ObjCRuntime.Selector,Foundation.NSObject)", | ||
"Foundation.NSTimerActionDispatcher::.ctor(System.Action`1<Foundation.NSTimer>)", | ||
"Foundation.NSUserDefaults::.ctor(System.String,Foundation.NSUserDefaultsType)", | ||
"GameKit.GKScore::.ctor(System.String)", | ||
"GameplayKit.GKPath::.ctor(System.Numerics.Vector2[],System.Single,System.Boolean)", | ||
"GameplayKit.GKPath::.ctor(System.Numerics.Vector3[],System.Single,System.Boolean)", | ||
"HomeKit.HMMatterHome::.ctor(Foundation.NSCoder)", | ||
"HomeKit.HMMatterHome::.ctor(Foundation.NSObjectFlag)", | ||
"HomeKit.HMMatterHome::.ctor(Foundation.NSUuid,System.String)", | ||
"HomeKit.HMMatterHome::.ctor(ObjCRuntime.NativeHandle)", | ||
"HomeKit.HMMatterRequestHandler::.ctor(Foundation.NSObjectFlag)", | ||
"HomeKit.HMMatterRequestHandler::.ctor(ObjCRuntime.NativeHandle)", | ||
"HomeKit.HMMatterRoom::.ctor(Foundation.NSCoder)", | ||
"HomeKit.HMMatterRoom::.ctor(Foundation.NSObjectFlag)", | ||
"HomeKit.HMMatterRoom::.ctor(Foundation.NSUuid,System.String)", | ||
"HomeKit.HMMatterRoom::.ctor(ObjCRuntime.NativeHandle)", | ||
"HomeKit.HMMatterTopology::.ctor(Foundation.NSCoder)", | ||
"HomeKit.HMMatterTopology::.ctor(Foundation.NSObjectFlag)", | ||
"HomeKit.HMMatterTopology::.ctor(HomeKit.HMMatterHome[])", | ||
"HomeKit.HMMatterTopology::.ctor(ObjCRuntime.NativeHandle)", | ||
"Intents.INPriceRange::.ctor(Intents.INPriceRangeOption,Foundation.NSDecimalNumber,System.String)", | ||
"Intents.INSaveProfileInCarIntent::.ctor(Foundation.NSNumber,System.String)", | ||
"Intents.INSetProfileInCarIntent::.ctor(Foundation.NSNumber,System.String,Foundation.NSNumber)", | ||
"MapKit.MKMapCameraZoomRange::.ctor(System.Double,MapKit.MKMapCameraZoomRangeType)", | ||
"MapKit.MKPointOfInterestFilter::.ctor(MapKit.MKPointOfInterestCategory[],MapKit.MKPointOfInterestFilterType)", | ||
"ModelIO.MDLMesh::.ctor(ModelIO.MDLMesh,System.Int32,System.UInt32,ModelIO.IMDLMeshBufferAllocator)", | ||
"ModelIO.MDLMesh::.ctor(System.Numerics.Vector3,CoreGraphics.NVector2i,ModelIO.MDLGeometryType,ModelIO.IMDLMeshBufferAllocator)", | ||
"ModelIO.MDLMesh::.ctor(System.Numerics.Vector3,CoreGraphics.NVector2i,System.Boolean,ModelIO.MDLGeometryType,ModelIO.IMDLMeshBufferAllocator,System.Nullable`1<System.Int32>,System.Nullable`1<System.Boolean>,System.Nullable`1<System.Boolean>)", | ||
"ModelIO.MDLMesh::.ctor(System.Numerics.Vector3,CoreGraphics.NVector2i,System.Boolean,System.Boolean,System.Boolean,ModelIO.MDLGeometryType,ModelIO.IMDLMeshBufferAllocator)", | ||
"ModelIO.MDLMesh::.ctor(System.Numerics.Vector3,CoreGraphics.NVector3i,System.Boolean,ModelIO.MDLGeometryType,ModelIO.IMDLMeshBufferAllocator)", | ||
"ModelIO.MDLMesh::.ctor(System.Numerics.Vector3,System.Boolean,ModelIO.MDLGeometryType,ModelIO.IMDLMeshBufferAllocator)", | ||
"ModelIO.MDLNoiseTexture::.ctor(System.Single,System.String,CoreGraphics.NVector2i,ModelIO.MDLTextureChannelEncoding,ModelIO.MDLNoiseTextureType)", | ||
"NetworkExtension.NEHotspotConfiguration::.ctor(System.String,System.Boolean)", | ||
"NetworkExtension.NEHotspotConfiguration::.ctor(System.String,System.String,System.Boolean,System.Boolean)", | ||
"NetworkExtension.NEHotspotConfiguration::.ctor(System.String,System.String,System.Boolean)", | ||
"NetworkExtension.NEHotspotConfiguration::.ctor(System.String)", | ||
"SpriteKit.SKUniform::.ctor(System.String,System.Numerics.Vector2)", | ||
"SpriteKit.SKUniform::.ctor(System.String,System.Numerics.Vector3)", | ||
"SpriteKit.SKUniform::.ctor(System.String,System.Numerics.Vector4)", | ||
"SpriteKit.SKVideoNode::.ctor(Foundation.NSUrl)", | ||
"SpriteKit.SKVideoNode::.ctor(System.String)", | ||
"SpriteKit.SKWarpGeometryGrid::.ctor(System.IntPtr,System.IntPtr,System.Numerics.Vector2[],System.Numerics.Vector2[])", | ||
"UIKit.UIControlEventProxy::.ctor(UIKit.UIControl,System.EventHandler)", | ||
"UIKit.UIImageStatusDispatcher::.ctor(UIKit.UIImage/SaveStatus)", | ||
"UIKit.UIVideoStatusDispatcher::.ctor(UIKit.UIVideo/SaveStatus)", | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using System.Collections.Generic; | ||
|
||
#nullable enable | ||
|
||
namespace Cecil.Tests { | ||
public partial class SetHandleTest { | ||
static HashSet<string> knownFailuresNobodyCallsHandleSetter = new HashSet<string> { | ||
"AddressBook.ABGroup::.ctor(AddressBook.ABRecord)", | ||
"AppKit.NSBitmapImageRep::.ctor(Foundation.NSObjectFlag,Foundation.NSObjectFlag)", | ||
"AppKit.NSGradient::Initialize(AppKit.NSColor[],System.Void*,AppKit.NSColorSpace)", | ||
"AppKit.NSImage::.ctor(Foundation.NSData,System.Boolean)", | ||
"AppKit.NSImage::.ctor(System.String,System.Boolean)", | ||
"AppKit.NSOpenGLPixelFormat::.ctor(AppKit.NSOpenGLPixelFormatAttribute[])", | ||
"AppKit.NSOpenGLPixelFormat::.ctor(System.Object[])", | ||
"AppKit.NSTextContainer::.ctor(CoreGraphics.CGSize,System.Boolean)", | ||
"AVFoundation.AVAudioRecorder::.ctor(Foundation.NSUrl,AVFoundation.AudioSettings,Foundation.NSError&)", | ||
"AVFoundation.AVAudioRecorder::.ctor(Foundation.NSUrl,AVFoundation.AVAudioFormat,Foundation.NSError&)", | ||
"CoreFoundation.CFMutableString::.ctor(CoreFoundation.CFString,System.IntPtr)", | ||
"CoreFoundation.CFMutableString::.ctor(System.String,System.IntPtr)", | ||
"CoreFoundation.CFSocket::Initialize(CoreFoundation.CFRunLoop,CoreFoundation.CFSocket/CreateSocket)", | ||
"CoreFoundation.CFString::.ctor(System.String)", | ||
"CoreFoundation.DispatchBlock::Retain()", | ||
"CoreFoundation.OSLog::.ctor(System.String,System.String)", | ||
"CoreGraphics.CGPattern::.ctor(CoreGraphics.CGRect,CoreGraphics.CGAffineTransform,System.Runtime.InteropServices.NFloat,System.Runtime.InteropServices.NFloat,CoreGraphics.CGPatternTiling,System.Boolean,CoreGraphics.CGPattern/DrawPattern)", | ||
"Foundation.NSAttributedString::.ctor(Foundation.NSData,Foundation.NSAttributedStringDataType,Foundation.NSDictionary&)", | ||
"Foundation.NSHttpCookie::CreateCookie(System.String,System.String,System.String,System.String,System.String,System.String,System.Nullable`1<System.Boolean>,System.Nullable`1<System.DateTime>,System.Nullable`1<System.Int32>,System.String,System.Nullable`1<System.Boolean>,System.Nullable`1<System.Int32>)", | ||
"Foundation.NSKeyedUnarchiver::.ctor(Foundation.NSData)", | ||
"Foundation.NSString::.ctor(System.String,System.Int32,System.Int32)", | ||
"Foundation.NSString::.ctor(System.String)", | ||
"Foundation.NSThread::.ctor(Foundation.NSObject,ObjCRuntime.Selector,Foundation.NSObject)", | ||
"Foundation.NSUrlProtectionSpace::.ctor(System.String,System.Int32,System.String,System.String,System.String,System.Boolean)", | ||
"Foundation.NSUrlProtectionSpace::.ctor(System.String,System.Int32,System.String,System.String,System.String)", | ||
"Foundation.NSUserDefaults::.ctor(System.String,Foundation.NSUserDefaultsType)", | ||
"Foundation.NSUuid::.ctor(System.Byte[])", | ||
"GameKit.GKScore::.ctor(System.String)", | ||
"GameplayKit.GKPath::.ctor(System.Numerics.Vector2[],System.Single,System.Boolean)", | ||
"GameplayKit.GKPath::.ctor(System.Numerics.Vector3[],System.Single,System.Boolean)", | ||
"Intents.INPriceRange::.ctor(Intents.INPriceRangeOption,Foundation.NSDecimalNumber,System.String)", | ||
"ModelIO.MDLNoiseTexture::.ctor(System.Single,System.String,CoreGraphics.NVector2i,ModelIO.MDLTextureChannelEncoding,ModelIO.MDLNoiseTextureType)", | ||
"MultipeerConnectivity.MCSession::.ctor(MultipeerConnectivity.MCPeerID,Security.SecIdentity,MultipeerConnectivity.MCEncryptionPreference)", | ||
"MultipeerConnectivity.MCSession::.ctor(MultipeerConnectivity.MCPeerID,Security.SecIdentity,Security.SecCertificate[],MultipeerConnectivity.MCEncryptionPreference)", | ||
"ScreenCaptureKit.SCContentFilter::.ctor(ScreenCaptureKit.SCDisplay,ScreenCaptureKit.SCRunningApplication[],ScreenCaptureKit.SCWindow[],ScreenCaptureKit.SCContentFilterOption)", | ||
"ScreenCaptureKit.SCContentFilter::.ctor(ScreenCaptureKit.SCDisplay,ScreenCaptureKit.SCWindow[],ScreenCaptureKit.SCContentFilterOption)", | ||
"Security.SecTrust2::.ctor(Security.SecTrust)", | ||
"SpriteKit.SKVideoNode::.ctor(Foundation.NSUrl)", | ||
"SpriteKit.SKVideoNode::.ctor(System.String)", | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Collections.Generic; | ||
|
||
using Mono.Cecil; | ||
using Mono.Cecil.Cil; | ||
using NUnit.Framework; | ||
|
||
using Xamarin.Tests; | ||
using Xamarin.Utils; | ||
|
||
namespace Cecil.Tests { | ||
public partial class SetHandleTest { | ||
static string GetLocation (MethodDefinition? method) | ||
{ | ||
if (method?.DebugInformation?.HasSequencePoints == true) { | ||
var seq = method.DebugInformation.SequencePoints [0]; | ||
return seq.Document.Url + ":" + seq.StartLine + ": "; | ||
} | ||
return string.Empty; | ||
} | ||
|
||
static bool VerifyMethod (MethodDefinition method, IList<Instruction> instructions, out string? reason) | ||
{ | ||
reason = null; | ||
|
||
foreach (var instr in instructions) { | ||
if (instr.OpCode != OpCodes.Call) | ||
continue; | ||
|
||
var target = instr.Operand as MethodReference; | ||
if (target is null) { | ||
reason = $"Call instructions calling null?"; | ||
return false; | ||
} | ||
if (target.Name != "set_Handle") | ||
continue; | ||
|
||
// A class can call its own Handle property | ||
if (target.DeclaringType == method.DeclaringType) | ||
continue; | ||
|
||
if (target.DeclaringType.Is ("Foundation", "NSObject")) { | ||
reason = $"Call to NSObject.Handle setter."; | ||
return false; | ||
} | ||
|
||
if (target.DeclaringType.Is ("ObjCRuntime", "DisposableObject")) { | ||
reason = $"Call to DisposableObject.Handle setter."; | ||
return false; | ||
} | ||
|
||
Console.WriteLine ($"Another Handle property? {target.DeclaringType} called in {method.RenderMethod ()}"); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
[Test] | ||
public void NobodyCallsHandleSetter () | ||
{ | ||
Configuration.IgnoreIfAnyIgnoredPlatforms (); | ||
|
||
var failures = new Dictionary<string, FailureWithMessageAndLocation> (); | ||
foreach (var info in Helper.NetPlatformImplementationAssemblyDefinitions) { | ||
foreach (var method in info.Assembly.EnumerateMethods (v => v.HasBody)) { | ||
if (!VerifyMethod (method, method.Body.Instructions, out var failureReason)) { | ||
var msg = $"{method.RenderMethod ()} Failed NSObject.Handle setter verification: {failureReason}"; | ||
// Uncomment this to make finding and fixing known failures easier | ||
// Console.WriteLine ($"{GetLocation (method)}{msg}"); | ||
failures [method.RenderMethod ()] = new FailureWithMessageAndLocation (msg, GetLocation (method)); | ||
} | ||
} | ||
} | ||
|
||
Helper.AssertFailures (failures, | ||
knownFailuresNobodyCallsHandleSetter, | ||
nameof (knownFailuresNobodyCallsHandleSetter), | ||
"Don't call NSObject.Handle's setter directly, use InitializeHandle instead.", (v) => $"{v.Location}: {v.Message}"); | ||
} | ||
} | ||
} |
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.