[linker] Mark all TypeConverter if TypeDescriptor is used. Fixes #3372 (#3396)

Moving to reference sources added a few, new converters so the existing
logic to preserve them was not complete.

This update the list of converters, sorted like the reference sources
(RS) for easier reviews.

It also adds:
* a canary test in "dont link" that will fail it the RS code change
or is replaced;
* more complete unit tests to ensure all cases works

https://github.com/xamarin/xamarin-macios/issues/3372
This commit is contained in:
Sebastien Pouliot 2018-02-05 21:19:46 -05:00 коммит произвёл GitHub
Родитель 9c2010e440
Коммит e390fefe08
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 137 добавлений и 8 удалений

Просмотреть файл

@ -8,6 +8,7 @@
// //
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
@ -107,6 +108,53 @@ namespace DontLink {
Assert.True (de.IsReadOnly, "IsReadOnly"); Assert.True (de.IsReadOnly, "IsReadOnly");
} }
[Test]
public void TypeDescriptorCanary ()
{
// this will fail is ReflectTypeDescriptionProvider.cs is modified
var rtdp = Type.GetType ("System.ComponentModel.ReflectTypeDescriptionProvider, System");
Assert.NotNull (rtdp, "type");
var p = rtdp.GetProperty ("IntrinsicTypeConverters", BindingFlags.Static | BindingFlags.NonPublic);
Assert.NotNull (p, "property");
var ht = (Hashtable) p.GetGetMethod (true).Invoke (null, null);
Assert.NotNull (ht, "Hashtable");
Assert.That (ht.Count, Is.EqualTo (26), "Count");
foreach (var item in ht.Values) {
var name = item.ToString ();
switch (name) {
case "System.ComponentModel.DateTimeOffsetConverter":
case "System.ComponentModel.DecimalConverter":
case "System.ComponentModel.StringConverter":
case "System.ComponentModel.SByteConverter":
case "System.ComponentModel.CollectionConverter":
case "System.ComponentModel.ReferenceConverter":
case "System.ComponentModel.TypeConverter":
case "System.ComponentModel.DateTimeConverter":
case "System.ComponentModel.UInt64Converter":
case "System.ComponentModel.ArrayConverter":
case "System.ComponentModel.NullableConverter":
case "System.ComponentModel.Int16Converter":
case "System.ComponentModel.CultureInfoConverter":
case "System.ComponentModel.SingleConverter":
case "System.ComponentModel.UInt16Converter":
case "System.ComponentModel.GuidConverter":
case "System.ComponentModel.DoubleConverter":
case "System.ComponentModel.Int32Converter":
case "System.ComponentModel.TimeSpanConverter":
case "System.ComponentModel.CharConverter":
case "System.ComponentModel.Int64Converter":
case "System.ComponentModel.BooleanConverter":
case "System.ComponentModel.UInt32Converter":
case "System.ComponentModel.ByteConverter":
case "System.ComponentModel.EnumConverter":
break;
default:
Assert.Fail ($"Unknown type descriptor {name}");
break;
}
}
}
#if __TVOS__ || __WATCHOS__ #if __TVOS__ || __WATCHOS__
void AssertThrowsWrappedNotSupportedException (Action action, string message) void AssertThrowsWrappedNotSupportedException (Action action, string message)
{ {

Просмотреть файл

@ -493,7 +493,82 @@ namespace LinkSdk {
[Test] [Test]
public void TypeDescriptor_A7793 () public void TypeDescriptor_A7793 ()
{ {
Assert.NotNull (TypeDescriptor.GetConverter (typeof (bool))); var c = TypeDescriptor.GetConverter (typeof (DateTimeOffset));
Assert.That (c.GetType ().Name, Is.EqualTo ("DateTimeOffsetConverter"), "DateTimeOffsetConverter");
c = TypeDescriptor.GetConverter (typeof (decimal));
Assert.That (c.GetType ().Name, Is.EqualTo ("DecimalConverter"), "DecimalConverter");
c = TypeDescriptor.GetConverter (typeof (string));
Assert.That (c.GetType ().Name, Is.EqualTo ("StringConverter"), "StringConverter");
c = TypeDescriptor.GetConverter (typeof (sbyte));
Assert.That (c.GetType ().Name, Is.EqualTo ("SByteConverter"), "SByteConverter");
c = TypeDescriptor.GetConverter (typeof (Collection<string>));
Assert.That (c.GetType ().Name, Is.EqualTo ("CollectionConverter"), "CollectionConverter");
c = TypeDescriptor.GetConverter (typeof (INSCoding));
Assert.That (c.GetType ().Name, Is.EqualTo ("ReferenceConverter"), "ReferenceConverter");
c = TypeDescriptor.GetConverter (typeof (Type));
Assert.That (c.GetType ().Name, Is.EqualTo ("TypeConverter"), "TypeConverter");
c = TypeDescriptor.GetConverter (typeof (ulong));
Assert.That (c.GetType ().Name, Is.EqualTo ("UInt64Converter"), "UInt64Converter");
c = TypeDescriptor.GetConverter (typeof (int[]));
Assert.That (c.GetType ().Name, Is.EqualTo ("ArrayConverter"), "ArrayConverter");
c = TypeDescriptor.GetConverter (typeof (int?));
Assert.That (c.GetType ().Name, Is.EqualTo ("NullableConverter"), "NullableConverter");
c = TypeDescriptor.GetConverter (typeof (short));
Assert.That (c.GetType ().Name, Is.EqualTo ("Int16Converter"), "Int16Converter");
c = TypeDescriptor.GetConverter (typeof (CultureInfo));
Assert.That (c.GetType ().Name, Is.EqualTo ("CultureInfoConverter"), "CultureInfoConverter");
c = TypeDescriptor.GetConverter (typeof (float));
Assert.That (c.GetType ().Name, Is.EqualTo ("SingleConverter"), "SingleConverter");
c = TypeDescriptor.GetConverter (typeof (ushort));
Assert.That (c.GetType ().Name, Is.EqualTo ("UInt16Converter"), "UInt16Converter");
c = TypeDescriptor.GetConverter (typeof (Guid));
Assert.That (c.GetType ().Name, Is.EqualTo ("GuidConverter"), "GuidConverter");
c = TypeDescriptor.GetConverter (typeof (double));
Assert.That (c.GetType ().Name, Is.EqualTo ("DoubleConverter"), "DoubleConverter");
c = TypeDescriptor.GetConverter (typeof (int));
Assert.That (c.GetType ().Name, Is.EqualTo ("Int32Converter"), "Int32Converter");
c = TypeDescriptor.GetConverter (typeof (TimeSpan));
Assert.That (c.GetType ().Name, Is.EqualTo ("TimeSpanConverter"), "TimeSpanConverter");
c = TypeDescriptor.GetConverter (typeof (char));
Assert.That (c.GetType ().Name, Is.EqualTo ("CharConverter"), "CharConverter");
c = TypeDescriptor.GetConverter (typeof (long));
Assert.That (c.GetType ().Name, Is.EqualTo ("Int64Converter"), "Int64Converter");
c = TypeDescriptor.GetConverter (typeof (bool));
Assert.That (c.GetType ().Name, Is.EqualTo ("BooleanConverter"), "BooleanConverter");
c = TypeDescriptor.GetConverter (typeof (long));
Assert.That (c.GetType ().Name, Is.EqualTo ("Int64Converter"), "Int64Converter");
c = TypeDescriptor.GetConverter (typeof (uint));
Assert.That (c.GetType ().Name, Is.EqualTo ("UInt32Converter"), "UInt32Converter");
c = TypeDescriptor.GetConverter (typeof (FileShare));
Assert.That (c.GetType ().Name, Is.EqualTo ("EnumConverter"), "EnumConverter");
// special case - it's not in the default list we reflect in dont link tests
c = TypeDescriptor.GetConverter (typeof (IComponent));
Assert.That (c.GetType ().Name, Is.EqualTo ("ComponentConverter"), "ComponentConverter");
} }
[Test] [Test]

Просмотреть файл

@ -303,28 +303,34 @@ namespace Xamarin.Linker.Steps {
switch (type.Name) { switch (type.Name) {
case "TypeDescriptor": case "TypeDescriptor":
// DefaultConverters are created using Activator.CreateInstance // DefaultConverters are created using Activator.CreateInstance
// keep in sync with ReflectTypeDescriptionProvider.cs
MarkMethods (GetType ("System", "System.ComponentModel.BooleanConverter")); MarkMethods (GetType ("System", "System.ComponentModel.BooleanConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.ByteConverter")); MarkMethods (GetType ("System", "System.ComponentModel.ByteConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.SByteConverter")); MarkMethods (GetType ("System", "System.ComponentModel.SByteConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.StringConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.CharConverter")); MarkMethods (GetType ("System", "System.ComponentModel.CharConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.Int16Converter")); MarkMethods (GetType ("System", "System.ComponentModel.DoubleConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.StringConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.Int32Converter")); MarkMethods (GetType ("System", "System.ComponentModel.Int32Converter"));
MarkMethods (GetType ("System", "System.ComponentModel.Int16Converter"));
MarkMethods (GetType ("System", "System.ComponentModel.Int64Converter")); MarkMethods (GetType ("System", "System.ComponentModel.Int64Converter"));
MarkMethods (GetType ("System", "System.ComponentModel.SingleConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.UInt16Converter")); MarkMethods (GetType ("System", "System.ComponentModel.UInt16Converter"));
MarkMethods (GetType ("System", "System.ComponentModel.UInt32Converter")); MarkMethods (GetType ("System", "System.ComponentModel.UInt32Converter"));
MarkMethods (GetType ("System", "System.ComponentModel.UInt64Converter")); MarkMethods (GetType ("System", "System.ComponentModel.UInt64Converter"));
MarkMethods (GetType ("System", "System.ComponentModel.SingleConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.DoubleConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.DecimalConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.TypeConverter")); MarkMethods (GetType ("System", "System.ComponentModel.TypeConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.ArrayConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.CultureInfoConverter")); MarkMethods (GetType ("System", "System.ComponentModel.CultureInfoConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.DateTimeConverter")); MarkMethods (GetType ("System", "System.ComponentModel.DateTimeConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.GuidConverter")); MarkMethods (GetType ("System", "System.ComponentModel.DateTimeOffsetConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.DecimalConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.TimeSpanConverter")); MarkMethods (GetType ("System", "System.ComponentModel.TimeSpanConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.GuidConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.ArrayConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.CollectionConverter")); MarkMethods (GetType ("System", "System.ComponentModel.CollectionConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.EnumConverter")); MarkMethods (GetType ("System", "System.ComponentModel.EnumConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.ReferenceConverter"));
MarkMethods (GetType ("System", "System.ComponentModel.NullableConverter"));
// special case - it's not in the Hashtable from the above file (but needed)
MarkMethods (GetType ("System", "System.ComponentModel.ComponentConverter"));
break; break;
} }
break; break;