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

github.com/mono/cecil.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJb Evain <jbevain@gmail.com>2015-07-07 19:53:04 +0300
committerJb Evain <jbevain@gmail.com>2015-07-07 19:53:04 +0300
commit9ba8f0215f4826f827c3ef0ce261974ce9402500 (patch)
treed0fd671b45f0c5dbcb275ecc862d3f1f604fa427
parent3654d4b9db4301dcaa07ca56c6acddd3799154e0 (diff)
Add support for resolving calls to vararg methods
-rw-r--r--Mono.Cecil/MetadataResolver.cs21
-rw-r--r--Test/Mono.Cecil.Tests/Linq.cs5
-rw-r--r--Test/Mono.Cecil.Tests/MethodTests.cs18
3 files changed, 37 insertions, 7 deletions
diff --git a/Mono.Cecil/MetadataResolver.cs b/Mono.Cecil/MetadataResolver.cs
index 97d3c00..70d9265 100644
--- a/Mono.Cecil/MetadataResolver.cs
+++ b/Mono.Cecil/MetadataResolver.cs
@@ -258,6 +258,12 @@ namespace Mono.Cecil {
if (!AreSame (method.ReturnType, reference.ReturnType))
continue;
+ if (method.IsVarArg () != reference.IsVarArg ())
+ continue;
+
+ if (method.IsVarArg () && IsVarArgCallTo (method, reference))
+ return method;
+
if (method.HasParameters != reference.HasParameters)
continue;
@@ -290,6 +296,21 @@ namespace Mono.Cecil {
return true;
}
+ private static bool IsVarArgCallTo (MethodDefinition method, MethodReference reference)
+ {
+ if (method.Parameters.Count >= reference.Parameters.Count)
+ return false;
+
+ if (reference.GetSentinelPosition () != method.Parameters.Count)
+ return false;
+
+ for (int i = 0; i < method.Parameters.Count; i++)
+ if (!AreSame (method.Parameters [i].ParameterType, reference.Parameters [i].ParameterType))
+ return false;
+
+ return true;
+ }
+
static bool AreSame (TypeSpecification a, TypeSpecification b)
{
if (!AreSame (a.ElementType, b.ElementType))
diff --git a/Test/Mono.Cecil.Tests/Linq.cs b/Test/Mono.Cecil.Tests/Linq.cs
index 4f870e0..d1fac18 100644
--- a/Test/Mono.Cecil.Tests/Linq.cs
+++ b/Test/Mono.Cecil.Tests/Linq.cs
@@ -41,6 +41,11 @@ namespace System.Linq {
return enumerator.Current;
}
}
+
+ public static T First<T> (this IEnumerable<T> self, Func<T, bool> predicate)
+ {
+ return self.Where (t => predicate (t)).First ();
+ }
}
}
diff --git a/Test/Mono.Cecil.Tests/MethodTests.cs b/Test/Mono.Cecil.Tests/MethodTests.cs
index bc76aa6..bbf1742 100644
--- a/Test/Mono.Cecil.Tests/MethodTests.cs
+++ b/Test/Mono.Cecil.Tests/MethodTests.cs
@@ -155,18 +155,22 @@ namespace Mono.Cecil.Tests {
Assert.IsTrue (bar.IsVarArg ());
Assert.IsFalse (baz.IsVarArg ());
- Assert.IsTrue(foo.IsVarArg ());
+ Assert.IsTrue (foo.IsVarArg ());
- var bar_reference = (MethodReference) baz.Body.Instructions.Where (i => i.Offset == 0x000a).First ().Operand;
+ var foo_reference = (MethodReference) baz.Body.Instructions.First (i => i.Offset == 0x000a).Operand;
- Assert.IsTrue (bar_reference.IsVarArg ());
- Assert.AreEqual (0, bar_reference.GetSentinelPosition ());
+ Assert.IsTrue (foo_reference.IsVarArg ());
+ Assert.AreEqual (0, foo_reference.GetSentinelPosition ());
- var foo_reference = (MethodReference) baz.Body.Instructions.Where (i => i.Offset == 0x0023).First ().Operand;
+ Assert.AreEqual (foo, foo_reference.Resolve ());
- Assert.IsTrue (foo_reference.IsVarArg ());
+ var bar_reference = (MethodReference) baz.Body.Instructions.First (i => i.Offset == 0x0023).Operand;
+
+ Assert.IsTrue (bar_reference.IsVarArg ());
+
+ Assert.AreEqual (1, bar_reference.GetSentinelPosition ());
- Assert.AreEqual (1, foo_reference.GetSentinelPosition ());
+ Assert.AreEqual (bar, bar_reference.Resolve ());
});
}