public static MethodReference ImportCtorReference(this ModuleDefinition module, TypeReference type, TypeReference[] parameterTypes)
{
- var ctorKey = $"{type}.ctor({(parameterTypes == null ? "" : string.Join(",", parameterTypes.Select(tr => (tr.Scope.Name, tr.Namespace, tr.Name))))})";
+ var ctorKey = $"{type}.ctor({(parameterTypes == null ? "" : string.Join(",", parameterTypes.Select(SerializeTypeReference)))})";
if (MethodRefCache.TryGetValue((module, ctorKey), out var ctorRef))
return ctorRef;
ctorRef = module.ImportCtorReference(type, classArguments: null, predicate: md => {
public static MethodReference ImportCtorReference(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type, int paramCount, TypeReference[] classArguments)
{
- var ctorKey = $"{type}<{(string.Join(",", classArguments.Select(tr => (tr.Scope.Name, tr.Namespace, tr.Name))))}>.ctor({(string.Join(",", Enumerable.Repeat("_", paramCount)))})";
+ var ctorKey = $"{type}<{string.Join(",", classArguments.Select(SerializeTypeReference))}>.ctor({(string.Join(",", Enumerable.Repeat("_", paramCount)))})";
if (!MethodRefCache.TryGetValue((module, ctorKey), out var ctorRef))
MethodRefCache.Add((module, ctorKey), ctorRef = module.ImportCtorReference(module.GetTypeDefinition(type), classArguments, predicate: md => md.Parameters.Count == paramCount));
return ctorRef;
foreach (var property in typedef.BaseType.ResolveCached().Properties(true))
yield return property;
}
+
+ static string SerializeTypeReference(TypeReference tr)
+ {
+ var serialized = $"{tr.Scope.Name},{tr.Namespace},{tr.Name}";
+ var gitr = tr as GenericInstanceType;
+ return gitr == null ? serialized : $"{serialized}<{string.Join(",", gitr.GenericArguments.Select(SerializeTypeReference))}>";
+ }
}
}
\ No newline at end of file
--- /dev/null
+using System;
+using NUnit.Framework;
+using Mono.Cecil;
+using Xamarin.Forms.Build.Tasks;
+
+namespace Xamarin.Forms.XamlcUnitTests
+{
+ [TestFixture]
+ public class ModuleDefinitionExtensionsTests
+ {
+ class WithGenericInstanceCtorParameter
+ {
+ public WithGenericInstanceCtorParameter(Tuple<byte> argument)
+ {
+ }
+
+ public WithGenericInstanceCtorParameter(Tuple<short> argument)
+ {
+ }
+ }
+
+ ModuleDefinition module;
+
+ [SetUp]
+ public void SetUp()
+ {
+ var resolver = new XamlCAssemblyResolver();
+ resolver.AddAssembly(Uri.UnescapeDataString((new UriBuilder(typeof(ModuleDefinitionExtensionsTests).Assembly.CodeBase)).Path));
+ resolver.AddAssembly(Uri.UnescapeDataString((new UriBuilder(typeof(byte).Assembly.CodeBase)).Path));
+
+ module = ModuleDefinition.CreateModule("foo", new ModuleParameters {
+ AssemblyResolver = resolver,
+ Kind = ModuleKind.Dll
+ });
+ }
+
+ [Test]
+ public void TestImportCtorReferenceWithGenericInstanceCtorParameter()
+ {
+ var type = module.ImportReference(typeof(WithGenericInstanceCtorParameter));
+ var byteTuple = module.ImportReference(typeof(Tuple<byte>));
+ var byteTupleCtor = module.ImportCtorReference(type, new[] { byteTuple });
+ var int16Tuple = module.ImportReference(typeof(Tuple<short>));
+ var int16TupleCtor = module.ImportCtorReference(type, new[] { int16Tuple });
+
+ Assert.AreEqual("System.Tuple`1<System.Byte>", byteTupleCtor.Parameters[0].ParameterType.FullName);
+ Assert.AreEqual("System.Tuple`1<System.Int16>", int16TupleCtor.Parameters[0].ParameterType.FullName);
+ }
+
+ [Test]
+ public void TestImportCtorReferenceWithGenericInstanceTypeParameter()
+ {
+ var byteTuple = module.ImportReference(typeof(Tuple<byte>));
+ var byteTupleCtor = module.ImportCtorReference(("mscorlib", "System", "Tuple`1"), 1, new[] { byteTuple });
+ var in16Tuple = module.ImportReference(typeof(Tuple<short>));
+ var int16TupleCtor = module.ImportCtorReference(("mscorlib", "System", "Tuple`1"), 1, new[] { in16Tuple });
+
+ Assert.AreEqual("System.Tuple`1<System.Byte>", ((GenericInstanceType)byteTupleCtor.DeclaringType).GenericArguments[0].FullName);
+ Assert.AreEqual("System.Tuple`1<System.Int16>", ((GenericInstanceType)int16TupleCtor.DeclaringType).GenericArguments[0].FullName);
+ }
+ }
+}