Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/linker/Linker.Steps/MarkStep.cs74
-rw-r--r--src/linker/Linker/TypeReferenceExtensions.cs6
-rw-r--r--test/Mono.Linker.Tests.Cases/ComponentModel/CustomTypeConvertor.cs68
-rw-r--r--test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs27
-rw-r--r--test/Mono.Linker.Tests/TestCases/TestDatabase.cs7
-rw-r--r--test/Mono.Linker.Tests/TestCases/TestSuites.cs8
6 files changed, 163 insertions, 27 deletions
diff --git a/src/linker/Linker.Steps/MarkStep.cs b/src/linker/Linker.Steps/MarkStep.cs
index f91f7a9c1..8a067acf4 100644
--- a/src/linker/Linker.Steps/MarkStep.cs
+++ b/src/linker/Linker.Steps/MarkStep.cs
@@ -1141,19 +1141,24 @@ namespace Mono.Linker.Steps {
return;
foreach (CustomAttribute attribute in type.CustomAttributes) {
- switch (attribute.Constructor.DeclaringType.FullName) {
- case "System.Xml.Serialization.XmlSchemaProviderAttribute":
+ var attrType = attribute.Constructor.DeclaringType;
+ switch (attrType.Name) {
+ case "XmlSchemaProviderAttribute" when attrType.Namespace == "System.Xml.Serialization":
MarkXmlSchemaProvider (type, attribute);
break;
- case "System.Diagnostics.DebuggerDisplayAttribute":
+ case "DebuggerDisplayAttribute" when attrType.Namespace == "System.Diagnostics":
MarkTypeWithDebuggerDisplayAttribute (type, attribute);
break;
- case "System.Diagnostics.DebuggerTypeProxyAttribute":
+ case "DebuggerTypeProxyAttribute" when attrType.Namespace == "System.Diagnostics":
MarkTypeWithDebuggerTypeProxyAttribute (type, attribute);
break;
- case "System.Diagnostics.Tracing.EventDataAttribute":
+ case "EventDataAttribute" when attrType.Namespace == "System.Diagnostics.Tracing":
MarkMethodsIf (type.Methods, IsPublicInstancePropertyMethod);
break;
+ case "TypeConverterAttribute" when attrType.Namespace == "System.ComponentModel":
+ // The attribute can be applied anywhere but in reality it's always associated with type
+ MarkTypeConverterDependency (attribute);
+ break;
}
}
}
@@ -1181,6 +1186,30 @@ namespace Mono.Linker.Steps {
MarkNamedMethod (type, method_name);
}
+ void MarkTypeConverterDependency (CustomAttribute attribute)
+ {
+ var args = attribute.ConstructorArguments;
+ if (args.Count < 1)
+ return;
+
+ TypeDefinition tdef = null;
+ switch (attribute.ConstructorArguments [0].Value) {
+ case string s:
+ tdef = ResolveFullyQualifiedTypeName (s);
+ break;
+ case TypeReference type:
+ tdef = type.Resolve ();
+ break;
+ }
+
+ if (tdef == null)
+ return;
+
+ MarkMethodsIf (tdef.Methods, l =>
+ l.IsDefaultConstructor () ||
+ l.Parameters.Count == 1 && l.Parameters [0].ParameterType.IsTypeOf ("System", "Type"));
+ }
+
void MarkTypeWithDebuggerDisplayAttribute (TypeDefinition type, CustomAttribute attribute)
{
if (_context.KeepMembersForDebugger) {
@@ -1540,6 +1569,25 @@ namespace Mono.Linker.Steps {
return td;
}
+ TypeDefinition ResolveFullyQualifiedTypeName (string name)
+ {
+ if (!TypeNameParser.TryParseTypeAssemblyQualifiedName (name, out string typeName, out string assemblyName))
+ return null;
+
+ foreach (var assemblyDefinition in _context.GetAssemblies ()) {
+ if (assemblyName != null && assemblyDefinition.Name.Name != assemblyName)
+ continue;
+
+ var foundType = assemblyDefinition.MainModule.GetType (typeName);
+ if (foundType == null)
+ continue;
+
+ return foundType;
+ }
+
+ return null;
+ }
+
protected TypeReference GetOriginalType (TypeReference type)
{
while (type is TypeSpecification) {
@@ -2369,21 +2417,7 @@ namespace Mono.Linker.Steps {
continue;
}
- var name = (string)first_arg.Operand;
-
- if (!TypeNameParser.TryParseTypeAssemblyQualifiedName (name, out string typeName, out string assemblyName))
- continue;
-
- TypeDefinition foundType = null;
- foreach (var assemblyDefinition in _context.GetAssemblies ()) {
- if (assemblyName != null && assemblyDefinition.Name.Name != assemblyName)
- continue;
-
- foundType = assemblyDefinition.MainModule.GetType (typeName);
- if (foundType != null)
- break;
- }
-
+ TypeDefinition foundType = ResolveFullyQualifiedTypeName ((string) first_arg.Operand);
if (foundType == null)
continue;
diff --git a/src/linker/Linker/TypeReferenceExtensions.cs b/src/linker/Linker/TypeReferenceExtensions.cs
index 13d9db7aa..ae271a0d4 100644
--- a/src/linker/Linker/TypeReferenceExtensions.cs
+++ b/src/linker/Linker/TypeReferenceExtensions.cs
@@ -231,5 +231,11 @@ namespace Mono.Linker
throw new NotImplementedException ();
}
+
+ public static bool IsTypeOf (this TypeReference type, string ns, string name)
+ {
+ return type.Name == name
+ && type.Namespace == ns;
+ }
}
}
diff --git a/test/Mono.Linker.Tests.Cases/ComponentModel/CustomTypeConvertor.cs b/test/Mono.Linker.Tests.Cases/ComponentModel/CustomTypeConvertor.cs
new file mode 100644
index 000000000..4f94ed07e
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/ComponentModel/CustomTypeConvertor.cs
@@ -0,0 +1,68 @@
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Metadata;
+
+namespace Mono.Linker.Tests.Cases.ComponentModel
+{
+ [TypeConverter (typeof (Custom1))]
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (TypeConverterAttribute))]
+ class CustomDataType
+ {
+ [Kept]
+ [KeptBaseType (typeof (TypeConverter))]
+ class Custom1 : TypeConverter
+ {
+ [Kept]
+ public Custom1 (Type type)
+ {
+ }
+
+ [Kept]
+ public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ return "test";
+ }
+ }
+ }
+
+ [TypeConverter ("Mono.Linker.Tests.Cases.ComponentModel.CustomDataType_2/Custom2")]
+
+ [Kept]
+ [KeptAttributeAttribute (typeof (TypeConverterAttribute))]
+ class CustomDataType_2
+ {
+ [Kept]
+ [KeptBaseType (typeof (TypeConverter))]
+ class Custom2 : TypeConverter
+ {
+ [Kept]
+ public Custom2 ()
+ {
+ }
+
+ [Kept]
+ public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ return "test";
+ }
+ }
+ }
+
+ [Reference ("System.dll")]
+ public class CustomTypeConvertor
+ {
+ public static void Main ()
+ {
+ var tc1 = TypeDescriptor.GetConverter (typeof (CustomDataType));
+ var res1 = tc1.ConvertFromString ("from");
+
+ var tc2 = TypeDescriptor.GetConverter (typeof (CustomDataType_2));
+ var res2 = tc2.ConvertFromString ("from");
+
+ }
+ }
+}
diff --git a/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs
index 93c7eeb5c..07a01b1ae 100644
--- a/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs
+++ b/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs
@@ -11,7 +11,7 @@ namespace Mono.Linker.Tests.Cases.Reflection {
TestEmptyString ();
TestFullString ();
TestGenericString ();
- TestFullStringConst();
+ TestFullStringConst ();
TestTypeAsmName ();
TestType ();
TestPointer ();
@@ -21,6 +21,7 @@ namespace Mono.Linker.Tests.Cases.Reflection {
TestMultiDimensionalArray ();
TestMultiDimensionalArrayFullString ();
TestMultiDimensionalArrayAsmName ();
+ TestDeeplyNested ();
}
[Kept]
@@ -61,10 +62,10 @@ namespace Mono.Linker.Tests.Cases.Reflection {
public class FullConst { }
[Kept]
- public static void TestFullStringConst()
+ public static void TestFullStringConst ()
{
const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+FullConst, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
- var typeKept = Type.GetType(reflectionTypeKeptString, false);
+ var typeKept = Type.GetType (reflectionTypeKeptString, false);
}
[Kept]
@@ -118,7 +119,7 @@ namespace Mono.Linker.Tests.Cases.Reflection {
}
[Kept]
- public class ArrayOfArray{ }
+ public class ArrayOfArray { }
[Kept]
public static void TestArrayOfArray ()
@@ -129,7 +130,7 @@ namespace Mono.Linker.Tests.Cases.Reflection {
[Kept]
- public class MultiDimensionalArray{ }
+ public class MultiDimensionalArray { }
[Kept]
public static void TestMultiDimensionalArray ()
@@ -157,5 +158,21 @@ namespace Mono.Linker.Tests.Cases.Reflection {
const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+MultiDimensionalArrayAsmName[,], test";
var typeKept = Type.GetType (reflectionTypeKeptString, false);
}
+
+ [Kept]
+ class Nested1 {
+ [Kept]
+ class N2 {
+ [Kept]
+ class N3 {
+ }
+ }
+ }
+
+ [Kept]
+ static void TestDeeplyNested ()
+ {
+ var typeKept = Type.GetType ("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Nested1+N2+N3");
+ }
}
}
diff --git a/test/Mono.Linker.Tests/TestCases/TestDatabase.cs b/test/Mono.Linker.Tests/TestCases/TestDatabase.cs
index 874f555d3..893b55508 100644
--- a/test/Mono.Linker.Tests/TestCases/TestDatabase.cs
+++ b/test/Mono.Linker.Tests/TestCases/TestDatabase.cs
@@ -75,7 +75,12 @@ namespace Mono.Linker.Tests.TestCases
{
return NUnitCasesBySuiteName ("Reflection");
}
-
+
+ public static IEnumerable<TestCaseData> ComponentModelTests ()
+ {
+ return NUnitCasesBySuiteName ("ComponentModel");
+ }
+
public static IEnumerable<TestCaseData> SymbolsTests ()
{
return NUnitCasesBySuiteName ("Symbols");
diff --git a/test/Mono.Linker.Tests/TestCases/TestSuites.cs b/test/Mono.Linker.Tests/TestCases/TestSuites.cs
index 90d2f2e69..b3aa7ad50 100644
--- a/test/Mono.Linker.Tests/TestCases/TestSuites.cs
+++ b/test/Mono.Linker.Tests/TestCases/TestSuites.cs
@@ -90,7 +90,13 @@ namespace Mono.Linker.Tests.TestCases
{
Run (testCase);
}
-
+
+ [TestCaseSource (typeof (TestDatabase), nameof (TestDatabase.ComponentModelTests))]
+ public void ComponentModelTests (TestCase testCase)
+ {
+ Run (testCase);
+ }
+
[TestCaseSource (typeof (TestDatabase), nameof (TestDatabase.PreserveDependenciesTests))]
public void PreserveDependenciesTests (TestCase testCase)
{