xamarin-macios/tests/introspection/ApiCtorInitTest.cs

663 строки
27 KiB
C#
Исходник Обычный вид История

//
// Test the generated API `init` selectors are usable by the binding consumers
//
// Authors:
// Sebastien Pouliot <sebastien@xamarin.com>
//
// Copyright 2012-2015 Xamarin Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
using System;
using System.Reflection;
[MetalPerformanceShaders] Xcode 9 bindings (#3005) * [MetalPerformanceShaders] Activate bindings for Xamarin.Mac and add n… (#2816) * [MetalPerformaceShaders] Several MPSCnnKernel properties should be readonly (#2938) The subclasses versions of the properties need Override, cannot be removed since it would break visibility for iOS 10 * Remove some [Model] attributes that sholdn't be needed * Fix introspection test crashes * More introspection fixes * NN does not need to be PascalCased Remove unneeded Models and BaseTypes * PR Whitespace fixes and renamings * Paste fail * More fixes from PR comments * [MPS] Adds new intro test, fixes ctors and xtro output * Removes duplicated availability attributes. * Removes obsoleted API from macOS since mps is new to it. * Fixes xtro output. * Adds missing API. * Fixes parameterless ctors, some of them do not really work, found by our new intro test and disabled the one that seem to not make sense due to the presence of DesignatedInitializers. * Fixes a selector typo. * Adds new `ShouldNotExposeDefaultCtorTest` to intro. ShouldNotExposeDefaultCtorTest ============================== This test checks for types with a parameterless ctor that are subclasses of `NSObject` and then cheks if the BaseType of said objects also expose a parameterless ctor (all in .NET land), if this is not the case it reports them and so they can manually audited. Also this test has the ability to print alloc/init ObjC code by setting `genObjCTestCode` to `true` so you can take this code into an Xcode project and easily tests the ctors. It seems that xtro (sharpie) does not have a complete picture of when a ctor must be exposed hence the hability to generate this code and manually test. Right now this test is just enabled for MPS since it is the scope of this PR. In the future it should be enabled for all other frameworks and the output be manually audited. * [MPS] Fixes premature collection possible in bindings (bug 59547) and implements feedback. https://bugzilla.xamarin.com/show_bug.cgi?id=59547 * Fixes premature collection possible in bindings im MPSKernel.cs * Fixes MPSImageHistogramTest from using deprecated API. * Removes renamed selectors and typos from ApiSelectorTest and ApiTypoTest. * [MPS] Reenable Copy API and DesignatedInitializer xtro feedback * Implement more feedback * More feedback
2017-11-28 23:29:05 +03:00
using System.Linq;
using System.Text;
using NUnit.Framework;
#if HAS_ARKIT
using ARKit;
#endif
using Foundation;
using ObjCRuntime;
namespace Introspection {
public abstract class ApiCtorInitTest : ApiBaseTest {
string instance_type_name;
/// <summary>
/// Gets or sets a value indicating whether this test fixture will log untested types.
/// </summary>
/// <value><c>true</c> if log untested types; otherwise, <c>false</c>.</value>
public bool LogUntestedTypes { get; set; }
/// <summary>
/// Override this method if you want the test to skip some specific types.
/// By default types decorated with [Model] will be skipped.
/// </summary>
/// <param name="type">The Type to be tested</param>
protected virtual bool Skip (Type type)
{
if (type.ContainsGenericParameters)
return true;
switch (type.Name) {
case "JSExport":
// This is interesting: Apple defines a private JSExport class - if you try to define your own in an Objective-C project you get this warning at startup:
// objc[334]: Class JSExport is implemented in both /Applications/Xcode91.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/JavaScriptCore.framework/JavaScriptCore (0x112c1e430) and /Users/rolf/Library/Developer/CoreSimulator/Devices/AC5323CF-225F-44D9-AA18-A37B7C28CA68/data/Containers/Bundle/Application/DEF9EAFC-CB5C-454F-97F5-669BBD00A609/jsexporttest.app/jsexporttest (0x105b49df0). One of the two will be used. Which one is undefined.
// Due to how we treat models, we'll always look the Objective-C type up at runtime (even with the static registrar),
// see that there's an existing JSExport type, and use that one instead of creating a new type.
// This is problematic, because Apple's JSExport is completely unusable, and will crash if you try to do anything.
return true;
// on iOS 8.2 (beta 1) we get: NSInvalidArgumentException Caller did not provide an activityType, and this process does not have a NSUserActivityTypes in its Info.plist.
// even if we specify an NSUserActivityTypes in the Info.plist - might be a bug or there's a new (undocumented) requirement
case "NSUserActivity":
return true;
case "NEPacketTunnelProvider":
return true;
// On iOS 14 (beta 4) we get: [NISimulator] To simulate Nearby Interaction distance and direction, launch two or more simulators and
// move the simulator windows around the screen.
// The same error occurs when trying to default init NISession in Xcode.
// It seems that it is only possible to create a NISession when there are two devices or sims running, which makes sense given the description of
// NISession from Apple API docs: "An object that identifies a unique connection between two peer devices"
case "NISession":
return true;
case "NSUnitDispersion": // -init should never be called on NSUnit!
case "NSUnitVolume": // -init should never be called on NSUnit!
case "NSUnitDuration": // -init should never be called on NSUnit!
case "NSUnitElectricCharge": // -init should never be called on NSUnit!
case "NSUnitElectricCurrent": // -init should never be called on NSUnit!
case "NSUnitElectricPotentialDifference": // -init should never be called on NSUnit!
case "NSUnitElectricResistance": // -init should never be called on NSUnit!
case "NSUnit": // -init should never be called on NSUnit!
case "NSUnitEnergy": // -init should never be called on NSUnit!
case "NSUnitAcceleration": // -init should never be called on NSUnit!
case "NSUnitFrequency": // -init should never be called on NSUnit!
case "NSUnitAngle": // -init should never be called on NSUnit!
case "NSUnitFuelEfficiency": // -init should never be called on NSUnit!
case "NSUnitArea": // -init should never be called on NSUnit!
case "NSUnitIlluminance": // -init should never be called on NSUnit!
case "NSUnitConcentrationMass": // -init should never be called on NSUnit!
case "NSUnitLength": // -init should never be called on NSUnit!
case "NSUnitMass": // -init should never be called on NSUnit!
case "NSUnitPower": // -init should never be called on NSUnit!
case "NSUnitPressure": // -init should never be called on NSUnit!
case "NSUnitSpeed": // -init should never be called on NSUnit!
return true;
#if !NET // NSMenuView does not exist in .NET
case "NSMenuView":
return TestRuntime.IsVM; // skip on vms due to hadware problems
#endif // !NET
[MetalPerformanceShaders] Xcode 9 bindings (#3005) * [MetalPerformanceShaders] Activate bindings for Xamarin.Mac and add n… (#2816) * [MetalPerformaceShaders] Several MPSCnnKernel properties should be readonly (#2938) The subclasses versions of the properties need Override, cannot be removed since it would break visibility for iOS 10 * Remove some [Model] attributes that sholdn't be needed * Fix introspection test crashes * More introspection fixes * NN does not need to be PascalCased Remove unneeded Models and BaseTypes * PR Whitespace fixes and renamings * Paste fail * More fixes from PR comments * [MPS] Adds new intro test, fixes ctors and xtro output * Removes duplicated availability attributes. * Removes obsoleted API from macOS since mps is new to it. * Fixes xtro output. * Adds missing API. * Fixes parameterless ctors, some of them do not really work, found by our new intro test and disabled the one that seem to not make sense due to the presence of DesignatedInitializers. * Fixes a selector typo. * Adds new `ShouldNotExposeDefaultCtorTest` to intro. ShouldNotExposeDefaultCtorTest ============================== This test checks for types with a parameterless ctor that are subclasses of `NSObject` and then cheks if the BaseType of said objects also expose a parameterless ctor (all in .NET land), if this is not the case it reports them and so they can manually audited. Also this test has the ability to print alloc/init ObjC code by setting `genObjCTestCode` to `true` so you can take this code into an Xcode project and easily tests the ctors. It seems that xtro (sharpie) does not have a complete picture of when a ctor must be exposed hence the hability to generate this code and manually test. Right now this test is just enabled for MPS since it is the scope of this PR. In the future it should be enabled for all other frameworks and the output be manually audited. * [MPS] Fixes premature collection possible in bindings (bug 59547) and implements feedback. https://bugzilla.xamarin.com/show_bug.cgi?id=59547 * Fixes premature collection possible in bindings im MPSKernel.cs * Fixes MPSImageHistogramTest from using deprecated API. * Removes renamed selectors and typos from ApiSelectorTest and ApiTypoTest. * [MPS] Reenable Copy API and DesignatedInitializer xtro feedback * Implement more feedback * More feedback
2017-11-28 23:29:05 +03:00
case "MPSCnnNeuron": // Cannot directly initialize MPSCNNNeuron. Use one of the sub-classes of MPSCNNNeuron
case "MPSCnnNeuronPReLU":
case "MPSCnnNeuronHardSigmoid":
case "MPSCnnNeuronSoftPlus":
return true;
case "MPSCnnBinaryConvolution": // [MPSCNNBinaryConvolution initWithDevice:] is not allowed. Please use initializers that are not marked NS_UNAVAILABLE.
case "MPSCnnDilatedPoolingMax": // [MPSCNNDilatedPoolingMax initWithDevice:] is not allowed. Please use initializers that are not marked NS_UNAVAILABLE.
case "MPSCnnPoolingL2Norm": // [MPSCNNPoolingL2Norm initWithDevice:] is not allowed. Please use initializers that are not marked NS_UNAVAILABLE.
return true;
case "MPSCnnBinaryFullyConnected": // Please initialize the MPSCNNBinaryFullyConnected class with initWithDevice:convolutionDescriptor:kernelWeights:biasTerms
return true;
case "MPSCnnUpsampling": // Cannot directly initialize MPSCNNUpsampling. Use one of the sub-classes of MPSCNNUpsampling
case "MPSCnnUpsamplingBilinear":
case "MPSCnnUpsamplingNearest":
return true;
case "MPSImageArithmetic": // Cannot directly initialize MPSImageArithmetic. Use one of the sub-classes of MPSImageArithmetic.
return true;
[Submission] Fix all the selectors that apple warns about. (#9268) (#9408) * [Submission] Fix all the selectors that apple warns about. (#9268) We have noticed the following message from Apple when performing submissions with Xamarin.iOS: > ITMS-90338: Non-public API usage - The app references non-public > selectors in WcBc.iOS: behaviorTypes, convolutionState, > discoverAllContactUserInfosWithCompletionHandler:, > discoverAllContactsCompletionBlock, > discoverUserInfoWithEmailAddress:completionHandler:, > discoverUserInfoWithUserRecordID:completionHandler:, > discoverUserInfosCompletionBlock, displayContact, drawableResizesAsynchronously, > encodeToCommandBuffer:sourceImage:convolutionState:, > encodeToCommandBuffer:sourceImage:destinationImage:state:, > getProperty:onChannel:responseHandler:, hasProperty:onChannel:responseHandler:, > initWithEmailAddresses:userRecordIDs:, initWithMIDIEntity:dataReadyHandler:, > initWithZoneID:options:, initWithZoneID:subscriptionID:options:, > isPublicDatabase, mouseUpAction, newDrawable, propertyChangedCallback, > removeAllAppearanceStreams, replaceTextStorage:, retrieveConnectedPeripherals, > retrievePeripherals:, setDiscoverAllContactsCompletionBlock:, > setDiscoverUserInfosCompletionBlock:, setDrawableResizesAsynchronously:, > setEditedMask:, setMouseUpAction:, setMovieControlMode:, > setProperty:onChannel:responseHandler:, setPropertyChangedCallback:, > setSocketFamily:, setTemporaryAttributes:forCharacterRange:, setUserRecordIDs:, > sourceOffset, subscriptionOptions, takeBackgroundColorFrom:, takePasswordFrom:, > temporalAntialiasingEnabled, userRecordIDs. If method names in your source code > match the private Apple APIs listed above, altering your method names will help > prevent this app from being flagged in future submissions. In addition, note > that one or more of the above APIs may be located in a static library that was > included with your app. If so, they must be removed. For further information, > visit the Technical Support Information at http://developer.apple.com/support/technical/ All of them have been removed but without a break in the API excep "initWithMIDIEntity:dataReadyHandler:" wich does look like an error on Apples side. Empty stubs are used as much as possible except on those cases in which a handler is called or an output variable should be modified (buffer, out param) to minimize the users surprise at runtime.
2020-08-21 23:30:51 +03:00
case "CKDiscoverUserInfosOperation": // deprecated, throws exception
case "CKSubscription":
case "MPSCnnConvolutionState":
return true;
case "AVSpeechSynthesisVoice": // Calling description crashes the test
#if __WATCHOS__
return TestRuntime.CheckXcodeVersion (12, 2); // CheckExactXcodeVersion is not implemented in watchOS yet but will be covered by iOS parrot below
#else
return TestRuntime.CheckExactXcodeVersion (12, 2, beta: 3);
#endif
case "SKView":
// Causes a crash later. Filed as radar://18440271.
// Apple said they won't fix this ('init' isn't a designated initializer)
return true;
case "HMMatterRequestHandler": // got removed and the current API throws an exception at run time.
return true;
#if __MACCATALYST__
case "PKIdentityButton":
return true;
#endif
#if !XAMCORE_5_0
case "GKHybridStrategist":
return true; // GKHybridStrategist has been removed from our bindings
#endif
}
switch (type.Namespace) {
case "SafetyKit":
return true; // SafetyKit requires a custom entitlement, and will throw exceptions if it's not present.
#if __IOS__
case "WatchKit":
return true; // WatchKit has been removed from iOS.
#elif MONOMAC
case "QTKit":
return true; // QTKit has been removed from macos.
#endif
}
[mtouch] Add `force-rejected-types-removal` optimization (#8009) This optimization can be enabled when it's not possible to use the managed linker (e.g. **Don't link**) or when the managed linker cannot remove references to deprecated types that would cause an application to be rejected by Apple. References to the existing types will be renamed, e.g. `UIWebView` to `DeprecatedWebView`, in every assemblies. The type definition is also renamed (for validity) and all custom attributes on the types and their members will be removed. Code inside the members will be replaced with a `throw new NotSupportedException ();`. The msbuild test app `MyReleaseBuild` has been updated to test that the optimization is working as expected (device builds are slow so reusing this test has little impact in test time). Basically the test ensure that `UIWebView` is used and cannot be removed by the compiler (optimization) or the managed linker (since it's referenced). Since the optimization is enabled then we can `grep` then final `.app` directory to ensure there's no mention of `UIWebView` inside any of the files that would be submitted. The application can be run, by itself, and will turn green if OK, red if `DeprecatedWebView` can't be found (skeleton replacement for `UIWebView`) or orange if a `NotSupportedException` is thrown. Finally introspection tests have been updated to skip over the deprecated (and renamed) types. It should not be an issue right now, since this optimization is not enabled by default, but it made testing easier.
2020-03-02 17:20:29 +03:00
// skip types that we renamed / rewrite since they won't behave correctly (by design)
if (SkipDueToRejectedTypes (type))
return true;
return SkipDueToAttribute (type);
}
/// <summary>
/// Checks that the Handle property of the specified NSObject instance is not null (not IntPtr.Zero).
/// </summary>
/// <param name="obj">NSObject instance to validate</param>
protected virtual void CheckHandle (NSObject obj)
{
if (obj.Handle == IntPtr.Zero)
ReportError ("{0} : Handle", instance_type_name);
}
/// <summary>
/// Checks that ToString does not return null (not helpful for debugging) and that it does not crash.
/// </summary>
/// <param name="obj">NSObject instance to validate</param>
protected virtual void CheckToString (NSObject obj)
{
if (obj.ToString () is null)
ReportError ("{0} : ToString", instance_type_name);
}
bool GetIsDirectBinding (NSObject obj)
{
int flags = TestRuntime.GetFlags (obj);
return (flags & 4) == 4;
}
/// <summary>
/// Checks that the IsDirectBinding property is identical to the IsWrapper property of the Register attribute.
/// </summary>
/// <param name="obj">Object.</param>
protected virtual void CheckIsDirectBinding (NSObject obj)
{
var attrib = obj.GetType ().GetCustomAttribute<RegisterAttribute> (false);
// only check types that we register - that way we avoid the 118 MonoTouch.CoreImagge.CI* "special" types
if (attrib is null)
return;
var is_wrapper = attrib is not null && attrib.IsWrapper;
var is_direct_binding = GetIsDirectBinding (obj);
if (is_direct_binding != is_wrapper)
ReportError ("{0} : IsDirectBinding (expected {1}, got {2})", instance_type_name, is_wrapper, is_direct_binding);
}
/// <summary>
/// Skip, or not, the specified pproperty from being verified.
/// </summary>
/// <param name="pi">PropertyInfo candidate</param>
protected virtual bool Skip (PropertyInfo pi)
{
// manually bound API can have the attributes only on the property (and not on the getter/setter)
return SkipDueToAttribute (pi);
}
/// <summary>
/// Dispose the specified NSObject instance. In some cases objects cannot be disposed safely.
/// Override this method to keep them alive while the remaining tests execute.
/// </summary>
/// <param name="obj">NSObject instance to dispose</param>
/// <param name="type">Type of the object, to be used if special logic is required.</param>
protected virtual void Dispose (NSObject obj, Type type)
{
//***** ApiCtorInitTest.DefaultCtorAllowed
//2017-01-23 15:52:09.762 introspection[4084:16658258] *** -[NSKeyedArchiver dealloc]: warning: NSKeyedArchiver deallocated without having had -finishEncoding called on it.
(obj as NSKeyedArchiver)?.FinishEncoding ();
obj.Dispose ();
}
protected virtual void CheckNSObjectProtocol (NSObject obj)
{
// not documented to allow null, but commonly used this way. OTOH it's not clear what code answer this
// (it might be different implementations) but we can make sure that Apple allows null with this test
// ref: https://bugzilla.xamarin.com/show_bug.cgi?id=35924
var kind_of_null = obj.IsKindOfClass (null);
if (kind_of_null)
ReportError ("{0} : IsKindOfClass(null) failed", instance_type_name);
var is_member_of_null = obj.IsMemberOfClass (null);
if (is_member_of_null)
ReportError ("{0} : IsMemberOfClass(null) failed", instance_type_name);
var respond_to_null = obj.RespondsToSelector (null);
if (respond_to_null)
ReportError ("{0} : RespondToSelector(null) failed", instance_type_name);
var conforms_to_null = obj.ConformsToProtocol (IntPtr.Zero);
if (conforms_to_null)
ReportError ("{0} : ConformsToProtocol(null) failed", instance_type_name);
}
// if a .ctor is obsolete then it's because it was not usable (nor testable)
protected override bool SkipDueToAttribute (MemberInfo member)
{
if (member is null)
return false;
return MemberHasObsolete (member) || base.SkipDueToAttribute (member);
}
[Test]
public void DefaultCtorAllowed ()
{
Errors = 0;
ErrorData.Clear ();
int n = 0;
foreach (Type t in Assembly.GetTypes ()) {
if (t.IsAbstract || !NSObjectType.IsAssignableFrom (t))
continue;
if (Skip (t))
continue;
var ctor = t.GetConstructor (Type.EmptyTypes);
if (SkipDueToAttribute (ctor))
continue;
if ((ctor is null) || ctor.IsAbstract) {
if (LogUntestedTypes)
Console.WriteLine ("[WARNING] {0} was skipped because it had no default constructor", t);
continue;
}
instance_type_name = t.FullName;
if (LogProgress)
Console.WriteLine ("{0}. {1}", n, instance_type_name);
NSObject obj = null;
try {
obj = ctor.Invoke (null) as NSObject;
CheckHandle (obj);
CheckToString (obj);
CheckIsDirectBinding (obj);
CheckNSObjectProtocol (obj);
Dispose (obj, t);
} catch (Exception e) {
// Objective-C exception thrown
if (!ContinueOnFailure)
throw;
TargetInvocationException tie = (e as TargetInvocationException);
if (tie is not null)
e = tie.InnerException;
ReportError ("Default constructor not allowed for {0} : {1}", instance_type_name, e.Message);
}
n++;
}
Assert.AreEqual (0, Errors, "{0} potential errors found in {1} default ctor validated{2}", Errors, n, Errors == 0 ? string.Empty : ":\n" + ErrorData.ToString () + "\n");
}
// .NET constructors are not virtual, so we need to re-expose the base class .ctor when a subclass is created.
// That's very important for designated initializer since we can end up with no correct/safe way to create
// subclasses of an existing type
[Test]
public void DesignatedInitializer ()
{
Errors = 0;
int n = 0;
foreach (Type t in Assembly.GetTypes ()) {
if (SkipCheckShouldReExposeBaseCtor (t))
continue;
// we only care for NSObject subclasses that we expose publicly
if (!t.IsPublic || !NSObjectType.IsAssignableFrom (t))
continue;
// we only care about wrapper types (types with a native counterpart), and they all have a Register attribute.
var typeRegisterAttribute = t.GetCustomAttribute<RegisterAttribute> (false);
if (typeRegisterAttribute is null)
continue;
int designated = 0;
foreach (var ctor in t.GetConstructors ()) {
if (ctor.GetCustomAttribute<DesignatedInitializerAttribute> () is null)
continue;
designated++;
}
// that does not mean that inlining is not required, i.e. it might be useful, even needed
// but it's not a showstopper for subclassing so we'll start with those cases
if (designated > 0)
continue;
var base_class = t.BaseType;
// NSObject ctor requirements are handled by the generator
if (base_class == NSObjectType)
continue;
foreach (var ctor in base_class.GetConstructors ()) {
// if the base ctor is a designated (not a convenience) initializer then we should re-expose it
if (ctor.GetCustomAttribute<DesignatedInitializerAttribute> () is null)
continue;
// check if this ctor (from base type) is exposed in the current (subclass) type
if (!Match (ctor, t))
ReportError ("{0} should re-expose {1}::{2}", t, base_class.Name, ctor.ToString ().Replace ("Void ", String.Empty));
n++;
}
}
Assert.AreEqual (0, Errors, "{0} potential errors found in {1} designated initializer validated", Errors, n);
}
protected virtual bool Match (ConstructorInfo ctor, Type type)
{
var cstr = ctor.ToString ();
switch (type.Name) {
case "MKTileOverlayRenderer":
// NSInvalidArgumentEception Expected a MKTileOverlay
// looks like Apple has not yet added a DI for this type, but it should be `initWithTileOverlay:`
if (cstr == $"Void .ctor(MapKit.IMKOverlay)")
return true;
break;
case "MPSMatrixMultiplication":
// marked as NS_UNAVAILABLE - Use the above initialization method instead.
case "MPSImageHistogram":
// Could not initialize an instance of the type 'MetalPerformanceShaders.MPSImageHistogram': the native 'initWithDevice:' method returned nil.
// make sense: there's a `initWithDevice:histogramInfo:` DI
if (cstr == $"Void .ctor(Metal.IMTLDevice)")
return true;
break;
case "NSDataDetector":
// -[NSDataDetector initWithPattern:options:error:]: Not valid for NSDataDetector
if (cstr == $"Void .ctor(Foundation.NSString, Foundation.NSRegularExpressionOptions, Foundation.NSError ByRef)")
return true;
break;
case "SKStoreProductViewController":
case "SKCloudServiceSetupViewController":
// SKStoreProductViewController and SKCloudServiceSetupViewController are OS View Controllers which can't be customized. Therefore they shouldn't re-expose initWithNibName:bundle:
if (cstr == $"Void .ctor(System.String, Foundation.NSBundle)")
return true;
break;
case "MKCompassButton":
case "MKScaleView":
case "MKUserTrackingButton":
// Xcode9 added types that are created only from static methods (no init)
return true;
#if __TVOS__
case "UISearchBar":
// - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER __TVOS_PROHIBITED;
return true;
case "TVDigitEntryViewController":
// full screen, no customization w/NIB
return true;
case "TVDocumentViewController":
// as documented
return true;
#endif
case "PdfAnnotationButtonWidget":
case "PdfAnnotationChoiceWidget":
case "PdfAnnotationCircle":
case "PdfAnnotationFreeText":
case "PdfAnnotationInk":
case "PdfAnnotationLine":
case "PdfAnnotationLink":
case "PdfAnnotationMarkup":
case "PdfAnnotationPopup":
case "PdfAnnotationSquare":
case "PdfAnnotationStamp":
case "PdfAnnotationText":
case "PdfAnnotationTextWidget":
// This ctor was introduced in 10,13 but all of the above objects are deprecated in 10,12
// so it does not make much sense to expose this ctor in all the deprecated subclasses
if (cstr == $"Void .ctor(CoreGraphics.CGRect, Foundation.NSString, Foundation.NSDictionary)")
return true;
break;
case "VNTargetedImageRequest": // Explicitly disabled
if (cstr == $"Void .ctor(Vision.VNRequestCompletionHandler)")
return true;
break;
2017-08-12 20:09:46 +03:00
case "PKPaymentRequestShippingContactUpdate":
// a more precise designated initializer is provided
if (cstr == $"Void .ctor(PassKit.PKPaymentSummaryItem[])")
2017-08-12 20:09:46 +03:00
return true;
break;
case "NSApplication": // Does not make sense, also it crashes
case "NSBitmapImageRep": // exception raised
case "NSCachedImageRep": // exception raised
case "NSCIImageRep": // exception raised
case "NSCustomImageRep": // exception raised
case "NSEPSImageRep": // exception raised
case "NSPdfImageRep": // exception raised
if (cstr == $"Void .ctor()")
return true;
break;
case "AUPannerView": // Do not make sense without the AudioUnit
case "AUGenericView": // Do not make sense without the AudioUnit
if (cstr == $"Void .ctor(CoreGraphics.CGRect)")
return true;
break;
case "MDLNoiseTexture":
case "MDLSkyCubeTexture":
case "MDLNormalMapTexture":
case "MDLUrlTexture":
case "MDLCheckerboardTexture":
case "MDLColorSwatchTexture":
// they don't make sense without extra arguments
return true;
case "ASCredentialProviderViewController": // goal is to "provides a standard interface for creating a credential provider extension", not a custom one
case "ASAccountAuthenticationModificationViewController":
case "INUIAddVoiceShortcutViewController": // Doesn't make sense without INVoiceShortcut and there is no other way to set this unless you use the other only .ctor
case "INUIEditVoiceShortcutViewController": // Doesn't make sense without INVoiceShortcut and there is no other way to set this unless you use the other only .ctor
case "ILClassificationUIExtensionViewController": // Meant to be an extension
if (cstr == $"Void .ctor(System.String, Foundation.NSBundle)")
return true;
break;
case "MPSImageReduceUnary": // Not meant to be used, only subclasses
case "MPSCnnArithmetic": // Not meant to be used, only subclasses
case "MPSCnnArithmeticGradient": // Not meant to be used, only subclasses
case "MPSNNOptimizer": // Not meant to be used, only subclasses
case "MPSNNReduceBinary": // Not meant to be used, only subclasses
case "MPSNNReduceUnary": // Not meant to be used, only subclasses
case "MPSMatrixRandom": // Not meant to be used, only subclasses
if (cstr == "Void .ctor(Metal.IMTLDevice)" || cstr == $"Void .ctor(Foundation.NSCoder, Metal.IMTLDevice)")
return true;
break;
case "MPSTemporaryNDArray": // NS_UNAVAILABLE
if (ctor.ToString () == $"Void .ctor(Metal.IMTLDevice, MetalPerformanceShaders.MPSNDArrayDescriptor)")
return true;
break;
case "MFMailComposeViewController": // You are meant to use the system provided one
case "MFMessageComposeViewController": // You are meant to use the system provided one
case "GKFriendRequestComposeViewController": // You are meant to use the system provided one
case "GKGameCenterViewController": // You are meant to use the system provided one
case "GKMatchmakerViewController": // You are meant to use the system provided one
case "GKTurnBasedMatchmakerViewController": // You are meant to use the system provided one
case "UIImagePickerController": // You are meant to use the system provided one
case "UIVideoEditorController": // You are meant to use the system provided one
case "VNDocumentCameraViewController": // Explicitly disabled on the headers
if (cstr == $"Void .ctor(System.String, Foundation.NSBundle)")
return true;
if (cstr == $"Void .ctor(UIKit.UIViewController)")
return true;
break;
case "UICollectionViewCompositionalLayout":
// Explicitly disabled ctors - (instancetype)init NS_UNAVAILABLE;
return true;
case "NSPickerTouchBarItem": // You are meant to use the static factory methods
if (cstr == $"Void .ctor(System.String)")
return true;
break;
case "NSMenuToolbarItem": // No ctor specified
if (cstr == $"Void .ctor(System.String)")
return true;
break;
case "NSStepperTouchBarItem": // You are meant to use the static factory methods
if (cstr == $"Void .ctor(System.String)")
return true;
break;
case "NSSharingServicePickerToolbarItem": // This type doesn't have .ctors
if (cstr == $"Void .ctor(System.String)")
return true;
break;
case "UIRefreshControl": // init should be used instead.
if (cstr == $"Void .ctor(CoreGraphics.CGRect)")
return true;
break;
case "PKAddSecureElementPassViewController":
// no overview available yet... unlikely that it can be customized
if (cstr == "Void .ctor(System.String, Foundation.NSBundle)")
return true;
break;
case "PKPayLaterView":
// headers have: (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
if (cstr == "Void .ctor(CoreGraphics.CGRect)")
return true;
break;
case "VNDetectedPoint":
// This class is not meant to be instantiated
if (cstr == "Void .ctor(Double, Double)")
return true;
break;
case "VNStatefulRequest":
// This class uses another overload to get instantiated
if (cstr == "Void .ctor(Vision.VNRequestCompletionHandler)")
return true;
break;
}
var ep = ctor.GetParameters ();
// NonPublic to get `protected` which can be autogenerated for abstract types (subclassing a non-abstract type)
foreach (var candidate in type.GetConstructors (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) {
var cp = candidate.GetParameters ();
if (ep.Length != cp.Length)
continue;
var result = true;
for (int i = 0; i < ep.Length; i++) {
var cpt = cp [i].ParameterType;
var ept = ep [i].ParameterType;
if (cpt == ept)
continue;
if (!cp [i].ParameterType.IsSubclassOf (ep [i].ParameterType))
result = false;
}
if (result)
return true;
}
return false;
}
[MetalPerformanceShaders] Xcode 9 bindings (#3005) * [MetalPerformanceShaders] Activate bindings for Xamarin.Mac and add n… (#2816) * [MetalPerformaceShaders] Several MPSCnnKernel properties should be readonly (#2938) The subclasses versions of the properties need Override, cannot be removed since it would break visibility for iOS 10 * Remove some [Model] attributes that sholdn't be needed * Fix introspection test crashes * More introspection fixes * NN does not need to be PascalCased Remove unneeded Models and BaseTypes * PR Whitespace fixes and renamings * Paste fail * More fixes from PR comments * [MPS] Adds new intro test, fixes ctors and xtro output * Removes duplicated availability attributes. * Removes obsoleted API from macOS since mps is new to it. * Fixes xtro output. * Adds missing API. * Fixes parameterless ctors, some of them do not really work, found by our new intro test and disabled the one that seem to not make sense due to the presence of DesignatedInitializers. * Fixes a selector typo. * Adds new `ShouldNotExposeDefaultCtorTest` to intro. ShouldNotExposeDefaultCtorTest ============================== This test checks for types with a parameterless ctor that are subclasses of `NSObject` and then cheks if the BaseType of said objects also expose a parameterless ctor (all in .NET land), if this is not the case it reports them and so they can manually audited. Also this test has the ability to print alloc/init ObjC code by setting `genObjCTestCode` to `true` so you can take this code into an Xcode project and easily tests the ctors. It seems that xtro (sharpie) does not have a complete picture of when a ctor must be exposed hence the hability to generate this code and manually test. Right now this test is just enabled for MPS since it is the scope of this PR. In the future it should be enabled for all other frameworks and the output be manually audited. * [MPS] Fixes premature collection possible in bindings (bug 59547) and implements feedback. https://bugzilla.xamarin.com/show_bug.cgi?id=59547 * Fixes premature collection possible in bindings im MPSKernel.cs * Fixes MPSImageHistogramTest from using deprecated API. * Removes renamed selectors and typos from ApiSelectorTest and ApiTypoTest. * [MPS] Reenable Copy API and DesignatedInitializer xtro feedback * Implement more feedback * More feedback
2017-11-28 23:29:05 +03:00
[Test]
public void ShouldNotExposeDefaultCtorTest ()
{
Errors = 0;
int n = 0;
// Set to 'true' to generate alloc/init ObjC code of types that fail this test.
bool genObjCTestCode = false;
var objCCode = genObjCTestCode ? new StringBuilder () : null;
var types = Assembly.GetTypes ();
var cifiltertype = types.FirstOrDefault (c => c.Name == "CIFilter");
foreach (Type t in types) {
// TODO: Remove this MPS check in the future, at the time of writing this we currently only care about MPS.
if (!t.Name.StartsWith ("MPS", StringComparison.OrdinalIgnoreCase))
continue;
if (!t.IsPublic || !NSObjectType.IsAssignableFrom (t))
continue;
// ignore CIFilter derived subclasses since they are specially generated
if (cifiltertype is not null && t.IsSubclassOf (cifiltertype))
[MetalPerformanceShaders] Xcode 9 bindings (#3005) * [MetalPerformanceShaders] Activate bindings for Xamarin.Mac and add n… (#2816) * [MetalPerformaceShaders] Several MPSCnnKernel properties should be readonly (#2938) The subclasses versions of the properties need Override, cannot be removed since it would break visibility for iOS 10 * Remove some [Model] attributes that sholdn't be needed * Fix introspection test crashes * More introspection fixes * NN does not need to be PascalCased Remove unneeded Models and BaseTypes * PR Whitespace fixes and renamings * Paste fail * More fixes from PR comments * [MPS] Adds new intro test, fixes ctors and xtro output * Removes duplicated availability attributes. * Removes obsoleted API from macOS since mps is new to it. * Fixes xtro output. * Adds missing API. * Fixes parameterless ctors, some of them do not really work, found by our new intro test and disabled the one that seem to not make sense due to the presence of DesignatedInitializers. * Fixes a selector typo. * Adds new `ShouldNotExposeDefaultCtorTest` to intro. ShouldNotExposeDefaultCtorTest ============================== This test checks for types with a parameterless ctor that are subclasses of `NSObject` and then cheks if the BaseType of said objects also expose a parameterless ctor (all in .NET land), if this is not the case it reports them and so they can manually audited. Also this test has the ability to print alloc/init ObjC code by setting `genObjCTestCode` to `true` so you can take this code into an Xcode project and easily tests the ctors. It seems that xtro (sharpie) does not have a complete picture of when a ctor must be exposed hence the hability to generate this code and manually test. Right now this test is just enabled for MPS since it is the scope of this PR. In the future it should be enabled for all other frameworks and the output be manually audited. * [MPS] Fixes premature collection possible in bindings (bug 59547) and implements feedback. https://bugzilla.xamarin.com/show_bug.cgi?id=59547 * Fixes premature collection possible in bindings im MPSKernel.cs * Fixes MPSImageHistogramTest from using deprecated API. * Removes renamed selectors and typos from ApiSelectorTest and ApiTypoTest. * [MPS] Reenable Copy API and DesignatedInitializer xtro feedback * Implement more feedback * More feedback
2017-11-28 23:29:05 +03:00
continue;
if (SkipCheckShouldNotExposeDefaultCtor (t))
continue;
var ctor = t.GetConstructor (Type.EmptyTypes);
if (SkipDueToAttribute (ctor))
continue;
if (ctor is null || ctor.IsAbstract) {
[MetalPerformanceShaders] Xcode 9 bindings (#3005) * [MetalPerformanceShaders] Activate bindings for Xamarin.Mac and add n… (#2816) * [MetalPerformaceShaders] Several MPSCnnKernel properties should be readonly (#2938) The subclasses versions of the properties need Override, cannot be removed since it would break visibility for iOS 10 * Remove some [Model] attributes that sholdn't be needed * Fix introspection test crashes * More introspection fixes * NN does not need to be PascalCased Remove unneeded Models and BaseTypes * PR Whitespace fixes and renamings * Paste fail * More fixes from PR comments * [MPS] Adds new intro test, fixes ctors and xtro output * Removes duplicated availability attributes. * Removes obsoleted API from macOS since mps is new to it. * Fixes xtro output. * Adds missing API. * Fixes parameterless ctors, some of them do not really work, found by our new intro test and disabled the one that seem to not make sense due to the presence of DesignatedInitializers. * Fixes a selector typo. * Adds new `ShouldNotExposeDefaultCtorTest` to intro. ShouldNotExposeDefaultCtorTest ============================== This test checks for types with a parameterless ctor that are subclasses of `NSObject` and then cheks if the BaseType of said objects also expose a parameterless ctor (all in .NET land), if this is not the case it reports them and so they can manually audited. Also this test has the ability to print alloc/init ObjC code by setting `genObjCTestCode` to `true` so you can take this code into an Xcode project and easily tests the ctors. It seems that xtro (sharpie) does not have a complete picture of when a ctor must be exposed hence the hability to generate this code and manually test. Right now this test is just enabled for MPS since it is the scope of this PR. In the future it should be enabled for all other frameworks and the output be manually audited. * [MPS] Fixes premature collection possible in bindings (bug 59547) and implements feedback. https://bugzilla.xamarin.com/show_bug.cgi?id=59547 * Fixes premature collection possible in bindings im MPSKernel.cs * Fixes MPSImageHistogramTest from using deprecated API. * Removes renamed selectors and typos from ApiSelectorTest and ApiTypoTest. * [MPS] Reenable Copy API and DesignatedInitializer xtro feedback * Implement more feedback * More feedback
2017-11-28 23:29:05 +03:00
if (LogUntestedTypes)
Console.WriteLine ("[WARNING] {0} was skipped because it had no default constructor", t);
continue;
}
if (LogProgress)
Console.WriteLine ($"{n}: {t.FullName}");
var parentType = t.BaseType;
var parentCtor = parentType.GetConstructor (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
if (parentCtor is null) {
[MetalPerformanceShaders] Xcode 9 bindings (#3005) * [MetalPerformanceShaders] Activate bindings for Xamarin.Mac and add n… (#2816) * [MetalPerformaceShaders] Several MPSCnnKernel properties should be readonly (#2938) The subclasses versions of the properties need Override, cannot be removed since it would break visibility for iOS 10 * Remove some [Model] attributes that sholdn't be needed * Fix introspection test crashes * More introspection fixes * NN does not need to be PascalCased Remove unneeded Models and BaseTypes * PR Whitespace fixes and renamings * Paste fail * More fixes from PR comments * [MPS] Adds new intro test, fixes ctors and xtro output * Removes duplicated availability attributes. * Removes obsoleted API from macOS since mps is new to it. * Fixes xtro output. * Adds missing API. * Fixes parameterless ctors, some of them do not really work, found by our new intro test and disabled the one that seem to not make sense due to the presence of DesignatedInitializers. * Fixes a selector typo. * Adds new `ShouldNotExposeDefaultCtorTest` to intro. ShouldNotExposeDefaultCtorTest ============================== This test checks for types with a parameterless ctor that are subclasses of `NSObject` and then cheks if the BaseType of said objects also expose a parameterless ctor (all in .NET land), if this is not the case it reports them and so they can manually audited. Also this test has the ability to print alloc/init ObjC code by setting `genObjCTestCode` to `true` so you can take this code into an Xcode project and easily tests the ctors. It seems that xtro (sharpie) does not have a complete picture of when a ctor must be exposed hence the hability to generate this code and manually test. Right now this test is just enabled for MPS since it is the scope of this PR. In the future it should be enabled for all other frameworks and the output be manually audited. * [MPS] Fixes premature collection possible in bindings (bug 59547) and implements feedback. https://bugzilla.xamarin.com/show_bug.cgi?id=59547 * Fixes premature collection possible in bindings im MPSKernel.cs * Fixes MPSImageHistogramTest from using deprecated API. * Removes renamed selectors and typos from ApiSelectorTest and ApiTypoTest. * [MPS] Reenable Copy API and DesignatedInitializer xtro feedback * Implement more feedback * More feedback
2017-11-28 23:29:05 +03:00
ReportError ($"Type '{t.FullName}' is a possible candidate for [DisableDefaultCtor] because its BaseType '{parentType.FullName}' does not have one.");
// Useful to test in Xcode
if (genObjCTestCode) {
var export = t.GetCustomAttribute<RegisterAttribute> ();
var typeName = export?.Name ?? t.Name;
objCCode.AppendLine ($"{typeName}* test{n} = [[{typeName} alloc] init];");
}
}
n++;
}
Assert.AreEqual (0, Errors, $"{Errors} potential errors found in {n} BaseType empty ctor validated: \n{ErrorData}\n{(genObjCTestCode ? $"\n\n{objCCode}\n" : string.Empty)}");
}
protected virtual bool SkipCheckShouldNotExposeDefaultCtor (Type type)
{
if (type.ContainsGenericParameters)
return true;
foreach (object ca in type.GetCustomAttributes (false)) {
if (ca is ProtocolAttribute || ca is ModelAttribute)
return true;
}
return SkipDueToAttribute (type);
}
[MetalPerformanceShaders] Xcode 9 bindings (#3005) * [MetalPerformanceShaders] Activate bindings for Xamarin.Mac and add n… (#2816) * [MetalPerformaceShaders] Several MPSCnnKernel properties should be readonly (#2938) The subclasses versions of the properties need Override, cannot be removed since it would break visibility for iOS 10 * Remove some [Model] attributes that sholdn't be needed * Fix introspection test crashes * More introspection fixes * NN does not need to be PascalCased Remove unneeded Models and BaseTypes * PR Whitespace fixes and renamings * Paste fail * More fixes from PR comments * [MPS] Adds new intro test, fixes ctors and xtro output * Removes duplicated availability attributes. * Removes obsoleted API from macOS since mps is new to it. * Fixes xtro output. * Adds missing API. * Fixes parameterless ctors, some of them do not really work, found by our new intro test and disabled the one that seem to not make sense due to the presence of DesignatedInitializers. * Fixes a selector typo. * Adds new `ShouldNotExposeDefaultCtorTest` to intro. ShouldNotExposeDefaultCtorTest ============================== This test checks for types with a parameterless ctor that are subclasses of `NSObject` and then cheks if the BaseType of said objects also expose a parameterless ctor (all in .NET land), if this is not the case it reports them and so they can manually audited. Also this test has the ability to print alloc/init ObjC code by setting `genObjCTestCode` to `true` so you can take this code into an Xcode project and easily tests the ctors. It seems that xtro (sharpie) does not have a complete picture of when a ctor must be exposed hence the hability to generate this code and manually test. Right now this test is just enabled for MPS since it is the scope of this PR. In the future it should be enabled for all other frameworks and the output be manually audited. * [MPS] Fixes premature collection possible in bindings (bug 59547) and implements feedback. https://bugzilla.xamarin.com/show_bug.cgi?id=59547 * Fixes premature collection possible in bindings im MPSKernel.cs * Fixes MPSImageHistogramTest from using deprecated API. * Removes renamed selectors and typos from ApiSelectorTest and ApiTypoTest. * [MPS] Reenable Copy API and DesignatedInitializer xtro feedback * Implement more feedback * More feedback
2017-11-28 23:29:05 +03:00
protected virtual bool SkipCheckShouldReExposeBaseCtor (Type type)
{
[MetalPerformanceShaders] Xcode 9 bindings (#3005) * [MetalPerformanceShaders] Activate bindings for Xamarin.Mac and add n… (#2816) * [MetalPerformaceShaders] Several MPSCnnKernel properties should be readonly (#2938) The subclasses versions of the properties need Override, cannot be removed since it would break visibility for iOS 10 * Remove some [Model] attributes that sholdn't be needed * Fix introspection test crashes * More introspection fixes * NN does not need to be PascalCased Remove unneeded Models and BaseTypes * PR Whitespace fixes and renamings * Paste fail * More fixes from PR comments * [MPS] Adds new intro test, fixes ctors and xtro output * Removes duplicated availability attributes. * Removes obsoleted API from macOS since mps is new to it. * Fixes xtro output. * Adds missing API. * Fixes parameterless ctors, some of them do not really work, found by our new intro test and disabled the one that seem to not make sense due to the presence of DesignatedInitializers. * Fixes a selector typo. * Adds new `ShouldNotExposeDefaultCtorTest` to intro. ShouldNotExposeDefaultCtorTest ============================== This test checks for types with a parameterless ctor that are subclasses of `NSObject` and then cheks if the BaseType of said objects also expose a parameterless ctor (all in .NET land), if this is not the case it reports them and so they can manually audited. Also this test has the ability to print alloc/init ObjC code by setting `genObjCTestCode` to `true` so you can take this code into an Xcode project and easily tests the ctors. It seems that xtro (sharpie) does not have a complete picture of when a ctor must be exposed hence the hability to generate this code and manually test. Right now this test is just enabled for MPS since it is the scope of this PR. In the future it should be enabled for all other frameworks and the output be manually audited. * [MPS] Fixes premature collection possible in bindings (bug 59547) and implements feedback. https://bugzilla.xamarin.com/show_bug.cgi?id=59547 * Fixes premature collection possible in bindings im MPSKernel.cs * Fixes MPSImageHistogramTest from using deprecated API. * Removes renamed selectors and typos from ApiSelectorTest and ApiTypoTest. * [MPS] Reenable Copy API and DesignatedInitializer xtro feedback * Implement more feedback * More feedback
2017-11-28 23:29:05 +03:00
return SkipDueToAttribute (type);
}
#if HAS_ARKIT
/// <summary>
/// Ensures that all subclasses of a base class that conforms to IARAnchorCopying re-expose its constructor.
/// Note: we cannot have constructors in protocols so we have to inline them in every subclass.
/// </summary>
[Test]
public void ARAnchorCopyingCtorTest ()
{
Errors = 0;
foreach (Type t in Assembly.GetTypes ()) {
if (t.Name == "IARAnchorCopying" || t.Name == "ARAnchorCopyingWrapper")
continue;
if (!typeof (IARAnchorCopying).IsAssignableFrom (t))
continue;
if (t.GetConstructor (new Type [] { typeof (ARAnchor) }) is null)
ReportError ("{0} should re-expose IARAnchorCopying::.ctor(ARAnchor)", t);
}
Assert.AreEqual (0, Errors, "{0} potential errors found when validating if subclasses of 'ARAnchor' re-expose 'IARAnchorCopying' constructor", Errors);
}
#endif
}
}