internal static ExactMethodMatcher GetMatcherFromTarget(InstrumentationTarget target)
{
string methodName = target.Target.Name;
var parameters = target.Target.Parameters;
string[] parameterTypeNames = null;
if (target.Target.ContainsGenericParameters)
{
var method = target.Target;
var genericArgs = method.GenericArguments;
// Match up the generic arguments to the parameter types as required
List<string> tempParamTypeNames = new List<string>();
foreach (var parameter in parameters)
{
if (parameter.Type.IsGenericType)
{
tempParamTypeNames.Add(GetGenericParameterTypeName(parameter.Type, genericArgs));
}
else if (parameter.Type.IsGenericParameter)
{
tempParamTypeNames.Add(string.Format("<{0}>", GetGenericParameterTypeName(parameter.Type, genericArgs)));
}
else
{
tempParamTypeNames.Add(GetFriendlyTypeName(parameter.Type));
}
}
parameterTypeNames = tempParamTypeNames.ToArray();
}
else
{
parameterTypeNames = (parameters ?? Enumerable.Empty<IParameterDetails>()).Select(x => GetFriendlyTypeName(x.Type)).ToArray();
}
// This is a kludge to compensate for a problem specifying parameters in the instrumentation file
// where a parameter is a closed generic with more than one generic type parameter - for example,
// Dictionary<string, int> or KeyValuePair<string, string>. To get around the problem, if we detect
// such a method, we'll just output a parameterless matcher definition. This has the negative side-effect
// that we'll inadvertently instrument all overloads of the method (if any exist), even if they don't
// match our instrumentation criteria
if (parameters != null && parameters.Any(x => x.Type.IsGenericType && x.Type.GenericArguments.Count() > 1))
{
parameterTypeNames = new string[0];
}
else if (parameters == null || !parameters.Any())
{
parameterTypeNames = new[]{ "void" };
}
return new ExactMethodMatcher(methodName, parameterTypeNames.ToArray());
}