private void GetMethodInfo(ICSharpCode.NRefactory.CSharp.Expression expression, List<object> argumentValues, Type[] types, CodeContext codeContext, string invocation, object container, out MethodInfo methodInfo)
{
methodInfo = null;
if (expression is ICSharpCode.NRefactory.CSharp.IdentifierExpression)
{
methodInfo = container.GetType().GetMethod(invocation, types);
}
else if (expression is ICSharpCode.NRefactory.CSharp.MemberReferenceExpression)
{
ICSharpCode.NRefactory.CSharp.MemberReferenceExpression mre = expression as ICSharpCode.NRefactory.CSharp.MemberReferenceExpression;
bool doTypesHaveNull = false;
foreach (var item in types)
{
if (item == null)
{
doTypesHaveNull = true;
}
}
Type typeToCallGetMethodOn;
if (container is Type)
{
typeToCallGetMethodOn = (container as Type);
}
else if (container is TypeReference)
{
typeToCallGetMethodOn = (container as TypeReference).Type;
}
else
{
typeToCallGetMethodOn = container.GetType();
}
if (doTypesHaveNull)
{
// Let's hope there's no ambiguity or else we're in trouble...
methodInfo = typeToCallGetMethodOn.GetMethod(mre.MemberName);
}
else
{
bool shouldTryAgain = false; ;
try
{
methodInfo = typeToCallGetMethodOn.GetMethod(mre.MemberName, types);
}
catch
{
shouldTryAgain = true;
}
if(shouldTryAgain || methodInfo == null)
{
// The method doesn't exist, but it could be because
// the parser evaluated the types as one type (like int)
// but they are really of another type (like float).
var candidates = typeToCallGetMethodOn.GetMethods();
foreach (var candidate in candidates)
{
if (candidate.Name == mre.MemberName &&
candidate.GetParameters().Length == types.Length)
{
methodInfo = candidate;
break;
}
}
}
}
}
else if (expression is InvocationExpression)
{
InvocationExpression ie = expression as InvocationExpression;
if (container is Type)
{
methodInfo = (container as Type).GetMethod(ie.Target.GetText(), types);
}
else
{
methodInfo = container.GetType().GetMethod(ie.Target.GetText(), types);
}
}
else
{
throw new NotImplementedException();
}
}