2021-08-11 11:06:46 +03:00
|
|
|
//
|
2016-05-05 03:14:32 +03:00
|
|
|
// Test fixture for class_ptr introspection tests
|
|
|
|
//
|
|
|
|
// Authors:
|
|
|
|
// Alex Soto <alex.soto@xamarin.com>
|
|
|
|
//
|
|
|
|
// Copyright 2012-2014, 2016 Xamarin Inc.
|
|
|
|
//
|
|
|
|
using System;
|
|
|
|
using System.Reflection;
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
using NUnit.Framework;
|
|
|
|
using Xamarin.Utils;
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
|
|
|
using Foundation;
|
|
|
|
using ObjCRuntime;
|
|
|
|
|
2021-11-18 11:06:09 +03:00
|
|
|
#if !NET
|
|
|
|
using NativeHandle = System.IntPtr;
|
|
|
|
#endif
|
|
|
|
|
2016-05-05 03:14:32 +03:00
|
|
|
namespace Introspection {
|
|
|
|
|
|
|
|
public abstract class ApiClassPtrTest : ApiBaseTest {
|
|
|
|
|
|
|
|
protected virtual bool Skip (Type type)
|
|
|
|
{
|
|
|
|
// skip delegate (and other protocol references)
|
|
|
|
foreach (object ca in type.GetCustomAttributes (false)) {
|
|
|
|
if (ca is ProtocolAttribute)
|
|
|
|
return true;
|
|
|
|
if (ca is ModelAttribute)
|
|
|
|
return true;
|
|
|
|
}
|
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;
|
|
|
|
|
2016-05-05 03:14:32 +03:00
|
|
|
return SkipDueToAttribute (type);
|
|
|
|
}
|
|
|
|
|
|
|
|
Type GetExtendedType (Type extensionType)
|
|
|
|
{
|
2022-11-07 17:20:26 +03:00
|
|
|
var method =
|
2016-05-05 03:14:32 +03:00
|
|
|
(from m in extensionType.GetMethods (BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
|
2022-11-07 17:20:26 +03:00
|
|
|
where m.IsDefined (typeof (ExtensionAttribute), false)
|
|
|
|
select m).FirstOrDefault ();
|
2016-05-05 03:14:32 +03:00
|
|
|
|
2023-05-05 18:52:19 +03:00
|
|
|
if (method is not null) {
|
2016-05-05 03:14:32 +03:00
|
|
|
var paramType = method.GetParameters () [0].ParameterType;
|
|
|
|
if (paramType.Name == "String")
|
|
|
|
return typeof (NSString);
|
|
|
|
else
|
|
|
|
return paramType;
|
2022-11-07 17:20:26 +03:00
|
|
|
} else
|
2016-05-05 03:14:32 +03:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-11-07 17:20:26 +03:00
|
|
|
IntPtr GetClassPtrFromRegister (Type t)
|
2016-05-05 03:14:32 +03:00
|
|
|
{
|
|
|
|
var attribs = t.GetCustomAttributes (typeof (RegisterAttribute), true);
|
|
|
|
if (attribs.Length > 0) {
|
|
|
|
var register = ((RegisterAttribute) attribs [0]);
|
|
|
|
return Class.GetHandle (register.Name);
|
|
|
|
}
|
|
|
|
return IntPtr.Zero;
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void VerifyClassPtr ()
|
|
|
|
{
|
|
|
|
foreach (Type t in Assembly.GetTypes ()) {
|
|
|
|
if (t.IsNested || !NSObjectType.IsAssignableFrom (t))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (t.ContainsGenericParameters)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (Skip (t))
|
|
|
|
continue;
|
2022-11-07 17:20:26 +03:00
|
|
|
|
2016-05-05 03:14:32 +03:00
|
|
|
FieldInfo fi = t.GetField ("class_ptr", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
|
2023-05-05 18:52:19 +03:00
|
|
|
if (fi is null)
|
2022-11-07 17:20:26 +03:00
|
|
|
continue;
|
2021-11-18 11:06:09 +03:00
|
|
|
IntPtr class_ptr = (IntPtr) (NativeHandle) fi.GetValue (null);
|
2016-05-05 03:14:32 +03:00
|
|
|
IntPtr register_class_ptr = GetClassPtrFromRegister (t);
|
|
|
|
|
|
|
|
Assert.AreEqual (class_ptr, register_class_ptr, "class_ptr and RegisterAttribute are different: " + t.Name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void VerifyClassPtrCategories ()
|
|
|
|
{
|
2022-11-07 17:20:26 +03:00
|
|
|
foreach (Type t in Assembly.GetTypes ().Where (t => t.IsClass && t.IsSealed && t.IsAbstract)) {
|
2016-05-05 03:14:32 +03:00
|
|
|
if (Skip (t))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
FieldInfo fi = t.GetField ("class_ptr", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
|
2023-05-05 18:52:19 +03:00
|
|
|
if (fi is null)
|
2016-05-05 03:14:32 +03:00
|
|
|
continue;
|
2021-11-18 11:06:09 +03:00
|
|
|
IntPtr class_ptr = (IntPtr) (NativeHandle) fi.GetValue (null);
|
2016-05-05 03:14:32 +03:00
|
|
|
|
|
|
|
var extendedType = GetExtendedType (t);
|
|
|
|
IntPtr extended_class_ptr;
|
2023-05-05 18:52:19 +03:00
|
|
|
if (extendedType is null)
|
2016-05-05 03:14:32 +03:00
|
|
|
extended_class_ptr = IntPtr.Zero;
|
|
|
|
else
|
|
|
|
extended_class_ptr = GetClassPtrFromRegister (extendedType);
|
|
|
|
|
|
|
|
Assert.AreEqual (class_ptr, extended_class_ptr, "class_ptr and RegisterAttribute from extended class are different: " + t.Name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|